[Midnightbsd-cvs] src [11254] trunk/contrib/ipfilter: upate

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jul 1 19:55:17 EDT 2018


Revision: 11254
          http://svnweb.midnightbsd.org/src/?rev=11254
Author:   laffer1
Date:     2018-07-01 19:55:17 -0400 (Sun, 01 Jul 2018)
Log Message:
-----------
upate

Added Paths:
-----------
    trunk/contrib/ipfilter/WhatsNew50.txt
    trunk/contrib/ipfilter/arc4random.c
    trunk/contrib/ipfilter/genmask.c
    trunk/contrib/ipfilter/ip_dstlist.c
    trunk/contrib/ipfilter/ip_dstlist.h
    trunk/contrib/ipfilter/ip_fil_compat.c
    trunk/contrib/ipfilter/ipf_rb.h
    trunk/contrib/ipfilter/lib/allocmbt.c
    trunk/contrib/ipfilter/lib/assigndefined.c
    trunk/contrib/ipfilter/lib/connecttcp.c
    trunk/contrib/ipfilter/lib/dupmbt.c
    trunk/contrib/ipfilter/lib/familyname.c
    trunk/contrib/ipfilter/lib/findword.c
    trunk/contrib/ipfilter/lib/freembt.c
    trunk/contrib/ipfilter/lib/ftov.c
    trunk/contrib/ipfilter/lib/geticmptype.c
    trunk/contrib/ipfilter/lib/icmptypename.c
    trunk/contrib/ipfilter/lib/icmptypes.c
    trunk/contrib/ipfilter/lib/interror.c
    trunk/contrib/ipfilter/lib/ipf_perror.c
    trunk/contrib/ipfilter/lib/load_dstlist.c
    trunk/contrib/ipfilter/lib/load_dstlistnode.c
    trunk/contrib/ipfilter/lib/mb_hexdump.c
    trunk/contrib/ipfilter/lib/msgdsize.c
    trunk/contrib/ipfilter/lib/parsefields.c
    trunk/contrib/ipfilter/lib/parseipfexpr.c
    trunk/contrib/ipfilter/lib/parsewhoisline.c
    trunk/contrib/ipfilter/lib/poolio.c
    trunk/contrib/ipfilter/lib/prependmbt.c
    trunk/contrib/ipfilter/lib/printactiveaddr.c
    trunk/contrib/ipfilter/lib/printaddr.c
    trunk/contrib/ipfilter/lib/printdstl_live.c
    trunk/contrib/ipfilter/lib/printdstlist.c
    trunk/contrib/ipfilter/lib/printdstlistdata.c
    trunk/contrib/ipfilter/lib/printdstlistnode.c
    trunk/contrib/ipfilter/lib/printdstlistpolicy.c
    trunk/contrib/ipfilter/lib/printfieldhdr.c
    trunk/contrib/ipfilter/lib/printhost.c
    trunk/contrib/ipfilter/lib/printipfexpr.c
    trunk/contrib/ipfilter/lib/printiphdr.c
    trunk/contrib/ipfilter/lib/printlookup.c
    trunk/contrib/ipfilter/lib/printnataddr.c
    trunk/contrib/ipfilter/lib/printnatfield.c
    trunk/contrib/ipfilter/lib/printnatside.c
    trunk/contrib/ipfilter/lib/printpoolfield.c
    trunk/contrib/ipfilter/lib/printstatefields.c
    trunk/contrib/ipfilter/lib/printtcpflags.c
    trunk/contrib/ipfilter/lib/printunit.c
    trunk/contrib/ipfilter/lib/save_execute.c
    trunk/contrib/ipfilter/lib/save_file.c
    trunk/contrib/ipfilter/lib/save_nothing.c
    trunk/contrib/ipfilter/lib/save_syslog.c
    trunk/contrib/ipfilter/lib/save_v1trap.c
    trunk/contrib/ipfilter/lib/save_v2trap.c
    trunk/contrib/ipfilter/lib/vtof.c
    trunk/contrib/ipfilter/ml_ipl.c
    trunk/contrib/ipfilter/mlfk_ipl.c
    trunk/contrib/ipfilter/mli_ipl.c
    trunk/contrib/ipfilter/mln_ipl.c
    trunk/contrib/ipfilter/mln_rule.c
    trunk/contrib/ipfilter/mlo_ipl.c
    trunk/contrib/ipfilter/mlo_rule.c
    trunk/contrib/ipfilter/mls_ipl.c
    trunk/contrib/ipfilter/mls_rule.c
    trunk/contrib/ipfilter/mlso_rule.c
    trunk/contrib/ipfilter/radix_ipf.c
    trunk/contrib/ipfilter/sys/
    trunk/contrib/ipfilter/sys/tree.h
    trunk/contrib/ipfilter/tools/ipfsyncd.c

Added: trunk/contrib/ipfilter/WhatsNew50.txt
===================================================================
--- trunk/contrib/ipfilter/WhatsNew50.txt	                        (rev 0)
+++ trunk/contrib/ipfilter/WhatsNew50.txt	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,83 @@
+What's new in 5.1
+=================
+
+General
+-------
+* all of the tuneables can now be set at any time, not just whilst disabled
+  or prior to loading rules;
+
+* group identifiers may now be a number or name (universal);
+
+* man pages rewritten
+
+* tunables can now be set via ipf.conf;
+
+Logging
+-------
+* ipmon.conf can now be used to generate SNMPv1 and SNMPv2 traps using
+  information from log entries from the kernel;
+
+NAT changes
+-----------
+* DNS proxy for the kernel that can block queries based on domain names;        
+
+* FTP proxy can be configured to limit data connections to one or many
+  connections per client;
+
+* NAT on IPv6 is now supported;
+
+* rewrite command allows changing both the source and destination address
+  in a single NAT rule;
+
+* simple encapsulation can now be configured with ipnat.conf,
+
+* TFTP proxy now included;
+
+Packet Filtering
+----------------
+* acceptance of ICMP packets for "keep state" rules can be refined through
+  the use of filtering rules;
+
+* alternative form for writing rules using simple filtering expressions;
+
+* CIPSO headers now recognised and analysed for filtering on DOI;
+
+* comments can now be a part of a rule and loaded into the kernel and
+  thus displayed with ipfstat;
+
+* decapsulation rules allow filtering on inner headers, providing they
+  are not encrypted;
+
+* interface names, aside from that the packet is on, can be present in
+  filter rules;
+
+* internally now a single list of filter rules, there is no longer an
+  IPv4 and IPv6 list;
+
+* rules can now be added with an expiration time, allowing for their
+  automatic removal after some period of time;
+
+* single file, ipf.conf, can now be used for both IPv4 and IPv6 rules;
+
+* stateful filtering now allows for limits to be placed on the number
+  of distinct hosts allowed per rule;
+
+Pools
+-----
+* addresses added to a pool via the command line (only!) can be given
+  an expiration timeout;
+
+* destination lists are a new type of address pool, primarily for use with
+  NAT rdr rules, supporting newer algorithms for target selection;
+
+* raw whois information saved to a file can be used to populate a pool;
+
+Solaris
+-------
+* support for use in zones with exclusive IP instances fully supported.
+
+Tools
+-----
+* use of matching expressions allows for refining what is displayed or
+  flushed;
+


Property changes on: trunk/contrib/ipfilter/WhatsNew50.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/arc4random.c
===================================================================
--- trunk/contrib/ipfilter/arc4random.c	                        (rev 0)
+++ trunk/contrib/ipfilter/arc4random.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,277 @@
+/*-
+ * THE BEER-WARE LICENSE
+ *
+ * <dan at FreeBSD.ORG> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff.  If we meet some day, and you
+ * think this stuff is worth it, you can buy me a beer in return.
+ *
+ * Dan Moschuk
+ */
+#if !defined(SOLARIS2) && !defined(__osf__)
+# include <sys/cdefs.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef __FreeBSD__
+# include <sys/kernel.h>
+#endif
+#if !defined(__osf__)
+# include <sys/random.h>
+#endif
+#ifdef __FreeBSD__
+# include <sys/libkern.h>
+#endif
+#include <sys/lock.h>
+#ifndef __osf__
+# include <sys/mutex.h>
+#endif
+#include <sys/time.h>
+
+#if defined(SOLARIS2) && (SOLARIS2 < 9)
+# include <netinet/in_systm.h>
+#endif
+#include <sys/socket.h>
+#include <net/if.h>
+#ifdef __osf__
+# include <net/route.h>
+#endif
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include "netinet/ip_compat.h"
+#ifdef HAS_SYS_MD5_H
+# include <sys/md5.h>
+#else
+# include "md5.h"
+#endif
+
+#ifdef NEED_LOCAL_RAND
+#if !defined(__GNUC__)
+# define __inline
+#endif
+
+#define	ARC4_RESEED_BYTES 65536
+#define	ARC4_RESEED_SECONDS 300
+#define	ARC4_KEYBYTES (256 / 8)
+
+static u_int8_t arc4_i, arc4_j;
+static int arc4_numruns = 0;
+static u_int8_t arc4_sbox[256];
+static time_t arc4_t_reseed;
+static ipfmutex_t arc4_mtx;
+static MD5_CTX md5ctx;
+
+static u_int8_t arc4_randbyte(void);
+static int ipf_read_random(void *dest, int length);
+
+static __inline void
+arc4_swap(u_int8_t *a, u_int8_t *b)
+{
+	u_int8_t c;
+
+	c = *a;
+	*a = *b;
+	*b = c;
+}
+
+/*
+ * Stir our S-box.
+ */
+static void
+arc4_randomstir (void)
+{
+	u_int8_t key[256];
+	int r, n;
+	struct timeval tv_now;
+
+	/*
+	 * XXX read_random() returns unsafe numbers if the entropy
+	 * device is not loaded -- MarkM.
+	 */
+	r = ipf_read_random(key, ARC4_KEYBYTES);
+	GETKTIME(&tv_now);
+	MUTEX_ENTER(&arc4_mtx);
+	/* If r == 0 || -1, just use what was on the stack. */
+	if (r > 0) {
+		for (n = r; n < sizeof(key); n++)
+			key[n] = key[n % r];
+	}
+
+	for (n = 0; n < 256; n++) {
+		arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
+		arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
+	}
+
+	/* Reset for next reseed cycle. */
+	arc4_t_reseed = tv_now.tv_sec + ARC4_RESEED_SECONDS;
+	arc4_numruns = 0;
+
+	/*
+	 * Throw away the first N words of output, as suggested in the
+	 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
+	 * by Fluher, Mantin, and Shamir.  (N = 768 in our case.)
+	 */
+	for (n = 0; n < 768*4; n++)
+		arc4_randbyte();
+	MUTEX_EXIT(&arc4_mtx);
+}
+
+/*
+ * Initialize our S-box to its beginning defaults.
+ */
+static void
+arc4_init(void)
+{
+	int n;
+
+	MD5Init(&md5ctx);
+
+	MUTEX_INIT(&arc4_mtx, "arc4_mtx");
+	arc4_i = arc4_j = 0;
+	for (n = 0; n < 256; n++)
+		arc4_sbox[n] = (u_int8_t) n;
+
+	arc4_t_reseed = 0;
+}
+
+
+/*
+ * Generate a random byte.
+ */
+static u_int8_t
+arc4_randbyte(void)
+{
+	u_int8_t arc4_t;
+
+	arc4_i = (arc4_i + 1) % 256;
+	arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256;
+
+	arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]);
+
+	arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256;
+	return arc4_sbox[arc4_t];
+}
+
+/*
+ * MPSAFE
+ */
+void
+arc4rand(void *ptr, u_int len, int reseed)
+{
+	u_int8_t *p;
+	struct timeval tv;
+
+	GETKTIME(&tv);
+	if (reseed ||
+	   (arc4_numruns > ARC4_RESEED_BYTES) ||
+	   (tv.tv_sec > arc4_t_reseed))
+		arc4_randomstir();
+
+	MUTEX_ENTER(&arc4_mtx);
+	arc4_numruns += len;
+	p = ptr;
+	while (len--)
+		*p++ = arc4_randbyte();
+	MUTEX_EXIT(&arc4_mtx);
+}
+
+uint32_t
+ipf_random(void)
+{
+	uint32_t ret;
+
+	arc4rand(&ret, sizeof ret, 0);
+	return ret;
+}
+
+
+static u_char pot[ARC4_RESEED_BYTES];
+static u_char *pothead = pot, *pottail = pot;
+static int inpot = 0;
+
+/*
+ * This is not very strong, and this is understood, but the aim isn't to
+ * be cryptographically strong - it is just to make up something that is
+ * pseudo random.
+ */
+void
+ipf_rand_push(void *src, int length)
+{
+	static int arc4_inited = 0;
+	u_char *nsrc;
+	int mylen;
+
+	if (arc4_inited == 0) {
+		arc4_init();
+		arc4_inited = 1;
+	}
+
+	if (length < 64) {
+		MD5Update(&md5ctx, src, length);
+		return;
+	}
+
+	nsrc = src;
+	mylen = length;
+
+#if defined(_SYS_MD5_H) && defined(SOLARIS2)
+# define	buf	buf_un.buf8
+#endif
+	MUTEX_ENTER(&arc4_mtx);
+	while ((mylen > 64)  && (sizeof(pot) - inpot > sizeof(md5ctx.buf))) {
+		MD5Update(&md5ctx, nsrc, 64);
+		mylen -= 64;
+		nsrc += 64;
+		if (pottail + sizeof(md5ctx.buf) > pot + sizeof(pot)) {
+			int left, numbytes;
+
+			numbytes = pot + sizeof(pot) - pottail;
+			bcopy(md5ctx.buf, pottail, numbytes);
+			left = sizeof(md5ctx.buf) - numbytes;
+			pottail = pot;
+			bcopy(md5ctx.buf + sizeof(md5ctx.buf) - left,
+			      pottail, left);
+			pottail += left;
+		} else {
+			bcopy(md5ctx.buf, pottail, sizeof(md5ctx.buf));
+			pottail += sizeof(md5ctx.buf);
+		}
+		inpot += 64;
+	}
+	MUTEX_EXIT(&arc4_mtx);
+#if defined(_SYS_MD5_H) && defined(SOLARIS2)
+# undef buf
+#endif
+}
+
+
+static int
+ipf_read_random(void *dest, int length)
+{
+	if (length > inpot)
+		return 0;
+
+	MUTEX_ENTER(&arc4_mtx);
+	if (pothead + length > pot + sizeof(pot)) {
+		int left, numbytes;
+
+		left = length;
+		numbytes = pot + sizeof(pot) - pothead;
+		bcopy(pothead, dest, numbytes);
+		left -= numbytes;
+		pothead = pot;
+		bcopy(pothead, dest + length - left, left);
+		pothead += left;
+	} else {
+		bcopy(pothead, dest, length);
+		pothead += length;
+	}
+	inpot -= length;
+	if (inpot == 0)
+		pothead = pottail = pot;
+	MUTEX_EXIT(&arc4_mtx);
+
+	return length;
+}
+
+#endif /* NEED_LOCAL_RAND */


Property changes on: trunk/contrib/ipfilter/arc4random.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/genmask.c
===================================================================
--- trunk/contrib/ipfilter/genmask.c	                        (rev 0)
+++ trunk/contrib/ipfilter/genmask.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+
+#include "ipf.h"
+
+
+int genmask(family, msk, mskp)
+	int family;
+	char *msk;
+	i6addr_t *mskp;
+{
+	char *endptr = 0L;
+	u_32_t addr;
+	int bits;
+
+	if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) {
+		/* possibly of the form xxx.xxx.xxx.xxx
+		 * or 0xYYYYYYYY */
+		switch (family)
+		{
+#ifdef USE_INET6
+		case AF_INET6 :
+			if (inet_pton(AF_INET6, msk, &mskp->in4) != 1)
+				return -1;
+			break;
+#endif
+		case AF_INET :
+			if (inet_aton(msk, &mskp->in4) == 0)
+				return -1;
+			break;
+		default :
+			return -1;
+			/*NOTREACHED*/
+		}
+	} else {
+		/*
+		 * set x most significant bits
+		 */
+		bits = (int)strtol(msk, &endptr, 0);
+
+		switch (family)
+		{
+		case AF_INET6 :
+			if ((*endptr != '\0') || (bits < 0) || (bits > 128))
+				return -1;
+			fill6bits(bits, mskp->i6);
+			break;
+		case AF_INET :
+			if (*endptr != '\0' || bits > 32 || bits < 0)
+				return -1;
+			if (bits == 0)
+				addr = 0;
+			else
+				addr = htonl(0xffffffff << (32 - bits));
+			mskp->in4.s_addr = addr;
+			break;
+		default :
+			return -1;
+			/*NOTREACHED*/
+		}
+	}
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/genmask.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/ip_dstlist.c
===================================================================
--- trunk/contrib/ipfilter/ip_dstlist.c	                        (rev 0)
+++ trunk/contrib/ipfilter/ip_dstlist.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#if defined(KERNEL) || defined(_KERNEL)
+# undef KERNEL
+# undef _KERNEL
+# define        KERNEL	1
+# define        _KERNEL	1
+#endif
+#if defined(__osf__)
+# define _PROTO_NET_H_
+#endif
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#if !defined(_KERNEL) && !defined(__KERNEL__)
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# define _KERNEL
+# ifdef __OpenBSD__
+struct file;
+# endif
+# include <sys/uio.h>
+# undef _KERNEL
+#else
+# include <sys/systm.h>
+# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000)
+#  include <sys/proc.h>
+# endif
+#endif
+#include <sys/time.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
+#include <sys/socket.h>
+#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__))
+# include <sys/mbuf.h>
+#endif
+#if defined(__SVR4) || defined(__svr4__)
+# include <sys/filio.h>
+# include <sys/byteorder.h>
+# ifdef _KERNEL
+#  include <sys/dditypes.h>
+# endif
+# include <sys/stream.h>
+# include <sys/kmem.h>
+#endif
+#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
+# include <sys/malloc.h>
+#endif
+
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_dstlist.h"
+
+/* END OF INCLUDES */
+
+#ifdef HAS_SYS_MD5_H
+# include <sys/md5.h>
+#else
+# include "md5.h"
+#endif
+
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_dstlist.c,v 1.13.2.12 2012/07/20 08:40:19 darren_r Exp $";
+#endif
+
+typedef struct ipf_dstl_softc_s {
+	ippool_dst_t	*dstlist[LOOKUP_POOL_SZ];
+	ippool_dst_t	**tails[LOOKUP_POOL_SZ];
+	ipf_dstl_stat_t	stats;
+} ipf_dstl_softc_t;
+
+
+static void *ipf_dstlist_soft_create __P((ipf_main_softc_t *));
+static void ipf_dstlist_soft_destroy __P((ipf_main_softc_t *, void *));
+static int ipf_dstlist_soft_init __P((ipf_main_softc_t *, void *));
+static void ipf_dstlist_soft_fini __P((ipf_main_softc_t *, void *));
+static int ipf_dstlist_addr_find __P((ipf_main_softc_t *, void *, int,
+				      void *, u_int));
+static size_t ipf_dstlist_flush __P((ipf_main_softc_t *, void *,
+				     iplookupflush_t *));
+static int ipf_dstlist_iter_deref __P((ipf_main_softc_t *, void *, int, int,
+				       void *));
+static int ipf_dstlist_iter_next __P((ipf_main_softc_t *, void *, ipftoken_t *,
+				      ipflookupiter_t *));
+static int ipf_dstlist_node_add __P((ipf_main_softc_t *, void *,
+				     iplookupop_t *, int));
+static int ipf_dstlist_node_del __P((ipf_main_softc_t *, void *,
+				     iplookupop_t *, int));
+static int ipf_dstlist_stats_get __P((ipf_main_softc_t *, void *,
+				      iplookupop_t *));
+static int ipf_dstlist_table_add __P((ipf_main_softc_t *, void *,
+				      iplookupop_t *));
+static int ipf_dstlist_table_del __P((ipf_main_softc_t *, void *,
+				      iplookupop_t *));
+static int ipf_dstlist_table_deref __P((ipf_main_softc_t *, void *, void *));
+static void *ipf_dstlist_table_find __P((void *, int, char *));
+static void ipf_dstlist_table_free __P((ipf_dstl_softc_t *, ippool_dst_t *));
+static void ipf_dstlist_table_remove __P((ipf_main_softc_t *,
+					  ipf_dstl_softc_t *, ippool_dst_t *));
+static void ipf_dstlist_table_clearnodes __P((ipf_dstl_softc_t *,
+					      ippool_dst_t *));
+static ipf_dstnode_t *ipf_dstlist_select __P((fr_info_t *, ippool_dst_t *));
+static void *ipf_dstlist_select_ref __P((void *, int, char *));
+static void ipf_dstlist_node_free __P((ipf_dstl_softc_t *, ippool_dst_t *, ipf_dstnode_t *));
+static int ipf_dstlist_node_deref __P((void *, ipf_dstnode_t *));
+static void ipf_dstlist_expire __P((ipf_main_softc_t *, void *));
+static void ipf_dstlist_sync __P((ipf_main_softc_t *, void *));
+
+ipf_lookup_t ipf_dstlist_backend = {
+	IPLT_DSTLIST,
+	ipf_dstlist_soft_create,
+	ipf_dstlist_soft_destroy,
+	ipf_dstlist_soft_init,
+	ipf_dstlist_soft_fini,
+	ipf_dstlist_addr_find,
+	ipf_dstlist_flush,
+	ipf_dstlist_iter_deref,
+	ipf_dstlist_iter_next,
+	ipf_dstlist_node_add,
+	ipf_dstlist_node_del,
+	ipf_dstlist_stats_get,
+	ipf_dstlist_table_add,
+	ipf_dstlist_table_del,
+	ipf_dstlist_table_deref,
+	ipf_dstlist_table_find,
+	ipf_dstlist_select_ref,
+	ipf_dstlist_select_node,
+	ipf_dstlist_expire,
+	ipf_dstlist_sync
+};
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_soft_create                                     */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*                                                                          */
+/* Allocating a chunk of memory filled with 0's is enough for the current   */
+/* soft context used with destination lists.                                */
+/* ------------------------------------------------------------------------ */
+static void *
+ipf_dstlist_soft_create(softc)
+	ipf_main_softc_t *softc;
+{
+	ipf_dstl_softc_t *softd;
+	int i;
+
+	KMALLOC(softd, ipf_dstl_softc_t *);
+	if (softd == NULL) {
+		IPFERROR(120028);
+		return NULL;
+	}
+
+	bzero((char *)softd, sizeof(*softd));
+	for (i = 0; i <= IPL_LOGMAX; i++)
+		softd->tails[i] = &softd->dstlist[i];
+
+	return softd;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_soft_destroy                                    */
+/* Returns:     Nil                                                         */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*                                                                          */
+/* For destination lists, the only thing we have to do when destroying the  */
+/* soft context is free it!                                                 */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_soft_destroy(softc, arg)
+	ipf_main_softc_t *softc;
+	void *arg;
+{
+	ipf_dstl_softc_t *softd = arg;
+
+	KFREE(softd);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_soft_init                                       */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*                                                                          */
+/* There is currently no soft context for destination list management.      */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_soft_init(softc, arg)
+	ipf_main_softc_t *softc;
+	void *arg;
+{
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_soft_fini                                       */
+/* Returns:     Nil                                                         */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*                                                                          */
+/* There is currently no soft context for destination list management.      */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_soft_fini(softc, arg)
+	ipf_main_softc_t *softc;
+	void *arg;
+{
+	ipf_dstl_softc_t *softd = arg;
+	int i;
+
+	for (i = -1; i <= IPL_LOGMAX; i++) {
+		while (softd->dstlist[i + 1] != NULL) {
+			ipf_dstlist_table_remove(softc, softd,
+						 softd->dstlist[i + 1]);
+		}
+	}
+
+	ASSERT(softd->stats.ipls_numderefnodes == 0);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_addr_find                                       */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg1(I)  - pointer to local context to use                  */
+/*              arg2(I)  - pointer to local context to use                  */
+/*              arg3(I)  - pointer to local context to use                  */
+/*              arg4(I)  - pointer to local context to use                  */
+/*                                                                          */
+/* There is currently no such thing as searching a destination list for an  */
+/* address so this function becomes a no-op. Its presence is required as    */
+/* ipf_lookup_res_name() stores the "addr_find" function pointer in the     */
+/* pointer passed in to it as funcptr, although it could be a generic null- */
+/* op function rather than a specific one.                                  */
+/* ------------------------------------------------------------------------ */
+/*ARGSUSED*/
+static int
+ipf_dstlist_addr_find(softc, arg1, arg2, arg3, arg4)
+	ipf_main_softc_t *softc;
+	void *arg1, *arg3;
+	int arg2;
+	u_int arg4;
+{
+	return -1;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_flush                                           */
+/* Returns:     int      - number of objects deleted                        */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              fop(I)   - pointer to lookup flush operation data           */
+/*                                                                          */
+/* Flush all of the destination tables that match the data passed in with   */
+/* the iplookupflush_t. There are two ways to match objects: the device for */
+/* which they are to be used with and their name.                           */
+/* ------------------------------------------------------------------------ */
+static size_t
+ipf_dstlist_flush(softc, arg, fop)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupflush_t *fop;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ippool_dst_t *node, *next;
+	int n, i;
+
+	for (n = 0, i = -1; i <= IPL_LOGMAX; i++) {
+		if (fop->iplf_unit != IPLT_ALL && fop->iplf_unit != i)
+			continue;
+		for (node = softd->dstlist[i + 1]; node != NULL; node = next) {
+			next = node->ipld_next;
+
+			if ((*fop->iplf_name != '\0') &&
+			    strncmp(fop->iplf_name, node->ipld_name,
+				    FR_GROUPLEN))
+				continue;
+
+			ipf_dstlist_table_remove(softc, softd, node);
+			n++;
+		}
+	}
+	return n;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_iter_deref                                      */
+/* Returns:     int      - 0 = success, else error                          */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              otype(I) - type of data structure to iterate through        */
+/*              unit(I)  - device we are working with                       */
+/*              data(I)  - address of object in kernel space                */
+/*                                                                          */
+/* This function is called when the iteration token is being free'd and is  */
+/* responsible for dropping the reference count of the structure it points  */
+/* to.                                                                      */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_iter_deref(softc, arg, otype, unit, data)
+	ipf_main_softc_t *softc;
+	void *arg;
+	int otype, unit;
+	void *data;
+{
+	if (data == NULL) {
+		IPFERROR(120001);
+		return EINVAL;
+	}
+
+	if (unit < -1 || unit > IPL_LOGMAX) {
+		IPFERROR(120002);
+		return EINVAL;
+	}
+
+	switch (otype)
+	{
+	case IPFLOOKUPITER_LIST :
+		ipf_dstlist_table_deref(softc, arg, (ippool_dst_t *)data);
+		break;
+
+	case IPFLOOKUPITER_NODE :
+		ipf_dstlist_node_deref(arg, (ipf_dstnode_t *)data);
+		break;
+	}
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_iter_next                                       */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*              uid(I)   - uid of process doing the ioctl                   */
+/*                                                                          */
+/* This function is responsible for either selecting the next destination   */
+/* list or node on a destination list to be returned as a user process      */
+/* iterates through the list of destination lists or nodes.                 */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_iter_next(softc, arg, token, iter)
+	ipf_main_softc_t *softc;
+	void *arg;
+	ipftoken_t *token;
+	ipflookupiter_t *iter;
+{
+	ipf_dstnode_t zn, *nextnode = NULL, *node = NULL;
+	ippool_dst_t zero, *next = NULL, *dsttab = NULL;
+	ipf_dstl_softc_t *softd = arg;
+	int err = 0;
+	void *hint;
+
+	switch (iter->ili_otype)
+	{
+	case IPFLOOKUPITER_LIST :
+		dsttab = token->ipt_data;
+		if (dsttab == NULL) {
+			next = softd->dstlist[(int)iter->ili_unit + 1];
+		} else {
+			next = dsttab->ipld_next;
+		}
+
+		if (next != NULL) {
+			ATOMIC_INC32(next->ipld_ref);
+			token->ipt_data = next;
+			hint = next->ipld_next;
+		} else {
+			bzero((char *)&zero, sizeof(zero));
+			next = &zero;
+			token->ipt_data = NULL;
+			hint = NULL;
+		}
+		break;
+
+	case IPFLOOKUPITER_NODE :
+		node = token->ipt_data;
+		if (node == NULL) {
+			dsttab = ipf_dstlist_table_find(arg, iter->ili_unit,
+							iter->ili_name);
+			if (dsttab == NULL) {
+				IPFERROR(120004);
+				err = ESRCH;
+				nextnode = NULL;
+			} else {
+				if (dsttab->ipld_dests == NULL)
+					nextnode = NULL;
+				else
+					nextnode = *dsttab->ipld_dests;
+				dsttab = NULL;
+			}
+		} else {
+			nextnode = node->ipfd_next;
+		}
+
+		if (nextnode != NULL) {
+			MUTEX_ENTER(&nextnode->ipfd_lock);
+			nextnode->ipfd_ref++;
+			MUTEX_EXIT(&nextnode->ipfd_lock);
+			token->ipt_data = nextnode;
+			hint = nextnode->ipfd_next;
+		} else {
+			bzero((char *)&zn, sizeof(zn));
+			nextnode = &zn;
+			token->ipt_data = NULL;
+			hint = NULL;
+		}
+		break;
+	default :
+		IPFERROR(120003);
+		err = EINVAL;
+		break;
+	}
+
+	if (err != 0)
+		return err;
+
+	switch (iter->ili_otype)
+	{
+	case IPFLOOKUPITER_LIST :
+		if (dsttab != NULL)
+			ipf_dstlist_table_deref(softc, arg, dsttab);
+		err = COPYOUT(next, iter->ili_data, sizeof(*next));
+		if (err != 0) {
+			IPFERROR(120005);
+			err = EFAULT;
+		}
+		break;
+
+	case IPFLOOKUPITER_NODE :
+		if (node != NULL)
+			ipf_dstlist_node_deref(arg, node);
+		err = COPYOUT(nextnode, iter->ili_data, sizeof(*nextnode));
+		if (err != 0) {
+			IPFERROR(120006);
+			err = EFAULT;
+		}
+		break;
+	}
+
+	if (hint == NULL)
+		ipf_token_mark_complete(token);
+
+	return err;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_node_add                                        */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*              uid(I)   - uid of process doing the ioctl                   */
+/* Locks:       WRITE(ipf_poolrw)                                           */
+/*                                                                          */
+/* Add a new node to a destination list. To do this, we only copy in the    */
+/* frdest_t structure because that contains the only data required from the */
+/* application to create a new node. The frdest_t doesn't contain the name  */
+/* itself. When loading filter rules, fd_name is a 'pointer' to the name.   */
+/* In this case, the 'pointer' does not work, instead it is the length of   */
+/* the name and the name is immediately following the frdest_t structure.   */
+/* fd_name must include the trailing \0, so it should be strlen(str) + 1.   */
+/* For simple sanity checking, an upper bound on the size of fd_name is     */
+/* imposed - 128.                                                          */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_node_add(softc, arg, op, uid)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupop_t *op;
+	int uid;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ipf_dstnode_t *node, **nodes;
+	ippool_dst_t *d;
+	frdest_t dest;
+	int err;
+
+	if (op->iplo_size < sizeof(frdest_t)) {
+		IPFERROR(120007);
+		return EINVAL;
+	}
+
+	err = COPYIN(op->iplo_struct, &dest, sizeof(dest));
+	if (err != 0) {
+		IPFERROR(120009);
+		return EFAULT;
+	}
+
+	d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name);
+	if (d == NULL) {
+		IPFERROR(120010);
+		return ESRCH;
+	}
+
+	switch (dest.fd_addr.adf_family)
+	{
+	case AF_INET :
+	case AF_INET6 :
+		break;
+	default :
+		IPFERROR(120019);
+		return EINVAL;
+	}
+
+	if (dest.fd_name < -1 || dest.fd_name > 128) {
+		IPFERROR(120018);
+		return EINVAL;
+	}
+
+	KMALLOCS(node, ipf_dstnode_t *, sizeof(*node) + dest.fd_name);
+	if (node == NULL) {
+		softd->stats.ipls_nomem++;
+		IPFERROR(120008);
+		return ENOMEM;
+	}
+	bzero((char *)node, sizeof(*node) + dest.fd_name);
+
+	bcopy(&dest, &node->ipfd_dest, sizeof(dest));
+	node->ipfd_size = sizeof(*node) + dest.fd_name;
+
+	if (dest.fd_name > 0) {
+		/*
+		 * fd_name starts out as the length of the string to copy
+		 * in (including \0) and ends up being the offset from
+		 * fd_names (0).
+		 */
+		err = COPYIN((char *)op->iplo_struct + sizeof(dest),
+			     node->ipfd_names, dest.fd_name);
+		if (err != 0) {
+			IPFERROR(120017);
+			KFREES(node, node->ipfd_size);
+			return EFAULT;
+		}
+		node->ipfd_dest.fd_name = 0;
+	} else {
+		node->ipfd_dest.fd_name = -1;
+	}
+
+	if (d->ipld_nodes == d->ipld_maxnodes) {
+		KMALLOCS(nodes, ipf_dstnode_t **,
+			 sizeof(*nodes) * (d->ipld_maxnodes + 1));
+		if (nodes == NULL) {
+			softd->stats.ipls_nomem++;
+			IPFERROR(120022);
+			KFREES(node, node->ipfd_size);
+			return ENOMEM;
+		}
+		if (d->ipld_dests != NULL) {
+			bcopy(d->ipld_dests, nodes,
+			      sizeof(*nodes) * d->ipld_maxnodes);
+			KFREES(d->ipld_dests, sizeof(*nodes) * d->ipld_nodes);
+			nodes[0]->ipfd_pnext = nodes;
+		}
+		d->ipld_dests = nodes;
+		d->ipld_maxnodes++;
+	}
+	d->ipld_dests[d->ipld_nodes] = node;
+	d->ipld_nodes++;
+
+	if (d->ipld_nodes == 1) {
+		node->ipfd_pnext = d->ipld_dests;
+	} else if (d->ipld_nodes > 1) {
+		node->ipfd_pnext = &d->ipld_dests[d->ipld_nodes - 2]->ipfd_next;
+	}
+	*node->ipfd_pnext = node;
+
+	MUTEX_INIT(&node->ipfd_lock, "ipf dst node lock");
+	node->ipfd_uid = uid;
+	node->ipfd_ref = 1;
+	if (node->ipfd_dest.fd_name == 0)
+		(void) ipf_resolvedest(softc, node->ipfd_names,
+				       &node->ipfd_dest, AF_INET);
+#ifdef USE_INET6
+	if (node->ipfd_dest.fd_name == 0 &&
+	    node->ipfd_dest.fd_ptr == (void *)-1)
+		(void) ipf_resolvedest(softc, node->ipfd_names,
+				       &node->ipfd_dest, AF_INET6);
+#endif
+
+	softd->stats.ipls_numnodes++;
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_node_deref                                      */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  arg(I)  - pointer to local context to use                   */
+/*              node(I) - pointer to destionation node to free              */
+/*                                                                          */
+/* Dereference the use count by one. If it drops to zero then we can assume */
+/* that it has been removed from any lists/tables and is ripe for freeing.  */
+/* The pointer to context is required for the purpose of maintaining        */
+/* statistics.                                                              */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_node_deref(arg, node)
+	void *arg;
+	ipf_dstnode_t *node;
+{
+	ipf_dstl_softc_t *softd = arg;
+	int ref;
+
+	MUTEX_ENTER(&node->ipfd_lock);
+	ref = --node->ipfd_ref;
+	MUTEX_EXIT(&node->ipfd_lock);
+
+	if (ref > 0)
+		return 0;
+
+	if ((node->ipfd_flags & IPDST_DELETE) != 0)
+		softd->stats.ipls_numderefnodes--;
+	MUTEX_DESTROY(&node->ipfd_lock);
+	KFREES(node, node->ipfd_size);
+	softd->stats.ipls_numnodes--;
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_node_del                                        */
+/* Returns:     int      - 0 = success, else error                          */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*              uid(I)   - uid of process doing the ioctl                   */
+/*                                                                          */
+/* Look for a matching destination node on the named table and free it if   */
+/* found. Because the name embedded in the frdest_t is variable in length,  */
+/* it is necessary to allocate some memory locally, to complete this op.    */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_node_del(softc, arg, op, uid)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupop_t *op;
+	int uid;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ipf_dstnode_t *node;
+	frdest_t frd, *temp;
+	ippool_dst_t *d;
+	size_t size;
+	int err;
+
+	d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name);
+	if (d == NULL) {
+		IPFERROR(120012);
+		return ESRCH;
+	}
+
+	err = COPYIN(op->iplo_struct, &frd, sizeof(frd));
+	if (err != 0) {
+		IPFERROR(120011);
+		return EFAULT;
+	}
+
+	size = sizeof(*temp) + frd.fd_name;
+	KMALLOCS(temp, frdest_t *, size);
+	if (temp == NULL) {
+		softd->stats.ipls_nomem++;
+		IPFERROR(120026);
+		return ENOMEM;
+	}
+
+	err = COPYIN(op->iplo_struct, temp, size);
+	if (err != 0) {
+		IPFERROR(120027);
+		return EFAULT;
+	}
+
+	MUTEX_ENTER(&d->ipld_lock);
+	for (node = *d->ipld_dests; node != NULL; node = node->ipfd_next) {
+		if ((uid != 0) && (node->ipfd_uid != uid))
+			continue;
+		if (node->ipfd_size != size)
+			continue;
+		if (!bcmp(&node->ipfd_dest.fd_ip6, &frd.fd_ip6,
+			  size - offsetof(frdest_t, fd_ip6))) {
+			ipf_dstlist_node_free(softd, d, node);
+			MUTEX_EXIT(&d->ipld_lock);
+			KFREES(temp, size);
+			return 0;
+		}
+	}
+	MUTEX_EXIT(&d->ipld_lock);
+	KFREES(temp, size);
+
+	return ESRCH;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_node_free                                       */
+/* Returns:     Nil                                                         */
+/* Parameters:  softd(I) - pointer to the destination list context          */
+/*              d(I)     - pointer to destination list                      */
+/*              node(I)  - pointer to node to free                          */
+/* Locks:       MUTEX(ipld_lock) or WRITE(ipf_poolrw)                       */
+/*                                                                          */
+/* Free the destination node by first removing it from any lists and then   */
+/* checking if this was the last reference held to the object. While the    */
+/* array of pointers to nodes is compacted, its size isn't reduced (by way  */
+/* of allocating a new smaller one and copying) because the belief is that  */
+/* it is likely the array will again reach that size.                       */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_node_free(softd, d, node)
+	ipf_dstl_softc_t *softd;
+	ippool_dst_t *d;
+	ipf_dstnode_t *node;
+{
+	int i;
+
+	/*
+	 * Compact the array of pointers to nodes.
+	 */
+	for (i = 0; i < d->ipld_nodes; i++)
+		if (d->ipld_dests[i] == node)
+			break;
+	if (d->ipld_nodes - i > 1) {
+		bcopy(&d->ipld_dests[i + 1], &d->ipld_dests[i],
+		      sizeof(*d->ipld_dests) * (d->ipld_nodes - i - 1));
+	}
+	d->ipld_nodes--;
+
+	if (node->ipfd_pnext != NULL)
+		*node->ipfd_pnext = node->ipfd_next;
+	if (node->ipfd_next != NULL)
+		node->ipfd_next->ipfd_pnext = node->ipfd_pnext;
+	node->ipfd_pnext = NULL;
+	node->ipfd_next = NULL;
+
+	if ((node->ipfd_flags & IPDST_DELETE) == 0) {
+		softd->stats.ipls_numderefnodes++;
+		node->ipfd_flags |= IPDST_DELETE;
+	}
+
+	ipf_dstlist_node_deref(softd, node);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_stats_get                                       */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*                                                                          */
+/* Return the current statistics for destination lists. This may be for all */
+/* of them or just information pertaining to a particular table.            */
+/* ------------------------------------------------------------------------ */
+/*ARGSUSED*/
+static int
+ipf_dstlist_stats_get(softc, arg, op)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupop_t *op;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ipf_dstl_stat_t stats;
+	int unit, i, err = 0;
+
+	if (op->iplo_size != sizeof(ipf_dstl_stat_t)) {
+		IPFERROR(120023);
+		return EINVAL;
+	}
+
+	stats = softd->stats;
+	unit = op->iplo_unit;
+	if (unit == IPL_LOGALL) {
+		for (i = 0; i <= IPL_LOGMAX; i++)
+			stats.ipls_list[i] = softd->dstlist[i];
+	} else if (unit >= 0 && unit <= IPL_LOGMAX) {
+		void *ptr;
+
+		if (op->iplo_name[0] != '\0')
+			ptr = ipf_dstlist_table_find(softd, unit,
+						     op->iplo_name);
+		else
+			ptr = softd->dstlist[unit + 1];
+		stats.ipls_list[unit] = ptr;
+	} else {
+		IPFERROR(120024);
+		err = EINVAL;
+	}
+
+	if (err == 0) {
+		err = COPYOUT(&stats, op->iplo_struct, sizeof(stats));
+		if (err != 0) {
+			IPFERROR(120025);
+			return EFAULT;
+		}
+	}
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_add                                       */
+/* Returns:     int      - 0 = success, else error                          */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*                                                                          */
+/* Add a new destination table to the list of those available for the given */
+/* device. Because we seldom operate on these objects (find/add/delete),    */
+/* they are just kept in a simple linked list.                              */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_table_add(softc, arg, op)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupop_t *op;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ippool_dst_t user, *d, *new;
+	int unit, err;
+
+	d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name);
+	if (d != NULL) {
+		IPFERROR(120013);
+		return EEXIST;
+	}
+
+	err = COPYIN(op->iplo_struct, &user, sizeof(user));
+	if (err != 0) {
+		IPFERROR(120021);
+		return EFAULT;
+	}
+
+	KMALLOC(new, ippool_dst_t *);
+	if (new == NULL) {
+		softd->stats.ipls_nomem++;
+		IPFERROR(120014);
+		return ENOMEM;
+	}
+	bzero((char *)new, sizeof(*new));
+
+	MUTEX_INIT(&new->ipld_lock, "ipf dst table lock");
+
+	strncpy(new->ipld_name, op->iplo_name, FR_GROUPLEN);
+	unit = op->iplo_unit;
+	new->ipld_unit = unit;
+	new->ipld_policy = user.ipld_policy;
+	new->ipld_seed = ipf_random();
+	new->ipld_ref = 1;
+
+	new->ipld_pnext = softd->tails[unit + 1];
+	*softd->tails[unit + 1] = new;
+	softd->tails[unit + 1] = &new->ipld_next;
+	softd->stats.ipls_numlists++;
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_del                                       */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*                                                                          */
+/* Find a named destinstion list table and delete it. If there are other    */
+/* references to it, the caller isn't told.                                 */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_table_del(softc, arg, op)
+	ipf_main_softc_t *softc;
+	void *arg;
+	iplookupop_t *op;
+{
+	ippool_dst_t *d;
+
+	d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name);
+	if (d == NULL) {
+		IPFERROR(120015);
+		return ESRCH;
+	}
+
+	if (d->ipld_dests != NULL) {
+		IPFERROR(120016);
+		return EBUSY;
+	}
+
+	ipf_dstlist_table_remove(softc, arg, d);
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_remove                                    */
+/* Returns:     Nil                                                         */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              softd(I) - pointer to the destination list context          */
+/*              d(I)     - pointer to destination list                      */
+/*                                                                          */
+/* Remove a given destination list from existance. While the IPDST_DELETE   */
+/* flag is set every time we call this function and the reference count is  */
+/* non-zero, the "numdereflists" counter is always incremented because the  */
+/* decision about whether it will be freed or not is not made here. This    */
+/* means that the only action the code can take here is to treat it as if   */
+/* it will become a detached.                                               */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_table_remove(softc, softd, d)
+	ipf_main_softc_t *softc;
+	ipf_dstl_softc_t *softd;
+	ippool_dst_t *d;
+{
+
+	if (softd->tails[d->ipld_unit + 1] == &d->ipld_next)
+		softd->tails[d->ipld_unit + 1] = d->ipld_pnext;
+
+	if (d->ipld_pnext != NULL)
+		*d->ipld_pnext = d->ipld_next;
+	if (d->ipld_next != NULL)
+		d->ipld_next->ipld_pnext = d->ipld_pnext;
+	d->ipld_pnext = NULL;
+	d->ipld_next = NULL;
+
+	ipf_dstlist_table_clearnodes(softd, d);
+
+	softd->stats.ipls_numdereflists++;
+	d->ipld_flags |= IPDST_DELETE;
+
+	ipf_dstlist_table_deref(softc, softd, d);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_free                                      */
+/* Returns:     Nil                                                         */
+/* Parameters:  softd(I) - pointer to the destination list context          */
+/*              d(I)   - pointer to destination list                        */
+/*                                                                          */
+/* Free up a destination list data structure and any other memory that was  */
+/* directly allocated as part of creating it. Individual destination list   */
+/* nodes are not freed. It is assumed the caller will have already emptied  */
+/* the destination list.                                                    */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_table_free(softd, d)
+	ipf_dstl_softc_t *softd;
+	ippool_dst_t *d;
+{
+	MUTEX_DESTROY(&d->ipld_lock);
+
+	if ((d->ipld_flags & IPDST_DELETE) != 0)
+		softd->stats.ipls_numdereflists--;
+	softd->stats.ipls_numlists--;
+
+	if (d->ipld_dests != NULL) {
+		KFREES(d->ipld_dests,
+		       d->ipld_maxnodes * sizeof(*d->ipld_dests));
+	}
+
+	KFREE(d);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_deref                                     */
+/* Returns:     int - 0 = success, else error                               */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*              op(I)    - pointer to lookup operation data                 */
+/*                                                                          */
+/* Drops the reference count on a destination list table object and free's  */
+/* it if 0 has been reached.                                                */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_dstlist_table_deref(softc, arg, table)
+	ipf_main_softc_t *softc;
+	void *arg;
+	void *table;
+{
+	ippool_dst_t *d = table;
+
+	d->ipld_ref--;
+	if (d->ipld_ref > 0)
+		return d->ipld_ref;
+
+	ipf_dstlist_table_free(arg, d);
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_clearnodes                                */
+/* Returns:     Nil                                                         */
+/* Parameters:  softd(I) - pointer to the destination list context          */
+/*              dst(I)   - pointer to destination list                      */
+/*                                                                          */
+/* Free all of the destination nodes attached to the given table.           */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_table_clearnodes(softd, dst)
+	ipf_dstl_softc_t *softd;
+	ippool_dst_t *dst;
+{
+	ipf_dstnode_t *node;
+
+	if (dst->ipld_dests == NULL)
+		return;
+
+	while ((node = *dst->ipld_dests) != NULL) {
+		ipf_dstlist_node_free(softd, dst, node);
+	}
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_table_find                                      */
+/* Returns:     int      - 0 = success, else error                          */
+/* Parameters:  arg(I)   - pointer to local context to use                  */
+/*              unit(I)  - device we are working with                       */
+/*              name(I)  - destination table name to find                   */
+/*                                                                          */
+/* Return a pointer to a destination table that matches the unit+name that  */
+/* is passed in.                                                            */
+/* ------------------------------------------------------------------------ */
+static void *
+ipf_dstlist_table_find(arg, unit, name)
+	void *arg;
+	int unit;
+	char *name;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ippool_dst_t *d;
+
+	for (d = softd->dstlist[unit + 1]; d != NULL; d = d->ipld_next) {
+		if ((d->ipld_unit == unit) &&
+		    !strncmp(d->ipld_name, name, FR_GROUPLEN)) {
+			return d;
+		}
+	}
+
+	return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_select_ref                                      */
+/* Returns:     void *   - NULL = failure, else pointer to table            */
+/* Parameters:  arg(I)   - pointer to local context to use                  */
+/*              unit(I)  - device we are working with                       */
+/*              name(I)  - destination table name to find                   */
+/*                                                                          */
+/* Attempt to find a destination table that matches the name passed in and  */
+/* if successful, bump up the reference count on it because we intend to    */
+/* store the pointer to it somewhere else.                                  */
+/* ------------------------------------------------------------------------ */
+static void *
+ipf_dstlist_select_ref(arg, unit, name)
+	void *arg;
+	int unit;
+	char *name;
+{
+	ippool_dst_t *d;
+
+	d = ipf_dstlist_table_find(arg, unit, name);
+	if (d != NULL) {
+		MUTEX_ENTER(&d->ipld_lock);
+		d->ipld_ref++;
+		MUTEX_EXIT(&d->ipld_lock);
+	}
+	return d;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_select                                          */
+/* Returns:     void * - NULL = failure, else pointer to table              */
+/* Parameters:  fin(I) - pointer to packet information                      */
+/*              d(I)   - pointer to destination list                        */
+/*                                                                          */
+/* Find the next node in the destination list to be used according to the   */
+/* defined policy. Of these, "connection" is the most expensive policy to   */
+/* implement as it always looks for the node with the least number of       */
+/* connections associated with it.                                          */
+/*                                                                          */
+/* The hashes exclude the port numbers so that all protocols map to the     */
+/* same destination. Otherwise, someone doing a ping would target a         */
+/* different server than their TCP connection, etc. MD-5 is used to         */
+/* transform the addressese into something random that the other end could  */
+/* not easily guess and use in an attack. ipld_seed introduces an unknown   */
+/* into the hash calculation to increase the difficult of an attacker       */
+/* guessing the bucket.                                                     */
+/*                                                                          */
+/* One final comment: mixing different address families in a single pool    */
+/* will currently result in failures as the address family of the node is   */
+/* only matched up with that in the packet as the last step. While this can */
+/* be coded around for the weighted connection and round-robin models, it   */
+/* cannot be supported for the hash/random models as they do not search and */
+/* nor is the algorithm conducive to searching.                             */
+/* ------------------------------------------------------------------------ */
+static ipf_dstnode_t *
+ipf_dstlist_select(fin, d)
+	fr_info_t *fin;
+	ippool_dst_t *d;
+{
+	ipf_dstnode_t *node, *sel;
+	int connects;
+	u_32_t hash[4];
+	MD5_CTX ctx;
+	int family;
+	int x;
+
+	if (d->ipld_dests == NULL || *d->ipld_dests == NULL)
+		return NULL;
+
+	family = fin->fin_family;
+
+	MUTEX_ENTER(&d->ipld_lock);
+
+	switch (d->ipld_policy)
+	{
+	case IPLDP_ROUNDROBIN:
+		sel = d->ipld_selected;
+		if (sel == NULL) {
+			sel = *d->ipld_dests;
+		} else {
+			sel = sel->ipfd_next;
+			if (sel == NULL)
+				sel = *d->ipld_dests;
+		}
+		break;
+
+	case IPLDP_CONNECTION:
+		if (d->ipld_selected == NULL) {
+			sel = *d->ipld_dests;
+			break;
+		}
+
+		sel = d->ipld_selected;
+		connects = 0x7fffffff;
+		node = sel->ipfd_next;
+		if (node == NULL)
+			node = *d->ipld_dests;
+		while (node != d->ipld_selected) {
+			if (node->ipfd_states == 0) {
+				sel = node;
+				break;
+			}
+			if (node->ipfd_states < connects) {
+				sel = node;
+				connects = node->ipfd_states;
+			}
+			node = node->ipfd_next;
+			if (node == NULL)
+				node = *d->ipld_dests;
+		}
+		break;
+
+	case IPLDP_RANDOM :
+		x = ipf_random() % d->ipld_nodes;
+		sel = d->ipld_dests[x];
+		break;
+
+	case IPLDP_HASHED :
+		MD5Init(&ctx);
+		MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed));
+		MD5Update(&ctx, (u_char *)&fin->fin_src6,
+			  sizeof(fin->fin_src6));
+		MD5Update(&ctx, (u_char *)&fin->fin_dst6,
+			  sizeof(fin->fin_dst6));
+		MD5Final((u_char *)hash, &ctx);
+		x = hash[0] % d->ipld_nodes;
+		sel = d->ipld_dests[x];
+		break;
+
+	case IPLDP_SRCHASH :
+		MD5Init(&ctx);
+		MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed));
+		MD5Update(&ctx, (u_char *)&fin->fin_src6,
+			  sizeof(fin->fin_src6));
+		MD5Final((u_char *)hash, &ctx);
+		x = hash[0] % d->ipld_nodes;
+		sel = d->ipld_dests[x];
+		break;
+
+	case IPLDP_DSTHASH :
+		MD5Init(&ctx);
+		MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed));
+		MD5Update(&ctx, (u_char *)&fin->fin_dst6,
+			  sizeof(fin->fin_dst6));
+		MD5Final((u_char *)hash, &ctx);
+		x = hash[0] % d->ipld_nodes;
+		sel = d->ipld_dests[x];
+		break;
+
+	default :
+		sel = NULL;
+		break;
+	}
+
+	if (sel->ipfd_dest.fd_addr.adf_family != family)
+		sel = NULL;
+	d->ipld_selected = sel;
+
+	MUTEX_EXIT(&d->ipld_lock);
+
+	return sel;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_select_node                                     */
+/* Returns:     int      - -1 == failure, 0 == success                      */
+/* Parameters:  fin(I)   - pointer to packet information                    */
+/*              group(I) - destination pool to search                       */
+/*              addr(I)  - pointer to store selected address                */
+/*              pfdp(O)  - pointer to storage for selected destination node */
+/*                                                                          */
+/* This function is only responsible for obtaining the next IP address for  */
+/* use and storing it in the caller's address space (addr). "addr" is only  */
+/* used for storage if pfdp is NULL. No permanent reference is currently    */
+/* kept on the node.                                                        */
+/* ------------------------------------------------------------------------ */
+int
+ipf_dstlist_select_node(fin, group, addr, pfdp)
+	fr_info_t *fin;
+	void *group;
+	u_32_t *addr;
+	frdest_t *pfdp;
+{
+#ifdef USE_MUTEXES
+	ipf_main_softc_t *softc = fin->fin_main_soft;
+#endif
+	ippool_dst_t *d = group;
+	ipf_dstnode_t *node;
+	frdest_t *fdp;
+
+	READ_ENTER(&softc->ipf_poolrw);
+
+	node = ipf_dstlist_select(fin, d);
+	if (node == NULL) {
+		RWLOCK_EXIT(&softc->ipf_poolrw);
+		return -1;
+	}
+
+	if (pfdp != NULL) {
+		bcopy(&node->ipfd_dest, pfdp, sizeof(*pfdp));
+	} else {
+		if (fin->fin_family == AF_INET) {
+			addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0];
+		} else if (fin->fin_family == AF_INET6) {
+			addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0];
+			addr[1] = node->ipfd_dest.fd_addr.adf_addr.i6[1];
+			addr[2] = node->ipfd_dest.fd_addr.adf_addr.i6[2];
+			addr[3] = node->ipfd_dest.fd_addr.adf_addr.i6[3];
+		}
+	}
+
+	fdp = &node->ipfd_dest;
+	if (fdp->fd_ptr == NULL)
+		fdp->fd_ptr = fin->fin_ifp;
+
+	MUTEX_ENTER(&node->ipfd_lock);
+	node->ipfd_states++;
+	MUTEX_EXIT(&node->ipfd_lock);
+
+	RWLOCK_EXIT(&softc->ipf_poolrw);
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_expire                                          */
+/* Returns:     Nil                                                         */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*                                                                          */
+/* There are currently no objects to expire in destination lists.           */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_dstlist_expire(softc, arg)
+	ipf_main_softc_t *softc;
+	void *arg;
+{
+	return;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_dstlist_sync                                            */
+/* Returns:     Nil                                                         */
+/* Parameters:  softc(I) - pointer to soft context main structure           */
+/*              arg(I)   - pointer to local context to use                  */
+/*                                                                          */
+/* When a network interface appears or disappears, we need to revalidate    */
+/* all of the network interface names that have been configured as a target */
+/* in a destination list.                                                   */
+/* ------------------------------------------------------------------------ */
+void
+ipf_dstlist_sync(softc, arg)
+	ipf_main_softc_t *softc;
+	void *arg;
+{
+	ipf_dstl_softc_t *softd = arg;
+	ipf_dstnode_t *node;
+	ippool_dst_t *list;
+	int i;
+	int j;
+
+	for (i = 0; i < IPL_LOGMAX; i++) {
+		for (list = softd->dstlist[i]; list != NULL;
+		     list = list->ipld_next) {
+			for (j = 0; j < list->ipld_maxnodes; j++) {
+				node = list->ipld_dests[j];
+				if (node == NULL)
+					continue;
+				if (node->ipfd_dest.fd_name == -1)
+					continue;
+				(void) ipf_resolvedest(softc,
+						       node->ipfd_names,
+						       &node->ipfd_dest,
+						       AF_INET);
+			}
+		}
+	}
+}


Property changes on: trunk/contrib/ipfilter/ip_dstlist.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/ip_dstlist.h
===================================================================
--- trunk/contrib/ipfilter/ip_dstlist.h	                        (rev 0)
+++ trunk/contrib/ipfilter/ip_dstlist.h	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: ip_dstlist.h,v 1.5.2.6 2012/07/22 08:04:23 darren_r Exp $
+ */
+
+#ifndef	__IP_DSTLIST_H__
+#define	__IP_DSTLIST_H__
+
+typedef struct ipf_dstnode {
+	struct ipf_dstnode	*ipfd_next;
+	struct ipf_dstnode	**ipfd_pnext;
+	ipfmutex_t		ipfd_lock;
+	frdest_t		ipfd_dest;
+	u_long			ipfd_syncat;
+	int			ipfd_flags;
+	int			ipfd_size;
+	int			ipfd_states;
+	int			ipfd_ref;
+	int			ipfd_uid;
+	char			ipfd_names[1];
+} ipf_dstnode_t;
+
+typedef enum ippool_policy_e {
+	IPLDP_NONE = 0,
+	IPLDP_ROUNDROBIN,
+	IPLDP_CONNECTION,
+	IPLDP_RANDOM,
+	IPLDP_HASHED,
+	IPLDP_SRCHASH,
+	IPLDP_DSTHASH
+} ippool_policy_t;
+
+typedef struct ippool_dst {
+	struct ippool_dst	*ipld_next;
+	struct ippool_dst	**ipld_pnext;
+	ipfmutex_t		ipld_lock;
+	int			ipld_seed;
+	int			ipld_unit;
+	int			ipld_ref;
+	int			ipld_flags;
+	int			ipld_nodes;
+	int			ipld_maxnodes;
+	ippool_policy_t		ipld_policy;
+	ipf_dstnode_t		**ipld_dests;
+	ipf_dstnode_t		*ipld_selected;
+	char			ipld_name[FR_GROUPLEN];
+} ippool_dst_t;
+
+#define	IPDST_DELETE		0x01
+
+typedef	struct dstlist_stat_s {
+	void			*ipls_list[LOOKUP_POOL_SZ];
+	int			ipls_numlists;
+	u_long			ipls_nomem;
+	int			ipls_numnodes;
+	int			ipls_numdereflists;
+	int			ipls_numderefnodes;
+} ipf_dstl_stat_t;
+
+extern ipf_lookup_t ipf_dstlist_backend;
+
+extern int ipf_dstlist_select_node __P((fr_info_t *, void *, u_32_t *,
+					frdest_t *));
+
+#endif /* __IP_DSTLIST_H__ */


Property changes on: trunk/contrib/ipfilter/ip_dstlist.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/ip_fil_compat.c
===================================================================
--- trunk/contrib/ipfilter/ip_fil_compat.c	                        (rev 0)
+++ trunk/contrib/ipfilter/ip_fil_compat.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,4854 @@
+/*
+ * Copyright (C) 2002-2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#if defined(KERNEL) || defined(_KERNEL)
+# undef KERNEL
+# undef _KERNEL
+# define        KERNEL	1
+# define        _KERNEL	1
+#endif
+#if defined(__osf__)
+# define _PROTO_NET_H_
+#endif
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#if __FreeBSD_version >= 220000 && defined(_KERNEL)
+# include <sys/fcntl.h>
+# include <sys/filio.h>
+#else
+# include <sys/ioctl.h>
+#endif
+#if !defined(_KERNEL)
+# include <string.h>
+# define _KERNEL
+# ifdef __OpenBSD__
+struct file;
+# endif
+# include <sys/uio.h>
+# undef _KERNEL
+#endif
+#include <sys/socket.h>
+#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
+# include "radix_ipf_local.h"
+# define _RADIX_H_
+#endif
+#include <net/if.h>
+#if defined(__FreeBSD__)
+#  include <sys/cdefs.h>
+#  include <sys/proc.h>
+#endif
+#if defined(_KERNEL)
+# include <sys/systm.h>
+# if !defined(__SVR4) && !defined(__svr4__)
+#  include <sys/mbuf.h>
+# endif
+#endif
+#include <netinet/in.h>
+
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_pool.h"
+#include "netinet/ip_htable.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
+#include "netinet/ip_auth.h"
+/* END OF INCLUDES */
+
+/*
+ * NetBSD has moved to 64bit time_t for all architectures.
+ * For some, such as sparc64, there is no change because long is already
+ * 64bit, but for others (i386), there is...
+ */
+#ifdef IPFILTER_COMPAT
+
+# ifdef __NetBSD__
+typedef struct timeval_l {
+	long	tv_sec;
+	long	tv_usec;
+} timeval_l_t;
+# endif
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct tcpinfo4 {
+	u_short		ts_sport;
+	u_short		ts_dport;
+	tcpdata_t	ts_data[2];
+} tcpinfo4_t;
+
+static void ipf_v5tcpinfoto4 __P((tcpinfo_t *, tcpinfo4_t *));
+
+static void
+ipf_v5tcpinfoto4(v5, v4)
+	tcpinfo_t *v5;
+	tcpinfo4_t *v4;
+{
+	v4->ts_sport = v5->ts_sport;
+	v4->ts_dport = v5->ts_dport;
+	v4->ts_data[0] = v5->ts_data[0];
+	v4->ts_data[1] = v5->ts_data[1];
+}
+
+typedef struct	fr_ip4	{
+	u_32_t	fi_v:4;
+	u_32_t	fi_xx:4;
+	u_32_t	fi_tos:8;
+	u_32_t	fi_ttl:8;
+	u_32_t	fi_p:8;
+	u_32_t	fi_optmsk;
+	i6addr_t fi_src;
+	i6addr_t fi_dst;
+	u_short	ofi_secmsk;
+	u_short	ofi_auth;
+	u_32_t	fi_flx;
+	u_32_t	fi_tcpmsk;
+	u_32_t	fi_res1;
+} frip4_t;
+
+typedef struct	frpcmp4	{
+	int	frp_cmp;
+	u_short	frp_port;
+	u_short	frp_top;
+} frpcmp4_t;
+
+typedef	struct	frtuc4	{
+	u_char	ftu_tcpfm;
+	u_char	ftu_tcpf;
+	frpcmp4_t	ftu_src;
+	frpcmp4_t	ftu_dst;
+} frtuc4_t;
+
+typedef	struct	fripf4	{
+	frip4_t fri_ip;
+	frip4_t fri_mip;
+
+	u_short	fri_icmpm;
+	u_short	fri_icmp;
+
+	frtuc4_t	fri_tuc;
+	int	fri_satype;
+	int	fri_datype;
+	int	fri_sifpidx;
+	int	fri_difpidx;
+} fripf4_t;
+
+typedef struct frdest_4 {
+	void		*fd_ifp;
+	i6addr_t	ofd_ip6;
+	char		fd_ifname[LIFNAMSIZ];
+} frdest_4_t;
+
+/* ------------------------------------------------------------------------ */
+
+/* 5.1.0 new release (current)
+ * 4.1.34 changed the size of the time structure used for pps
+ * 4.1.16 moved the location of fr_flineno
+ * 4.1.0 base version
+ */
+typedef	struct	frentry_4_1_34 {
+	ipfmutex_t	fr_lock;
+	struct	frentry	*fr_next;
+	struct	frentry	**fr_grp;
+	struct	ipscan	*fr_isc;
+	void	*fr_ifas[4];
+	void	*fr_ptr;	/* for use with fr_arg */
+	char	*fr_comment;	/* text comment for rule */
+	int	fr_ref;		/* reference count - for grouping */
+	int	fr_statecnt;	/* state count - for limit rules */
+	int	fr_flineno;	/* line number from conf file */
+	U_QUAD_T	fr_hits;
+	U_QUAD_T	fr_bytes;
+	union {
+		struct timeval	frp_lastpkt;
+		char	frp_bytes[12];
+	} fr_lpu;
+	int		fr_curpps;
+	union	{
+		void		*fru_data;
+		char		*fru_caddr;
+		fripf4_t	*fru_ipf;
+		frentfunc_t	fru_func;
+	} fr_dun;
+	ipfunc_t fr_func; 	/* call this function */
+	int	fr_dsize;
+	int	fr_pps;
+	int	fr_statemax;	/* max reference count */
+	u_32_t	fr_type;
+	u_32_t	fr_flags;	/* per-rule flags && options (see below) */
+	u_32_t	fr_logtag;	/* user defined log tag # */
+	u_32_t	fr_collect;	/* collection number */
+	u_int	fr_arg;		/* misc. numeric arg for rule */
+	u_int	fr_loglevel;	/* syslog log facility + priority */
+	u_int	fr_age[2];	/* non-TCP timeouts */
+	u_char	fr_v;
+	u_char	fr_icode;	/* return ICMP code */
+	char	fr_group[FR_GROUPLEN];	/* group to which this rule belongs */
+	char	fr_grhead[FR_GROUPLEN];	/* group # which this rule starts */
+	ipftag_t fr_nattag;
+	char	fr_ifnames[4][LIFNAMSIZ];
+	char	fr_isctag[16];
+	frdest_4_t fr_tifs[2];	/* "to"/"reply-to" interface */
+	frdest_4_t fr_dif;	/* duplicate packet interface */
+	u_int	fr_cksum;	/* checksum on filter rules for performance */
+} frentry_4_1_34_t;
+
+typedef	struct	frentry_4_1_16 {
+	ipfmutex_t	fr_lock;
+	struct	frentry	*fr_next;
+	struct	frentry	**fr_grp;
+	struct	ipscan	*fr_isc;
+	void	*fr_ifas[4];
+	void	*fr_ptr;
+	char	*fr_comment;
+	int	fr_ref;
+	int	fr_statecnt;
+	int	fr_flineno;
+	U_QUAD_T	fr_hits;
+	U_QUAD_T	fr_bytes;
+	union {
+#ifdef __NetBSD__
+		timeval_l_t	frp_lastpkt;
+#else
+		struct timeval	frp_lastpkt;
+#endif
+	} fr_lpu;
+	int		fr_curpps;
+	union	{
+		void		*fru_data;
+		caddr_t		fru_caddr;
+		fripf4_t	*fru_ipf;
+		frentfunc_t	fru_func;
+	} fr_dun;
+	ipfunc_t fr_func;
+	int	fr_dsize;
+	int	fr_pps;
+	int	fr_statemax;
+	u_32_t	fr_type;
+	u_32_t	fr_flags;
+	u_32_t	fr_logtag;
+	u_32_t	fr_collect;
+	u_int	fr_arg;
+	u_int	fr_loglevel;
+	u_int	fr_age[2];
+	u_char	fr_v;
+	u_char	fr_icode;
+	char	fr_group[FR_GROUPLEN];
+	char	fr_grhead[FR_GROUPLEN];
+	ipftag_t fr_nattag;
+	char	fr_ifnames[4][LIFNAMSIZ];
+	char	fr_isctag[16];
+	frdest_4_t fr_tifs[2];
+	frdest_4_t fr_dif;
+	u_int	fr_cksum;
+} frentry_4_1_16_t;
+
+typedef	struct	frentry_4_1_0 {
+	ipfmutex_t	fr_lock;
+	struct	frentry	*fr_next;
+	struct	frentry	**fr_grp;
+	struct	ipscan	*fr_isc;
+	void	*fr_ifas[4];
+	void	*fr_ptr;
+	char	*fr_comment;
+	int	fr_ref;
+	int	fr_statecnt;
+	U_QUAD_T	fr_hits;
+	U_QUAD_T	fr_bytes;
+	union {
+#ifdef __NetBSD__
+		timeval_l_t	frp_lastpkt;
+#else
+		struct timeval	frp_lastpkt;
+#endif
+	} fr_lpu;
+	int		fr_curpps;
+
+	union	{
+		void		*fru_data;
+		caddr_t		fru_caddr;
+		fripf4_t	*fru_ipf;
+		frentfunc_t	fru_func;
+	} fr_dun;
+	/*
+	 * Fields after this may not change whilst in the kernel.
+	 */
+	ipfunc_t fr_func;
+	int	fr_dsize;
+	int	fr_pps;
+	int	fr_statemax;
+	int	fr_flineno;
+	u_32_t	fr_type;
+	u_32_t	fr_flags;
+	u_32_t	fr_logtag;
+	u_32_t	fr_collect;
+	u_int	fr_arg;
+	u_int	fr_loglevel;
+	u_int	fr_age[2];
+	u_char	fr_v;
+	u_char	fr_icode;
+	char	fr_group[FR_GROUPLEN];
+	char	fr_grhead[FR_GROUPLEN];
+	ipftag_t fr_nattag;
+	char	fr_ifnames[4][LIFNAMSIZ];
+	char	fr_isctag[16];
+	frdest_4_t fr_tifs[2];
+	frdest_4_t fr_dif;
+	u_int	fr_cksum;
+} frentry_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.32 removed both fin_state and fin_nat, added fin_pktnum
+ * 4.1.24 added fin_cksum
+ * 4.1.23 added fin_exthdr
+ * 4.1.11 added fin_ifname
+ * 4.1.4  added fin_hbuf
+ */
+typedef	struct	fr_info_4_1_32 {
+	void	*fin_ifp;		/* interface packet is `on' */
+	frip4_t	fin_fi;		/* IP Packet summary */
+	union	{
+		u_short	fid_16[2];	/* TCP/UDP ports, ICMP code/type */
+		u_32_t	fid_32;
+	} fin_dat;
+	int	fin_out;		/* in or out ? 1 == out, 0 == in */
+	int	fin_rev;		/* state only: 1 = reverse */
+	u_short	fin_hlen;		/* length of IP header in bytes */
+	u_char	ofin_tcpf;		/* TCP header flags (SYN, ACK, etc) */
+	u_char	fin_icode;		/* ICMP error to return */
+	u_32_t	fin_rule;		/* rule # last matched */
+	char	fin_group[FR_GROUPLEN];	/* group number, -1 for none */
+	struct	frentry *fin_fr;	/* last matching rule */
+	void	*fin_dp;		/* start of data past IP header */
+	int	fin_dlen;		/* length of data portion of packet */
+	int	fin_plen;
+	int	fin_ipoff;		/* # bytes from buffer start to hdr */
+	u_short	fin_id;			/* IP packet id field */
+	u_short	fin_off;
+	int	fin_depth;		/* Group nesting depth */
+	int	fin_error;		/* Error code to return */
+	int	fin_cksum;		/* -1 bad, 1 good, 0 not done */
+	u_int	fin_pktnum;
+	void	*fin_nattag;
+	void	*fin_exthdr;
+	ip_t	*ofin_ip;
+	mb_t	**fin_mp;		/* pointer to pointer to mbuf */
+	mb_t	*fin_m;			/* pointer to mbuf */
+#ifdef	MENTAT
+	mb_t	*fin_qfm;		/* pointer to mblk where pkt starts */
+	void	*fin_qpi;
+	char	fin_ifname[LIFNAMSIZ];
+#endif
+#ifdef	__sgi
+	void	*fin_hbuf;
+#endif
+} fr_info_4_1_32_t;
+
+typedef struct  fr_info_4_1_24 {
+	void    *fin_ifp;
+	frip4_t fin_fi;
+	union   {
+		u_short fid_16[2];
+		u_32_t  fid_32;
+	} fin_dat;
+	int     fin_out;
+	int     fin_rev;
+	u_short fin_hlen;
+	u_char  ofin_tcpf;
+	u_char  fin_icode;
+	u_32_t  fin_rule;
+	char    fin_group[FR_GROUPLEN];
+	struct  frentry *fin_fr;
+	void    *fin_dp;
+	int     fin_dlen;
+	int     fin_plen;
+	int     fin_ipoff;
+	u_short fin_id;
+	u_short fin_off;
+	int     fin_depth;
+	int     fin_error;
+	int     fin_cksum;
+	void	*fin_state;
+	void	*fin_nat;
+	void    *fin_nattag;
+	void    *fin_exthdr;
+	ip_t    *ofin_ip;
+	mb_t    **fin_mp;
+	mb_t    *fin_m;
+#ifdef  MENTAT
+	mb_t    *fin_qfm;
+	void    *fin_qpi;
+	char    fin_ifname[LIFNAMSIZ];
+#endif
+#ifdef  __sgi
+	void    *fin_hbuf;
+#endif
+} fr_info_4_1_24_t;
+
+typedef struct  fr_info_4_1_23 {
+	void    *fin_ifp;
+	frip4_t fin_fi;
+	union   {
+		u_short fid_16[2];
+		u_32_t  fid_32;
+	} fin_dat;
+	int     fin_out;
+	int     fin_rev;
+	u_short fin_hlen;
+	u_char  ofin_tcpf;
+	u_char  fin_icode;
+	u_32_t  fin_rule;
+	char    fin_group[FR_GROUPLEN];
+	struct  frentry *fin_fr;
+	void    *fin_dp;
+	int     fin_dlen;
+	int     fin_plen;
+	int     fin_ipoff;
+	u_short fin_id;
+	u_short fin_off;
+	int     fin_depth;
+	int     fin_error;
+	void	*fin_state;
+	void	*fin_nat;
+	void    *fin_nattag;
+	void    *fin_exthdr;
+	ip_t    *ofin_ip;
+	mb_t    **fin_mp;
+	mb_t    *fin_m;
+#ifdef  MENTAT
+	mb_t    *fin_qfm;
+	void    *fin_qpi;
+	char    fin_ifname[LIFNAMSIZ];
+#endif
+#ifdef  __sgi
+	void    *fin_hbuf;
+#endif
+} fr_info_4_1_23_t;
+
+typedef struct  fr_info_4_1_11 {
+	void    *fin_ifp;
+	frip4_t fin_fi;
+	union   {
+		u_short fid_16[2];
+		u_32_t  fid_32;
+	} fin_dat;
+	int     fin_out;
+	int     fin_rev;
+	u_short fin_hlen;
+	u_char  ofin_tcpf;
+	u_char  fin_icode;
+	u_32_t  fin_rule;
+	char    fin_group[FR_GROUPLEN];
+	struct  frentry *fin_fr;
+	void    *fin_dp;
+	int     fin_dlen;
+	int     fin_plen;
+	int     fin_ipoff;
+	u_short fin_id;
+	u_short fin_off;
+	int     fin_depth;
+	int     fin_error;
+	void	*fin_state;
+	void	*fin_nat;
+	void    *fin_nattag;
+	ip_t    *ofin_ip;
+	mb_t    **fin_mp;
+	mb_t    *fin_m;
+#ifdef  MENTAT
+	mb_t    *fin_qfm;
+	void    *fin_qpi;
+	char    fin_ifname[LIFNAMSIZ];
+#endif
+#ifdef  __sgi
+	void    *fin_hbuf;
+#endif
+} fr_info_4_1_11_t;
+
+/* ------------------------------------------------------------------------ */
+
+typedef	struct	filterstats_4_1 {
+	u_long	fr_pass;	/* packets allowed */
+	u_long	fr_block;	/* packets denied */
+	u_long	fr_nom;		/* packets which don't match any rule */
+	u_long	fr_short;	/* packets which are short */
+	u_long	fr_ppkl;	/* packets allowed and logged */
+	u_long	fr_bpkl;	/* packets denied and logged */
+	u_long	fr_npkl;	/* packets unmatched and logged */
+	u_long	fr_pkl;		/* packets logged */
+	u_long	fr_skip;	/* packets to be logged but buffer full */
+	u_long	fr_ret;		/* packets for which a return is sent */
+	u_long	fr_acct;	/* packets for which counting was performed */
+	u_long	fr_bnfr;	/* bad attempts to allocate fragment state */
+	u_long	fr_nfr;		/* new fragment state kept */
+	u_long	fr_cfr;		/* add new fragment state but complete pkt */
+	u_long	fr_bads;	/* bad attempts to allocate packet state */
+	u_long	fr_ads;		/* new packet state kept */
+	u_long	fr_chit;	/* cached hit */
+	u_long	fr_tcpbad;	/* TCP checksum check failures */
+	u_long	fr_pull[2];	/* good and bad pullup attempts */
+	u_long	fr_badsrc;	/* source received doesn't match route */
+	u_long	fr_badttl;	/* TTL in packet doesn't reach minimum */
+	u_long	fr_bad;		/* bad IP packets to the filter */
+	u_long	fr_ipv6;	/* IPv6 packets in/out */
+	u_long	fr_ppshit;	/* dropped because of pps ceiling */
+	u_long	fr_ipud;	/* IP id update failures */
+} filterstats_4_1_t;
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.33 changed the size of f_locks from IPL_LOGMAX to IPL_LOGSIZE
+ */
+typedef	struct	friostat_4_1_33	{
+	struct	filterstats_4_1	of_st[2];
+	struct	frentry	*f_ipf[2][2];
+	struct	frentry	*f_acct[2][2];
+	struct	frentry	*f_ipf6[2][2];
+	struct	frentry	*f_acct6[2][2];
+	struct	frentry	*f_auth;
+	struct	frgroup	*f_groups[IPL_LOGSIZE][2];
+	u_long	f_froute[2];
+	u_long	f_ticks;
+	int	f_locks[IPL_LOGSIZE];
+	size_t	f_kmutex_sz;
+	size_t	f_krwlock_sz;
+	int	f_defpass;	/* default pass - from fr_pass */
+	int	f_active;	/* 1 or 0 - active rule set */
+	int	f_running;	/* 1 if running, else 0 */
+	int	f_logging;	/* 1 if enabled, else 0 */
+	int	f_features;
+	char	f_version[32];	/* version string */
+} friostat_4_1_33_t;
+
+typedef struct friostat_4_1_0	{
+	struct filterstats_4_1 of_st[2];
+	struct frentry	*f_ipf[2][2];
+	struct frentry	*f_acct[2][2];
+	struct frentry	*f_ipf6[2][2];
+	struct frentry	*f_acct6[2][2];
+	struct frentry	*f_auth;
+	struct frgroup	*f_groups[IPL_LOGSIZE][2];
+	u_long	f_froute[2];
+	u_long	f_ticks;
+	int	f_locks[IPL_LOGMAX];
+	size_t	f_kmutex_sz;
+	size_t	f_krwlock_sz;
+	int	f_defpass;
+	int	f_active;
+	int	f_running;
+	int	f_logging;
+	int	f_features;
+	char	f_version[32];
+} friostat_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.14 added in_lock
+ */
+typedef	struct	ipnat_4_1_14	{
+	ipfmutex_t	in_lock;
+	struct	ipnat	*in_next;		/* NAT rule list next */
+	struct	ipnat	*in_rnext;		/* rdr rule hash next */
+	struct	ipnat	**in_prnext;		/* prior rdr next ptr */
+	struct	ipnat	*in_mnext;		/* map rule hash next */
+	struct	ipnat	**in_pmnext;		/* prior map next ptr */
+	struct	ipftq	*in_tqehead[2];
+	void		*in_ifps[2];
+	void		*in_apr;
+	char		*in_comment;
+	i6addr_t	in_next6;
+	u_long		in_space;
+	u_long		in_hits;
+	u_int		in_use;
+	u_int		in_hv;
+	int		in_flineno;		/* conf. file line number */
+	u_short		in_pnext;
+	u_char		in_v;
+	u_char		in_xxx;
+	/* From here to the end is covered by IPN_CMPSIZ */
+	u_32_t		in_flags;
+	u_32_t		in_mssclamp;		/* if != 0 clamp MSS to this */
+	u_int		in_age[2];
+	int		in_redir;		/* see below for values */
+	int		in_p;			/* protocol. */
+	i6addr_t	in_in[2];
+	i6addr_t	in_out[2];
+	i6addr_t	in_src[2];
+	frtuc4_t	in_tuc;
+	u_short		in_port[2];
+	u_short		in_ppip;		/* ports per IP. */
+	u_short		in_ippip;		/* IP #'s per IP# */
+	char		in_ifnames[2][LIFNAMSIZ];
+	char		in_plabel[APR_LABELLEN];	/* proxy label. */
+	ipftag_t	in_tag;
+} ipnat_4_1_14_t;
+
+typedef	struct	ipnat_4_1_0	{
+	struct	ipnat	*in_next;
+	struct	ipnat	*in_rnext;
+	struct	ipnat	**in_prnext;
+	struct	ipnat	*in_mnext;
+	struct	ipnat	**in_pmnext;
+	struct	ipftq	*in_tqehead[2];
+	void		*in_ifps[2];
+	void		*in_apr;
+	char		*in_comment;
+	i6addr_t	in_next6;
+	u_long		in_space;
+	u_long		in_hits;
+	u_int		in_use;
+	u_int		in_hv;
+	int		in_flineno;
+	u_short		in_pnext;
+	u_char		in_v;
+	u_char		in_xxx;
+	u_32_t		in_flags;
+	u_32_t		in_mssclamp;
+	u_int		in_age[2];
+	int		in_redir;
+	int		in_p;
+	i6addr_t	in_in[2];
+	i6addr_t	in_out[2];
+	i6addr_t	in_src[2];
+	frtuc4_t	in_tuc;
+	u_short		in_port[2];
+	u_short		in_ppip;
+	u_short		in_ippip;
+	char		in_ifnames[2][LIFNAMSIZ];
+	char		in_plabel[APR_LABELLEN];
+	ipftag_t	in_tag;
+} ipnat_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+typedef	struct	natlookup_4_1_1 {
+	struct	in_addr	onl_inip;
+	struct	in_addr	onl_outip;
+	struct	in_addr	onl_realip;
+	int	nl_flags;
+	u_short	nl_inport;
+	u_short	nl_outport;
+	u_short	nl_realport;
+} natlookup_4_1_1_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 4.1.25 added nat_seqnext (current)
+ * 4.1.14 added nat_redir
+ * 4.1.3  moved nat_rev
+ * 4.1.2  added nat_rev
+ */
+typedef	struct	nat_4_1_25	{
+	ipfmutex_t	nat_lock;
+	struct	nat_4_1_25	*nat_next;
+	struct	nat_4_1_25	**nat_pnext;
+	struct	nat_4_1_25	*nat_hnext[2];
+	struct	nat_4_1_25	**nat_phnext[2];
+	struct	hostmap	*nat_hm;
+	void		*nat_data;
+	struct	nat_4_1_25	**nat_me;
+	struct	ipstate	*nat_state;
+	struct	ap_session	*nat_aps;
+	frentry_t	*nat_fr;
+	struct	ipnat_4_1_14	*nat_ptr;
+	void		*nat_ifps[2];
+	void		*nat_sync;
+	ipftqent_t	nat_tqe;
+	u_32_t		nat_flags;
+	u_32_t		nat_sumd[2];
+	u_32_t		nat_ipsumd;
+	u_32_t		nat_mssclamp;
+	i6addr_t	nat_inip6;
+	i6addr_t	nat_outip6;
+	i6addr_t	nat_oip6;
+	U_QUAD_T	nat_pkts[2];
+	U_QUAD_T	nat_bytes[2];
+	union	{
+		udpinfo_t	nat_unu;
+		tcpinfo4_t	nat_unt;
+		icmpinfo_t	nat_uni;
+		greinfo_t	nat_ugre;
+	} nat_un;
+	u_short		nat_oport;
+	u_short		nat_use;
+	u_char		nat_p;
+	int		nat_dir;
+	int		nat_ref;
+	int		nat_hv[2];
+	char		nat_ifnames[2][LIFNAMSIZ];
+	int		nat_rev;
+	int		nat_redir;
+	u_32_t		nat_seqnext[2];
+} nat_4_1_25_t;
+
+typedef	struct	nat_4_1_14	{
+	ipfmutex_t	nat_lock;
+	struct	nat	*nat_next;
+	struct	nat	**nat_pnext;
+	struct	nat	*nat_hnext[2];
+	struct	nat	**nat_phnext[2];
+	struct	hostmap	*nat_hm;
+	void		*nat_data;
+	struct	nat	**nat_me;
+	struct	ipstate	*nat_state;
+	struct	ap_session	*nat_aps;
+	frentry_t	*nat_fr;
+	struct	ipnat	*nat_ptr;
+	void		*nat_ifps[2];
+	void		*nat_sync;
+	ipftqent_t	nat_tqe;
+	u_32_t		nat_flags;
+	u_32_t		nat_sumd[2];
+	u_32_t		nat_ipsumd;
+	u_32_t		nat_mssclamp;
+	i6addr_t	nat_inip6;
+	i6addr_t	nat_outip6;
+	i6addr_t	nat_oip6;
+	U_QUAD_T	nat_pkts[2];
+	U_QUAD_T	nat_bytes[2];
+	union	{
+		udpinfo_t	nat_unu;
+		tcpinfo4_t	nat_unt;
+		icmpinfo_t	nat_uni;
+		greinfo_t	nat_ugre;
+	} nat_un;
+	u_short		nat_oport;
+	u_short		nat_use;
+	u_char		nat_p;
+	int		nat_dir;
+	int		nat_ref;
+	int		nat_hv[2];
+	char		nat_ifnames[2][LIFNAMSIZ];
+	int		nat_rev;
+	int		nat_redir;
+} nat_4_1_14_t;
+
+typedef	struct	nat_4_1_3	{
+	ipfmutex_t	nat_lock;
+	struct	nat	*nat_next;
+	struct	nat	**nat_pnext;
+	struct	nat	*nat_hnext[2];
+	struct	nat	**nat_phnext[2];
+	struct	hostmap	*nat_hm;
+	void		*nat_data;
+	struct	nat	**nat_me;
+	struct	ipstate	*nat_state;
+	struct	ap_session	*nat_aps;
+	frentry_t	*nat_fr;
+	struct	ipnat	*nat_ptr;
+	void		*nat_ifps[2];
+	void		*nat_sync;
+	ipftqent_t	nat_tqe;
+	u_32_t		nat_flags;
+	u_32_t		nat_sumd[2];
+	u_32_t		nat_ipsumd;
+	u_32_t		nat_mssclamp;
+	i6addr_t	nat_inip6;
+	i6addr_t	nat_outip6;
+	i6addr_t	nat_oip6;
+	U_QUAD_T	nat_pkts[2];
+	U_QUAD_T	nat_bytes[2];
+	union	{
+		udpinfo_t	nat_unu;
+		tcpinfo4_t	nat_unt;
+		icmpinfo_t	nat_uni;
+		greinfo_t	nat_ugre;
+	} nat_un;
+	u_short		nat_oport;
+	u_short		nat_use;
+	u_char		nat_p;
+	int		nat_dir;
+	int		nat_ref;
+	int		nat_hv[2];
+	char		nat_ifnames[2][LIFNAMSIZ];
+	int		nat_rev;
+} nat_4_1_3_t;
+
+
+
+typedef struct  nat_save_4_1_34    {
+	void			*ipn_next;
+	struct	nat_4_1_25	ipn_nat;
+	struct	ipnat_4_1_14	ipn_ipnat;
+	struct	frentry_4_1_34 	ipn_fr;
+	int			ipn_dsize;
+	char			ipn_data[4];
+} nat_save_4_1_34_t;
+
+typedef	struct	nat_save_4_1_16	{
+	void		*ipn_next;
+	nat_4_1_14_t	ipn_nat;
+	ipnat_t		ipn_ipnat;
+	frentry_4_1_16_t	ipn_fr;
+	int		ipn_dsize;
+	char		ipn_data[4];
+} nat_save_4_1_16_t;
+
+typedef	struct	nat_save_4_1_14	{
+	void		*ipn_next;
+	nat_4_1_14_t	ipn_nat;
+	ipnat_t		ipn_ipnat;
+	frentry_4_1_0_t	ipn_fr;
+	int		ipn_dsize;
+	char		ipn_data[4];
+} nat_save_4_1_14_t;
+
+typedef	struct	nat_save_4_1_3	{
+	void		*ipn_next;
+	nat_4_1_3_t	ipn_nat;
+	ipnat_4_1_0_t	ipn_ipnat;
+	frentry_4_1_0_t	ipn_fr;
+	int		ipn_dsize;
+	char		ipn_data[4];
+} nat_save_4_1_3_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.32 added ns_uncreate
+ * 4.1.27 added ns_orphans
+ * 4.1.16 added ns_ticks
+ */
+typedef	struct	natstat_4_1_32	{
+	u_long	ns_mapped[2];
+	u_long	ns_rules;
+	u_long	ns_added;
+	u_long	ns_expire;
+	u_long	ns_inuse;
+	u_long	ns_logged;
+	u_long	ns_logfail;
+	u_long	ns_memfail;
+	u_long	ns_badnat;
+	u_long	ns_addtrpnt;
+	nat_t	**ns_table[2];
+	hostmap_t **ns_maptable;
+	ipnat_t	*ns_list;
+	void	*ns_apslist;
+	u_int	ns_wilds;
+	u_int	ns_nattab_sz;
+	u_int	ns_nattab_max;
+	u_int	ns_rultab_sz;
+	u_int	ns_rdrtab_sz;
+	u_int	ns_trpntab_sz;
+	u_int	ns_hostmap_sz;
+	nat_t	*ns_instances;
+	hostmap_t *ns_maplist;
+	u_long	*ns_bucketlen[2];
+	u_long	ns_ticks;
+	u_int	ns_orphans;
+	u_long	ns_uncreate[2][2];
+} natstat_4_1_32_t;
+
+typedef struct  natstat_4_1_27 {
+	u_long	ns_mapped[2];
+	u_long	ns_rules;
+	u_long	ns_added;
+	u_long	ns_expire;
+	u_long	ns_inuse;
+	u_long	ns_logged;
+	u_long	ns_logfail;
+	u_long	ns_memfail;
+	u_long	ns_badnat;
+	u_long	ns_addtrpnt;
+	nat_t	**ns_table[2];
+	hostmap_t **ns_maptable;
+	ipnat_t *ns_list;
+	void    *ns_apslist;
+	u_int   ns_wilds;
+	u_int   ns_nattab_sz;
+	u_int   ns_nattab_max;
+	u_int   ns_rultab_sz;
+	u_int   ns_rdrtab_sz;
+	u_int   ns_trpntab_sz;
+	u_int   ns_hostmap_sz;
+	nat_t   *ns_instances;
+	hostmap_t *ns_maplist;
+	u_long  *ns_bucketlen[2];
+	u_long  ns_ticks;
+	u_int   ns_orphans;
+} natstat_4_1_27_t;
+
+typedef struct  natstat_4_1_16 {
+	u_long	ns_mapped[2];
+	u_long	ns_rules;
+	u_long	ns_added;
+	u_long	ns_expire;
+	u_long	ns_inuse;
+	u_long	ns_logged;
+	u_long	ns_logfail;
+	u_long	ns_memfail;
+	u_long	ns_badnat;
+	u_long	ns_addtrpnt;
+	nat_t	**ns_table[2];
+	hostmap_t **ns_maptable;
+	ipnat_t *ns_list;
+	void    *ns_apslist;
+	u_int   ns_wilds;
+	u_int   ns_nattab_sz;
+	u_int   ns_nattab_max;
+	u_int   ns_rultab_sz;
+	u_int   ns_rdrtab_sz;
+	u_int   ns_trpntab_sz;
+	u_int   ns_hostmap_sz;
+	nat_t   *ns_instances;
+	hostmap_t *ns_maplist;
+	u_long  *ns_bucketlen[2];
+	u_long  ns_ticks;
+} natstat_4_1_16_t;
+
+typedef struct  natstat_4_1_0 {
+	u_long	ns_mapped[2];
+	u_long	ns_rules;
+	u_long	ns_added;
+	u_long	ns_expire;
+	u_long	ns_inuse;
+	u_long	ns_logged;
+	u_long	ns_logfail;
+	u_long	ns_memfail;
+	u_long	ns_badnat;
+	u_long	ns_addtrpnt;
+	nat_t	**ns_table[2];
+	hostmap_t **ns_maptable;
+	ipnat_t *ns_list;
+	void    *ns_apslist;
+	u_int   ns_wilds;
+	u_int   ns_nattab_sz;
+	u_int   ns_nattab_max;
+	u_int   ns_rultab_sz;
+	u_int   ns_rdrtab_sz;
+	u_int   ns_trpntab_sz;
+	u_int   ns_hostmap_sz;
+	nat_t   *ns_instances;
+	hostmap_t *ns_maplist;
+	u_long  *ns_bucketlen[2];
+} natstat_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.32 fra_info:removed both fin_state & fin_nat, added fin_pktnum
+ * 4.1.29 added fra_flx
+ * 4.1.24 fra_info:added fin_cksum
+ * 4.1.23 fra_info:added fin_exthdr
+ * 4.1.11 fra_info:added fin_ifname
+ * 4.1.4  fra_info:added fin_hbuf
+ */
+
+typedef struct  frauth_4_1_32 {
+	int	fra_age;
+	int	fra_len;
+	int	fra_index;
+	u_32_t	fra_pass;
+	fr_info_4_1_32_t	fra_info;
+	char	*fra_buf;
+	u_32_t	fra_flx;
+#ifdef	MENTAT
+	queue_t	*fra_q;
+	mb_t	*fra_m;
+#endif
+} frauth_4_1_32_t;
+
+typedef struct  frauth_4_1_29 {
+	int	fra_age;
+	int	fra_len;
+	int	fra_index;
+	u_32_t	fra_pass;
+	fr_info_4_1_24_t	fra_info;
+	char	*fra_buf;
+	u_32_t	fra_flx;
+#ifdef	MENTAT
+	queue_t	*fra_q;
+	mb_t	*fra_m;
+#endif
+} frauth_4_1_29_t;
+
+typedef struct  frauth_4_1_24 {
+	int	fra_age;
+	int	fra_len;
+	int	fra_index;
+	u_32_t	fra_pass;
+	fr_info_4_1_24_t	fra_info;
+	char	*fra_buf;
+#ifdef	MENTAT
+	queue_t	*fra_q;
+	mb_t	*fra_m;
+#endif
+} frauth_4_1_24_t;
+
+typedef struct  frauth_4_1_23 {
+	int	fra_age;
+	int	fra_len;
+	int	fra_index;
+	u_32_t	fra_pass;
+	fr_info_4_1_23_t	fra_info;
+	char	*fra_buf;
+#ifdef	MENTAT
+	queue_t	*fra_q;
+	mb_t	*fra_m;
+#endif
+} frauth_4_1_23_t;
+
+typedef struct  frauth_4_1_11 {
+	int	fra_age;
+	int	fra_len;
+	int	fra_index;
+	u_32_t	fra_pass;
+	fr_info_4_1_11_t	fra_info;
+	char	*fra_buf;
+#ifdef	MENTAT
+	queue_t	*fra_q;
+	mb_t	*fra_m;
+#endif
+} frauth_4_1_11_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.16 removed is_nat
+ */
+typedef struct ipstate_4_1_16 {
+	ipfmutex_t	is_lock;
+	struct	ipstate	*is_next;
+	struct	ipstate	**is_pnext;
+	struct	ipstate	*is_hnext;
+	struct	ipstate	**is_phnext;
+	struct	ipstate	**is_me;
+	void		*is_ifp[4];
+	void		*is_sync;
+	frentry_t	*is_rule;
+	struct	ipftq	*is_tqehead[2];
+	struct	ipscan	*is_isc;
+	U_QUAD_T	is_pkts[4];
+	U_QUAD_T	is_bytes[4];
+	U_QUAD_T	is_icmppkts[4];
+	struct	ipftqent is_sti;
+	u_int	is_frage[2];
+	int	is_ref;			/* reference count */
+	int	is_isninc[2];
+	u_short	is_sumd[2];
+	i6addr_t	is_src;
+	i6addr_t	is_dst;
+	u_int	is_pass;
+	u_char	is_p;			/* Protocol */
+	u_char	is_v;
+	u_32_t	is_hv;
+	u_32_t	is_tag;
+	u_32_t	is_opt[2];		/* packet options set */
+	u_32_t	is_optmsk[2];		/*    "      "    mask */
+	u_short	is_sec;			/* security options set */
+	u_short	is_secmsk;		/*    "        "    mask */
+	u_short	is_auth;		/* authentication options set */
+	u_short	is_authmsk;		/*    "              "    mask */
+	union {
+		icmpinfo_t	is_ics;
+		tcpinfo4_t	is_ts;
+		udpinfo_t	is_us;
+		greinfo_t	is_ug;
+	} is_ps;
+	u_32_t	is_flags;
+	int	is_flx[2][2];
+	u_32_t	is_rulen;		/* rule number when created */
+	u_32_t	is_s0[2];
+	u_short	is_smsk[2];
+	char	is_group[FR_GROUPLEN];
+	char	is_sbuf[2][16];
+	char	is_ifname[4][LIFNAMSIZ];
+} ipstate_4_1_16_t;
+
+typedef struct ipstate_4_1_0 {
+	ipfmutex_t	is_lock;
+	struct	ipstate	*is_next;
+	struct	ipstate	**is_pnext;
+	struct	ipstate	*is_hnext;
+	struct	ipstate	**is_phnext;
+	struct	ipstate	**is_me;
+	void		*is_ifp[4];
+	void		*is_sync;
+	void		*is_nat[2];
+	frentry_t	*is_rule;
+	struct	ipftq	*is_tqehead[2];
+	struct	ipscan	*is_isc;
+	U_QUAD_T	is_pkts[4];
+	U_QUAD_T	is_bytes[4];
+	U_QUAD_T	is_icmppkts[4];
+	struct	ipftqent is_sti;
+	u_int	is_frage[2];
+	int	is_ref;
+	int	is_isninc[2];
+	u_short	is_sumd[2];
+	i6addr_t	is_src;
+	i6addr_t	is_dst;
+	u_int	is_pass;
+	u_char	is_p;
+	u_char	is_v;
+	u_32_t	is_hv;
+	u_32_t	is_tag;
+	u_32_t	is_opt[2];
+	u_32_t	is_optmsk[2];
+	u_short	is_sec;
+	u_short	is_secmsk;
+	u_short	is_auth;
+	u_short	is_authmsk;
+	union {
+		icmpinfo_t	is_ics;
+		tcpinfo4_t	is_ts;
+		udpinfo_t	is_us;
+		greinfo_t	is_ug;
+	} is_ps;
+	u_32_t	is_flags;
+	int	is_flx[2][2];
+	u_32_t	is_rulen;
+	u_32_t	is_s0[2];
+	u_short	is_smsk[2];
+	char	is_group[FR_GROUPLEN];
+	char	is_sbuf[2][16];
+	char	is_ifname[4][LIFNAMSIZ];
+} ipstate_4_1_0_t;
+
+typedef	struct	ipstate_save_4_1_34	{
+	void	*ips_next;
+	struct	ipstate_4_1_16	ips_is;
+	struct	frentry_4_1_34	ips_fr;
+} ipstate_save_4_1_34_t;
+
+typedef	struct	ipstate_save_4_1_16	{
+	void		*ips_next;
+	ipstate_4_1_0_t	ips_is;
+	frentry_4_1_16_t	ips_fr;
+} ipstate_save_4_1_16_t;
+
+typedef	struct	ipstate_save_4_1_0	{
+	void		*ips_next;
+	ipstate_4_1_0_t	ips_is;
+	frentry_4_1_0_t	ips_fr;
+} ipstate_save_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * 5.1.0  new release (current)
+ * 4.1.21 added iss_tcptab
+ */
+typedef	struct	ips_stat_4_1_21 {
+	u_long	iss_hits;
+	u_long	iss_miss;
+	u_long	iss_max;
+	u_long	iss_maxref;
+	u_long	iss_tcp;
+	u_long	iss_udp;
+	u_long	iss_icmp;
+	u_long	iss_nomem;
+	u_long	iss_expire;
+	u_long	iss_fin;
+	u_long	iss_active;
+	u_long	iss_logged;
+	u_long	iss_logfail;
+	u_long	iss_inuse;
+	u_long	iss_wild;
+	u_long	iss_killed;
+	u_long	iss_ticks;
+	u_long	iss_bucketfull;
+	int	iss_statesize;
+	int	iss_statemax;
+	ipstate_t **iss_table;
+	ipstate_t *iss_list;
+	u_long	*iss_bucketlen;
+	ipftq_t	*iss_tcptab;
+} ips_stat_4_1_21_t;
+
+typedef	struct	ips_stat_4_1_0 {
+	u_long	iss_hits;
+	u_long	iss_miss;
+	u_long	iss_max;
+	u_long	iss_maxref;
+	u_long	iss_tcp;
+	u_long	iss_udp;
+	u_long	iss_icmp;
+	u_long	iss_nomem;
+	u_long	iss_expire;
+	u_long	iss_fin;
+	u_long	iss_active;
+	u_long	iss_logged;
+	u_long	iss_logfail;
+	u_long	iss_inuse;
+	u_long	iss_wild;
+	u_long	iss_killed;
+	u_long	iss_ticks;
+	u_long	iss_bucketfull;
+	int	iss_statesize;
+	int	iss_statemax;
+	ipstate_t **iss_table;
+	ipstate_t *iss_list;
+	u_long	*iss_bucketlen;
+} ips_stat_4_1_0_t;
+
+/* ------------------------------------------------------------------------ */
+
+typedef	struct	ipfrstat_4_1_1 {
+	u_long	ifs_exists;	/* add & already exists */
+	u_long	ifs_nomem;
+	u_long	ifs_new;
+	u_long	ifs_hits;
+	u_long	ifs_expire;
+	u_long	ifs_inuse;
+	u_long	ifs_retrans0;
+	u_long	ifs_short;
+	struct	ipfr	**ifs_table;
+	struct	ipfr	**ifs_nattab;
+} ipfrstat_4_1_1_t;
+
+/* ------------------------------------------------------------------------ */
+static int ipf_addfrstr __P((char *, int, char *, int));
+static void ipf_v4iptov5 __P((frip4_t *, fr_ip_t *));
+static void ipf_v5iptov4 __P((fr_ip_t *, frip4_t *));
+static void ipfv4tuctov5 __P((frtuc4_t *, frtuc_t *));
+static void ipfv5tuctov4 __P((frtuc_t *, frtuc4_t *));
+static int ipf_v4fripftov5 __P((fripf4_t *, char *));
+static void ipf_v5fripftov4 __P((fripf_t *, fripf4_t *));
+static int fr_frflags4to5 __P((u_32_t));
+static int fr_frflags5to4 __P((u_32_t));
+
+static void friostat_current_to_4_1_0 __P((void *, friostat_4_1_0_t *, int));
+static void friostat_current_to_4_1_33 __P((void *, friostat_4_1_33_t *, int));
+static void ipstate_current_to_4_1_0 __P((void *, ipstate_4_1_0_t *));
+static void ipstate_current_to_4_1_16 __P((void *, ipstate_4_1_16_t *));
+static void ipnat_current_to_4_1_0 __P((void *, ipnat_4_1_0_t *));
+static void ipnat_current_to_4_1_14 __P((void *, ipnat_4_1_14_t *));
+static void frauth_current_to_4_1_11 __P((void *, frauth_4_1_11_t *));
+static void frauth_current_to_4_1_23 __P((void *, frauth_4_1_23_t *));
+static void frauth_current_to_4_1_24 __P((void *, frauth_4_1_24_t *));
+static void frauth_current_to_4_1_29 __P((void *, frauth_4_1_29_t *));
+static void frentry_current_to_4_1_0 __P((void *, frentry_4_1_0_t *));
+static void frentry_current_to_4_1_16 __P((void *, frentry_4_1_16_t *));
+static void frentry_current_to_4_1_34 __P((void *, frentry_4_1_34_t *));
+static void fr_info_current_to_4_1_11 __P((void *, fr_info_4_1_11_t *));
+static void fr_info_current_to_4_1_23 __P((void *, fr_info_4_1_23_t *));
+static void fr_info_current_to_4_1_24 __P((void *, fr_info_4_1_24_t *));
+static void nat_save_current_to_4_1_3 __P((void *, nat_save_4_1_3_t *));
+static void nat_save_current_to_4_1_14 __P((void *, nat_save_4_1_14_t *));
+static void nat_save_current_to_4_1_16 __P((void *, nat_save_4_1_16_t *));
+static void ipstate_save_current_to_4_1_0 __P((void *, ipstate_save_4_1_0_t *));
+static void ipstate_save_current_to_4_1_16 __P((void *, ipstate_save_4_1_16_t *));
+static void ips_stat_current_to_4_1_0 __P((void *, ips_stat_4_1_0_t *));
+static void ips_stat_current_to_4_1_21 __P((void *, ips_stat_4_1_21_t *));
+static void natstat_current_to_4_1_0 __P((void *, natstat_4_1_0_t *));
+static void natstat_current_to_4_1_16 __P((void *, natstat_4_1_16_t *));
+static void natstat_current_to_4_1_27 __P((void *, natstat_4_1_27_t *));
+static void natstat_current_to_4_1_32 __P((void *, natstat_4_1_32_t *));
+static void nat_current_to_4_1_3 __P((void *, nat_4_1_3_t *));
+static void nat_current_to_4_1_14 __P((void *, nat_4_1_14_t *));
+static void nat_current_to_4_1_25 __P((void *, nat_4_1_25_t *));
+
+static void friostat_4_1_0_to_current __P((friostat_4_1_0_t *, void *));
+static void friostat_4_1_33_to_current __P((friostat_4_1_33_t *, void *));
+static void ipnat_4_1_0_to_current __P((ipnat_4_1_0_t *, void *, int));
+static void ipnat_4_1_14_to_current __P((ipnat_4_1_14_t *, void *, int));
+static void frauth_4_1_11_to_current __P((frauth_4_1_11_t *, void *));
+static void frauth_4_1_23_to_current __P((frauth_4_1_23_t *, void *));
+static void frauth_4_1_24_to_current __P((frauth_4_1_24_t *, void *));
+static void frauth_4_1_29_to_current __P((frauth_4_1_29_t *, void *));
+static void frauth_4_1_32_to_current __P((frauth_4_1_32_t *, void *));
+static void frentry_4_1_0_to_current __P((ipf_main_softc_t *, frentry_4_1_0_t *, void *, int));
+static void frentry_4_1_16_to_current __P((ipf_main_softc_t *, frentry_4_1_16_t *, void *, int));
+static void frentry_4_1_34_to_current __P((ipf_main_softc_t *, frentry_4_1_34_t *, void *, int));
+static void fr_info_4_1_11_to_current __P((fr_info_4_1_11_t *, void *));
+static void fr_info_4_1_23_to_current __P((fr_info_4_1_23_t *, void *));
+static void fr_info_4_1_24_to_current __P((fr_info_4_1_24_t *, void *));
+static void fr_info_4_1_32_to_current __P((fr_info_4_1_32_t *, void *));
+static void nat_save_4_1_3_to_current __P((ipf_main_softc_t *, nat_save_4_1_3_t *, void *));
+static void nat_save_4_1_14_to_current __P((ipf_main_softc_t *, nat_save_4_1_14_t *, void *));
+static void nat_save_4_1_16_to_current __P((ipf_main_softc_t *, nat_save_4_1_16_t *, void *));
+
+/* ------------------------------------------------------------------------ */
+/* In this section is a series of short routines that deal with translating */
+/* the smaller data structures used above as their internal changes make    */
+/* them inappropriate for simple assignment.                                */
+/* ------------------------------------------------------------------------ */
+
+
+static int
+ipf_addfrstr(char *names, int namelen, char *str, int maxlen)
+{
+	char *t;
+	int i;
+
+	for (i = maxlen, t = str; (*t != '\0') && (i > 0); i--) {
+		names[namelen++] = *t++;
+	}
+	names[namelen++] = '\0';
+	return namelen;
+}
+
+
+static void
+ipf_v4iptov5(v4, v5)
+	frip4_t *v4;
+	fr_ip_t *v5;
+{
+	v5->fi_v = v4->fi_v;
+	v5->fi_p = v4->fi_p;
+	v5->fi_xx = v4->fi_xx;
+	v5->fi_tos = v4->fi_tos;
+	v5->fi_ttl = v4->fi_ttl;
+	v5->fi_p = v4->fi_p;
+	v5->fi_optmsk = v4->fi_optmsk;
+	v5->fi_src = v4->fi_src;
+	v5->fi_dst = v4->fi_dst;
+	v5->fi_secmsk = v4->ofi_secmsk;
+	v5->fi_auth = v4->ofi_auth;
+	v5->fi_flx = v4->fi_flx;
+	v5->fi_tcpmsk = v4->fi_tcpmsk;
+}
+
+static void
+ipf_v5iptov4(v5, v4)
+	fr_ip_t *v5;
+	frip4_t *v4;
+{
+	v4->fi_v = v5->fi_v;
+	v4->fi_p = v5->fi_p;
+	v4->fi_xx = v5->fi_xx;
+	v4->fi_tos = v5->fi_tos;
+	v4->fi_ttl = v5->fi_ttl;
+	v4->fi_p = v5->fi_p;
+	v4->fi_optmsk = v5->fi_optmsk;
+	v4->fi_src = v5->fi_src;
+	v4->fi_dst = v5->fi_dst;
+	v4->ofi_secmsk = v5->fi_secmsk;
+	v4->ofi_auth = v5->fi_auth;
+	v4->fi_flx = v5->fi_flx;
+	v4->fi_tcpmsk = v5->fi_tcpmsk;
+}
+
+
+static void
+ipfv4tuctov5(v4, v5)
+	frtuc4_t *v4;
+	frtuc_t *v5;
+{
+	v5->ftu_src.frp_cmp = v4->ftu_src.frp_cmp;
+	v5->ftu_src.frp_port = v4->ftu_src.frp_port;
+	v5->ftu_src.frp_top = v4->ftu_src.frp_top;
+	v5->ftu_dst.frp_cmp = v4->ftu_dst.frp_cmp;
+	v5->ftu_dst.frp_port = v4->ftu_dst.frp_port;
+	v5->ftu_dst.frp_top = v4->ftu_dst.frp_top;
+}
+
+
+static void
+ipfv5tuctov4(v5, v4)
+	frtuc_t *v5;
+	frtuc4_t *v4;
+{
+	v4->ftu_src.frp_cmp = v5->ftu_src.frp_cmp;
+	v4->ftu_src.frp_port = v5->ftu_src.frp_port;
+	v4->ftu_src.frp_top = v5->ftu_src.frp_top;
+	v4->ftu_dst.frp_cmp = v5->ftu_dst.frp_cmp;
+	v4->ftu_dst.frp_port = v5->ftu_dst.frp_port;
+	v4->ftu_dst.frp_top = v5->ftu_dst.frp_top;
+}
+
+
+static int
+ipf_v4fripftov5(frp4, dst)
+	fripf4_t *frp4;
+	char *dst;
+{
+	fripf_t *frp;
+
+	frp = (fripf_t *)dst;
+
+	ipf_v4iptov5(&frp4->fri_ip, &frp->fri_ip);
+	ipf_v4iptov5(&frp4->fri_mip, &frp->fri_mip);
+	frp->fri_icmpm = frp4->fri_icmpm;
+	frp->fri_icmp = frp4->fri_icmp;
+	frp->fri_tuc.ftu_tcpfm = frp4->fri_tuc.ftu_tcpfm;
+	frp->fri_tuc.ftu_tcpf = frp4->fri_tuc.ftu_tcpf;
+	ipfv4tuctov5(&frp4->fri_tuc, &frp->fri_tuc);
+	frp->fri_satype = frp4->fri_satype;
+	frp->fri_datype = frp4->fri_datype;
+	frp->fri_sifpidx = frp4->fri_sifpidx;
+	frp->fri_difpidx = frp4->fri_difpidx;
+	return 0;
+}
+
+
+static void
+ipf_v5fripftov4(frp, frp4)
+	fripf_t *frp;
+	fripf4_t *frp4;
+{
+
+	ipf_v5iptov4(&frp->fri_ip, &frp4->fri_ip);
+	ipf_v5iptov4(&frp->fri_mip, &frp4->fri_mip);
+	frp4->fri_icmpm = frp->fri_icmpm;
+	frp4->fri_icmp = frp->fri_icmp;
+	frp4->fri_tuc.ftu_tcpfm = frp->fri_tuc.ftu_tcpfm;
+	frp4->fri_tuc.ftu_tcpf = frp->fri_tuc.ftu_tcpf;
+	ipfv5tuctov4(&frp->fri_tuc, &frp4->fri_tuc);
+	frp4->fri_satype = frp->fri_satype;
+	frp4->fri_datype = frp->fri_datype;
+	frp4->fri_sifpidx = frp->fri_sifpidx;
+	frp4->fri_difpidx = frp->fri_difpidx;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* ipf_in_compat is the first of two service routines. It is responsible for*/
+/* converting data structures from user space into what's required by the   */
+/* kernel module.                                                           */
+/* ------------------------------------------------------------------------ */
+int
+ipf_in_compat(softc, obj, ptr, size)
+	ipf_main_softc_t *softc;
+	ipfobj_t *obj;
+	void *ptr;
+	int size;
+{
+	int error;
+	int sz;
+
+	IPFERROR(140000);
+	error = EINVAL;
+
+	switch (obj->ipfo_type)
+	{
+	default :
+		break;
+
+	case IPFOBJ_FRENTRY :
+		if (obj->ipfo_rev >= 4013400) {
+			frentry_4_1_34_t *old;
+
+			KMALLOC(old, frentry_4_1_34_t *);
+			if (old == NULL) {
+				IPFERROR(140001);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				if (old->fr_type != FR_T_NONE &&
+				    old->fr_type != FR_T_IPF) {
+					IPFERROR(140002);
+					error = EINVAL;
+					KFREE(old);
+					break;
+				}
+				frentry_4_1_34_to_current(softc, old,
+							  ptr, size);
+			} else {
+				IPFERROR(140003);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4011600) {
+			frentry_4_1_16_t *old;
+
+			KMALLOC(old, frentry_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140004);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				if (old->fr_type != FR_T_NONE &&
+				    old->fr_type != FR_T_IPF) {
+					IPFERROR(140005);
+					error = EINVAL;
+					KFREE(old);
+					break;
+				}
+				frentry_4_1_16_to_current(softc, old,
+							  ptr, size);
+			} else {
+				IPFERROR(140006);
+			}
+			KFREE(old);
+		} else {
+			frentry_4_1_0_t *old;
+
+			KMALLOC(old, frentry_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140007);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				if (old->fr_type != FR_T_NONE &&
+				    old->fr_type != FR_T_IPF) {
+					IPFERROR(140008);
+					error = EINVAL;
+					KFREE(old);
+					break;
+				}
+				frentry_4_1_0_to_current(softc, old, ptr, size);
+			} else {
+				IPFERROR(140009);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_IPFSTAT :
+		if (obj->ipfo_rev >= 4013300) {
+			friostat_4_1_33_t *old;
+
+			KMALLOC(old, friostat_4_1_33_t *);
+			if (old == NULL) {
+				IPFERROR(140010);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				friostat_4_1_33_to_current(old, ptr);
+			} else {
+				IPFERROR(140011);
+			}
+		} else {
+			friostat_4_1_0_t *old;
+
+			KMALLOC(old, friostat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140012);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				friostat_4_1_0_to_current(old, ptr);
+			} else {
+				IPFERROR(140013);
+			}
+		}
+		break;
+
+	case IPFOBJ_IPFINFO :	/* unused */
+		break;
+
+	case IPFOBJ_IPNAT :
+		if (obj->ipfo_rev >= 4011400) {
+			ipnat_4_1_14_t *old;
+
+			KMALLOC(old, ipnat_4_1_14_t *);
+			if (old == NULL) {
+				IPFERROR(140014);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				ipnat_4_1_14_to_current(old, ptr, size);
+			} else {
+				IPFERROR(140015);
+			}
+			KFREE(old);
+		} else {
+			ipnat_4_1_0_t *old;
+
+			KMALLOC(old, ipnat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140016);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				ipnat_4_1_0_to_current(old, ptr, size);
+			} else {
+				IPFERROR(140017);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_NATSTAT :
+		/*
+		 * Statistics are not copied in.
+		 */
+		break;
+
+	case IPFOBJ_NATSAVE :
+		if (obj->ipfo_rev >= 4011600) {
+			nat_save_4_1_16_t *old16;
+
+			KMALLOC(old16, nat_save_4_1_16_t *);
+			if (old16 == NULL) {
+				IPFERROR(140018);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old16, sizeof(*old16));
+			if (error == 0) {
+				nat_save_4_1_16_to_current(softc, old16, ptr);
+			} else {
+				IPFERROR(140019);
+			}
+			KFREE(old16);
+		} else if (obj->ipfo_rev >= 4011400) {
+			nat_save_4_1_14_t *old14;
+
+			KMALLOC(old14, nat_save_4_1_14_t *);
+			if (old14 == NULL) {
+				IPFERROR(140020);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old14, sizeof(*old14));
+			if (error == 0) {
+				nat_save_4_1_14_to_current(softc, old14, ptr);
+			} else {
+				IPFERROR(140021);
+			}
+			KFREE(old14);
+		} else if (obj->ipfo_rev >= 4010300) {
+			nat_save_4_1_3_t *old3;
+
+			KMALLOC(old3, nat_save_4_1_3_t *);
+			if (old3 == NULL) {
+				IPFERROR(140022);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old3, sizeof(*old3));
+			if (error == 0) {
+				nat_save_4_1_3_to_current(softc, old3, ptr);
+			} else {
+				IPFERROR(140023);
+			}
+			KFREE(old3);
+		}
+		break;
+
+	case IPFOBJ_STATESAVE :
+		if (obj->ipfo_rev >= 4013400) {
+			ipstate_save_4_1_34_t *old;
+
+			KMALLOC(old, ipstate_save_4_1_34_t *);
+			if (old == NULL) {
+				IPFERROR(140024);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140025);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4011600) {
+			ipstate_save_4_1_16_t *old;
+
+			KMALLOC(old, ipstate_save_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140026);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140027);
+			}
+			KFREE(old);
+		} else {
+			ipstate_save_4_1_0_t *old;
+
+			KMALLOC(old, ipstate_save_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140028);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140029);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_IPSTATE :
+		/*
+		 * This structure is not copied in by itself.
+		 */
+		break;
+
+	case IPFOBJ_STATESTAT :
+		/*
+		 * Statistics are not copied in.
+		 */
+		break;
+
+	case IPFOBJ_FRAUTH :
+		if (obj->ipfo_rev >= 4013200) {
+			frauth_4_1_32_t *old32;
+
+			KMALLOC(old32, frauth_4_1_32_t *);
+			if (old32 == NULL) {
+				IPFERROR(140030);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old32, sizeof(*old32));
+			if (error == 0) {
+				frauth_4_1_32_to_current(old32, ptr);
+			} else {
+				IPFERROR(140031);
+			}
+			KFREE(old32);
+		} else if (obj->ipfo_rev >= 4012900) {
+			frauth_4_1_29_t *old29;
+
+			KMALLOC(old29, frauth_4_1_29_t *);
+			if (old29 == NULL) {
+				IPFERROR(140032);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old29, sizeof(*old29));
+			if (error == 0) {
+				frauth_4_1_29_to_current(old29, ptr);
+			} else {
+				IPFERROR(140033);
+			}
+			KFREE(old29);
+		} else if (obj->ipfo_rev >= 4012400) {
+			frauth_4_1_24_t *old24;
+
+			KMALLOC(old24, frauth_4_1_24_t *);
+			if (old24 == NULL) {
+				IPFERROR(140034);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old24, sizeof(*old24));
+			if (error == 0) {
+				frauth_4_1_24_to_current(old24, ptr);
+			} else {
+				IPFERROR(140035);
+			}
+			KFREE(old24);
+		} else if (obj->ipfo_rev >= 4012300) {
+			frauth_4_1_23_t *old23;
+
+			KMALLOC(old23, frauth_4_1_23_t *);
+			if (old23 == NULL) {
+				IPFERROR(140036);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old23, sizeof(*old23));
+			if (error == 0)
+				frauth_4_1_23_to_current(old23, ptr);
+			KFREE(old23);
+		} else if (obj->ipfo_rev >= 4011100) {
+			frauth_4_1_11_t *old11;
+
+			KMALLOC(old11, frauth_4_1_11_t *);
+			if (old11 == NULL) {
+				IPFERROR(140037);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old11, sizeof(*old11));
+			if (error == 0) {
+				frauth_4_1_11_to_current(old11, ptr);
+			} else {
+				IPFERROR(140038);
+			}
+			KFREE(old11);
+		}
+		break;
+
+	case IPFOBJ_NAT :
+		if (obj->ipfo_rev >= 4011400) {
+			sz = sizeof(nat_4_1_14_t);
+		} else if (obj->ipfo_rev >= 4010300) {
+			sz = sizeof(nat_4_1_3_t);
+		} else {
+			break;
+		}
+		bzero(ptr, sizeof(nat_t));
+		error = COPYIN(obj->ipfo_ptr, ptr, sz);
+		if (error != 0) {
+			IPFERROR(140039);
+		}
+		break;
+
+	case IPFOBJ_FRIPF :
+		if (obj->ipfo_rev < 5000000) {
+			fripf4_t *old;
+
+			KMALLOC(old, fripf4_t *);
+			if (old == NULL) {
+				IPFERROR(140040);
+				error = ENOMEM;
+				break;
+			}
+			error = COPYIN(obj->ipfo_ptr, old, sizeof(*old));
+			if (error == 0) {
+				ipf_v4fripftov5(old, ptr);
+			} else {
+				IPFERROR(140041);
+			}
+			KFREE(old);
+		}
+		break;
+	}
+
+	return error;
+}
+/* ------------------------------------------------------------------------ */
+
+
+/*
+ * flags is v4 flags, returns v5 flags.
+ */
+static int
+fr_frflags4to5(flags)
+	u_32_t flags;
+{
+	u_32_t nflags = 0;
+
+	switch (flags & 0xf) {
+	case 0x0 :
+		nflags |= FR_CALL;
+		break;
+	case 0x1 :
+		nflags |= FR_BLOCK;
+		break;
+	case 0x2 :
+		nflags |= FR_PASS;
+		break;
+	case 0x3 :
+		nflags |= FR_AUTH;
+		break;
+	case 0x4 :
+		nflags |= FR_PREAUTH;
+		break;
+	case 0x5 :
+		nflags |= FR_ACCOUNT;
+		break;
+	case 0x6 :
+		nflags |= FR_SKIP;
+		break;
+	default :
+		break;
+	}
+
+	if (flags & 0x00010)
+		nflags |= FR_LOG;
+	if (flags & 0x00020)
+		nflags |= FR_CALLNOW;
+	if (flags & 0x00080)
+		nflags |= FR_NOTSRCIP;
+	if (flags & 0x00040)
+		nflags |= FR_NOTDSTIP;
+	if (flags & 0x00100)
+		nflags |= FR_QUICK;
+	if (flags & 0x00200)
+		nflags |= FR_KEEPFRAG;
+	if (flags & 0x00400)
+		nflags |= FR_KEEPSTATE;
+	if (flags & 0x00800)
+		nflags |= FR_FASTROUTE;
+	if (flags & 0x01000)
+		nflags |= FR_RETRST;
+	if (flags & 0x02000)
+		nflags |= FR_RETICMP;
+	if (flags & 0x03000)
+		nflags |= FR_FAKEICMP;
+	if (flags & 0x04000)
+		nflags |= FR_OUTQUE;
+	if (flags & 0x08000)
+		nflags |= FR_INQUE;
+	if (flags & 0x10000)
+		nflags |= FR_LOGBODY;
+	if (flags & 0x20000)
+		nflags |= FR_LOGFIRST;
+	if (flags & 0x40000)
+		nflags |= FR_LOGORBLOCK;
+	if (flags & 0x100000)
+		nflags |= FR_FRSTRICT;
+	if (flags & 0x200000)
+		nflags |= FR_STSTRICT;
+	if (flags & 0x400000)
+		nflags |= FR_NEWISN;
+	if (flags & 0x800000)
+		nflags |= FR_NOICMPERR;
+	if (flags & 0x1000000)
+		nflags |= FR_STATESYNC;
+	if (flags & 0x8000000)
+		nflags |= FR_NOMATCH;
+	if (flags & 0x40000000)
+		nflags |= FR_COPIED;
+	if (flags & 0x80000000)
+		nflags |= FR_INACTIVE;
+
+	return nflags;
+}
+
+static void
+frentry_4_1_34_to_current(softc, old, current, size)
+	ipf_main_softc_t *softc;
+	frentry_4_1_34_t *old;
+	void *current;
+	int size;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	fr->fr_comment = -1;
+	fr->fr_ref = old->fr_ref;
+	fr->fr_statecnt = old->fr_statecnt;
+	fr->fr_hits = old->fr_hits;
+	fr->fr_bytes = old->fr_bytes;
+	fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec;
+	fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec;
+	bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun));
+	fr->fr_func = old->fr_func;
+	fr->fr_dsize = old->fr_dsize;
+	fr->fr_pps = old->fr_pps;
+	fr->fr_statemax = old->fr_statemax;
+	fr->fr_flineno = old->fr_flineno;
+	fr->fr_type = old->fr_type;
+	fr->fr_flags = fr_frflags4to5(old->fr_flags);
+	fr->fr_logtag = old->fr_logtag;
+	fr->fr_collect = old->fr_collect;
+	fr->fr_arg = old->fr_arg;
+	fr->fr_loglevel = old->fr_loglevel;
+	fr->fr_age[0] = old->fr_age[0];
+	fr->fr_age[1] = old->fr_age[1];
+	fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6;
+	fr->fr_tifs[0].fd_type = FRD_NORMAL;
+	fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6;
+	fr->fr_tifs[1].fd_type = FRD_NORMAL;
+	fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6;
+	fr->fr_dif.fd_type = FRD_NORMAL;
+	if (old->fr_v == 4)
+		fr->fr_family = AF_INET;
+	if (old->fr_v == 6)
+		fr->fr_family = AF_INET6;
+	fr->fr_icode = old->fr_icode;
+	fr->fr_cksum = old->fr_cksum;
+	fr->fr_namelen = 0;
+	fr->fr_ifnames[0] = -1;
+	fr->fr_ifnames[1] = -1;
+	fr->fr_ifnames[2] = -1;
+	fr->fr_ifnames[3] = -1;
+	fr->fr_dif.fd_name = -1;
+	fr->fr_tifs[0].fd_name = -1;
+	fr->fr_tifs[1].fd_name = -1;
+	fr->fr_group = -1;
+	fr->fr_grhead = -1;
+	fr->fr_icmphead = -1;
+	if (size == 0) {
+		fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2;
+		fr->fr_size += sizeof(fripf_t) + 16;
+		fr->fr_size += 9;	/* room for \0's */
+	} else {
+		char *names = fr->fr_names;
+		int nlen = fr->fr_namelen;
+
+		fr->fr_size = size;
+		if (old->fr_ifnames[0][0] != '\0') {
+			fr->fr_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[1][0] != '\0') {
+			fr->fr_ifnames[1] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[2][0] != '\0') {
+			fr->fr_ifnames[2] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[3][0] != '\0') {
+			fr->fr_ifnames[3] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[0].fd_ifname[0] != '\0') {
+			fr->fr_tifs[0].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[0].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[1].fd_ifname[0] != '\0') {
+			fr->fr_tifs[1].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[1].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_dif.fd_ifname[0] != '\0') {
+			fr->fr_dif.fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_dif.fd_ifname, LIFNAMSIZ);
+		}
+		if (old->fr_group[0] != '\0') {
+			fr->fr_group = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_group, LIFNAMSIZ);
+		}
+		if (old->fr_grhead[0] != '\0') {
+			fr->fr_grhead = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_grhead, LIFNAMSIZ);
+		}
+		fr->fr_namelen = nlen;
+
+		if (old->fr_type == FR_T_IPF) {
+			int offset = fr->fr_namelen;
+			ipfobj_t obj;
+			int error;
+
+			obj.ipfo_type = IPFOBJ_FRIPF;
+			obj.ipfo_rev = 4010100;
+			obj.ipfo_ptr = old->fr_data;
+
+			if ((offset & 7) != 0)
+				offset += 8 - (offset & 7);
+			error = ipf_in_compat(softc, &obj,
+					      fr->fr_names + offset, 0);
+			if (error == 0) {
+				fr->fr_data = fr->fr_names + offset;
+				fr->fr_dsize = sizeof(fripf_t);
+			}
+		}
+	}
+}
+
+static void
+frentry_4_1_16_to_current(softc, old, current, size)
+	ipf_main_softc_t *softc;
+	frentry_4_1_16_t *old;
+	void *current;
+	int size;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	fr->fr_comment = -1;
+	fr->fr_ref = old->fr_ref;
+	fr->fr_statecnt = old->fr_statecnt;
+	fr->fr_hits = old->fr_hits;
+	fr->fr_bytes = old->fr_bytes;
+	fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec;
+	fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec;
+	bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun));
+	fr->fr_func = old->fr_func;
+	fr->fr_dsize = old->fr_dsize;
+	fr->fr_pps = old->fr_pps;
+	fr->fr_statemax = old->fr_statemax;
+	fr->fr_flineno = old->fr_flineno;
+	fr->fr_type = old->fr_type;
+	fr->fr_flags = fr_frflags4to5(old->fr_flags);
+	fr->fr_logtag = old->fr_logtag;
+	fr->fr_collect = old->fr_collect;
+	fr->fr_arg = old->fr_arg;
+	fr->fr_loglevel = old->fr_loglevel;
+	fr->fr_age[0] = old->fr_age[0];
+	fr->fr_age[1] = old->fr_age[1];
+	fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6;
+	fr->fr_tifs[0].fd_type = FRD_NORMAL;
+	fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6;
+	fr->fr_tifs[1].fd_type = FRD_NORMAL;
+	fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6;
+	fr->fr_dif.fd_type = FRD_NORMAL;
+	if (old->fr_v == 4)
+		fr->fr_family = AF_INET;
+	if (old->fr_v == 6)
+		fr->fr_family = AF_INET6;
+	fr->fr_icode = old->fr_icode;
+	fr->fr_cksum = old->fr_cksum;
+	fr->fr_namelen = 0;
+	fr->fr_ifnames[0] = -1;
+	fr->fr_ifnames[1] = -1;
+	fr->fr_ifnames[2] = -1;
+	fr->fr_ifnames[3] = -1;
+	fr->fr_dif.fd_name = -1;
+	fr->fr_tifs[0].fd_name = -1;
+	fr->fr_tifs[1].fd_name = -1;
+	fr->fr_group = -1;
+	fr->fr_grhead = -1;
+	fr->fr_icmphead = -1;
+	if (size == 0) {
+		fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2;
+		fr->fr_size += 9;	/* room for \0's */
+	} else {
+		char *names = fr->fr_names;
+		int nlen = fr->fr_namelen;
+
+		fr->fr_size = size;
+		if (old->fr_ifnames[0][0] != '\0') {
+			fr->fr_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[1][0] != '\0') {
+			fr->fr_ifnames[1] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[2][0] != '\0') {
+			fr->fr_ifnames[2] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[3][0] != '\0') {
+			fr->fr_ifnames[3] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[0].fd_ifname[0] != '\0') {
+			fr->fr_tifs[0].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[0].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[1].fd_ifname[0] != '\0') {
+			fr->fr_tifs[1].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[1].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_dif.fd_ifname[0] != '\0') {
+			fr->fr_dif.fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_dif.fd_ifname, LIFNAMSIZ);
+		}
+		if (old->fr_group[0] != '\0') {
+			fr->fr_group = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_group, LIFNAMSIZ);
+		}
+		if (old->fr_grhead[0] != '\0') {
+			fr->fr_grhead = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_grhead, LIFNAMSIZ);
+		}
+		fr->fr_namelen = nlen;
+
+		if (old->fr_type == FR_T_IPF) {
+			int offset = fr->fr_namelen;
+			ipfobj_t obj;
+			int error;
+
+			obj.ipfo_type = IPFOBJ_FRIPF;
+			obj.ipfo_rev = 4010100;
+			obj.ipfo_ptr = old->fr_data;
+
+			if ((offset & 7) != 0)
+				offset += 8 - (offset & 7);
+			error = ipf_in_compat(softc, &obj,
+					      fr->fr_names + offset, 0);
+			if (error == 0) {
+				fr->fr_data = fr->fr_names + offset;
+				fr->fr_dsize = sizeof(fripf_t);
+			}
+		}
+	}
+}
+
+
+static void
+frentry_4_1_0_to_current(softc, old, current, size)
+	ipf_main_softc_t *softc;
+	frentry_4_1_0_t *old;
+	void *current;
+	int size;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	fr->fr_size = sizeof(*fr);
+	fr->fr_comment = -1;
+	fr->fr_ref = old->fr_ref;
+	fr->fr_statecnt = old->fr_statecnt;
+	fr->fr_hits = old->fr_hits;
+	fr->fr_bytes = old->fr_bytes;
+	fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec;
+	fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec;
+	bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun));
+	fr->fr_func = old->fr_func;
+	fr->fr_dsize = old->fr_dsize;
+	fr->fr_pps = old->fr_pps;
+	fr->fr_statemax = old->fr_statemax;
+	fr->fr_flineno = old->fr_flineno;
+	fr->fr_type = old->fr_type;
+	fr->fr_flags = fr_frflags4to5(old->fr_flags);
+	fr->fr_logtag = old->fr_logtag;
+	fr->fr_collect = old->fr_collect;
+	fr->fr_arg = old->fr_arg;
+	fr->fr_loglevel = old->fr_loglevel;
+	fr->fr_age[0] = old->fr_age[0];
+	fr->fr_age[1] = old->fr_age[1];
+	fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6;
+	fr->fr_tifs[0].fd_type = FRD_NORMAL;
+	fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6;
+	fr->fr_tifs[1].fd_type = FRD_NORMAL;
+	fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6;
+	fr->fr_dif.fd_type = FRD_NORMAL;
+	if (old->fr_v == 4)
+		fr->fr_family = AF_INET;
+	if (old->fr_v == 6)
+		fr->fr_family = AF_INET6;
+	fr->fr_icode = old->fr_icode;
+	fr->fr_cksum = old->fr_cksum;
+	fr->fr_namelen = 0;
+	fr->fr_ifnames[0] = -1;
+	fr->fr_ifnames[1] = -1;
+	fr->fr_ifnames[2] = -1;
+	fr->fr_ifnames[3] = -1;
+	fr->fr_dif.fd_name = -1;
+	fr->fr_tifs[0].fd_name = -1;
+	fr->fr_tifs[1].fd_name = -1;
+	fr->fr_group = -1;
+	fr->fr_grhead = -1;
+	fr->fr_icmphead = -1;
+	if (size == 0) {
+		fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2;
+		fr->fr_size += 9;	/* room for \0's */
+	} else {
+		char *names = fr->fr_names;
+		int nlen = fr->fr_namelen;
+
+		fr->fr_size = size;
+		if (old->fr_ifnames[0][0] != '\0') {
+			fr->fr_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[1][0] != '\0') {
+			fr->fr_ifnames[1] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[2][0] != '\0') {
+			fr->fr_ifnames[2] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_ifnames[3][0] != '\0') {
+			fr->fr_ifnames[3] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3],
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[0].fd_ifname[0] != '\0') {
+			fr->fr_tifs[0].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[0].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_tifs[1].fd_ifname[0] != '\0') {
+			fr->fr_tifs[1].fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_tifs[1].fd_ifname,
+					    LIFNAMSIZ);
+		}
+		if (old->fr_dif.fd_ifname[0] != '\0') {
+			fr->fr_dif.fd_name = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_dif.fd_ifname, LIFNAMSIZ);
+		}
+		if (old->fr_group[0] != '\0') {
+			fr->fr_group = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_group, LIFNAMSIZ);
+		}
+		if (old->fr_grhead[0] != '\0') {
+			fr->fr_grhead = nlen;
+			nlen = ipf_addfrstr(names, nlen,
+					    old->fr_grhead, LIFNAMSIZ);
+		}
+		fr->fr_namelen = nlen;
+
+		if (old->fr_type == FR_T_IPF) {
+			int offset = fr->fr_namelen;
+			ipfobj_t obj;
+			int error;
+
+			obj.ipfo_type = IPFOBJ_FRIPF;
+			obj.ipfo_rev = 4010100;
+			obj.ipfo_ptr = old->fr_data;
+
+			if ((offset & 7) != 0)
+				offset += 8 - (offset & 7);
+				offset += 8 - (offset & 7);
+			error = ipf_in_compat(softc, &obj,
+					      fr->fr_names + offset, 0);
+			if (error == 0) {
+				fr->fr_data = fr->fr_names + offset;
+				fr->fr_dsize = sizeof(fripf_t);
+			}
+		}
+	}
+}
+
+
+static void
+friostat_4_1_33_to_current(old, current)
+	friostat_4_1_33_t *old;
+	void *current;
+{
+	friostat_t *fiop = (friostat_t *)current;
+
+	bcopy(&old->of_st[0], &fiop->f_st[0].fr_pass, sizeof(old->of_st[0]));
+	bcopy(&old->of_st[1], &fiop->f_st[1].fr_pass, sizeof(old->of_st[1]));
+
+	fiop->f_ipf[0][0] = old->f_ipf[0][0];
+	fiop->f_ipf[0][1] = old->f_ipf[0][1];
+	fiop->f_ipf[1][0] = old->f_ipf[1][0];
+	fiop->f_ipf[1][1] = old->f_ipf[1][1];
+	fiop->f_acct[0][0] = old->f_acct[0][0];
+	fiop->f_acct[0][1] = old->f_acct[0][1];
+	fiop->f_acct[1][0] = old->f_acct[1][0];
+	fiop->f_acct[1][1] = old->f_acct[1][1];
+	fiop->f_auth = fiop->f_auth;
+	bcopy(&old->f_groups, &fiop->f_groups, sizeof(old->f_groups));
+	bcopy(&old->f_froute, &fiop->f_froute, sizeof(old->f_froute));
+	fiop->f_ticks = old->f_ticks;
+	bcopy(&old->f_locks, &fiop->f_locks, sizeof(old->f_locks));
+	fiop->f_defpass = old->f_defpass;
+	fiop->f_active = old->f_active;
+	fiop->f_running = old->f_running;
+	fiop->f_logging = old->f_logging;
+	fiop->f_features = old->f_features;
+	bcopy(old->f_version, fiop->f_version, sizeof(old->f_version));
+}
+
+
+static void
+friostat_4_1_0_to_current(old, current)
+	friostat_4_1_0_t *old;
+	void *current;
+{
+	friostat_t *fiop = (friostat_t *)current;
+
+	bcopy(&old->of_st[0], &fiop->f_st[0].fr_pass, sizeof(old->of_st[0]));
+	bcopy(&old->of_st[1], &fiop->f_st[1].fr_pass, sizeof(old->of_st[1]));
+
+	fiop->f_ipf[0][0] = old->f_ipf[0][0];
+	fiop->f_ipf[0][1] = old->f_ipf[0][1];
+	fiop->f_ipf[1][0] = old->f_ipf[1][0];
+	fiop->f_ipf[1][1] = old->f_ipf[1][1];
+	fiop->f_acct[0][0] = old->f_acct[0][0];
+	fiop->f_acct[0][1] = old->f_acct[0][1];
+	fiop->f_acct[1][0] = old->f_acct[1][0];
+	fiop->f_acct[1][1] = old->f_acct[1][1];
+	fiop->f_auth = fiop->f_auth;
+	bcopy(&old->f_groups, &fiop->f_groups, sizeof(old->f_groups));
+	bcopy(&old->f_froute, &fiop->f_froute, sizeof(old->f_froute));
+	fiop->f_ticks = old->f_ticks;
+	bcopy(&old->f_locks, &fiop->f_locks, sizeof(old->f_locks));
+	fiop->f_defpass = old->f_defpass;
+	fiop->f_active = old->f_active;
+	fiop->f_running = old->f_running;
+	fiop->f_logging = old->f_logging;
+	fiop->f_features = old->f_features;
+	bcopy(old->f_version, fiop->f_version, sizeof(old->f_version));
+}
+
+
+static void
+ipnat_4_1_14_to_current(old, current, size)
+	ipnat_4_1_14_t *old;
+	void *current;
+	int size;
+{
+	ipnat_t *np = (ipnat_t *)current;
+
+	np->in_space = old->in_space;
+	np->in_hv[0] = old->in_hv;
+	np->in_hv[1] = old->in_hv;
+	np->in_flineno = old->in_flineno;
+	if (old->in_redir == NAT_REDIRECT)
+		np->in_dpnext = old->in_pnext;
+	else
+		np->in_spnext = old->in_pnext;
+	np->in_v[0] = old->in_v;
+	np->in_v[1] = old->in_v;
+	np->in_flags = old->in_flags;
+	np->in_mssclamp = old->in_mssclamp;
+	np->in_age[0] = old->in_age[0];
+	np->in_age[1] = old->in_age[1];
+	np->in_redir = old->in_redir;
+	np->in_pr[0] = old->in_p;
+	np->in_pr[1] = old->in_p;
+	if (np->in_redir == NAT_REDIRECT) {
+		np->in_ndst.na_nextaddr = old->in_next6;
+		np->in_ndst.na_addr[0] = old->in_in[0];
+		np->in_ndst.na_addr[1] = old->in_in[1];
+		np->in_ndst.na_atype = FRI_NORMAL;
+		np->in_odst.na_addr[0] = old->in_out[0];
+		np->in_odst.na_addr[1] = old->in_out[1];
+		np->in_odst.na_atype = FRI_NORMAL;
+		np->in_osrc.na_addr[0] = old->in_src[0];
+		np->in_osrc.na_addr[1] = old->in_src[1];
+		np->in_osrc.na_atype = FRI_NORMAL;
+	} else {
+		np->in_nsrc.na_nextaddr = old->in_next6;
+		np->in_nsrc.na_addr[0] = old->in_out[0];
+		np->in_nsrc.na_addr[1] = old->in_out[1];
+		np->in_nsrc.na_atype = FRI_NORMAL;
+		np->in_osrc.na_addr[0] = old->in_in[0];
+		np->in_osrc.na_addr[1] = old->in_in[1];
+		np->in_osrc.na_atype = FRI_NORMAL;
+		np->in_odst.na_addr[0] = old->in_src[0];
+		np->in_odst.na_addr[1] = old->in_src[1];
+		np->in_odst.na_atype = FRI_NORMAL;
+	}
+	ipfv4tuctov5(&old->in_tuc, &np->in_tuc);
+	if (np->in_redir == NAT_REDIRECT) {
+		np->in_dpmin = old->in_port[0];
+		np->in_dpmax = old->in_port[1];
+	} else {
+		np->in_spmin = old->in_port[0];
+		np->in_spmax = old->in_port[1];
+	}
+	np->in_ppip = old->in_ppip;
+	np->in_ippip = old->in_ippip;
+	np->in_tag = old->in_tag;
+
+	np->in_namelen = 0;
+	np->in_plabel = -1;
+	np->in_ifnames[0] = -1;
+	np->in_ifnames[1] = -1;
+
+	if (size == 0) {
+		np->in_size = sizeof(*np);
+		np->in_size += LIFNAMSIZ * 2 + APR_LABELLEN;
+		np->in_size += 3;
+	} else {
+		int nlen = np->in_namelen;
+		char *names = np->in_names;
+
+		if (old->in_ifnames[0][0] != '\0') {
+			np->in_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_ifnames[0],
+					    LIFNAMSIZ);
+		}
+		if (old->in_ifnames[1][0] != '\0') {
+			np->in_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_ifnames[1],
+					    LIFNAMSIZ);
+		}
+		if (old->in_plabel[0] != '\0') {
+			np->in_plabel = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_plabel,
+					    LIFNAMSIZ);
+		}
+		np->in_namelen = nlen;
+		np->in_size = size;
+	}
+}
+
+
+static void
+ipnat_4_1_0_to_current(old, current, size)
+	ipnat_4_1_0_t *old;
+	void *current;
+	int size;
+{
+	ipnat_t *np = (ipnat_t *)current;
+
+	np->in_space = old->in_space;
+	np->in_hv[0] = old->in_hv;
+	np->in_hv[1] = old->in_hv;
+	np->in_flineno = old->in_flineno;
+	if (old->in_redir == NAT_REDIRECT)
+		np->in_dpnext = old->in_pnext;
+	else
+		np->in_spnext = old->in_pnext;
+	np->in_v[0] = old->in_v;
+	np->in_v[1] = old->in_v;
+	np->in_flags = old->in_flags;
+	np->in_mssclamp = old->in_mssclamp;
+	np->in_age[0] = old->in_age[0];
+	np->in_age[1] = old->in_age[1];
+	np->in_redir = old->in_redir;
+	np->in_pr[0] = old->in_p;
+	np->in_pr[1] = old->in_p;
+	if (np->in_redir == NAT_REDIRECT) {
+		np->in_ndst.na_nextaddr = old->in_next6;
+		bcopy(&old->in_in, &np->in_ndst.na_addr, sizeof(old->in_in));
+		bcopy(&old->in_out, &np->in_odst.na_addr, sizeof(old->in_out));
+		bcopy(&old->in_src, &np->in_osrc.na_addr, sizeof(old->in_src));
+	} else {
+		np->in_nsrc.na_nextaddr = old->in_next6;
+		bcopy(&old->in_in, &np->in_osrc.na_addr, sizeof(old->in_in));
+		bcopy(&old->in_out, &np->in_nsrc.na_addr, sizeof(old->in_out));
+		bcopy(&old->in_src, &np->in_odst.na_addr, sizeof(old->in_src));
+	}
+	ipfv4tuctov5(&old->in_tuc, &np->in_tuc);
+	if (np->in_redir == NAT_REDIRECT) {
+		np->in_dpmin = old->in_port[0];
+		np->in_dpmax = old->in_port[1];
+	} else {
+		np->in_spmin = old->in_port[0];
+		np->in_spmax = old->in_port[1];
+	}
+	np->in_ppip = old->in_ppip;
+	np->in_ippip = old->in_ippip;
+	bcopy(&old->in_tag, &np->in_tag, sizeof(np->in_tag));
+
+	np->in_namelen = 0;
+	np->in_plabel = -1;
+	np->in_ifnames[0] = -1;
+	np->in_ifnames[1] = -1;
+
+	if (size == 0) {
+		np->in_size = sizeof(*np);
+		np->in_size += LIFNAMSIZ * 2 + APR_LABELLEN;
+		np->in_size += 3;
+	} else {
+		int nlen = np->in_namelen;
+		char *names = np->in_names;
+
+		if (old->in_ifnames[0][0] != '\0') {
+			np->in_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_ifnames[0],
+					    LIFNAMSIZ);
+		}
+		if (old->in_ifnames[1][0] != '\0') {
+			np->in_ifnames[0] = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_ifnames[1],
+					    LIFNAMSIZ);
+		}
+		if (old->in_plabel[0] != '\0') {
+			np->in_plabel = nlen;
+			nlen = ipf_addfrstr(names, nlen, old->in_plabel,
+					    LIFNAMSIZ);
+		}
+		np->in_namelen = nlen;
+		np->in_size = size;
+	}
+}
+
+
+static void
+frauth_4_1_32_to_current(old, current)
+	frauth_4_1_32_t *old;
+	void *current;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	fra->fra_age = old->fra_age;
+	fra->fra_len = old->fra_len;
+	fra->fra_index = old->fra_index;
+	fra->fra_pass = old->fra_pass;
+	fr_info_4_1_32_to_current(&old->fra_info, &fra->fra_info);
+	fra->fra_buf = old->fra_buf;
+	fra->fra_flx = old->fra_flx;
+#ifdef	MENTAT
+	fra->fra_q = old->fra_q;
+	fra->fra_m = old->fra_m;
+#endif
+}
+
+
+static void
+frauth_4_1_29_to_current(old, current)
+	frauth_4_1_29_t *old;
+	void *current;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	fra->fra_age = old->fra_age;
+	fra->fra_len = old->fra_len;
+	fra->fra_index = old->fra_index;
+	fra->fra_pass = old->fra_pass;
+	fr_info_4_1_24_to_current(&old->fra_info, &fra->fra_info);
+	fra->fra_buf = old->fra_buf;
+	fra->fra_flx = old->fra_flx;
+#ifdef	MENTAT
+	fra->fra_q = old->fra_q;
+	fra->fra_m = old->fra_m;
+#endif
+}
+
+
+static void
+frauth_4_1_24_to_current(old, current)
+	frauth_4_1_24_t *old;
+	void *current;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	fra->fra_age = old->fra_age;
+	fra->fra_len = old->fra_len;
+	fra->fra_index = old->fra_index;
+	fra->fra_pass = old->fra_pass;
+	fr_info_4_1_24_to_current(&old->fra_info, &fra->fra_info);
+	fra->fra_buf = old->fra_buf;
+#ifdef	MENTAT
+	fra->fra_q = old->fra_q;
+	fra->fra_m = old->fra_m;
+#endif
+}
+
+
+static void
+frauth_4_1_23_to_current(old, current)
+	frauth_4_1_23_t *old;
+	void *current;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	fra->fra_age = old->fra_age;
+	fra->fra_len = old->fra_len;
+	fra->fra_index = old->fra_index;
+	fra->fra_pass = old->fra_pass;
+	fr_info_4_1_23_to_current(&old->fra_info, &fra->fra_info);
+	fra->fra_buf = old->fra_buf;
+#ifdef	MENTAT
+	fra->fra_q = old->fra_q;
+	fra->fra_m = old->fra_m;
+#endif
+}
+
+
+static void
+frauth_4_1_11_to_current(old, current)
+	frauth_4_1_11_t *old;
+	void *current;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	fra->fra_age = old->fra_age;
+	fra->fra_len = old->fra_len;
+	fra->fra_index = old->fra_index;
+	fra->fra_pass = old->fra_pass;
+	fr_info_4_1_11_to_current(&old->fra_info, &fra->fra_info);
+	fra->fra_buf = old->fra_buf;
+#ifdef	MENTAT
+	fra->fra_q = old->fra_q;
+	fra->fra_m = old->fra_m;
+#endif
+}
+
+
+static void
+fr_info_4_1_32_to_current(old, current)
+	fr_info_4_1_32_t *old;
+	void *current;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	fin->fin_ifp = old->fin_ifp;
+	ipf_v4iptov5(&old->fin_fi, &fin->fin_fi);
+	bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat));
+	fin->fin_out = old->fin_out;
+	fin->fin_rev = old->fin_rev;
+	fin->fin_hlen = old->fin_hlen;
+	fin->fin_tcpf = old->ofin_tcpf;
+	fin->fin_icode = old->fin_icode;
+	fin->fin_rule = old->fin_rule;
+	bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group));
+	fin->fin_fr = old->fin_fr;
+	fin->fin_dp = old->fin_dp;
+	fin->fin_dlen = old->fin_dlen;
+	fin->fin_plen = old->fin_plen;
+	fin->fin_ipoff = old->fin_ipoff;
+	fin->fin_id = old->fin_id;
+	fin->fin_off = old->fin_off;
+	fin->fin_depth = old->fin_depth;
+	fin->fin_error = old->fin_error;
+	fin->fin_cksum = old->fin_cksum;
+	fin->fin_nattag = old->fin_nattag;
+	fin->fin_ip = old->ofin_ip;
+	fin->fin_mp = old->fin_mp;
+	fin->fin_m = old->fin_m;
+#ifdef  MENTAT
+	fin->fin_qfm = old->fin_qfm;
+	fin->fin_qpi = old->fin_qpi;
+#endif
+#ifdef  __sgi
+	fin->fin_hbuf = old->fin_hbuf;
+#endif
+}
+
+
+static void
+fr_info_4_1_24_to_current(old, current)
+	fr_info_4_1_24_t *old;
+	void *current;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	fin->fin_ifp = old->fin_ifp;
+	ipf_v4iptov5(&old->fin_fi, &fin->fin_fi);
+	bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat));
+	fin->fin_out = old->fin_out;
+	fin->fin_rev = old->fin_rev;
+	fin->fin_hlen = old->fin_hlen;
+	fin->fin_tcpf = old->ofin_tcpf;
+	fin->fin_icode = old->fin_icode;
+	fin->fin_rule = old->fin_rule;
+	bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group));
+	fin->fin_fr = old->fin_fr;
+	fin->fin_dp = old->fin_dp;
+	fin->fin_dlen = old->fin_dlen;
+	fin->fin_plen = old->fin_plen;
+	fin->fin_ipoff = old->fin_ipoff;
+	fin->fin_id = old->fin_id;
+	fin->fin_off = old->fin_off;
+	fin->fin_depth = old->fin_depth;
+	fin->fin_error = old->fin_error;
+	fin->fin_cksum = old->fin_cksum;
+	fin->fin_nattag = old->fin_nattag;
+	fin->fin_ip = old->ofin_ip;
+	fin->fin_mp = old->fin_mp;
+	fin->fin_m = old->fin_m;
+#ifdef  MENTAT
+	fin->fin_qfm = old->fin_qfm;
+	fin->fin_qpi = old->fin_qpi;
+#endif
+#ifdef  __sgi
+	fin->fin_hbuf = old->fin_hbuf;
+#endif
+}
+
+
+static void
+fr_info_4_1_23_to_current(old, current)
+	fr_info_4_1_23_t *old;
+	void *current;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	fin->fin_ifp = old->fin_ifp;
+	ipf_v4iptov5(&old->fin_fi, &fin->fin_fi);
+	bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat));
+	fin->fin_out = old->fin_out;
+	fin->fin_rev = old->fin_rev;
+	fin->fin_hlen = old->fin_hlen;
+	fin->fin_tcpf = old->ofin_tcpf;
+	fin->fin_icode = old->fin_icode;
+	fin->fin_rule = old->fin_rule;
+	bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group));
+	fin->fin_fr = old->fin_fr;
+	fin->fin_dp = old->fin_dp;
+	fin->fin_dlen = old->fin_dlen;
+	fin->fin_plen = old->fin_plen;
+	fin->fin_ipoff = old->fin_ipoff;
+	fin->fin_id = old->fin_id;
+	fin->fin_off = old->fin_off;
+	fin->fin_depth = old->fin_depth;
+	fin->fin_error = old->fin_error;
+	fin->fin_nattag = old->fin_nattag;
+	fin->fin_ip = old->ofin_ip;
+	fin->fin_mp = old->fin_mp;
+	fin->fin_m = old->fin_m;
+#ifdef  MENTAT
+	fin->fin_qfm = old->fin_qfm;
+	fin->fin_qpi = old->fin_qpi;
+#endif
+#ifdef  __sgi
+	fin->fin_hbuf = fin->fin_hbuf;
+#endif
+}
+
+
+static void
+fr_info_4_1_11_to_current(old, current)
+	fr_info_4_1_11_t *old;
+	void *current;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	fin->fin_ifp = old->fin_ifp;
+	ipf_v4iptov5(&old->fin_fi, &fin->fin_fi);
+	bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat));
+	fin->fin_out = old->fin_out;
+	fin->fin_rev = old->fin_rev;
+	fin->fin_hlen = old->fin_hlen;
+	fin->fin_tcpf = old->ofin_tcpf;
+	fin->fin_icode = old->fin_icode;
+	fin->fin_rule = old->fin_rule;
+	bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group));
+	fin->fin_fr = old->fin_fr;
+	fin->fin_dp = old->fin_dp;
+	fin->fin_dlen = old->fin_dlen;
+	fin->fin_plen = old->fin_plen;
+	fin->fin_ipoff = old->fin_ipoff;
+	fin->fin_id = old->fin_id;
+	fin->fin_off = old->fin_off;
+	fin->fin_depth = old->fin_depth;
+	fin->fin_error = old->fin_error;
+	fin->fin_nattag = old->fin_nattag;
+	fin->fin_ip = old->ofin_ip;
+	fin->fin_mp = old->fin_mp;
+	fin->fin_m = old->fin_m;
+#ifdef  MENTAT
+	fin->fin_qfm = old->fin_qfm;
+	fin->fin_qpi = old->fin_qpi;
+#endif
+#ifdef  __sgi
+	fin->fin_hbuf = fin->fin_hbuf;
+#endif
+}
+
+
+static void
+nat_4_1_3_to_current(nat_4_1_3_t *old, nat_t *current)
+{
+	bzero((void *)current, sizeof(*current));
+	bcopy((void *)old, (void *)current, sizeof(*old));
+}
+
+
+static void
+nat_4_1_14_to_current(nat_4_1_14_t *old, nat_t *current)
+{
+	bzero((void *)current, sizeof(*current));
+	bcopy((void *)old, (void *)current, sizeof(*old));
+}
+
+
+static void
+nat_save_4_1_16_to_current(softc, old, current)
+	ipf_main_softc_t *softc;
+	nat_save_4_1_16_t *old;
+	void *current;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	nats->ipn_next = old->ipn_next;
+	nat_4_1_14_to_current(&old->ipn_nat, &nats->ipn_nat);
+	bcopy(&old->ipn_ipnat, &nats->ipn_ipnat, sizeof(old->ipn_ipnat));
+	frentry_4_1_16_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0);
+	nats->ipn_dsize = old->ipn_dsize;
+	bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+nat_save_4_1_14_to_current(softc, old, current)
+	ipf_main_softc_t *softc;
+	nat_save_4_1_14_t *old;
+	void *current;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	nats->ipn_next = old->ipn_next;
+	nat_4_1_14_to_current(&old->ipn_nat, &nats->ipn_nat);
+	bcopy(&old->ipn_ipnat, &nats->ipn_ipnat, sizeof(old->ipn_ipnat));
+	frentry_4_1_0_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0);
+	nats->ipn_dsize = old->ipn_dsize;
+	bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+nat_save_4_1_3_to_current(softc, old, current)
+	ipf_main_softc_t *softc;
+	nat_save_4_1_3_t *old;
+	void *current;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	nats->ipn_next = old->ipn_next;
+	nat_4_1_3_to_current(&old->ipn_nat, &nats->ipn_nat);
+	ipnat_4_1_0_to_current(&old->ipn_ipnat, &nats->ipn_ipnat, 0);
+	frentry_4_1_0_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0);
+	nats->ipn_dsize = old->ipn_dsize;
+	bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+natstat_current_to_4_1_32(current, old)
+	void *current;
+	natstat_4_1_32_t *old;
+{
+	natstat_t *ns = (natstat_t *)current;
+
+	old->ns_mapped[0] = ns->ns_side[0].ns_translated;
+	old->ns_mapped[1] = ns->ns_side[1].ns_translated;
+	old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added;
+	old->ns_expire = ns->ns_expire;
+	old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_logged = ns->ns_log_ok;
+	old->ns_logfail = ns->ns_log_fail;
+	old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail;
+	old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat;
+	old->ns_addtrpnt = ns->ns_addtrpnt;
+	old->ns_table[0] = ns->ns_side[0].ns_table;
+	old->ns_table[1] = ns->ns_side[1].ns_table;
+	old->ns_maptable = NULL;
+	old->ns_list = ns->ns_list;
+	old->ns_apslist = NULL;
+	old->ns_wilds = ns->ns_wilds;
+	old->ns_nattab_sz = ns->ns_nattab_sz;
+	old->ns_nattab_max = ns->ns_nattab_max;
+	old->ns_rultab_sz = ns->ns_rultab_sz;
+	old->ns_rdrtab_sz = ns->ns_rdrtab_sz;
+	old->ns_trpntab_sz = ns->ns_trpntab_sz;
+	old->ns_hostmap_sz = 0;
+	old->ns_instances = ns->ns_instances;
+	old->ns_maplist = ns->ns_maplist;
+	old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen;
+	old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen;
+	old->ns_ticks = ns->ns_ticks;
+	old->ns_orphans = ns->ns_orphans;
+	old->ns_uncreate[0][0] = ns->ns_side[0].ns_uncreate[0];
+	old->ns_uncreate[0][1] = ns->ns_side[0].ns_uncreate[1];
+	old->ns_uncreate[1][0] = ns->ns_side[1].ns_uncreate[0];
+	old->ns_uncreate[1][1] = ns->ns_side[1].ns_uncreate[1];
+}
+
+
+static void
+natstat_current_to_4_1_27(current, old)
+	void *current;
+	natstat_4_1_27_t *old;
+{
+	natstat_t *ns = (natstat_t *)current;
+
+	old->ns_mapped[0] = ns->ns_side[0].ns_translated;
+	old->ns_mapped[1] = ns->ns_side[1].ns_translated;
+	old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added;
+	old->ns_expire = ns->ns_expire;
+	old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_logged = ns->ns_log_ok;
+	old->ns_logfail = ns->ns_log_fail;
+	old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail;
+	old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat;
+	old->ns_addtrpnt = ns->ns_addtrpnt;
+	old->ns_table[0] = ns->ns_side[0].ns_table;
+	old->ns_table[1] = ns->ns_side[1].ns_table;
+	old->ns_maptable = NULL;
+	old->ns_list = ns->ns_list;
+	old->ns_apslist = NULL;
+	old->ns_wilds = ns->ns_wilds;
+	old->ns_nattab_sz = ns->ns_nattab_sz;
+	old->ns_nattab_max = ns->ns_nattab_max;
+	old->ns_rultab_sz = ns->ns_rultab_sz;
+	old->ns_rdrtab_sz = ns->ns_rdrtab_sz;
+	old->ns_trpntab_sz = ns->ns_trpntab_sz;
+	old->ns_hostmap_sz = 0;
+	old->ns_instances = ns->ns_instances;
+	old->ns_maplist = ns->ns_maplist;
+	old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen;
+	old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen;
+	old->ns_ticks = ns->ns_ticks;
+	old->ns_orphans = ns->ns_orphans;
+}
+
+
+static void
+natstat_current_to_4_1_16(current, old)
+	void *current;
+	natstat_4_1_16_t *old;
+{
+	natstat_t *ns = (natstat_t *)current;
+
+	old->ns_mapped[0] = ns->ns_side[0].ns_translated;
+	old->ns_mapped[1] = ns->ns_side[1].ns_translated;
+	old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added;
+	old->ns_expire = ns->ns_expire;
+	old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_logged = ns->ns_log_ok;
+	old->ns_logfail = ns->ns_log_fail;
+	old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail;
+	old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat;
+	old->ns_addtrpnt = ns->ns_addtrpnt;
+	old->ns_table[0] = ns->ns_side[0].ns_table;
+	old->ns_table[1] = ns->ns_side[1].ns_table;
+	old->ns_maptable = NULL;
+	old->ns_list = ns->ns_list;
+	old->ns_apslist = NULL;
+	old->ns_wilds = ns->ns_wilds;
+	old->ns_nattab_sz = ns->ns_nattab_sz;
+	old->ns_nattab_max = ns->ns_nattab_max;
+	old->ns_rultab_sz = ns->ns_rultab_sz;
+	old->ns_rdrtab_sz = ns->ns_rdrtab_sz;
+	old->ns_trpntab_sz = ns->ns_trpntab_sz;
+	old->ns_hostmap_sz = 0;
+	old->ns_instances = ns->ns_instances;
+	old->ns_maplist = ns->ns_maplist;
+	old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen;
+	old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen;
+	old->ns_ticks = ns->ns_ticks;
+}
+
+
+static void
+natstat_current_to_4_1_0(current, old)
+	void *current;
+	natstat_4_1_0_t *old;
+{
+	natstat_t *ns = (natstat_t *)current;
+
+	old->ns_mapped[0] = ns->ns_side[0].ns_translated;
+	old->ns_mapped[1] = ns->ns_side[1].ns_translated;
+	old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added;
+	old->ns_expire = ns->ns_expire;
+	old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse;
+	old->ns_logged = ns->ns_log_ok;
+	old->ns_logfail = ns->ns_log_fail;
+	old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail;
+	old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat;
+	old->ns_addtrpnt = ns->ns_addtrpnt;
+	old->ns_table[0] = ns->ns_side[0].ns_table;
+	old->ns_table[1] = ns->ns_side[1].ns_table;
+	old->ns_maptable = NULL;
+	old->ns_list = ns->ns_list;
+	old->ns_apslist = NULL;
+	old->ns_wilds = ns->ns_wilds;
+	old->ns_nattab_sz = ns->ns_nattab_sz;
+	old->ns_nattab_max = ns->ns_nattab_max;
+	old->ns_rultab_sz = ns->ns_rultab_sz;
+	old->ns_rdrtab_sz = ns->ns_rdrtab_sz;
+	old->ns_trpntab_sz = ns->ns_trpntab_sz;
+	old->ns_hostmap_sz = 0;
+	old->ns_instances = ns->ns_instances;
+	old->ns_maplist = ns->ns_maplist;
+	old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen;
+	old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen;
+}
+
+
+static void
+ipstate_save_current_to_4_1_16(current, old)
+	void *current;
+	ipstate_save_4_1_16_t *old;
+{
+	ipstate_save_t *ips = (ipstate_save_t *)current;
+
+	old->ips_next = ips->ips_next;
+	ipstate_current_to_4_1_0(&ips->ips_is, &old->ips_is);
+	frentry_current_to_4_1_16(&ips->ips_fr, &old->ips_fr);
+}
+
+
+static void
+ipstate_save_current_to_4_1_0(current, old)
+	void *current;
+	ipstate_save_4_1_0_t *old;
+{
+	ipstate_save_t *ips = (ipstate_save_t *)current;
+
+	old->ips_next = ips->ips_next;
+	ipstate_current_to_4_1_0(&ips->ips_is, &old->ips_is);
+	frentry_current_to_4_1_0(&ips->ips_fr, &old->ips_fr);
+}
+
+
+int
+ipf_out_compat(softc, obj, ptr)
+	ipf_main_softc_t *softc;
+	ipfobj_t *obj;
+	void *ptr;
+{
+	frentry_t *fr;
+	int error;
+
+	IPFERROR(140042);
+	error = EINVAL;
+
+	switch (obj->ipfo_type)
+	{
+	default :
+		break;
+
+	case IPFOBJ_FRENTRY :
+		if (obj->ipfo_rev >= 4013400) {
+			frentry_4_1_34_t *old;
+
+			KMALLOC(old, frentry_4_1_34_t *);
+			if (old == NULL) {
+				IPFERROR(140043);
+				error = ENOMEM;
+				break;
+			}
+			frentry_current_to_4_1_34(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error == 0 && old->fr_dsize > 0) {
+				char *dst = obj->ipfo_ptr;
+
+				fr = ptr;
+				dst += sizeof(*old);
+				error = COPYOUT(fr->fr_data, dst,
+						old->fr_dsize);
+				if (error != 0) {
+					IPFERROR(140044);
+				}
+			}
+			KFREE(old);
+			obj->ipfo_size = sizeof(*old);
+		} else if (obj->ipfo_rev >= 4011600) {
+			frentry_4_1_16_t *old;
+
+			KMALLOC(old, frentry_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140045);
+				error = ENOMEM;
+				break;
+			}
+			frentry_current_to_4_1_16(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140046);
+			}
+			KFREE(old);
+			obj->ipfo_size = sizeof(*old);
+		} else {
+			frentry_4_1_0_t *old;
+
+			KMALLOC(old, frentry_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140047);
+				error = ENOMEM;
+				break;
+			}
+			frentry_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140048);
+			}
+			KFREE(old);
+			obj->ipfo_size = sizeof(*old);
+		}
+		break;
+
+	case IPFOBJ_IPFSTAT :
+		if (obj->ipfo_rev >= 4013300) {
+			friostat_4_1_33_t *old;
+
+			KMALLOC(old, friostat_4_1_33_t *);
+			if (old == NULL) {
+				IPFERROR(140049);
+				error = ENOMEM;
+				break;
+			}
+			friostat_current_to_4_1_33(ptr, old, obj->ipfo_rev);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140050);
+			}
+			KFREE(old);
+		} else {
+			friostat_4_1_0_t *old;
+
+			KMALLOC(old, friostat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140051);
+				error = ENOMEM;
+				break;
+			}
+			friostat_current_to_4_1_0(ptr, old, obj->ipfo_rev);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140052);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_IPFINFO :	/* unused */
+		break;
+
+	case IPFOBJ_IPNAT :
+		if (obj->ipfo_rev >= 4011400) {
+			ipnat_4_1_14_t *old;
+
+			KMALLOC(old, ipnat_4_1_14_t *);
+			if (old == NULL) {
+				IPFERROR(140053);
+				error = ENOMEM;
+				break;
+			}
+			ipnat_current_to_4_1_14(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140054);
+			}
+			KFREE(old);
+		} else {
+			ipnat_4_1_0_t *old;
+
+			KMALLOC(old, ipnat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140055);
+				error = ENOMEM;
+				break;
+			}
+			ipnat_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140056);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_NATSTAT :
+		if (obj->ipfo_rev >= 4013200) {
+			natstat_4_1_32_t *old;
+
+			KMALLOC(old, natstat_4_1_32_t *);
+			if (old == NULL) {
+				IPFERROR(140057);
+				error = ENOMEM;
+				break;
+			}
+			natstat_current_to_4_1_32(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140058);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4012700) {
+			natstat_4_1_27_t *old;
+
+			KMALLOC(old, natstat_4_1_27_t *);
+			if (old == NULL) {
+				IPFERROR(140059);
+				error = ENOMEM;
+				break;
+			}
+			natstat_current_to_4_1_27(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140060);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4011600) {
+			natstat_4_1_16_t *old;
+
+			KMALLOC(old, natstat_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140061);
+				error = ENOMEM;
+				break;
+			}
+			natstat_current_to_4_1_16(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140062);
+			}
+			KFREE(old);
+		} else {
+			natstat_4_1_0_t *old;
+
+			KMALLOC(old, natstat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140063);
+				error = ENOMEM;
+				break;
+			}
+			natstat_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140064);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_STATESAVE :
+		if (obj->ipfo_rev >= 4011600) {
+			ipstate_save_4_1_16_t *old;
+
+			KMALLOC(old, ipstate_save_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140065);
+				error = ENOMEM;
+				break;
+			}
+			ipstate_save_current_to_4_1_16(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140066);
+			}
+			KFREE(old);
+		} else {
+			ipstate_save_4_1_0_t *old;
+
+			KMALLOC(old, ipstate_save_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140067);
+				error = ENOMEM;
+				break;
+			}
+			ipstate_save_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140068);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_NATSAVE :
+		if (obj->ipfo_rev >= 4011600) {
+			nat_save_4_1_16_t *old16;
+
+			KMALLOC(old16, nat_save_4_1_16_t *);
+			if (old16 == NULL) {
+				IPFERROR(140069);
+				error = ENOMEM;
+				break;
+			}
+			nat_save_current_to_4_1_16(ptr, old16);
+			error = COPYOUT(&old16, obj->ipfo_ptr, sizeof(*old16));
+			if (error != 0) {
+				IPFERROR(140070);
+			}
+			KFREE(old16);
+		} else if (obj->ipfo_rev >= 4011400) {
+			nat_save_4_1_14_t *old14;
+
+			KMALLOC(old14, nat_save_4_1_14_t *);
+			if (old14 == NULL) {
+				IPFERROR(140071);
+				error = ENOMEM;
+				break;
+			}
+			nat_save_current_to_4_1_14(ptr, old14);
+			error = COPYOUT(&old14, obj->ipfo_ptr, sizeof(*old14));
+			if (error != 0) {
+				IPFERROR(140072);
+			}
+			KFREE(old14);
+		} else if (obj->ipfo_rev >= 4010300) {
+			nat_save_4_1_3_t *old3;
+
+			KMALLOC(old3, nat_save_4_1_3_t *);
+			if (old3 == NULL) {
+				IPFERROR(140073);
+				error = ENOMEM;
+				break;
+			}
+			nat_save_current_to_4_1_3(ptr, old3);
+			error = COPYOUT(&old3, obj->ipfo_ptr, sizeof(*old3));
+			if (error != 0) {
+				IPFERROR(140074);
+			}
+			KFREE(old3);
+		}
+		break;
+
+	case IPFOBJ_IPSTATE :
+		if (obj->ipfo_rev >= 4011600) {
+			ipstate_4_1_16_t *old;
+
+			KMALLOC(old, ipstate_4_1_16_t *);
+			if (old == NULL) {
+				IPFERROR(140075);
+				error = ENOMEM;
+				break;
+			}
+			ipstate_current_to_4_1_16(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140076);
+			}
+			KFREE(old);
+		} else {
+			ipstate_4_1_0_t *old;
+
+			KMALLOC(old, ipstate_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140077);
+				error = ENOMEM;
+				break;
+			}
+			ipstate_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140078);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_STATESTAT :
+		if (obj->ipfo_rev >= 4012100) {
+			ips_stat_4_1_21_t *old;
+
+			KMALLOC(old, ips_stat_4_1_21_t *);
+			if (old == NULL) {
+				IPFERROR(140079);
+				error = ENOMEM;
+				break;
+			}
+			ips_stat_current_to_4_1_21(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140080);
+			}
+			KFREE(old);
+		} else {
+			ips_stat_4_1_0_t *old;
+
+			KMALLOC(old, ips_stat_4_1_0_t *);
+			if (old == NULL) {
+				IPFERROR(140081);
+				error = ENOMEM;
+				break;
+			}
+			ips_stat_current_to_4_1_0(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140082);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_FRAUTH :
+		if (obj->ipfo_rev >= 4012900) {
+			frauth_4_1_29_t *old29;
+
+			KMALLOC(old29, frauth_4_1_29_t *);
+			if (old29 == NULL) {
+				IPFERROR(140083);
+				error = ENOMEM;
+				break;
+			}
+			frauth_current_to_4_1_29(ptr, old29);
+			error = COPYOUT(old29, obj->ipfo_ptr, sizeof(*old29));
+			if (error != 0) {
+				IPFERROR(140084);
+			}
+			KFREE(old29);
+		} else if (obj->ipfo_rev >= 4012400) {
+			frauth_4_1_24_t *old24;
+
+			KMALLOC(old24, frauth_4_1_24_t *);
+			if (old24 == NULL) {
+				IPFERROR(140085);
+				error = ENOMEM;
+				break;
+			}
+			frauth_current_to_4_1_24(ptr, old24);
+			error = COPYOUT(old24, obj->ipfo_ptr, sizeof(*old24));
+			if (error != 0) {
+				IPFERROR(140086);
+			}
+			KFREE(old24);
+		} else if (obj->ipfo_rev >= 4012300) {
+			frauth_4_1_23_t *old23;
+
+			KMALLOC(old23, frauth_4_1_23_t *);
+			if (old23 == NULL) {
+				IPFERROR(140087);
+				error = ENOMEM;
+				break;
+			}
+			frauth_current_to_4_1_23(ptr, old23);
+			error = COPYOUT(old23, obj->ipfo_ptr, sizeof(*old23));
+			if (error != 0) {
+				IPFERROR(140088);
+			}
+			KFREE(old23);
+		} else if (obj->ipfo_rev >= 4011100) {
+			frauth_4_1_11_t *old11;
+
+			KMALLOC(old11, frauth_4_1_11_t *);
+			if (old11 == NULL) {
+				IPFERROR(140089);
+				error = ENOMEM;
+				break;
+			}
+			frauth_current_to_4_1_11(ptr, old11);
+			error = COPYOUT(old11, obj->ipfo_ptr, sizeof(*old11));
+			if (error != 0) {
+				IPFERROR(140090);
+			}
+			KFREE(old11);
+		}
+		break;
+
+	case IPFOBJ_NAT :
+		if (obj->ipfo_rev >= 4012500) {
+			nat_4_1_25_t *old;
+
+			KMALLOC(old, nat_4_1_25_t *);
+			if (old == NULL) {
+				IPFERROR(140091);
+				error = ENOMEM;
+				break;
+			}
+			nat_current_to_4_1_25(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140092);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4011400) {
+			nat_4_1_14_t *old;
+
+			KMALLOC(old, nat_4_1_14_t *);
+			if (old == NULL) {
+				IPFERROR(140093);
+				error = ENOMEM;
+				break;
+			}
+			nat_current_to_4_1_14(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140094);
+			}
+			KFREE(old);
+		} else if (obj->ipfo_rev >= 4010300) {
+			nat_4_1_3_t *old;
+
+			KMALLOC(old, nat_4_1_3_t *);
+			if (old == NULL) {
+				IPFERROR(140095);
+				error = ENOMEM;
+				break;
+			}
+			nat_current_to_4_1_3(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140096);
+			}
+			KFREE(old);
+		}
+		break;
+
+	case IPFOBJ_FRIPF :
+		if (obj->ipfo_rev < 5000000) {
+			fripf4_t *old;
+
+			KMALLOC(old, fripf4_t *);
+			if (old == NULL) {
+				IPFERROR(140097);
+				error = ENOMEM;
+				break;
+			}
+			ipf_v5fripftov4(ptr, old);
+			error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old));
+			if (error != 0) {
+				IPFERROR(140098);
+			}
+			KFREE(old);
+		}
+		break;
+	}
+	return error;
+}
+
+
+static void
+friostat_current_to_4_1_33(current, old, rev)
+	void *current;
+	friostat_4_1_33_t *old;
+	int rev;
+{
+	friostat_t *fiop = (friostat_t *)current;
+
+	bcopy(&fiop->f_st[0].fr_pass, &old->of_st[0], sizeof(old->of_st[0]));
+	bcopy(&fiop->f_st[1].fr_pass, &old->of_st[1], sizeof(old->of_st[1]));
+
+	old->f_ipf[0][0] = fiop->f_ipf[0][0];
+	old->f_ipf[0][1] = fiop->f_ipf[0][1];
+	old->f_ipf[1][0] = fiop->f_ipf[1][0];
+	old->f_ipf[1][1] = fiop->f_ipf[1][1];
+	old->f_acct[0][0] = fiop->f_acct[0][0];
+	old->f_acct[0][1] = fiop->f_acct[0][1];
+	old->f_acct[1][0] = fiop->f_acct[1][0];
+	old->f_acct[1][1] = fiop->f_acct[1][1];
+	old->f_ipf6[0][0] = NULL;
+	old->f_ipf6[0][1] = NULL;
+	old->f_ipf6[1][0] = NULL;
+	old->f_ipf6[1][1] = NULL;
+	old->f_acct6[0][0] = NULL;
+	old->f_acct6[0][1] = NULL;
+	old->f_acct6[1][0] = NULL;
+	old->f_acct6[1][1] = NULL;
+	old->f_auth = fiop->f_auth;
+	bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups));
+	bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute));
+	old->f_ticks = fiop->f_ticks;
+	bcopy(&fiop->f_locks, &old->f_locks, sizeof(old->f_locks));
+	old->f_kmutex_sz = 0;
+	old->f_krwlock_sz = 0;
+	old->f_defpass = fiop->f_defpass;
+	old->f_active = fiop->f_active;
+	old->f_running = fiop->f_running;
+	old->f_logging = fiop->f_logging;
+	old->f_features = fiop->f_features;
+	sprintf(old->f_version, "IP Filter: v%d.%d.%d",
+		(rev / 1000000) % 100,
+		(rev / 10000) % 100,
+		(rev / 100) % 100);
+}
+
+
+static void
+friostat_current_to_4_1_0(current, old, rev)
+	void *current;
+	friostat_4_1_0_t *old;
+	int rev;
+{
+	friostat_t *fiop = (friostat_t *)current;
+
+	bcopy(&fiop->f_st[0].fr_pass, &old->of_st[0], sizeof(old->of_st[0]));
+	bcopy(&fiop->f_st[1].fr_pass, &old->of_st[1], sizeof(old->of_st[1]));
+
+	old->f_ipf[0][0] = fiop->f_ipf[0][0];
+	old->f_ipf[0][1] = fiop->f_ipf[0][1];
+	old->f_ipf[1][0] = fiop->f_ipf[1][0];
+	old->f_ipf[1][1] = fiop->f_ipf[1][1];
+	old->f_acct[0][0] = fiop->f_acct[0][0];
+	old->f_acct[0][1] = fiop->f_acct[0][1];
+	old->f_acct[1][0] = fiop->f_acct[1][0];
+	old->f_acct[1][1] = fiop->f_acct[1][1];
+	old->f_ipf6[0][0] = NULL;
+	old->f_ipf6[0][1] = NULL;
+	old->f_ipf6[1][0] = NULL;
+	old->f_ipf6[1][1] = NULL;
+	old->f_acct6[0][0] = NULL;
+	old->f_acct6[0][1] = NULL;
+	old->f_acct6[1][0] = NULL;
+	old->f_acct6[1][1] = NULL;
+	old->f_auth = fiop->f_auth;
+	bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups));
+	bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute));
+	old->f_ticks = fiop->f_ticks;
+	old->f_ipf[0][0] = fiop->f_ipf[0][0];
+	old->f_ipf[0][1] = fiop->f_ipf[0][1];
+	old->f_ipf[1][0] = fiop->f_ipf[1][0];
+	old->f_ipf[1][1] = fiop->f_ipf[1][1];
+	old->f_acct[0][0] = fiop->f_acct[0][0];
+	old->f_acct[0][1] = fiop->f_acct[0][1];
+	old->f_acct[1][0] = fiop->f_acct[1][0];
+	old->f_acct[1][1] = fiop->f_acct[1][1];
+	old->f_ipf6[0][0] = NULL;
+	old->f_ipf6[0][1] = NULL;
+	old->f_ipf6[1][0] = NULL;
+	old->f_ipf6[1][1] = NULL;
+	old->f_acct6[0][0] = NULL;
+	old->f_acct6[0][1] = NULL;
+	old->f_acct6[1][0] = NULL;
+	old->f_acct6[1][1] = NULL;
+	old->f_auth = fiop->f_auth;
+	bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups));
+	bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute));
+	old->f_ticks = fiop->f_ticks;
+	bcopy(&fiop->f_locks, &old->f_locks, sizeof(old->f_locks));
+	old->f_kmutex_sz = 0;
+	old->f_krwlock_sz = 0;
+	old->f_defpass = fiop->f_defpass;
+	old->f_active = fiop->f_active;
+	old->f_running = fiop->f_running;
+	old->f_logging = fiop->f_logging;
+	old->f_features = fiop->f_features;
+	sprintf(old->f_version, "IP Filter: v%d.%d.%d",
+		(rev / 1000000) % 100,
+		(rev / 10000) % 100,
+		(rev / 100) % 100);
+}
+
+
+/*
+ * nflags is v5 flags, returns v4 flags.
+ */
+static int
+fr_frflags5to4(nflags)
+	u_32_t nflags;
+{
+	u_32_t oflags = 0;
+
+	switch (nflags & FR_CMDMASK) {
+	case FR_CALL :
+		oflags = 0x0;
+		break;
+	case FR_BLOCK :
+		oflags = 0x1;
+		break;
+	case FR_PASS :
+		oflags = 0x2;
+		break;
+	case FR_AUTH :
+		oflags = 0x3;
+		break;
+	case FR_PREAUTH :
+		oflags = 0x4;
+		break;
+	case FR_ACCOUNT :
+		oflags = 0x5;
+		break;
+	case FR_SKIP :
+		oflags = 0x6;
+		break;
+	default :
+		break;
+	}
+
+	if (nflags & FR_LOG)
+		oflags |= 0x00010;
+	if (nflags & FR_CALLNOW)
+		oflags |= 0x00020;
+	if (nflags & FR_NOTSRCIP)
+		oflags |= 0x00080;
+	if (nflags & FR_NOTDSTIP)
+		oflags |= 0x00040;
+	if (nflags & FR_QUICK)
+		oflags |= 0x00100;
+	if (nflags & FR_KEEPFRAG)
+		oflags |= 0x00200;
+	if (nflags & FR_KEEPSTATE)
+		oflags |= 0x00400;
+	if (nflags & FR_FASTROUTE)
+		oflags |= 0x00800;
+	if (nflags & FR_RETRST)
+		oflags |= 0x01000;
+	if (nflags & FR_RETICMP)
+		oflags |= 0x02000;
+	if (nflags & FR_FAKEICMP)
+		oflags |= 0x03000;
+	if (nflags & FR_OUTQUE)
+		oflags |= 0x04000;
+	if (nflags & FR_INQUE)
+		oflags |= 0x08000;
+	if (nflags & FR_LOGBODY)
+		oflags |= 0x10000;
+	if (nflags & FR_LOGFIRST)
+		oflags |= 0x20000;
+	if (nflags & FR_LOGORBLOCK)
+		oflags |= 0x40000;
+	if (nflags & FR_FRSTRICT)
+		oflags |= 0x100000;
+	if (nflags & FR_STSTRICT)
+		oflags |= 0x200000;
+	if (nflags & FR_NEWISN)
+		oflags |= 0x400000;
+	if (nflags & FR_NOICMPERR)
+		oflags |= 0x800000;
+	if (nflags & FR_STATESYNC)
+		oflags |= 0x1000000;
+	if (nflags & FR_NOMATCH)
+		oflags |= 0x8000000;
+	if (nflags & FR_COPIED)
+		oflags |= 0x40000000;
+	if (nflags & FR_INACTIVE)
+		oflags |= 0x80000000;
+
+	return oflags;
+}
+
+
+static void
+frentry_current_to_4_1_34(current, old)
+	void *current;
+	frentry_4_1_34_t *old;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	old->fr_lock = fr->fr_lock;
+	old->fr_next = fr->fr_next;
+	old->fr_grp = (void *)fr->fr_grp;
+	old->fr_isc = fr->fr_isc;
+	old->fr_ifas[0] = fr->fr_ifas[0];
+	old->fr_ifas[1] = fr->fr_ifas[1];
+	old->fr_ifas[2] = fr->fr_ifas[2];
+	old->fr_ifas[3] = fr->fr_ifas[3];
+	old->fr_ptr = fr->fr_ptr;
+	old->fr_comment = NULL;
+	old->fr_ref = fr->fr_ref;
+	old->fr_statecnt = fr->fr_statecnt;
+	old->fr_hits = fr->fr_hits;
+	old->fr_bytes = fr->fr_bytes;
+	old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec;
+	old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec;
+	old->fr_curpps = fr->fr_curpps;
+	old->fr_dun.fru_data = fr->fr_dun.fru_data;
+	old->fr_func = fr->fr_func;
+	old->fr_dsize = fr->fr_dsize;
+	old->fr_pps = fr->fr_pps;
+	old->fr_statemax = fr->fr_statemax;
+	old->fr_flineno = fr->fr_flineno;
+	old->fr_type = fr->fr_type;
+	old->fr_flags = fr_frflags5to4(fr->fr_flags);
+	old->fr_logtag = fr->fr_logtag;
+	old->fr_collect = fr->fr_collect;
+	old->fr_arg = fr->fr_arg;
+	old->fr_loglevel = fr->fr_loglevel;
+	old->fr_age[0] = fr->fr_age[0];
+	old->fr_age[1] = fr->fr_age[1];
+	if (fr->fr_family == AF_INET)
+		old->fr_v = 4;
+	if (fr->fr_family == AF_INET6)
+		old->fr_v = 6;
+	old->fr_icode = fr->fr_icode;
+	old->fr_cksum = fr->fr_cksum;
+	old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6;
+	if (fr->fr_ifnames[0] >= 0) {
+		strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0],
+			LIFNAMSIZ);
+		old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[1] >= 0) {
+		strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1],
+			LIFNAMSIZ);
+		old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[2] >= 0) {
+		strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2],
+			LIFNAMSIZ);
+		old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[3] >= 0) {
+		strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3],
+			LIFNAMSIZ);
+		old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[0].fd_name >= 0) {
+		strncpy(old->fr_tifs[0].fd_ifname,
+			fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ);
+		old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[1].fd_name >= 0) {
+		strncpy(old->fr_tifs[1].fd_ifname,
+			fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ);
+		old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_dif.fd_name >= 0) {
+		strncpy(old->fr_dif.fd_ifname,
+			fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ);
+		old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_group >= 0) {
+		strncpy(old->fr_group, fr->fr_names + fr->fr_group,
+			FR_GROUPLEN);
+		old->fr_group[FR_GROUPLEN - 1] = '\0';
+	}
+	if (fr->fr_grhead >= 0) {
+		strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead,
+			FR_GROUPLEN);
+		old->fr_grhead[FR_GROUPLEN - 1] = '\0';
+	}
+}
+
+
+static void
+frentry_current_to_4_1_16(current, old)
+	void *current;
+	frentry_4_1_16_t *old;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	old->fr_lock = fr->fr_lock;
+	old->fr_next = fr->fr_next;
+	old->fr_grp = (void *)fr->fr_grp;
+	old->fr_isc = fr->fr_isc;
+	old->fr_ifas[0] = fr->fr_ifas[0];
+	old->fr_ifas[1] = fr->fr_ifas[1];
+	old->fr_ifas[2] = fr->fr_ifas[2];
+	old->fr_ifas[3] = fr->fr_ifas[3];
+	old->fr_ptr = fr->fr_ptr;
+	old->fr_comment = NULL;
+	old->fr_ref = fr->fr_ref;
+	old->fr_statecnt = fr->fr_statecnt;
+	old->fr_hits = fr->fr_hits;
+	old->fr_bytes = fr->fr_bytes;
+	old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec;
+	old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec;
+	old->fr_curpps = fr->fr_curpps;
+	old->fr_dun.fru_data = fr->fr_dun.fru_data;
+	old->fr_func = fr->fr_func;
+	old->fr_dsize = fr->fr_dsize;
+	old->fr_pps = fr->fr_pps;
+	old->fr_statemax = fr->fr_statemax;
+	old->fr_flineno = fr->fr_flineno;
+	old->fr_type = fr->fr_type;
+	old->fr_flags = fr_frflags5to4(fr->fr_flags);
+	old->fr_logtag = fr->fr_logtag;
+	old->fr_collect = fr->fr_collect;
+	old->fr_arg = fr->fr_arg;
+	old->fr_loglevel = fr->fr_loglevel;
+	old->fr_age[0] = fr->fr_age[0];
+	old->fr_age[1] = fr->fr_age[1];
+	if (old->fr_v == 4)
+		fr->fr_family = AF_INET;
+	if (old->fr_v == 6)
+		fr->fr_family = AF_INET6;
+	old->fr_icode = fr->fr_icode;
+	old->fr_cksum = fr->fr_cksum;
+	old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6;
+	if (fr->fr_ifnames[0] >= 0) {
+		strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0],
+			LIFNAMSIZ);
+		old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[1] >= 0) {
+		strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1],
+			LIFNAMSIZ);
+		old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[2] >= 0) {
+		strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2],
+			LIFNAMSIZ);
+		old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[3] >= 0) {
+		strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3],
+			LIFNAMSIZ);
+		old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[0].fd_name >= 0) {
+		strncpy(old->fr_tifs[0].fd_ifname,
+			fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ);
+		old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[1].fd_name >= 0) {
+		strncpy(old->fr_tifs[1].fd_ifname,
+			fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ);
+		old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_dif.fd_name >= 0) {
+		strncpy(old->fr_dif.fd_ifname,
+			fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ);
+		old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_group >= 0) {
+		strncpy(old->fr_group, fr->fr_names + fr->fr_group,
+			FR_GROUPLEN);
+		old->fr_group[FR_GROUPLEN - 1] = '\0';
+	}
+	if (fr->fr_grhead >= 0) {
+		strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead,
+			FR_GROUPLEN);
+		old->fr_grhead[FR_GROUPLEN - 1] = '\0';
+	}
+}
+
+
+static void
+frentry_current_to_4_1_0(current, old)
+	void *current;
+	frentry_4_1_0_t *old;
+{
+	frentry_t *fr = (frentry_t *)current;
+
+	old->fr_lock = fr->fr_lock;
+	old->fr_next = fr->fr_next;
+	old->fr_grp = (void *)fr->fr_grp;
+	old->fr_isc = fr->fr_isc;
+	old->fr_ifas[0] = fr->fr_ifas[0];
+	old->fr_ifas[1] = fr->fr_ifas[1];
+	old->fr_ifas[2] = fr->fr_ifas[2];
+	old->fr_ifas[3] = fr->fr_ifas[3];
+	old->fr_ptr = fr->fr_ptr;
+	old->fr_comment = NULL;
+	old->fr_ref = fr->fr_ref;
+	old->fr_statecnt = fr->fr_statecnt;
+	old->fr_hits = fr->fr_hits;
+	old->fr_bytes = fr->fr_bytes;
+	old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec;
+	old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec;
+	old->fr_curpps = fr->fr_curpps;
+	old->fr_dun.fru_data = fr->fr_dun.fru_data;
+	old->fr_func = fr->fr_func;
+	old->fr_dsize = fr->fr_dsize;
+	old->fr_pps = fr->fr_pps;
+	old->fr_statemax = fr->fr_statemax;
+	old->fr_flineno = fr->fr_flineno;
+	old->fr_type = fr->fr_type;
+	old->fr_flags = fr_frflags5to4(fr->fr_flags);
+	old->fr_logtag = fr->fr_logtag;
+	old->fr_collect = fr->fr_collect;
+	old->fr_arg = fr->fr_arg;
+	old->fr_loglevel = fr->fr_loglevel;
+	old->fr_age[0] = fr->fr_age[0];
+	old->fr_age[1] = fr->fr_age[1];
+	if (old->fr_v == 4)
+		fr->fr_family = AF_INET;
+	if (old->fr_v == 6)
+		fr->fr_family = AF_INET6;
+	old->fr_icode = fr->fr_icode;
+	old->fr_cksum = fr->fr_cksum;
+	old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6;
+	old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6;
+	if (fr->fr_ifnames[0] >= 0) {
+		strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0],
+			LIFNAMSIZ);
+		old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[1] >= 0) {
+		strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1],
+			LIFNAMSIZ);
+		old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[2] >= 0) {
+		strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2],
+			LIFNAMSIZ);
+		old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_ifnames[3] >= 0) {
+		strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3],
+			LIFNAMSIZ);
+		old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[0].fd_name >= 0) {
+		strncpy(old->fr_tifs[0].fd_ifname,
+			fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ);
+		old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_tifs[1].fd_name >= 0) {
+		strncpy(old->fr_tifs[1].fd_ifname,
+			fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ);
+		old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_dif.fd_name >= 0) {
+		strncpy(old->fr_dif.fd_ifname,
+			fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ);
+		old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0';
+	}
+	if (fr->fr_group >= 0) {
+		strncpy(old->fr_group, fr->fr_names + fr->fr_group,
+			FR_GROUPLEN);
+		old->fr_group[FR_GROUPLEN - 1] = '\0';
+	}
+	if (fr->fr_grhead >= 0) {
+		strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead,
+			FR_GROUPLEN);
+		old->fr_grhead[FR_GROUPLEN - 1] = '\0';
+	}
+}
+
+
+static void
+fr_info_current_to_4_1_24(current, old)
+	void *current;
+	fr_info_4_1_24_t *old;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	old->fin_ifp = fin->fin_ifp;
+	ipf_v5iptov4(&fin->fin_fi, &old->fin_fi);
+	bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat));
+	old->fin_out = fin->fin_out;
+	old->fin_rev = fin->fin_rev;
+	old->fin_hlen = fin->fin_hlen;
+	old->ofin_tcpf = fin->fin_tcpf;
+	old->fin_icode = fin->fin_icode;
+	old->fin_rule = fin->fin_rule;
+	bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group));
+	old->fin_fr = fin->fin_fr;
+	old->fin_dp = fin->fin_dp;
+	old->fin_dlen = fin->fin_dlen;
+	old->fin_plen = fin->fin_plen;
+	old->fin_ipoff = fin->fin_ipoff;
+	old->fin_id = fin->fin_id;
+	old->fin_off = fin->fin_off;
+	old->fin_depth = fin->fin_depth;
+	old->fin_error = fin->fin_error;
+	old->fin_cksum = fin->fin_cksum;
+	old->fin_state = NULL;
+	old->fin_nat = NULL;
+	old->fin_nattag = fin->fin_nattag;
+	old->fin_exthdr = NULL;
+	old->ofin_ip = fin->fin_ip;
+	old->fin_mp = fin->fin_mp;
+	old->fin_m = fin->fin_m;
+#ifdef  MENTAT
+	old->fin_qfm = fin->fin_qfm;
+	old->fin_qpi = fin->fin_qpi;
+	old->fin_ifname[0] = '\0';
+#endif
+#ifdef  __sgi
+	old->fin_hbuf = fin->fin_hbuf;
+#endif
+}
+
+
+static void
+fr_info_current_to_4_1_23(current, old)
+	void *current;
+	fr_info_4_1_23_t *old;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	old->fin_ifp = fin->fin_ifp;
+	ipf_v5iptov4(&fin->fin_fi, &old->fin_fi);
+	bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat));
+	old->fin_out = fin->fin_out;
+	old->fin_rev = fin->fin_rev;
+	old->fin_hlen = fin->fin_hlen;
+	old->ofin_tcpf = fin->fin_tcpf;
+	old->fin_icode = fin->fin_icode;
+	old->fin_rule = fin->fin_rule;
+	bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group));
+	old->fin_fr = fin->fin_fr;
+	old->fin_dp = fin->fin_dp;
+	old->fin_dlen = fin->fin_dlen;
+	old->fin_plen = fin->fin_plen;
+	old->fin_ipoff = fin->fin_ipoff;
+	old->fin_id = fin->fin_id;
+	old->fin_off = fin->fin_off;
+	old->fin_depth = fin->fin_depth;
+	old->fin_error = fin->fin_error;
+	old->fin_state = NULL;
+	old->fin_nat = NULL;
+	old->fin_nattag = fin->fin_nattag;
+	old->ofin_ip = fin->fin_ip;
+	old->fin_mp = fin->fin_mp;
+	old->fin_m = fin->fin_m;
+#ifdef  MENTAT
+	old->fin_qfm = fin->fin_qfm;
+	old->fin_qpi = fin->fin_qpi;
+	old->fin_ifname[0] = '\0';
+#endif
+#ifdef  __sgi
+	old->fin_hbuf = fin->fin_hbuf;
+#endif
+}
+
+
+static void
+fr_info_current_to_4_1_11(current, old)
+	void *current;
+	fr_info_4_1_11_t *old;
+{
+	fr_info_t *fin = (fr_info_t *)current;
+
+	old->fin_ifp = fin->fin_ifp;
+	ipf_v5iptov4(&fin->fin_fi, &old->fin_fi);
+	bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat));
+	old->fin_out = fin->fin_out;
+	old->fin_rev = fin->fin_rev;
+	old->fin_hlen = fin->fin_hlen;
+	old->ofin_tcpf = fin->fin_tcpf;
+	old->fin_icode = fin->fin_icode;
+	old->fin_rule = fin->fin_rule;
+	bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group));
+	old->fin_fr = fin->fin_fr;
+	old->fin_dp = fin->fin_dp;
+	old->fin_dlen = fin->fin_dlen;
+	old->fin_plen = fin->fin_plen;
+	old->fin_ipoff = fin->fin_ipoff;
+	old->fin_id = fin->fin_id;
+	old->fin_off = fin->fin_off;
+	old->fin_depth = fin->fin_depth;
+	old->fin_error = fin->fin_error;
+	old->fin_state = NULL;
+	old->fin_nat = NULL;
+	old->fin_nattag = fin->fin_nattag;
+	old->ofin_ip = fin->fin_ip;
+	old->fin_mp = fin->fin_mp;
+	old->fin_m = fin->fin_m;
+#ifdef  MENTAT
+	old->fin_qfm = fin->fin_qfm;
+	old->fin_qpi = fin->fin_qpi;
+	old->fin_ifname[0] = '\0';
+#endif
+#ifdef  __sgi
+	old->fin_hbuf = fin->fin_hbuf;
+#endif
+}
+
+
+static void
+frauth_current_to_4_1_29(current, old)
+	void *current;
+	frauth_4_1_29_t *old;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	old->fra_age = fra->fra_age;
+	old->fra_len = fra->fra_len;
+	old->fra_index = fra->fra_index;
+	old->fra_pass = fra->fra_pass;
+	fr_info_current_to_4_1_24(&fra->fra_info, &old->fra_info);
+	old->fra_buf = fra->fra_buf;
+	old->fra_flx = fra->fra_flx;
+#ifdef	MENTAT
+	old->fra_q = fra->fra_q;
+	old->fra_m = fra->fra_m;
+#endif
+}
+
+
+static void
+frauth_current_to_4_1_24(current, old)
+	void *current;
+	frauth_4_1_24_t *old;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	old->fra_age = fra->fra_age;
+	old->fra_len = fra->fra_len;
+	old->fra_index = fra->fra_index;
+	old->fra_pass = fra->fra_pass;
+	fr_info_current_to_4_1_24(&fra->fra_info, &old->fra_info);
+	old->fra_buf = fra->fra_buf;
+#ifdef	MENTAT
+	old->fra_q = fra->fra_q;
+	old->fra_m = fra->fra_m;
+#endif
+}
+
+
+static void
+frauth_current_to_4_1_23(current, old)
+	void *current;
+	frauth_4_1_23_t *old;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	old->fra_age = fra->fra_age;
+	old->fra_len = fra->fra_len;
+	old->fra_index = fra->fra_index;
+	old->fra_pass = fra->fra_pass;
+	fr_info_current_to_4_1_23(&fra->fra_info, &old->fra_info);
+	old->fra_buf = fra->fra_buf;
+#ifdef	MENTAT
+	old->fra_q = fra->fra_q;
+	old->fra_m = fra->fra_m;
+#endif
+}
+
+
+static void
+frauth_current_to_4_1_11(current, old)
+	void *current;
+	frauth_4_1_11_t *old;
+{
+	frauth_t *fra = (frauth_t *)current;
+
+	old->fra_age = fra->fra_age;
+	old->fra_len = fra->fra_len;
+	old->fra_index = fra->fra_index;
+	old->fra_pass = fra->fra_pass;
+	fr_info_current_to_4_1_11(&fra->fra_info, &old->fra_info);
+	old->fra_buf = fra->fra_buf;
+#ifdef	MENTAT
+	old->fra_q = fra->fra_q;
+	old->fra_m = fra->fra_m;
+#endif
+}
+
+
+static void
+ipnat_current_to_4_1_14(current, old)
+	void *current;
+	ipnat_4_1_14_t *old;
+{
+	ipnat_t *np = (ipnat_t *)current;
+
+	old->in_next = np->in_next;
+	old->in_rnext = np->in_rnext;
+	old->in_prnext = np->in_prnext;
+	old->in_mnext = np->in_mnext;
+	old->in_pmnext = np->in_pmnext;
+	old->in_tqehead[0] = np->in_tqehead[0];
+	old->in_tqehead[1] = np->in_tqehead[1];
+	old->in_ifps[0] = np->in_ifps[0];
+	old->in_ifps[1] = np->in_ifps[1];
+	old->in_apr = np->in_apr;
+	old->in_comment = np->in_comment;
+	old->in_space = np->in_space;
+	old->in_hits = np->in_hits;
+	old->in_use = np->in_use;
+	old->in_hv = np->in_hv[0];
+	old->in_flineno = np->in_flineno;
+	if (old->in_redir == NAT_REDIRECT)
+		old->in_pnext = np->in_dpnext;
+	else
+		old->in_pnext = np->in_spnext;
+	old->in_v = np->in_v[0];
+	old->in_flags = np->in_flags;
+	old->in_mssclamp = np->in_mssclamp;
+	old->in_age[0] = np->in_age[0];
+	old->in_age[1] = np->in_age[1];
+	old->in_redir = np->in_redir;
+	old->in_p = np->in_pr[0];
+	if (np->in_redir == NAT_REDIRECT) {
+		old->in_next6 = np->in_ndst.na_nextaddr;
+		old->in_in[0] = np->in_ndst.na_addr[0];
+		old->in_in[1] = np->in_ndst.na_addr[1];
+		old->in_out[0] = np->in_odst.na_addr[0];
+		old->in_out[1] = np->in_odst.na_addr[1];
+		old->in_src[0] = np->in_osrc.na_addr[0];
+		old->in_src[1] = np->in_osrc.na_addr[1];
+	} else {
+		old->in_next6 = np->in_nsrc.na_nextaddr;
+		old->in_out[0] = np->in_nsrc.na_addr[0];
+		old->in_out[1] = np->in_nsrc.na_addr[1];
+		old->in_in[0] = np->in_osrc.na_addr[0];
+		old->in_in[1] = np->in_osrc.na_addr[1];
+		old->in_src[0] = np->in_odst.na_addr[0];
+		old->in_src[1] = np->in_odst.na_addr[1];
+	}
+	ipfv5tuctov4(&np->in_tuc, &old->in_tuc);
+	if (np->in_redir == NAT_REDIRECT) {
+		old->in_port[0] = np->in_dpmin;
+		old->in_port[1] = np->in_dpmax;
+	} else {
+		old->in_port[0] = np->in_spmin;
+		old->in_port[1] = np->in_spmax;
+	}
+	old->in_ppip = np->in_ppip;
+	old->in_ippip = np->in_ippip;
+	bcopy(&np->in_tag, &old->in_tag, sizeof(np->in_tag));
+
+	if (np->in_ifnames[0] >= 0) {
+		strncpy(old->in_ifnames[0], np->in_names + np->in_ifnames[0],
+			LIFNAMSIZ);
+		old->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
+	}
+	if (np->in_ifnames[1] >= 0) {
+		strncpy(old->in_ifnames[1], np->in_names + np->in_ifnames[1],
+			LIFNAMSIZ);
+		old->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
+	}
+	if (np->in_plabel >= 0) {
+		strncpy(old->in_plabel, np->in_names + np->in_plabel,
+			APR_LABELLEN);
+		old->in_plabel[APR_LABELLEN - 1] = '\0';
+	}
+}
+
+
+static void
+ipnat_current_to_4_1_0(current, old)
+	void *current;
+	ipnat_4_1_0_t *old;
+{
+	ipnat_t *np = (ipnat_t *)current;
+
+	old->in_next = np->in_next;
+	old->in_rnext = np->in_rnext;
+	old->in_prnext = np->in_prnext;
+	old->in_mnext = np->in_mnext;
+	old->in_pmnext = np->in_pmnext;
+	old->in_tqehead[0] = np->in_tqehead[0];
+	old->in_tqehead[1] = np->in_tqehead[1];
+	old->in_ifps[0] = np->in_ifps[0];
+	old->in_ifps[1] = np->in_ifps[1];
+	old->in_apr = np->in_apr;
+	old->in_comment = np->in_comment;
+	old->in_space = np->in_space;
+	old->in_hits = np->in_hits;
+	old->in_use = np->in_use;
+	old->in_hv = np->in_hv[0];
+	old->in_flineno = np->in_flineno;
+	if (old->in_redir == NAT_REDIRECT)
+		old->in_pnext = np->in_dpnext;
+	else
+		old->in_pnext = np->in_spnext;
+	old->in_v = np->in_v[0];
+	old->in_flags = np->in_flags;
+	old->in_mssclamp = np->in_mssclamp;
+	old->in_age[0] = np->in_age[0];
+	old->in_age[1] = np->in_age[1];
+	old->in_redir = np->in_redir;
+	old->in_p = np->in_pr[0];
+	if (np->in_redir == NAT_REDIRECT) {
+		old->in_next6 = np->in_ndst.na_nextaddr;
+		old->in_in[0] = np->in_ndst.na_addr[0];
+		old->in_in[1] = np->in_ndst.na_addr[1];
+		old->in_out[0] = np->in_odst.na_addr[0];
+		old->in_out[1] = np->in_odst.na_addr[1];
+		old->in_src[0] = np->in_osrc.na_addr[0];
+		old->in_src[1] = np->in_osrc.na_addr[1];
+	} else {
+		old->in_next6 = np->in_nsrc.na_nextaddr;
+		old->in_out[0] = np->in_nsrc.na_addr[0];
+		old->in_out[1] = np->in_nsrc.na_addr[1];
+		old->in_in[0] = np->in_osrc.na_addr[0];
+		old->in_in[1] = np->in_osrc.na_addr[1];
+		old->in_src[0] = np->in_odst.na_addr[0];
+		old->in_src[1] = np->in_odst.na_addr[1];
+	}
+	ipfv5tuctov4(&np->in_tuc, &old->in_tuc);
+	if (np->in_redir == NAT_REDIRECT) {
+		old->in_port[0] = np->in_dpmin;
+		old->in_port[1] = np->in_dpmax;
+	} else {
+		old->in_port[0] = np->in_spmin;
+		old->in_port[1] = np->in_spmax;
+	}
+	old->in_ppip = np->in_ppip;
+	old->in_ippip = np->in_ippip;
+	bcopy(&np->in_tag, &old->in_tag, sizeof(np->in_tag));
+
+	if (np->in_ifnames[0] >= 0) {
+		strncpy(old->in_ifnames[0], np->in_names + np->in_ifnames[0],
+			LIFNAMSIZ);
+		old->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
+	}
+	if (np->in_ifnames[1] >= 0) {
+		strncpy(old->in_ifnames[1], np->in_names + np->in_ifnames[1],
+			LIFNAMSIZ);
+		old->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
+	}
+	if (np->in_plabel >= 0) {
+		strncpy(old->in_plabel, np->in_names + np->in_plabel,
+			APR_LABELLEN);
+		old->in_plabel[APR_LABELLEN - 1] = '\0';
+	}
+}
+
+
+static void
+ipstate_current_to_4_1_16(current, old)
+	void *current;
+	ipstate_4_1_16_t *old;
+{
+	ipstate_t *is = (ipstate_t *)current;
+
+	old->is_lock = is->is_lock;
+	old->is_next = is->is_next;
+	old->is_pnext = is->is_pnext;
+	old->is_hnext = is->is_hnext;
+	old->is_phnext = is->is_phnext;
+	old->is_me = is->is_me;
+	old->is_ifp[0] = is->is_ifp[0];
+	old->is_ifp[1] = is->is_ifp[1];
+	old->is_sync = is->is_sync;
+	old->is_rule = is->is_rule;
+	old->is_tqehead[0] = is->is_tqehead[0];
+	old->is_tqehead[1] = is->is_tqehead[1];
+	old->is_isc = is->is_isc;
+	old->is_pkts[0] = is->is_pkts[0];
+	old->is_pkts[1] = is->is_pkts[1];
+	old->is_pkts[2] = is->is_pkts[2];
+	old->is_pkts[3] = is->is_pkts[3];
+	old->is_bytes[0] = is->is_bytes[0];
+	old->is_bytes[1] = is->is_bytes[1];
+	old->is_bytes[2] = is->is_bytes[2];
+	old->is_bytes[3] = is->is_bytes[3];
+	old->is_icmppkts[0] = is->is_icmppkts[0];
+	old->is_icmppkts[1] = is->is_icmppkts[1];
+	old->is_icmppkts[2] = is->is_icmppkts[2];
+	old->is_icmppkts[3] = is->is_icmppkts[3];
+	old->is_sti = is->is_sti;
+	old->is_frage[0] = is->is_frage[0];
+	old->is_frage[1] = is->is_frage[1];
+	old->is_ref = is->is_ref;
+	old->is_isninc[0] = is->is_isninc[0];
+	old->is_isninc[1] = is->is_isninc[1];
+	old->is_sumd[0] = is->is_sumd[0];
+	old->is_sumd[1] = is->is_sumd[1];
+	old->is_src = is->is_src;
+	old->is_dst = is->is_dst;
+	old->is_pass = is->is_pass;
+	old->is_p = is->is_p;
+	old->is_v = is->is_v;
+	old->is_hv = is->is_hv;
+	old->is_tag = is->is_tag;
+	old->is_opt[0] = is->is_opt[0];
+	old->is_opt[1] = is->is_opt[1];
+	old->is_optmsk[0] = is->is_optmsk[0];
+	old->is_optmsk[1] = is->is_optmsk[1];
+	old->is_sec = is->is_sec;
+	old->is_secmsk = is->is_secmsk;
+	old->is_auth = is->is_auth;
+	old->is_authmsk = is->is_authmsk;
+	ipf_v5tcpinfoto4(&is->is_tcp, &old->is_tcp);
+	old->is_flags = is->is_flags;
+	old->is_flx[0][0] = is->is_flx[0][0];
+	old->is_flx[0][1] = is->is_flx[0][1];
+	old->is_flx[1][0] = is->is_flx[1][0];
+	old->is_flx[1][1] = is->is_flx[1][1];
+	old->is_rulen = is->is_rulen;
+	old->is_s0[0] = is->is_s0[0];
+	old->is_s0[1] = is->is_s0[1];
+	old->is_smsk[0] = is->is_smsk[0];
+	old->is_smsk[1] = is->is_smsk[1];
+	bcopy(is->is_group, old->is_group, sizeof(is->is_group));
+	bcopy(is->is_sbuf, old->is_sbuf, sizeof(is->is_sbuf));
+	bcopy(is->is_ifname, old->is_ifname, sizeof(is->is_ifname));
+}
+
+
+static void
+ipstate_current_to_4_1_0(current, old)
+	void *current;
+	ipstate_4_1_0_t *old;
+{
+	ipstate_t *is = (ipstate_t *)current;
+
+	old->is_lock = is->is_lock;
+	old->is_next = is->is_next;
+	old->is_pnext = is->is_pnext;
+	old->is_hnext = is->is_hnext;
+	old->is_phnext = is->is_phnext;
+	old->is_me = is->is_me;
+	old->is_ifp[0] = is->is_ifp[0];
+	old->is_ifp[1] = is->is_ifp[1];
+	old->is_sync = is->is_sync;
+	bzero(&old->is_nat, sizeof(old->is_nat));
+	old->is_rule = is->is_rule;
+	old->is_tqehead[0] = is->is_tqehead[0];
+	old->is_tqehead[1] = is->is_tqehead[1];
+	old->is_isc = is->is_isc;
+	old->is_pkts[0] = is->is_pkts[0];
+	old->is_pkts[1] = is->is_pkts[1];
+	old->is_pkts[2] = is->is_pkts[2];
+	old->is_pkts[3] = is->is_pkts[3];
+	old->is_bytes[0] = is->is_bytes[0];
+	old->is_bytes[1] = is->is_bytes[1];
+	old->is_bytes[2] = is->is_bytes[2];
+	old->is_bytes[3] = is->is_bytes[3];
+	old->is_icmppkts[0] = is->is_icmppkts[0];
+	old->is_icmppkts[1] = is->is_icmppkts[1];
+	old->is_icmppkts[2] = is->is_icmppkts[2];
+	old->is_icmppkts[3] = is->is_icmppkts[3];
+	old->is_sti = is->is_sti;
+	old->is_frage[0] = is->is_frage[0];
+	old->is_frage[1] = is->is_frage[1];
+	old->is_ref = is->is_ref;
+	old->is_isninc[0] = is->is_isninc[0];
+	old->is_isninc[1] = is->is_isninc[1];
+	old->is_sumd[0] = is->is_sumd[0];
+	old->is_sumd[1] = is->is_sumd[1];
+	old->is_src = is->is_src;
+	old->is_dst = is->is_dst;
+	old->is_pass = is->is_pass;
+	old->is_p = is->is_p;
+	old->is_v = is->is_v;
+	old->is_hv = is->is_hv;
+	old->is_tag = is->is_tag;
+	old->is_opt[0] = is->is_opt[0];
+	old->is_opt[1] = is->is_opt[1];
+	old->is_optmsk[0] = is->is_optmsk[0];
+	old->is_optmsk[1] = is->is_optmsk[1];
+	old->is_sec = is->is_sec;
+	old->is_secmsk = is->is_secmsk;
+	old->is_auth = is->is_auth;
+	old->is_authmsk = is->is_authmsk;
+	ipf_v5tcpinfoto4(&is->is_tcp, &old->is_tcp);
+	old->is_flags = is->is_flags;
+	old->is_flx[0][0] = is->is_flx[0][0];
+	old->is_flx[0][1] = is->is_flx[0][1];
+	old->is_flx[1][0] = is->is_flx[1][0];
+	old->is_flx[1][1] = is->is_flx[1][1];
+	old->is_rulen = is->is_rulen;
+	old->is_s0[0] = is->is_s0[0];
+	old->is_s0[1] = is->is_s0[1];
+	old->is_smsk[0] = is->is_smsk[0];
+	old->is_smsk[1] = is->is_smsk[1];
+	bcopy(is->is_group, old->is_group, sizeof(is->is_group));
+	bcopy(is->is_sbuf, old->is_sbuf, sizeof(is->is_sbuf));
+	bcopy(is->is_ifname, old->is_ifname, sizeof(is->is_ifname));
+}
+
+
+static void
+ips_stat_current_to_4_1_21(current, old)
+	void *current;
+	ips_stat_4_1_21_t *old;
+{
+	ips_stat_t *st = (ips_stat_t *)current;
+
+	old->iss_hits = st->iss_hits;
+	old->iss_miss = st->iss_check_miss;
+	old->iss_max = st->iss_max;
+	old->iss_maxref = st->iss_max_ref;
+	old->iss_tcp = st->iss_proto[IPPROTO_TCP];
+	old->iss_udp = st->iss_proto[IPPROTO_UDP];
+	old->iss_icmp = st->iss_proto[IPPROTO_ICMP];
+	old->iss_nomem = st->iss_nomem;
+	old->iss_expire = st->iss_expire;
+	old->iss_fin = st->iss_fin;
+	old->iss_active = st->iss_active;
+	old->iss_logged = st->iss_log_ok;
+	old->iss_logfail = st->iss_log_fail;
+	old->iss_inuse = st->iss_inuse;
+	old->iss_wild = st->iss_wild;
+	old->iss_ticks = st->iss_ticks;
+	old->iss_bucketfull = st->iss_bucket_full;
+	old->iss_statesize = st->iss_state_size;
+	old->iss_statemax = st->iss_state_max;
+	old->iss_table = st->iss_table;
+	old->iss_list = st->iss_list;
+	old->iss_bucketlen = (void *)st->iss_bucketlen;
+	old->iss_tcptab = st->iss_tcptab;
+}
+
+
+static void
+ips_stat_current_to_4_1_0(current, old)
+	void *current;
+	ips_stat_4_1_0_t *old;
+{
+	ips_stat_t *st = (ips_stat_t *)current;
+
+	old->iss_hits = st->iss_hits;
+	old->iss_miss = st->iss_check_miss;
+	old->iss_max = st->iss_max;
+	old->iss_maxref = st->iss_max_ref;
+	old->iss_tcp = st->iss_proto[IPPROTO_TCP];
+	old->iss_udp = st->iss_proto[IPPROTO_UDP];
+	old->iss_icmp = st->iss_proto[IPPROTO_ICMP];
+	old->iss_nomem = st->iss_nomem;
+	old->iss_expire = st->iss_expire;
+	old->iss_fin = st->iss_fin;
+	old->iss_active = st->iss_active;
+	old->iss_logged = st->iss_log_ok;
+	old->iss_logfail = st->iss_log_fail;
+	old->iss_inuse = st->iss_inuse;
+	old->iss_wild = st->iss_wild;
+	old->iss_ticks = st->iss_ticks;
+	old->iss_bucketfull = st->iss_bucket_full;
+	old->iss_statesize = st->iss_state_size;
+	old->iss_statemax = st->iss_state_max;
+	old->iss_table = st->iss_table;
+	old->iss_list = st->iss_list;
+	old->iss_bucketlen = (void *)st->iss_bucketlen;
+}
+
+
+static void
+nat_save_current_to_4_1_16(current, old)
+	void *current;
+	nat_save_4_1_16_t *old;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	old->ipn_next = nats->ipn_next;
+	bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat));
+	bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat));
+	frentry_current_to_4_1_16(&nats->ipn_fr, &old->ipn_fr);
+	old->ipn_dsize = nats->ipn_dsize;
+	bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+nat_save_current_to_4_1_14(current, old)
+	void *current;
+	nat_save_4_1_14_t *old;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	old->ipn_next = nats->ipn_next;
+	bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat));
+	bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat));
+	frentry_current_to_4_1_0(&nats->ipn_fr, &old->ipn_fr);
+	old->ipn_dsize = nats->ipn_dsize;
+	bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+nat_save_current_to_4_1_3(current, old)
+	void *current;
+	nat_save_4_1_3_t *old;
+{
+	nat_save_t *nats = (nat_save_t *)current;
+
+	old->ipn_next = nats->ipn_next;
+	bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat));
+	bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat));
+	frentry_current_to_4_1_0(&nats->ipn_fr, &old->ipn_fr);
+	old->ipn_dsize = nats->ipn_dsize;
+	bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data));
+}
+
+
+static void
+nat_current_to_4_1_25(current, old)
+	void *current;
+	nat_4_1_25_t *old;
+{
+	nat_t *nat = (nat_t *)current;
+
+	old->nat_lock = nat->nat_lock;
+	old->nat_next = (void *)nat->nat_next;
+	old->nat_pnext = (void *)nat->nat_pnext;
+	old->nat_hnext[0] = (void *)nat->nat_hnext[0];
+	old->nat_hnext[1] = (void *)nat->nat_hnext[1];
+	old->nat_phnext[0] = (void *)nat->nat_phnext[0];
+	old->nat_phnext[1] = (void *)nat->nat_phnext[1];
+	old->nat_hm = nat->nat_hm;
+	old->nat_data = nat->nat_data;
+	old->nat_me = (void *)nat->nat_me;
+	old->nat_state = nat->nat_state;
+	old->nat_aps = nat->nat_aps;
+	old->nat_fr = nat->nat_fr;
+	old->nat_ptr = (void *)nat->nat_ptr;
+	old->nat_ifps[0] = nat->nat_ifps[0];
+	old->nat_ifps[1] = nat->nat_ifps[1];
+	old->nat_sync = nat->nat_sync;
+	old->nat_tqe = nat->nat_tqe;
+	old->nat_flags = nat->nat_flags;
+	old->nat_sumd[0] = nat->nat_sumd[0];
+	old->nat_sumd[1] = nat->nat_sumd[1];
+	old->nat_ipsumd = nat->nat_ipsumd;
+	old->nat_mssclamp = nat->nat_mssclamp;
+	old->nat_pkts[0] = nat->nat_pkts[0];
+	old->nat_pkts[1] = nat->nat_pkts[1];
+	old->nat_bytes[0] = nat->nat_bytes[0];
+	old->nat_bytes[1] = nat->nat_bytes[1];
+	old->nat_ref = nat->nat_ref;
+	old->nat_dir = nat->nat_dir;
+	old->nat_p = nat->nat_pr[0];
+	old->nat_use = nat->nat_use;
+	old->nat_hv[0] = nat->nat_hv[0];
+	old->nat_hv[1] = nat->nat_hv[1];
+	old->nat_rev = nat->nat_rev;
+	old->nat_redir = nat->nat_redir;
+	bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ);
+	bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ);
+
+	if (nat->nat_redir == NAT_REDIRECT) {
+		old->nat_inip6 = nat->nat_ndst6;
+		old->nat_outip6 = nat->nat_odst6;
+		old->nat_oip6 = nat->nat_osrc6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_ndport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_odport;
+	} else {
+		old->nat_inip6 = nat->nat_osrc6;
+		old->nat_outip6 = nat->nat_nsrc6;
+		old->nat_oip6 = nat->nat_odst6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_osport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_nsport;
+	}
+}
+
+
+static void
+nat_current_to_4_1_14(current, old)
+	void *current;
+	nat_4_1_14_t *old;
+{
+	nat_t *nat = (nat_t *)current;
+
+	old->nat_lock = nat->nat_lock;
+	old->nat_next = nat->nat_next;
+	old->nat_pnext = NULL;
+	old->nat_hnext[0] = NULL;
+	old->nat_hnext[1] = NULL;
+	old->nat_phnext[0] = NULL;
+	old->nat_phnext[1] = NULL;
+	old->nat_hm = nat->nat_hm;
+	old->nat_data = nat->nat_data;
+	old->nat_me = (void *)nat->nat_me;
+	old->nat_state = nat->nat_state;
+	old->nat_aps = nat->nat_aps;
+	old->nat_fr = nat->nat_fr;
+	old->nat_ptr = nat->nat_ptr;
+	old->nat_ifps[0] = nat->nat_ifps[0];
+	old->nat_ifps[1] = nat->nat_ifps[1];
+	old->nat_sync = nat->nat_sync;
+	old->nat_tqe = nat->nat_tqe;
+	old->nat_flags = nat->nat_flags;
+	old->nat_sumd[0] = nat->nat_sumd[0];
+	old->nat_sumd[1] = nat->nat_sumd[1];
+	old->nat_ipsumd = nat->nat_ipsumd;
+	old->nat_mssclamp = nat->nat_mssclamp;
+	old->nat_pkts[0] = nat->nat_pkts[0];
+	old->nat_pkts[1] = nat->nat_pkts[1];
+	old->nat_bytes[0] = nat->nat_bytes[0];
+	old->nat_bytes[1] = nat->nat_bytes[1];
+	old->nat_ref = nat->nat_ref;
+	old->nat_dir = nat->nat_dir;
+	old->nat_p = nat->nat_pr[0];
+	old->nat_use = nat->nat_use;
+	old->nat_hv[0] = nat->nat_hv[0];
+	old->nat_hv[1] = nat->nat_hv[1];
+	old->nat_rev = nat->nat_rev;
+	bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ);
+	bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ);
+
+	if (nat->nat_redir == NAT_REDIRECT) {
+		old->nat_inip6 = nat->nat_ndst6;
+		old->nat_outip6 = nat->nat_odst6;
+		old->nat_oip6 = nat->nat_osrc6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_ndport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_odport;
+	} else {
+		old->nat_inip6 = nat->nat_osrc6;
+		old->nat_outip6 = nat->nat_nsrc6;
+		old->nat_oip6 = nat->nat_odst6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_osport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_nsport;
+	}
+}
+
+
+static void
+nat_current_to_4_1_3(current, old)
+	void *current;
+	nat_4_1_3_t *old;
+{
+	nat_t *nat = (nat_t *)current;
+
+	old->nat_lock = nat->nat_lock;
+	old->nat_next = nat->nat_next;
+	old->nat_pnext = NULL;
+	old->nat_hnext[0] = NULL;
+	old->nat_hnext[1] = NULL;
+	old->nat_phnext[0] = NULL;
+	old->nat_phnext[1] = NULL;
+	old->nat_hm = nat->nat_hm;
+	old->nat_data = nat->nat_data;
+	old->nat_me = (void *)nat->nat_me;
+	old->nat_state = nat->nat_state;
+	old->nat_aps = nat->nat_aps;
+	old->nat_fr = nat->nat_fr;
+	old->nat_ptr = nat->nat_ptr;
+	old->nat_ifps[0] = nat->nat_ifps[0];
+	old->nat_ifps[1] = nat->nat_ifps[1];
+	old->nat_sync = nat->nat_sync;
+	old->nat_tqe = nat->nat_tqe;
+	old->nat_flags = nat->nat_flags;
+	old->nat_sumd[0] = nat->nat_sumd[0];
+	old->nat_sumd[1] = nat->nat_sumd[1];
+	old->nat_ipsumd = nat->nat_ipsumd;
+	old->nat_mssclamp = nat->nat_mssclamp;
+	old->nat_pkts[0] = nat->nat_pkts[0];
+	old->nat_pkts[1] = nat->nat_pkts[1];
+	old->nat_bytes[0] = nat->nat_bytes[0];
+	old->nat_bytes[1] = nat->nat_bytes[1];
+	old->nat_ref = nat->nat_ref;
+	old->nat_dir = nat->nat_dir;
+	old->nat_p = nat->nat_pr[0];
+	old->nat_use = nat->nat_use;
+	old->nat_hv[0] = nat->nat_hv[0];
+	old->nat_hv[1] = nat->nat_hv[1];
+	old->nat_rev = nat->nat_rev;
+	bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ);
+	bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ);
+
+	if (nat->nat_redir == NAT_REDIRECT) {
+		old->nat_inip6 = nat->nat_ndst6;
+		old->nat_outip6 = nat->nat_odst6;
+		old->nat_oip6 = nat->nat_osrc6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_ndport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_odport;
+	} else {
+		old->nat_inip6 = nat->nat_osrc6;
+		old->nat_outip6 = nat->nat_nsrc6;
+		old->nat_oip6 = nat->nat_odst6;
+		old->nat_un.nat_unt.ts_sport = nat->nat_osport;
+		old->nat_un.nat_unt.ts_dport = nat->nat_nsport;
+	}
+}
+
+#endif /* IPFILTER_COMPAT */


Property changes on: trunk/contrib/ipfilter/ip_fil_compat.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/ipf_rb.h
===================================================================
--- trunk/contrib/ipfilter/ipf_rb.h	                        (rev 0)
+++ trunk/contrib/ipfilter/ipf_rb.h	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+typedef enum rbcolour_e {
+	C_BLACK = 0,
+	C_RED = 1
+} rbcolour_t;
+
+#define	RBI_LINK(_n, _t)							\
+	struct _n##_rb_link {						\
+		struct _t	*left;					\
+		struct _t	*right;					\
+		struct _t	*parent;				\
+		rbcolour_t	colour;					\
+	}
+
+#define	RBI_HEAD(_n, _t)						\
+struct _n##_rb_head {							\
+	struct _t	top;						\
+	int		count;						\
+	int		(* compare)(struct _t *, struct _t *);		\
+}
+
+#define	RBI_CODE(_n, _t, _f, _cmp)					\
+									\
+typedef	void	(*_n##_rb_walker_t)(_t *, void *);			\
+									\
+_t *	_n##_rb_delete(struct _n##_rb_head *, _t *);			\
+void	_n##_rb_init(struct _n##_rb_head *);				\
+void	_n##_rb_insert(struct _n##_rb_head *, _t *);			\
+_t *	_n##_rb_search(struct _n##_rb_head *, void *);			\
+void	_n##_rb_walktree(struct _n##_rb_head *, _n##_rb_walker_t, void *);\
+									\
+static void								\
+rotate_left(struct _n##_rb_head *head, _t *node)			\
+{									\
+	_t *parent, *tmp1, *tmp2;					\
+									\
+	parent = node->_f.parent;					\
+	tmp1 = node->_f.right;						\
+	tmp2 = tmp1->_f.left;						\
+	node->_f.right = tmp2;						\
+	if (tmp2 != & _n##_rb_zero)					\
+		tmp2->_f.parent = node;					\
+	if (parent == & _n##_rb_zero)					\
+		head->top._f.right = tmp1;				\
+	else if (parent->_f.right == node)				\
+		parent->_f.right = tmp1;				\
+	else								\
+		parent->_f.left = tmp1;					\
+	tmp1->_f.left = node;						\
+	tmp1->_f.parent = parent;					\
+	node->_f.parent = tmp1;						\
+}									\
+									\
+static void								\
+rotate_right(struct _n##_rb_head *head, _t *node)			\
+{									\
+	_t *parent, *tmp1, *tmp2;					\
+									\
+	parent = node->_f.parent;					\
+	tmp1 = node->_f.left;						\
+	tmp2 = tmp1->_f.right;						\
+	node->_f.left = tmp2;						\
+	if (tmp2 != &_n##_rb_zero)					\
+		tmp2->_f.parent = node;					\
+	if (parent == &_n##_rb_zero)					\
+		head->top._f.right = tmp1;				\
+	else if (parent->_f.right == node)				\
+		parent->_f.right = tmp1;				\
+	else								\
+		parent->_f.left = tmp1;					\
+	tmp1->_f.right = node;						\
+	tmp1->_f.parent = parent;					\
+	node->_f.parent = tmp1;						\
+}									\
+									\
+void									\
+_n##_rb_insert(struct _n##_rb_head *head, _t *node)			\
+{									\
+	_t *n, *parent, **p, *tmp1, *gparent;				\
+									\
+	parent = &head->top;						\
+	node->_f.left = &_n##_rb_zero;					\
+	node->_f.right = &_n##_rb_zero;					\
+	p = &head->top._f.right;					\
+	while ((n = *p) != &_n##_rb_zero) {				\
+		if (_cmp(node, n) < 0)					\
+			p = &n->_f.left;				\
+		else							\
+			p = &n->_f.right;				\
+		parent = n;						\
+	}								\
+	*p = node;							\
+	node->_f.colour = C_RED;					\
+	node->_f.parent = parent;					\
+									\
+	while ((node != &_n##_rb_zero) && (parent->_f.colour == C_RED)){\
+		gparent = parent->_f.parent;				\
+		if (parent == gparent->_f.left) {			\
+			tmp1 = gparent->_f.right;			\
+			if (tmp1->_f.colour == C_RED) {			\
+				parent->_f.colour = C_BLACK;		\
+				tmp1->_f.colour = C_BLACK;		\
+				gparent->_f.colour = C_RED;		\
+				node = gparent;				\
+			} else {					\
+				if (node == parent->_f.right) {		\
+					node = parent;			\
+					rotate_left(head, node);	\
+					parent = node->_f.parent;	\
+				}					\
+				parent->_f.colour = C_BLACK;		\
+				gparent->_f.colour = C_RED;		\
+				rotate_right(head, gparent);		\
+			}						\
+		} else {						\
+			tmp1 = gparent->_f.left;			\
+			if (tmp1->_f.colour == C_RED) {			\
+				parent->_f.colour = C_BLACK;		\
+				tmp1->_f.colour = C_BLACK;		\
+				gparent->_f.colour = C_RED;		\
+				node = gparent;				\
+			} else {					\
+				if (node == parent->_f.left) {		\
+					node = parent;			\
+					rotate_right(head, node);	\
+					parent = node->_f.parent;	\
+				}					\
+				parent->_f.colour = C_BLACK;		\
+				gparent->_f.colour = C_RED;		\
+				rotate_left(head, parent->_f.parent);	\
+			}						\
+		}							\
+		parent = node->_f.parent;				\
+	}								\
+	head->top._f.right->_f.colour = C_BLACK;			\
+	head->count++;						\
+}									\
+									\
+static void								\
+deleteblack(struct _n##_rb_head *head, _t *parent, _t *node)		\
+{									\
+	_t *tmp;							\
+									\
+	while ((node == &_n##_rb_zero || node->_f.colour == C_BLACK) &&	\
+	       node != &head->top) {					\
+		if (parent->_f.left == node) {				\
+			tmp = parent->_f.right;				\
+			if (tmp->_f.colour == C_RED) {			\
+				tmp->_f.colour = C_BLACK;		\
+				parent->_f.colour = C_RED;		\
+				rotate_left(head, parent);		\
+				tmp = parent->_f.right;			\
+			}						\
+			if ((tmp->_f.left == &_n##_rb_zero ||		\
+			     tmp->_f.left->_f.colour == C_BLACK) &&	\
+			    (tmp->_f.right == &_n##_rb_zero ||		\
+			     tmp->_f.right->_f.colour == C_BLACK)) {	\
+				tmp->_f.colour = C_RED;			\
+				node = parent;				\
+				parent = node->_f.parent;		\
+			} else {					\
+				if (tmp->_f.right == &_n##_rb_zero ||	\
+				    tmp->_f.right->_f.colour == C_BLACK) {\
+					_t *tmp2 = tmp->_f.left;	\
+									\
+					if (tmp2 != &_n##_rb_zero)	\
+						tmp2->_f.colour = C_BLACK;\
+					tmp->_f.colour = C_RED;		\
+					rotate_right(head, tmp);	\
+					tmp = parent->_f.right;		\
+				}					\
+				tmp->_f.colour = parent->_f.colour;	\
+				parent->_f.colour = C_BLACK;		\
+				if (tmp->_f.right != &_n##_rb_zero)	\
+					tmp->_f.right->_f.colour = C_BLACK;\
+				rotate_left(head, parent);		\
+				node = head->top._f.right;		\
+			}						\
+		} else {						\
+			tmp = parent->_f.left;				\
+			if (tmp->_f.colour == C_RED) {			\
+				tmp->_f.colour = C_BLACK;		\
+				parent->_f.colour = C_RED;		\
+				rotate_right(head, parent);		\
+				tmp = parent->_f.left;			\
+			}						\
+			if ((tmp->_f.left == &_n##_rb_zero ||		\
+			     tmp->_f.left->_f.colour == C_BLACK) &&	\
+			    (tmp->_f.right == &_n##_rb_zero ||		\
+			     tmp->_f.right->_f.colour == C_BLACK)) {	\
+				tmp->_f.colour = C_RED;			\
+				node = parent;				\
+				parent = node->_f.parent;		\
+			} else {					\
+				if (tmp->_f.left == &_n##_rb_zero ||	\
+				    tmp->_f.left->_f.colour == C_BLACK) {\
+					_t *tmp2 = tmp->_f.right;	\
+									\
+					if (tmp2 != &_n##_rb_zero)	\
+						tmp2->_f.colour = C_BLACK;\
+					tmp->_f.colour = C_RED;		\
+					rotate_left(head, tmp);		\
+					tmp = parent->_f.left;		\
+				}					\
+				tmp->_f.colour = parent->_f.colour;	\
+				parent->_f.colour = C_BLACK;		\
+				if (tmp->_f.left != &_n##_rb_zero)	\
+					tmp->_f.left->_f.colour = C_BLACK;\
+				rotate_right(head, parent);		\
+				node = head->top._f.right;		\
+				break;					\
+			}						\
+		}							\
+	}								\
+	if (node != &_n##_rb_zero)					\
+		node->_f.colour = C_BLACK;				\
+}									\
+									\
+_t *									\
+_n##_rb_delete(struct _n##_rb_head *head, _t *node)			\
+{									\
+	_t *child, *parent, *old = node, *left;				\
+	rbcolour_t color;						\
+									\
+	if (node->_f.left == &_n##_rb_zero) {				\
+		child = node->_f.right;					\
+	} else if (node->_f.right == &_n##_rb_zero) {			\
+		child = node->_f.left;					\
+	} else {							\
+		node = node->_f.right;					\
+		while ((left = node->_f.left) != &_n##_rb_zero)		\
+			node = left;					\
+		child = node->_f.right;					\
+		parent = node->_f.parent;				\
+		color = node->_f.colour;				\
+		if (child != &_n##_rb_zero)				\
+			child->_f.parent = parent;			\
+		if (parent != &_n##_rb_zero) {				\
+			if (parent->_f.left == node)			\
+				parent->_f.left = child;		\
+			else						\
+				parent->_f.right = child;		\
+		} else {						\
+			head->top._f.right = child;			\
+		}							\
+		if (node->_f.parent == old)				\
+			parent = node;					\
+		*node = *old;						\
+		if (old->_f.parent != &_n##_rb_zero) {			\
+			if (old->_f.parent->_f.left == old)		\
+				old->_f.parent->_f.left = node;		\
+			else						\
+				old->_f.parent->_f.right = node;	\
+		} else {						\
+			head->top._f.right = child;			\
+		}							\
+		old->_f.left->_f.parent = node;				\
+		if (old->_f.right != &_n##_rb_zero)			\
+			old->_f.right->_f.parent = node;		\
+		if (parent != &_n##_rb_zero) {				\
+			left = parent;					\
+		}							\
+		goto colour;						\
+	}								\
+	parent = node->_f.parent;					\
+	color= node->_f.colour;						\
+	if (child != &_n##_rb_zero)					\
+		child->_f.parent = parent;				\
+	if (parent != &_n##_rb_zero) {					\
+		if (parent->_f.left == node)				\
+			parent->_f.left = child;			\
+		else							\
+			parent->_f.right = child;			\
+	} else {							\
+		head->top._f.right = child;				\
+	}								\
+colour:									\
+	if (color == C_BLACK)						\
+		deleteblack(head, parent, node);			\
+	head->count--;							\
+	return old;							\
+}									\
+									\
+void									\
+_n##_rb_init(struct _n##_rb_head *head)					\
+{									\
+	memset(head, 0, sizeof(*head));					\
+	memset(&_n##_rb_zero, 0, sizeof(_n##_rb_zero));			\
+	head->top._f.left = &_n##_rb_zero;				\
+	head->top._f.right = &_n##_rb_zero;				\
+	head->top._f.parent = &head->top;				\
+	_n##_rb_zero._f.left = &_n##_rb_zero;				\
+	_n##_rb_zero._f.right = &_n##_rb_zero;				\
+	_n##_rb_zero._f.parent = &_n##_rb_zero;				\
+}									\
+									\
+void									\
+_n##_rb_walktree(struct _n##_rb_head *head, _n##_rb_walker_t func, void *arg)\
+{									\
+	_t *prev;							\
+	_t *next;							\
+	_t *node = head->top._f.right;					\
+	_t *base;							\
+									\
+	while (node != &_n##_rb_zero)					\
+		node = node->_f.left;					\
+									\
+	for (;;) {							\
+		base = node;						\
+		prev = node;						\
+		while ((node->_f.parent->_f.right == node) &&		\
+		       (node != &_n##_rb_zero))	{			\
+			prev = node;					\
+			node = node->_f.parent;				\
+		}							\
+									\
+		node = prev;						\
+		for (node = node->_f.parent->_f.right; node != &_n##_rb_zero;\
+		     node = node->_f.left)				\
+			prev = node;					\
+		next = prev;						\
+									\
+		if (node != &_n##_rb_zero)				\
+			func(node, arg);				\
+									\
+		node = next;						\
+		if (node == &_n##_rb_zero)				\
+			break;						\
+	}								\
+}									\
+									\
+_t *									\
+_n##_rb_search(struct _n##_rb_head *head, void *key)			\
+{									\
+	int	match;							\
+	_t	*node;							\
+	node = head->top._f.right;					\
+	while (node != &_n##_rb_zero) {					\
+		match = _cmp(key, node);				\
+		if (match == 0)						\
+			break;						\
+		if (match< 0)						\
+			node = node->_f.left;				\
+		else							\
+			node = node->_f.right;				\
+	}								\
+	if (node == &_n##_rb_zero || match != 0)			\
+		return (NULL);						\
+	return (node);							\
+}
+
+#define	RBI_DELETE(_n, _h, _v)		_n##_rb_delete(_h, _v)
+#define	RBI_FIELD(_n)			struct _n##_rb_link
+#define	RBI_INIT(_n, _h)		_n##_rb_init(_h)
+#define	RBI_INSERT(_n, _h, _v)		_n##_rb_insert(_h, _v)
+#define	RBI_ISEMPTY(_h)			((_h)->count == 0)
+#define	RBI_SEARCH(_n, _h, _k)		_n##_rb_search(_h, _k)
+#define	RBI_WALK(_n, _h, _w, _a)	_n##_rb_walktree(_h, _w, _a)
+#define	RBI_ZERO(_n)			_n##_rb_zero


Property changes on: trunk/contrib/ipfilter/ipf_rb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/allocmbt.c
===================================================================
--- trunk/contrib/ipfilter/lib/allocmbt.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/allocmbt.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: allocmbt.c,v 1.1.4.1 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+mb_t *allocmbt(size_t len)
+{
+	mb_t *m;
+
+	m = (mb_t *)malloc(sizeof(mb_t));
+	if (m == NULL)
+		return NULL;
+	m->mb_len = len;
+	m->mb_next = NULL;
+	m->mb_data = (char *)m->mb_buf;
+	return m;
+}


Property changes on: trunk/contrib/ipfilter/lib/allocmbt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/assigndefined.c
===================================================================
--- trunk/contrib/ipfilter/lib/assigndefined.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/assigndefined.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: assigndefined.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+void assigndefined(env)
+	char *env;
+{
+	char *s, *t;
+
+	if (env == NULL)
+		return;
+
+	for (s = strtok(env, ";"); s != NULL; s = strtok(NULL, ";")) {
+		t = strchr(s, '=');
+		if (t == NULL)
+			continue;
+		*t++ = '\0';
+		set_variable(s, t);
+		*--t = '=';
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/assigndefined.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/connecttcp.c
===================================================================
--- trunk/contrib/ipfilter/lib/connecttcp.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/connecttcp.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: connecttcp.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+#include <ctype.h>
+
+/*
+ * Format expected is one addres per line, at the start of each line.
+ */
+int
+connecttcp(char *server, int port)
+{
+	struct sockaddr_in sin;
+	struct hostent *host;
+	int fd;
+
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(port & 65535);
+
+	if (ISDIGIT(*server)) {
+		if (inet_aton(server, &sin.sin_addr) == -1) {
+			return -1;
+		}
+	} else {
+		host = gethostbyname(server);
+		if (host == NULL)
+			return -1;
+		memcpy(&sin.sin_addr, host->h_addr_list[0],
+		       sizeof(sin.sin_addr));
+	}
+
+	fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (fd == -1)
+		return -1;
+
+	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}


Property changes on: trunk/contrib/ipfilter/lib/connecttcp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/dupmbt.c
===================================================================
--- trunk/contrib/ipfilter/lib/dupmbt.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/dupmbt.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: dupmbt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+mb_t *dupmbt(orig)
+	mb_t *orig;
+{
+	mb_t *m;
+
+	m = (mb_t *)malloc(sizeof(mb_t));
+	if (m == NULL)
+		return NULL;
+	m->mb_len = orig->mb_len;
+	m->mb_next = NULL;
+	m->mb_data = (char *)m->mb_buf + (orig->mb_data - (char *)orig->mb_buf);
+	bcopy(orig->mb_data, m->mb_data, m->mb_len);
+	return m;
+}


Property changes on: trunk/contrib/ipfilter/lib/dupmbt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/familyname.c
===================================================================
--- trunk/contrib/ipfilter/lib/familyname.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/familyname.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,12 @@
+#include "ipf.h"
+
+const char *familyname(int family)
+{
+	if (family == AF_INET)
+		return "inet";
+#ifdef AF_INET6
+	if (family == AF_INET6)
+		return "inet6";
+#endif
+	return "unknown";
+}


Property changes on: trunk/contrib/ipfilter/lib/familyname.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/findword.c
===================================================================
--- trunk/contrib/ipfilter/lib/findword.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/findword.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: findword.c,v 1.3.4.1 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+
+wordtab_t *findword(words, name)
+	wordtab_t *words;
+	char *name;
+{
+	wordtab_t *w;
+
+	for (w = words; w->w_word != NULL; w++)
+		if (!strcmp(name, w->w_word))
+			break;
+	if (w->w_word == NULL)
+		return NULL;
+
+	return w;
+}


Property changes on: trunk/contrib/ipfilter/lib/findword.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/freembt.c
===================================================================
--- trunk/contrib/ipfilter/lib/freembt.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/freembt.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: freembt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+void freembt(m)
+	mb_t *m;
+{
+
+	free(m);
+}


Property changes on: trunk/contrib/ipfilter/lib/freembt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/ftov.c
===================================================================
--- trunk/contrib/ipfilter/lib/ftov.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/ftov.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,16 @@
+#include "ipf.h"
+
+int
+ftov(version)
+	int version;
+{
+#ifdef USE_INET6
+	if (version == AF_INET6)
+		return 6;
+#endif
+	if (version == AF_INET)
+		return 4;
+	if (version == AF_UNSPEC)
+		return 0;
+	return -1;
+}


Property changes on: trunk/contrib/ipfilter/lib/ftov.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/geticmptype.c
===================================================================
--- trunk/contrib/ipfilter/lib/geticmptype.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/geticmptype.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+#include "ipf.h"
+
+int geticmptype(family, name)
+	int family;
+	char *name;
+{
+	icmptype_t *i;
+
+	for (i = icmptypelist; i->it_name != NULL; i++) {
+		if (!strcmp(name, i->it_name)) {
+			if (family == AF_INET)
+				return i->it_v4;
+#ifdef USE_INET6
+			if (family == AF_INET6)
+				return i->it_v6;
+#endif
+			return -1;
+		}
+	}
+
+	return -1;
+}


Property changes on: trunk/contrib/ipfilter/lib/geticmptype.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/icmptypename.c
===================================================================
--- trunk/contrib/ipfilter/lib/icmptypename.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/icmptypename.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+#include "ipf.h"
+
+char *icmptypename(family, type)
+	int family, type;
+{
+	icmptype_t *i;
+
+	if ((type < 0) || (type > 255))
+		return NULL;
+
+	for (i = icmptypelist; i->it_name != NULL; i++) {
+		if ((family == AF_INET) && (i->it_v4 == type))
+			return i->it_name;
+#ifdef USE_INET6
+		if ((family == AF_INET6) && (i->it_v6 == type))
+			return i->it_name;
+#endif
+	}
+
+	return NULL;
+}


Property changes on: trunk/contrib/ipfilter/lib/icmptypename.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/icmptypes.c
===================================================================
--- trunk/contrib/ipfilter/lib/icmptypes.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/icmptypes.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+#include "ipf.h"
+
+#ifndef USE_INET6
+# undef		ICMP6_ECHO_REQUEST
+# define	ICMP6_ECHO_REQUEST	0
+# undef		ICMP6_ECHO_REPLY
+# define	ICMP6_ECHO_REPLY	0
+# undef		ICMP6_NI_QUERY
+# define	ICMP6_NI_QUERY		0
+# undef		ICMP6_NI_REPLY
+# define	ICMP6_NI_REPLY		0
+# undef		ICMP6_PARAM_PROB
+# define	ICMP6_PARAM_PROB	0
+# undef		ND_ROUTER_ADVERT
+# define	ND_ROUTER_ADVERT	0
+# undef		ND_ROUTER_SOLICIT
+# define	ND_ROUTER_SOLICIT	0
+# undef		ICMP6_TIME_EXCEEDED
+# define	ICMP6_TIME_EXCEEDED	0
+# undef		ICMP6_DST_UNREACH
+# define	ICMP6_DST_UNREACH	0
+# undef		ICMP6_PACKET_TOO_BIG
+# define	ICMP6_PACKET_TOO_BIG	0
+# undef		MLD_LISTENER_QUERY
+# define	MLD_LISTENER_QUERY	0
+# undef		MLD_LISTENER_REPORT
+# define	MLD_LISTENER_REPORT	0
+# undef		MLD_LISTENER_DONE
+# define	MLD_LISTENER_DONE	0
+# undef		ICMP6_MEMBERSHIP_QUERY
+# define	ICMP6_MEMBERSHIP_QUERY	0
+# undef		ICMP6_MEMBERSHIP_REPORT
+# define	ICMP6_MEMBERSHIP_REPORT	0
+# undef		ICMP6_MEMBERSHIP_REDUCTION
+# define	ICMP6_MEMBERSHIP_REDUCTION	0
+# undef		ND_NEIGHBOR_ADVERT
+# define	ND_NEIGHBOR_ADVERT	0
+# undef		ND_NEIGHBOR_SOLICIT
+# define	ND_NEIGHBOR_SOLICIT	0
+# undef		ICMP6_ROUTER_RENUMBERING
+# define	ICMP6_ROUTER_RENUMBERING	0
+# undef		ICMP6_WRUREQUEST
+# define	ICMP6_WRUREQUEST	0
+# undef		ICMP6_WRUREPLY
+# define	ICMP6_WRUREPLY		0
+# undef		ICMP6_FQDN_QUERY
+# define	ICMP6_FQDN_QUERY	0
+# undef		ICMP6_FQDN_REPLY
+# define	ICMP6_FQDN_REPLY	0
+#else
+# if !defined(MLD_LISTENER_QUERY)
+#  define	MLD_LISTENER_QUERY	130
+# endif
+# if !defined(MLD_LISTENER_REPORT)
+#  define	MLD_LISTENER_REPORT	131
+# endif
+# if !defined(MLD_LISTENER_DONE)
+#  define	MLD_LISTENER_DONE	132
+# endif
+# if defined(MLD_LISTENER_REDUCTION) && !defined(MLD_LISTENER_DONE)
+#  define	MLD_LISTENER_DONE	MLD_LISTENER_REDUCTION
+# endif
+#endif
+
+icmptype_t icmptypelist[] = {
+	{ "echo",	ICMP_ECHO,		ICMP6_ECHO_REQUEST },
+	{ "echorep",	ICMP_ECHOREPLY,		ICMP6_ECHO_REPLY },
+	{ "fqdnquery",	-1,			ICMP6_FQDN_QUERY },
+	{ "fqdnreply",	-1,			ICMP6_FQDN_REPLY },
+	{ "infoqry",	-1,			ICMP6_NI_QUERY },
+	{ "inforeq",	ICMP_IREQ,		ICMP6_NI_QUERY },
+	{ "inforep",	ICMP_IREQREPLY,		ICMP6_NI_REPLY },
+	{ "listendone",	-1,			MLD_LISTENER_DONE },
+	{ "listenqry",	-1,			MLD_LISTENER_QUERY },
+	{ "listenrep",	-1,			MLD_LISTENER_REPORT },
+	{ "maskrep",	ICMP_MASKREPLY,		-1 },
+	{ "maskreq",	ICMP_MASKREQ,		-1 },
+	{ "memberqry",	-1,			ICMP6_MEMBERSHIP_QUERY },
+	{ "memberred",	-1,			ICMP6_MEMBERSHIP_REDUCTION },
+	{ "memberreply",-1,			ICMP6_MEMBERSHIP_REPORT },
+	{ "neighadvert",	-1,		ND_NEIGHBOR_ADVERT },
+	{ "neighborsol",	-1,		ND_NEIGHBOR_SOLICIT },
+	{ "neighborsolicit",	-1,		ND_NEIGHBOR_SOLICIT },
+	{ "paramprob",	ICMP_PARAMPROB,		ICMP6_PARAM_PROB },
+	{ "redir",	ICMP_REDIRECT,		ND_REDIRECT },
+	{ "renumber",	-1,			ICMP6_ROUTER_RENUMBERING },
+	{ "routerad",	ICMP_ROUTERADVERT,	ND_ROUTER_ADVERT },
+	{ "routeradvert",ICMP_ROUTERADVERT,	ND_ROUTER_ADVERT },
+	{ "routersol",	ICMP_ROUTERSOLICIT,	ND_ROUTER_SOLICIT },
+	{ "routersolcit",ICMP_ROUTERSOLICIT,	ND_ROUTER_SOLICIT },
+	{ "squench",	ICMP_SOURCEQUENCH,	-1 },
+	{ "timest",	ICMP_TSTAMP,		-1 },
+	{ "timestrep",	ICMP_TSTAMPREPLY,	-1 },
+	{ "timex",	ICMP_TIMXCEED,		ICMP6_TIME_EXCEEDED },
+	{ "toobig",	-1,			ICMP6_PACKET_TOO_BIG },
+	{ "unreach",	ICMP_UNREACH,		ICMP6_DST_UNREACH },
+	{ "whorep",	-1,			ICMP6_WRUREPLY },
+	{ "whoreq",	-1,			ICMP6_WRUREQUEST },
+	{ NULL,		-1,			-1 }
+};


Property changes on: trunk/contrib/ipfilter/lib/icmptypes.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/interror.c
===================================================================
--- trunk/contrib/ipfilter/lib/interror.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/interror.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: interror.c,v 1.9.2.12 2012/07/22 08:03:39 darren_r Exp $
+ */
+
+#include "ipf.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+typedef	struct	{
+	int	iee_number;
+	char	*iee_text;
+} ipf_error_entry_t;
+
+static ipf_error_entry_t *find_error __P((int));
+
+#define	IPF_NUM_ERRORS	475
+
+/*
+ * NO REUSE OF NUMBERS!
+ *
+ * IF YOU WANT TO ADD AN ERROR TO THIS TABLE, _ADD_ A NEW NUMBER.
+ * DO _NOT_ USE AN EMPTY NUMBER OR FILL IN A GAP.
+ */
+static ipf_error_entry_t ipf_errors[IPF_NUM_ERRORS] = {
+	{	1,	"auth table locked/full" },
+	{	2,	"" },
+	{	3,	"copyinptr received bad address" },
+	{	4,	"copyoutptr received bad address" },
+	{	5,	"" },
+	{	6,	"cannot load a rule with FR_T_BUILTIN flag set" },
+	{	7,	"internal rule without FR_T_BUILDINT flag set" },
+	{	8,	"no data provided with filter rule" },
+	{	9,	"invalid ioctl for rule" },
+	{	10,	"rule protocol is not 4 or 6" },
+	{	11,	"cannot find rule function" },
+	{	12,	"cannot find rule group" },
+	{	13,	"group in/out does not match rule in/out" },
+	{	14,	"rule without in/out does not belong to a group" },
+	{	15,	"cannot determine where to append rule" },
+	{	16,	"malloc for rule data failed" },
+	{	17,	"copyin for rule data failed" },
+	{	18,	"" },
+	{	19,	"zero data size for BPF rule" },
+	{	20,	"BPF validation failed" },
+	{	21,	"incorrect data size for IPF rule" },
+	{	22,	"'keep state' rule included 'with oow'" },
+	{	23,	"bad interface index with dynamic source address" },
+	{	24,	"bad interface index with dynamic dest. address" },
+	{	25,	"match array verif failed for filter rule" },
+	{	26,	"bad filter rule type" },
+	{	27,	"rule not found for zero'stats" },
+	{	28,	"copyout failed for zero'ing stats" },
+	{	29,	"rule not found for removing" },
+	{	30,	"cannot remove internal rule" },
+	{	31,	"rule in use" },
+	{	32,	"rule already exists" },
+	{	33,	"no memory for another rule" },
+	{	34,	"could not find function" },
+	{	35,	"copyout failed for resolving function name -> addr" },
+	{	36,	"copyout failed for resolving function addr -> name" },
+	{	37,	"function name/addr resolving search failed" },
+	{	38,	"group map cannot find it's hash table" },
+	{	39,	"group map hash-table in/out do not match rule" },
+	{	40,	"bcopyout failed for SIOCIPFINTERROR" },
+	{	41,	"" },
+	{	42,	"ipfilter not enabled for NAT ioctl" },
+	{	43,	"ipfilter not enabled for state ioctl" },
+	{	44,	"ipfilter not enabled for auth ioctl" },
+	{	45,	"ipfilter not enbaled for sync ioctl" },
+	{	46,	"ipfilter not enabled for scan ioctl" },
+	{	47,	"ipfilter not enabled for lookup ioctl" },
+	{	48,	"unrecognised device minor number for ioctl" },
+	{	49,	"unrecognised object type for copying in ipfobj" },
+	{	50,	"mismatching object type for copying in ipfobj" },
+	{	51,	"object size too small for copying in ipfobj" },
+	{	52,	"object size mismatch for copying in ipfobj" },
+	{	53,	"compat object size too small for copying in ipfobj" },
+	{	54,	"compat object size mismatch for copying in ipfobj" },
+	{	55,	"error doing copyin of data for in ipfobj" },
+	{	56,	"unrecognised object type for size copy in ipfobj" },
+	{	57,	"object size too small for size copy in ipfobj" },
+	{	58,	"mismatching object type for size copy in ipfobj" },
+	{	59,	"object size mismatch for size copy in ipfobj" },
+	{	60,	"compat object size mismatch for size copy in ipfobj" },
+	{	61,	"error doing size copyin of data for in ipfobj" },
+	{	62,	"bad object type for size copy out ipfobj" },
+	{	63,	"mismatching object type for size copy out ipfobj" },
+	{	64,	"object size mismatch for size copy out ipfobj" },
+	{	65,	"compat object size wrong for size copy out ipfobj" },
+	{	66,	"error doing size copyout of data for out ipfobj" },
+	{	67,	"unrecognised object type for copying out ipfobj" },
+	{	68,	"mismatching object type for copying out ipfobj" },
+	{	69,	"object size too small for copying out ipfobj" },
+	{	70,	"object size mismatch for copying out ipfobj" },
+	{	71,	"compat object size too small for copying out ipfobj" },
+	{	72,	"compat object size mismatch for copying out ipfobj" },
+	{	73,	"error doing copyout of data for out ipfobj" },
+	{	74,	"attempt to add existing tunable name" },
+	{	75,	"cannot find tunable name to delete" },
+	{	76,	"internal data too big for next tunable" },
+	{	77,	"could not find tunable" },
+	{	78,	"tunable can only be changed when ipfilter disabled" },
+	{	79,	"new tunable value outside accepted range" },
+	{	80,	"ipftune called for unrecognised ioctl" },
+	{	81,	"" },
+	{	82,	"could not find token to delete" },
+	{	83,	"" },
+	{	84,	"attempt to get next rule when no more exist" },
+	{	85,	"value for iri_inout outside accepted range" },
+	{	86,	"value for iri_active outside accepted range" },
+	{	87,	"value for iri_nrules is 0" },
+	{	88,	"NULL pointer specified for where to copy rule to" },
+	{	89,	"copyout of rule failed" },
+	{	90,	"" },
+	{	91,	"could not get token for rule iteration" },
+	{	92,	"unrecognised generic iterator" },
+	{	93,	"could not find token for generic iterator" },
+	{	94,	"need write permissions to disable/enable ipfilter" },
+	{	95,	"error copying in enable/disable value" },
+	{	96,	"need write permissions to set ipf tunable" },
+	{	97,	"need write permissions to set ipf flags" },
+	{	98,	"error doing copyin of ipf flags" },
+	{	99,	"error doing copyout of ipf flags" },
+	{	100,	"need write permissions to add another rule" },
+	{	101,	"need write permissions to insert another rule" },
+	{	102,	"need write permissions to swap active rule set" },
+	{	103,	"error copying out current active rule set" },
+	{	104,	"need write permissions to zero ipf stats" },
+	{	105,	"need write permissions to flush ipf v4 rules" },
+	{	106,	"error copying out v4 flush results" },
+	{	107,	"error copying in v4 flush command" },
+	{	108,	"need write permissions to flush ipf v6 rules" },
+	{	109,	"error copying out v6 flush results" },
+	{	110,	"error copying in v6 flush command" },
+	{	111,	"error copying in new lock state for ipfilter" },
+	{	112,	"need write permissions to flush ipf logs" },
+	{	113,	"error copying out results of log flush" },
+	{	114,	"need write permissions to resync ipf" },
+	{	115,	"unrecognised ipf ioctl" },
+	{	116,	"error copying in match array" },
+	{	117,	"match array type is not IPFOBJ_IPFEXPR" },
+	{	118,	"bad size for match array" },
+	{	119,	"cannot allocate memory for match aray" },
+	{	120,	"error copying in match array" },
+	{	121,	"error verifying contents of match array" },
+	{	122,	"need write permissions to set ipf lock status" },
+	{	123,	"error copying in data for function resolution" },
+	{	124,	"error copying in ipfobj structure" },
+	{	125,	"error copying in ipfobj structure" },
+	{	126,	"error copying in ipfobj structure" },
+	{	127,	"error copying in ipfobj structure" },
+	{	128,	"no memory for filter rule comment" },
+	{	129,	"error copying in filter rule comment" },
+	{	130,	"error copying out filter rule comment" },
+	{	131,	"no memory for new rule alloc buffer" },
+	{	132,	"cannot find source lookup pool" },
+	{	133,	"unknown source address type" },
+	{	134,	"cannot find destination lookup pool" },
+	{	135,	"unknown destination address type" },
+	{	136,	"icmp head group name index incorrect" },
+	{	137,	"group head name index incorrect" },
+	{	138,	"group name index incorrect" },
+	{	139,	"to interface name index incorrect" },
+	{	140,	"dup-to interface name index incorrect" },
+	{	141,	"reply-to interface name index incorrect" },
+	{	142,	"could not initialise call now function" },
+	{	143,	"could not initialise call function" },
+	{	144,	"could not find destination list" },
+	{	145,	"auth rules cannot have dup/to/fastroute" },
+	{	146,	"incorrect size for object to copy out" },
+	{	147,	"object type out of bounds for kernel copyout" },
+	{	148,	"object size too small for kernel copyout" },
+	{	149,	"object size validation failed for kernel copyout" },
+	{	150,	"error copying data out for kernel copyout" },
+	{	151,	"version mismatch for kernel copyout" },
+/* -------------------------------------------------------------------------- */
+	{	10001,	"could not find token for auth iterator" },
+	{	10002,	"write permissions require to add/remove auth rule" },
+	{	10003,	"need write permissions to set auth lock" },
+	{	10004,	"error copying out results of auth flush" },
+	{	10005,	"unknown auth ioctl" },
+	{	10006,	"can only append or remove preauth rules" },
+	{	10007,	"NULL pointers passed in for preauth remove" },
+	{	10008,	"preauth rule not found to remove" },
+	{	10009,	"could not malloc memory for preauth entry" },
+	{	10010,	"unrecognised preauth rule ioctl command" },
+	{	10011,	"iterator data supplied with NULL pointer" },
+	{	10012,	"unknown auth iterator type" },
+	{	10013,	"iterator error copying out auth data" },
+	{	10014,	"sleep waiting for auth packet interrupted" },
+	{	10015,	"bad index supplied in auth reply" },
+	{	10016,	"error injecting outbound packet back into kernel" },
+	{	10017,	"error injecting inbound packet back into kernel" },
+	{	10018,	"could not attempt to inject packet back into kernel" },
+	{	10019,	"packet id does not match" },
+/* -------------------------------------------------------------------------- */
+	{	20001,	"invalid frag token data pointer supplied" },
+	{	20002,	"error copying out frag token data" },
+	{	20003,	"can only copy one fragment state entry at a time" },
+/* -------------------------------------------------------------------------- */
+	{	30001,	"incorrect object size to get hash table stats" },
+	{	30002,	"could not malloc memory for new hash table" },
+	{	30003,	"error coping in hash table structure" },
+	{	30004,	"hash table already exists" },
+	{	30005,	"mismach between new hash table and operation unit" },
+	{	30006,	"could not malloc memory for hash table base" },
+	{	30007,	"could not find hash table" },
+	{	30008,	"mismatch between hash table and operation unit" },
+	{	30009,	"could not find hash table for iterators next node" },
+	{	30010,	"unknown iterator tpe" },
+	{	30011,	"iterator error copying out hash table" },
+	{	30012,	"iterator error copying out hash table entry" },
+	{	30013,	"error copying out hash table statistics" },
+	{	30014,	"table node delete structure wrong size" },
+	{	30015,	"error copying in node to delete" },
+	{	30016,	"table to delete node from does not exist" },
+	{	30017,	"could not find table to remove node from" },
+	{	30018,	"table node add structure wrong size" },
+	{	30019,	"error copying in node to add" },
+	{	30020,	"could not find table to add node to" },
+	{	30021,	"node already exists in the table" },
+	{	30022,	"could not find node to delete in table" },
+	{	30023,	"uid mismatch on node to delete" },
+	{	30024,	"object size incorrect for hash table" },
+	{	30025,	"hash table size must be at least 1"},
+	{	30026,	"cannot allocate memory for hash table context" },
+/* -------------------------------------------------------------------------- */
+	{	40001,	"invalid minor device numebr for log read" },
+	{	40002,	"read size too small" },
+	{	40003,	"interrupted waiting for log data to read" },
+	{	40004,	"interrupted waiting for log data to read" },
+	{	40005,	"read size too large" },
+	{	40006,	"uiomove for read operation failed" },
+/* -------------------------------------------------------------------------- */
+	{	50001,	"unknown lookup ioctl" },
+	{	50002,	"error copying in object data for add node" },
+	{	50003,	"invalid unit for lookup add node" },
+	{	50004,	"incorrect size for adding a pool node" },
+	{	50005,	"error copying in pool node structure" },
+	{	50006,	"mismatch in pool node address/mask families" },
+	{	50007,	"could not find pool name" },
+	{	50008,	"node already exists in pool" },
+	{	50009,	"incorrect size for adding a hash node" },
+	{	50010,	"error copying in hash node structure" },
+	{	50011,	"could not find hash table name" },
+	{	50012,	"unrecognised object type for lookup add node" },
+	{	50013,	"invalid unit for lookup delete node" },
+	{	50014,	"incorrect size for deleting a pool node" },
+	{	50015,	"error copying in pool node structure" },
+	{	50016,	"could not find pool name" },
+	{	50017,	"could not find pool node" },
+	{	50018,	"incorrect size for removing a hash node" },
+	{	50019,	"error copying in hash node structure" },
+	{	50020,	"could not find hash table name" },
+	{	50021,	"unrecognised object type for lookup delete node" },
+	{	50022,	"error copying in add table data" },
+	{	50023,	"invalid unit for lookup add table" },
+	{	50024,	"pool name already exists" },
+	{	50025,	"hash table name already exists" },
+	{	50026,	"unrecognised object type for lookup add table" },
+	{	50027,	"error copying table data back out" },
+	{	50028,	"error copying in remove table data" },
+	{	50029,	"invalid unit for lookup remove table" },
+	{	50030,	"unrecognised object type for lookup remove table" },
+	{	50031,	"error copying in lookup stats structure" },
+	{	50032,	"invalid unit for lookup stats" },
+	{	50033,	"unrecognised object type for lookup stats" },
+	{	50034,	"error copying in flush lookup data" },
+	{	50035,	"invalid unit for lookup flush" },
+	{	50036,	"incorrect table type for lookup flush" },
+	{	50037,	"error copying out lookup flush results" },
+	{	50038,	"invalid unit for lookup iterator" },
+	{	50039,	"invalid unit for lookup iterator" },
+	{	50040,	"could not find token for lookup iterator" },
+	{	50041,	"unrecognised object type for lookup interator" },
+	{	50042,	"error copying in lookup delete node operation" },
+/* -------------------------------------------------------------------------- */
+	{	60001,	"insufficient privilege for NAT write operation" },
+	{	60002,	"need write permissions to flush NAT logs" },
+	{	60003,	"need write permissions to turn NAT logging on/off" },
+	{	60004,	"error copying out current NAT log setting" },
+	{	60005,	"error copying out bytes waiting to be read in NAT \
+log" },
+	{	60006,	"need write permissions to add NAT rule" },
+	{	60007,	"NAT rule already exists" },
+	{	60008,	"could not allocate memory for NAT rule" },
+	{	60009,	"need write permissions to remove NAT rule" },
+	{	60010,	"NAT rule could not be found" },
+	{	60011,	"could not find NAT entry for redirect lookup" },
+	{	60012,	"need write permissions to flush NAT table" },
+	{	60013,	"error copying in NAT flush command" },
+	{	60014,	"need write permissions to do matching NAT flush" },
+	{	60015,	"need write permissions to set NAT lock" },
+	{	60016,	"need write permissions to add entry to NAT table" },
+	{	60017,	"NAT not locked for size retrieval" },
+	{	60018,	"NAT not locked for fetching NAT table entry" },
+	{	60019,	"error copying in NAT token data for deletion" },
+	{	60020,	"unknown NAT ioctl" },
+	{	60021,	"" },
+	{	60022,	"resolving proxy name in NAT rule failed" },
+	{	60023,	"only reply age specified in NAT rule" },
+	{	60024,	"error doing copyin to determine NAT entry size" },
+	{	60025,	"error copying out NAT size of 0" },
+	{	60026,	"NAT entry not found" },
+	{	60027,	"error doing copyout of NAT entry size" },
+	{	60028,	"invalid data size for getting NAT entry" },
+	{	60029,	"could not malloc temporary space for NAT entry" },
+	{	60030,	"no NAT table entries present" },
+	{	60031,	"NAT entry to get next from not found" },
+	{	60032,	"not enough space for proxy structure" },
+	{	60033,	"not enough space for private proxy data" },
+	{	60034,	"NAT entry size is too large" },
+	{	60035,	"could not malloc memory for NAT entry sratch space" },
+	{	60036,	"" },
+	{	60037,	"could not malloc memory for NAT entry" },
+	{	60038,	"could not malloc memory for NAT entry rule" },
+	{	60039,	"could not resolve NAT entry rule's proxy" },
+	{	60040,	"cannot add outbound duplicate NAT entry" },
+	{	60041,	"cannot add inbound duplicate NAT entry" },
+	{	60042,	"cannot add NAT entry that is neither IN nor OUT" },
+	{	60043,	"could not malloc memory for NAT proxy data" },
+	{	60044,	"proxy data size too big" },
+	{	60045,	"could not malloc proxy private data for NAT entry" },
+	{	60046,	"could not malloc memory for new NAT filter rule" },
+	{	60047,	"could not find existing filter rule for NAT entry" },
+	{	60048,	"insertion into NAT table failed" },
+	{	60049,	"iterator error copying out hostmap data" },
+	{	60050,	"iterator error copying out NAT rule data" },
+	{	60051,	"iterator error copying out NAT entry data" },
+	{	60052,	"iterator data supplied with NULL pointer" },
+	{	60053,	"unknown NAT iterator type" },
+	{	60054,	"unknwon next address type" },
+	{	60055,	"iterator suppled with unknown type for get-next" },
+	{	60056,	"unknown lookup group for next address" },
+	{	60057,	"error copying out NAT log flush results" },
+	{	60058,	"bucket table type is incorrect" },
+	{	60059,	"error copying out NAT bucket table" },
+	{	60060,	"function not found for lookup" },
+	{	60061,	"address family not supported with SIOCSTPUT" },
+	{	60062,	"unknown timeout name" },
+	{	60063,	"cannot allocate new inbound NAT entry table" },
+	{	60064,	"cannot allocate new outbound NAT entry table" },
+	{	60065,	"cannot allocate new inbound NAT bucketlen table" },
+	{	60066,	"cannot allocate new outbound NAT bucketlen table" },
+	{	60067,	"cannot allocate new NAT rules table" },
+	{	60068,	"cannot allocate new NAT hostmap table" },
+	{	60069,	"new source lookup type is not dstlist" },
+	{	60070,	"cannot allocate NAT rule scratch space" },
+	{	60071,	"new destination lookup type is not dstlist" },
+	{	60072,	"function not found for lookup (ipv6)" },
+	{	60073,	"unknown lookup group for next address (ipv6)" },
+	{	60074,	"unknown next address type (ipv6)" },
+	{	60075,	"one object at a time must be copied" },
+/* -------------------------------------------------------------------------- */
+	{	70001,	"incorrect object size to get pool stats" },
+	{	70002,	"could not malloc memory for new pool node" },
+	{	70003,	"invalid addresss length for new pool node" },
+	{	70004,	"invalid mask length for new pool node" },
+	{	70005,	"error adding node to pool" },
+	{	70006,	"pool already exists" },
+	{	70007,	"could not malloc memory for new pool" },
+	{	70008,	"could not allocate radix tree for new pool" },
+	{	70009,	"could not find pool" },
+	{	70010,	"unknown pool name for iteration" },
+	{	70011,	"unknown pool iterator" },
+	{	70012,	"error copying out pool head" },
+	{	70013,	"error copying out pool node" },
+	{	70014,	"add node size incorrect" },
+	{	70015,	"error copying in pool node" },
+	{	70016,	"" },
+	{	70017,	"cannot find pool for node" },
+	{	70018,	"node entry already present in pool" },
+	{	70019,	"delete node size incorrect" },
+	{	70020,	"error copying in node to delete" },
+	{	70021,	"cannot find pool to delete node from" },
+	{	70022,	"cannot find node to delete in pool" },
+	{	70023,	"pool name already exists" },
+	{	70024,	"uid mismatch for node removal" },
+	{	70025,	"stats device unit is invalid" },
+	{	70026,	"error copying out statistics" },
+	{	70027,	"could not remove node from radix tree" },
+	{	70028,	"incorrect address length in pool node add" },
+	{	70029,	"incorrect mask length in pool node add" },
+	{	70030,	"incorrect address length in pool node remove" },
+	{	70031,	"incorrect mask length in pool node remove" },
+	{	70032,	"cannot allocate memory for pool context" },
+	{	70033,	"cannot allocate memory for radix tree context" },
+	{	70034,	"adding IPv6 node with incorrect address length" },
+	{	70035,	"IPv4 address not masked" },
+	{	70036,	"IPv6 address not masked" },
+	{	70037,	"removing IPv6 node with incorrect address length" },
+/* -------------------------------------------------------------------------- */
+	{	80001,	"could not find proxy" },
+	{	80002,	"proxy does not support control operations" },
+	{	80003,	"could not allocate data to hold proxy operation" },
+	{	80004,	"unknown proxy ioctl" },
+	{	80005,	"could not copyin proxy control structure" },
+	{	80006,	"DNS proxy could not find rule to delete" },
+	{	80007,	"DNS proxy found existing matching rule" },
+	{	80008,	"DNS proxy could not allocate memory for new rule" },
+	{	80009,	"DNS proxy unknown command request" },
+/* -------------------------------------------------------------------------- */
+	{	90001,	"could not malloc space for new scan structure" },
+	{	90002,	"scan tag already exists" },
+	{	90003,	"scan structure in use" },
+	{	90004,	"could not find matching scan tag for filter rule" },
+	{	90005,	"could not copyout scan statistics" },
+/* -------------------------------------------------------------------------- */
+	{	100001,	"cannot find matching state entry to remove" },
+	{	100002,	"error copying in v4 state flush command" },
+	{	100003,	"error copying out v4 state flush results" },
+	{	100004,	"error copying in v6 state flush command" },
+	{	100005,	"error copying out v6 state flush results" },
+	{	100006,	"" },
+	{	100007,	"" },
+	{	100008,	"need write permissions to flush state log" },
+	{	100009,	"erorr copyout results of flushing state log" },
+	{	100010,	"need write permissions to turn state logging on/off" },
+	{	100011,	"error copying in new state logging state" },
+	{	100012,	"error copying out current state logging state" },
+	{	100013,	"error copying out bytes waiting to be read in state \
+log" },
+	{	100014,	"need write permissions to set state lock" },
+	{	100015,	"need write permissions to add entry to state table" },
+	{	100016,	"state not locked for size retrieval" },
+	{	100017,	"error copying out hash table bucket lengths" },
+	{	100018,	"could not find token for state iterator" },
+	{	100019,	"error copying in state token data for deletion" },
+	{	100020,	"unknown state ioctl" },
+	{	100021,	"no state table entries present" },
+	{	100022,	"state entry to get next from not found" },
+	{	100023,	"could not malloc memory for state entry" },
+	{	100024,	"could not malloc memory for state entry rule" },
+	{	100025,	"could not copy back state entry to user space" },
+	{	100026,	"iterator data supplied with NULL pointer" },
+	{	100027,	"iterator supplied with 0 item count" },
+	{	100028,	"iterator type is incorrect" },
+	{	100029,	"invalid state token data pointer supplied" },
+	{	100030,	"error copying out next state entry" },
+	{	100031,	"unrecognised table request" },
+	{	100032,	"error copying out bucket length data" },
+	{	100033,	"could not find existing filter rule for state entry" },
+	{	100034,	"could not find timeout name" },
+	{	100035, "could not allocate new state table" },
+	{	100036, "could not allocate new state bucket length table" },
+/* -------------------------------------------------------------------------- */
+	{	110001,	"sync write header magic number is incorrect" },
+	{	110002,	"sync write header protocol is incorrect" },
+	{	110003,	"sync write header command is incorrect" },
+	{	110004,	"sync write header table number is incorrect" },
+	{	110005,	"data structure too small for sync write operation" },
+	{	110006,	"zero length data with sync write header" },
+	{	110007,	"insufficient data for sync write" },
+	{	110008,	"bad sync read size" },
+	{	110009,	"interrupted sync read (solaris)" },
+	{	110010,	"interrupted sync read (hpux)" },
+	{	110011,	"interrupted sync read (osf)" },
+	{	110012,	"interrupted sync read" },
+	{	110013,	"could not malloc memory for sync'd state" },
+	{	110014,	"could not malloc memory for sync-state list item" },
+	{	110015,	"sync update could not find state" },
+	{	110016,	"unrecognised sync state command" },
+	{	110017,	"could not malloc memory for new sync'd NAT entry" },
+	{	110018,	"could not malloc memory for sync-NAT list item" },
+	{	110019,	"sync update could not find NAT entry" },
+	{	110020,	"unrecognised sync NAT command" },
+	{	110021,	"ioctls are not handled with sync" },
+/* -------------------------------------------------------------------------- */
+	{	120001,	"null data pointer for iterator" },
+	{	120002,	"unit outside of acceptable range" },
+	{	120003,	"unknown iterator subtype" },
+	{	120004,	"cannot find dest. list for iteration" },
+	{	120005,	"error copying out destination iteration list" },
+	{	120006,	"error copying out destination iteration node" },
+	{	120007,	"wrong size for frdest_t structure" },
+	{	120008,	"cannot allocate memory for new destination node" },
+	{	120009,	"error copying in destination node to add" },
+	{	120010,	"could not find destination list to add node to" },
+	{	120011,	"error copying in destination node to remove" },
+	{	120012,	"could not find dest. list to remove node from" },
+	{	120013,	"destination list already exists" },
+	{	120014,	"could not allocate new destination table" },
+	{	120015,	"could not find destination list to remove" },
+	{	120016,	"destination list cannot be removed - it is busy" },
+	{	120017,	"error copying in names for destination" },
+	{	120018,	"destination name is too long/short" },
+	{	120019,	"unrecognised address family in destination" },
+	{	120020,	"" },
+	{	120021,	"error copying in new destination table" },
+	{	120022,	"cannot allocate memory for node table" },
+	{	120023,	"stats object size is incorrect for dest. lists" },
+	{	120024,	"stats device unit is invalid for dest. lists" },
+	{	120025,	"error copying out dest. list statistics" },
+	{	120026,	"cannot allocate memory for destination node" },
+	{	120027,	"error copying in destination node" },
+	{	120028,	"cannot allocate memory for destination context " },
+/* -------------------------------------------------------------------------- */
+	{	130001,	"ioctl denied by system security level" },
+	{	130002,	"ioctl operation on invalid minor device" },
+	{	130003,	"ioctl on device denied, ipfitler is disabled" },
+	{	130004,	"ioctl command not allowed when disabled" },
+	{	130005,	"ioctl denied due to insufficient authorisation" },
+	{	130006,	"cannot read while ipfilter is disabled" },
+	{	130007,	"read on minor device not supported" },
+	{	130008,	"cannot write while ipfilter is disabled" },
+	{	130009,	"write on minor device not supported" },
+	{	130010,	"poll on minor device is not supported" },
+	{	130011,	"error removing IPv4 filter hooks" },
+	{	130012,	"error removing IPv6 filter hooks" },
+	{	130013,	"attaching IPv4 hook failed" },
+	{	130014,	"attaching IPv6 hook failed" },
+	{	130015,	"ipf_init_all failed" },
+	{	130016,	"finding pfil head failed" },
+	{	130017,	"ipfilter is already initialised and running" },
+};
+
+
+static ipf_error_entry_t *
+find_error(errnum)
+	int errnum;
+{
+	ipf_error_entry_t *ie;
+
+	int l = -1, r = IPF_NUM_ERRORS + 1, step;
+	step = (r - l) / 2;;
+
+	while (step != 0) {
+		ie = ipf_errors + l + step;
+		if (ie->iee_number == errnum)
+			return ie;
+		step = l + step;
+		if (ie->iee_number > errnum)
+			r = step;
+		else
+			l = step;
+		step = (r - l) / 2;;
+	}
+
+	return NULL;
+}
+
+char *
+ipf_geterror(fd, func)
+	int fd;
+	ioctlfunc_t *func;
+{
+	static char text[80];
+	ipf_error_entry_t *ie;
+	int errnum;
+
+	if ((*func)(fd, SIOCIPFINTERROR, &errnum) == 0) {
+
+		ie = find_error(errnum);
+		if (ie != NULL)
+			return ie->iee_text;
+		sprintf(text, "unknown error %d", errnum);
+	} else {
+		sprintf(text, "retrieving error number failed (%d)", errno);
+	}
+	return text;
+}
+
+
+char *
+ipf_strerror(errnum)
+	int errnum;
+{
+	static char text[80];
+	ipf_error_entry_t *ie;
+
+
+	ie = find_error(errnum);
+	if (ie != NULL)
+		return ie->iee_text;
+
+	sprintf(text, "unknown error %d", errnum);
+	return text;
+}


Property changes on: trunk/contrib/ipfilter/lib/interror.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/ipf_perror.c
===================================================================
--- trunk/contrib/ipfilter/lib/ipf_perror.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/ipf_perror.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,47 @@
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "ipf.h"
+
+void
+ipf_perror(err, string)
+	int err;
+	char *string;
+{
+	if (err == 0)
+		fprintf(stderr, "%s\n", string);
+	else
+		fprintf(stderr, "%s: %s\n", string, ipf_strerror(err));
+}
+
+int
+ipf_perror_fd(fd, iocfunc, string)
+	int fd;
+	ioctlfunc_t iocfunc;
+	char *string;
+{
+	int save;
+	int realerr;
+
+	save = errno;
+	if ((*iocfunc)(fd, SIOCIPFINTERROR, &realerr) == -1)
+		realerr = 0;
+
+	errno = save;
+	fprintf(stderr, "%d:", realerr);
+	ipf_perror(realerr, string);
+	return realerr ? realerr : save;
+
+}
+
+void
+ipferror(fd, msg)
+	int fd;
+	char *msg;
+{
+	if (fd >= 0) {
+		ipf_perror_fd(fd, ioctl, msg);
+	} else {
+		fprintf(stderr, "0:");
+		perror(msg);
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/ipf_perror.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/load_dstlist.c
===================================================================
--- trunk/contrib/ipfilter/lib/load_dstlist.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/load_dstlist.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: load_dstlist.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "ipf.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_dstlist.h"
+
+
+int
+load_dstlist(dst, iocfunc, nodes)
+	ippool_dst_t *dst;
+	ioctlfunc_t iocfunc;
+	ipf_dstnode_t *nodes;
+{
+	iplookupop_t op;
+	ipf_dstnode_t *a;
+	ippool_dst_t dest;
+
+	if (dst->ipld_name[0] == '\0')
+		return -1;
+
+	if (pool_open() == -1)
+		return -1;
+
+	op.iplo_unit = dst->ipld_unit;
+	op.iplo_type = IPLT_DSTLIST;
+	op.iplo_arg = 0;
+	strncpy(op.iplo_name, dst->ipld_name, sizeof(op.iplo_name));
+	op.iplo_size = sizeof(dest);
+	op.iplo_struct = &dest;
+	bzero((char *)&dest, sizeof(dest));
+	dest.ipld_unit = dst->ipld_unit;
+	dest.ipld_policy = dst->ipld_policy;
+	dest.ipld_flags = dst->ipld_flags;
+	strncpy(dest.ipld_name, dst->ipld_name, sizeof(dest.ipld_name));
+
+	if ((opts & OPT_REMOVE) == 0) {
+		if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op))
+			if ((opts & OPT_DONOTHING) == 0) {
+				return ipf_perror_fd(pool_fd(), iocfunc,
+						  "add destination list table");
+			}
+	}
+
+	if ((opts & OPT_VERBOSE) != 0) {
+		dest.ipld_dests = dst->ipld_dests;
+		printdstlist(&dest, bcopywrap, dest.ipld_name, opts, nodes, NULL);
+		dest.ipld_dests = NULL;
+	}
+
+	for (a = nodes; a != NULL; a = a->ipfd_next)
+		load_dstlistnode(dst->ipld_unit, dest.ipld_name, a, iocfunc);
+
+	if ((opts & OPT_REMOVE) != 0) {
+		if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op))
+			if ((opts & OPT_DONOTHING) == 0) {
+				return ipf_perror_fd(pool_fd(), iocfunc,
+					      "delete destination list table");
+			}
+	}
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/load_dstlist.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/load_dstlistnode.c
===================================================================
--- trunk/contrib/ipfilter/lib/load_dstlistnode.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/load_dstlistnode.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: load_dstlistnode.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "ipf.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_pool.h"
+
+
+int
+load_dstlistnode(role, name, node, iocfunc)
+	int role;
+	char *name;
+	ipf_dstnode_t *node;
+	ioctlfunc_t iocfunc;
+{
+	iplookupop_t op;
+	frdest_t *dst;
+	char *what;
+	int err;
+
+	if (pool_open() == -1)
+		return -1;
+
+	dst = calloc(1, sizeof(*dst) + node->ipfd_dest.fd_name);
+	if (dst == NULL)
+		return -1;
+
+	op.iplo_unit = role;
+	op.iplo_type = IPLT_DSTLIST;
+	op.iplo_arg = 0;
+	op.iplo_struct = dst;
+	op.iplo_size = sizeof(*dst);
+	if (node->ipfd_dest.fd_name >= 0)
+		op.iplo_size += node->ipfd_dest.fd_name;
+	(void) strncpy(op.iplo_name, name, sizeof(op.iplo_name));
+
+	dst->fd_addr = node->ipfd_dest.fd_addr;
+	dst->fd_type = node->ipfd_dest.fd_type;
+	dst->fd_name = node->ipfd_dest.fd_name;
+	if (node->ipfd_dest.fd_name >= 0)
+		bcopy(node->ipfd_names, (char *)dst + sizeof(*dst),
+		      node->ipfd_dest.fd_name);
+
+	if ((opts & OPT_REMOVE) == 0) {
+		what = "add";
+		err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op);
+	} else {
+		what = "delete";
+		err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op);
+	}
+	free(dst);
+
+	if (err != 0) {
+		if ((opts & OPT_DONOTHING) == 0) {
+			char msg[80];
+
+			(void) sprintf(msg, "%s lookup node", what);
+			return ipf_perror_fd(pool_fd(), iocfunc, msg);
+		}
+	}
+
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/load_dstlistnode.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/mb_hexdump.c
===================================================================
--- trunk/contrib/ipfilter/lib/mb_hexdump.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/mb_hexdump.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: mb_hexdump.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+void
+mb_hexdump(m, fp)
+	mb_t *m;
+	FILE *fp;
+{
+	u_char *s;
+	int len;
+	int i;
+
+	for (; m != NULL; m = m->mb_next) {
+		len = m->mb_len;
+		for (s = (u_char *)m->mb_data, i = 0; i < len; i++) {
+			fprintf(fp, "%02x", *s++ & 0xff);
+			if (len - i > 1) {
+				i++;
+				fprintf(fp, "%02x", *s++ & 0xff);
+			}
+			fputc(' ', fp);
+		}
+	}
+	fputc('\n', fp);
+}


Property changes on: trunk/contrib/ipfilter/lib/mb_hexdump.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/msgdsize.c
===================================================================
--- trunk/contrib/ipfilter/lib/msgdsize.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/msgdsize.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: msgdsize.c,v 1.2.4.3 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+size_t msgdsize(orig)
+	mb_t *orig;
+{
+	size_t sz = 0;
+	mb_t *m;
+
+	for (m = orig; m != NULL; m = m->mb_next)
+		sz += m->mb_len;
+	return sz;
+}


Property changes on: trunk/contrib/ipfilter/lib/msgdsize.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/parsefields.c
===================================================================
--- trunk/contrib/ipfilter/lib/parsefields.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/parsefields.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,53 @@
+#include "ipf.h"
+#include <err.h>
+
+extern int nohdrfields;
+
+wordtab_t *parsefields(table, arg)
+	wordtab_t *table;
+	char *arg;
+{
+	wordtab_t *f, *fields;
+	char *s, *t;
+	int num;
+
+	fields = NULL;
+	num = 0;
+
+	for (s = strtok(arg, ","); s != NULL; s = strtok(NULL, ",")) {
+		t = strchr(s, '=');
+		if (t != NULL) {
+			*t++ = '\0';
+			if (*t == '\0')
+				nohdrfields = 1;
+		}
+
+		f = findword(table, s);
+		if (f == NULL) {
+			fprintf(stderr, "Unknown field '%s'\n", s);
+			exit(1);
+		}
+
+		num++;
+		if (fields == NULL) {
+			fields = malloc(2 * sizeof(*fields));
+		} else {
+			fields = realloc(fields, (num + 1) * sizeof(*fields));
+			if (fields == NULL) {
+				warnx("memory allocation error at %d in %s in %s", __LINE__, __FUNCTION__, __FILE__);
+				abort();
+			}
+		}
+
+		if (t == NULL) {
+			fields[num - 1].w_word = f->w_word;
+		} else {
+			fields[num - 1].w_word = t;
+		}
+		fields[num - 1].w_value = f->w_value;
+		fields[num].w_word = NULL;
+		fields[num].w_value = 0;
+	}
+
+	return fields;
+}


Property changes on: trunk/contrib/ipfilter/lib/parsefields.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/parseipfexpr.c
===================================================================
--- trunk/contrib/ipfilter/lib/parseipfexpr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/parseipfexpr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,283 @@
+#include "ipf.h"
+#include <ctype.h>
+
+
+typedef struct ipfopentry {
+	int	ipoe_cmd;
+	int	ipoe_nbasearg;
+	int	ipoe_maxarg;
+	int	ipoe_argsize;
+	char	*ipoe_word;
+} ipfopentry_t;
+
+static ipfopentry_t opwords[17] = {
+	{ IPF_EXP_IP_ADDR, 2, 0, 1, "ip.addr" },
+	{ IPF_EXP_IP6_ADDR, 2, 0, 4, "ip6.addr" },
+	{ IPF_EXP_IP_PR, 1, 0, 1, "ip.p" },
+	{ IPF_EXP_IP_SRCADDR, 2, 0, 1, "ip.src" },
+	{ IPF_EXP_IP_DSTADDR, 2, 0, 1, "ip.dst" },
+	{ IPF_EXP_IP6_SRCADDR, 2, 0, 4, "ip6.src" },
+	{ IPF_EXP_IP6_DSTADDR, 2, 0, 4, "ip6.dst" },
+	{ IPF_EXP_TCP_PORT, 1, 0, 1, "tcp.port" },
+	{ IPF_EXP_TCP_DPORT, 1, 0, 1, "tcp.dport" },
+	{ IPF_EXP_TCP_SPORT, 1, 0, 1, "tcp.sport" },
+	{ IPF_EXP_TCP_FLAGS, 2, 0, 1, "tcp.flags" },
+	{ IPF_EXP_UDP_PORT, 1, 0, 1, "udp.port" },
+	{ IPF_EXP_UDP_DPORT, 1, 0, 1, "udp.dport" },
+	{ IPF_EXP_UDP_SPORT, 1, 0, 1, "udp.sport" },
+	{ IPF_EXP_TCP_STATE, 1, 0, 1, "tcp.state" },
+	{ IPF_EXP_IDLE_GT, 1, 1, 1, "idle-gt" },
+	{ -1, 0, 0, 0, NULL  }
+};
+
+
+int *
+parseipfexpr(line, errorptr)
+	char *line;
+	char **errorptr;
+{
+	int not, items, asize, *oplist, osize, i;
+	char *temp, *arg, *s, *t, *ops, *error;
+	ipfopentry_t *e;
+	ipfexp_t *ipfe;
+
+	asize = 0;
+	error = NULL;
+	oplist = NULL;
+
+	temp = strdup(line);
+	if (temp == NULL) {
+		error = "strdup failed";
+		goto parseerror;
+	}
+
+	/*
+	 * Eliminate any white spaces to make parsing easier.
+	 */
+	for (s = temp; *s != '\0'; ) {
+		if (ISSPACE(*s))
+			strcpy(s, s + 1);
+		else
+			s++;
+	}
+
+	/*
+	 * Parse the string.
+	 * It should be sets of "ip.dst=1.2.3.4/32;" things.
+	 * There must be a "=" or "!=" and it must end in ";".
+	 */
+	if (temp[strlen(temp) - 1] != ';') {
+		error = "last character not ';'";
+		goto parseerror;
+	}
+
+	/*
+	 * Work through the list of complete operands present.
+	 */
+	for (ops = strtok(temp, ";"); ops != NULL; ops = strtok(NULL, ";")) {
+		arg = strchr(ops, '=');
+		if ((arg < ops + 2) || (arg == NULL)) {
+			error = "bad 'arg' vlaue";
+			goto parseerror;
+		}
+
+		if (*(arg - 1) == '!') {
+			*(arg - 1) = '\0';
+			not = 1;
+		} else {
+			not = 0;
+		}
+		*arg++ = '\0';
+
+
+		for (e = opwords; e->ipoe_word; e++) {
+			if (strcmp(ops, e->ipoe_word) == 0)
+				break;
+		}
+		if (e->ipoe_word == NULL) {
+			error = malloc(32);
+			if (error != NULL) {
+				sprintf(error, "keyword (%.10s) not found",
+					ops);
+			}
+			goto parseerror;
+		}
+
+		/*
+		 * Count the number of commas so we know how big to
+		 * build the array
+		 */
+		for (s = arg, items = 1; *s != '\0'; s++)
+			if (*s == ',')
+				items++;
+
+		if ((e->ipoe_maxarg != 0) && (items > e->ipoe_maxarg)) {
+			error = "too many items";
+			goto parseerror;
+		}
+
+		/*
+		 * osize will mark the end of where we have filled up to
+		 * and is thus where we start putting new data.
+		 */
+		osize = asize;
+		asize += 4 + (items * e->ipoe_nbasearg * e->ipoe_argsize);
+		if (oplist == NULL)
+			oplist = calloc(1, sizeof(int) * (asize + 2));
+		else
+			oplist = realloc(oplist, sizeof(int) * (asize + 2));
+		if (oplist == NULL) {
+			error = "oplist alloc failed";
+			goto parseerror;
+		}
+		ipfe = (ipfexp_t *)(oplist + osize);
+		osize += 4;
+		ipfe->ipfe_cmd = e->ipoe_cmd;
+		ipfe->ipfe_not = not;
+		ipfe->ipfe_narg = items * e->ipoe_nbasearg;
+		ipfe->ipfe_size = items * e->ipoe_nbasearg * e->ipoe_argsize;
+		ipfe->ipfe_size += 4;
+
+		for (s = arg; (*s != '\0') && (osize < asize); s = t) {
+			/*
+			 * Look for the end of this arg or the ',' to say
+			 * there is another following.
+			 */
+			for (t = s; (*t != '\0') && (*t != ','); t++)
+				;
+			if (*t == ',')
+				*t++ = '\0';
+
+			if (!strcasecmp(ops, "ip.addr") ||
+			    !strcasecmp(ops, "ip.src") ||
+			    !strcasecmp(ops, "ip.dst")) {
+				i6addr_t mask, addr;
+				char *delim;
+
+				delim = strchr(s, '/');
+				if (delim != NULL) {
+					*delim++ = '\0';
+					if (genmask(AF_INET, delim,
+						    &mask) == -1) {
+						error = "genmask failed";
+						goto parseerror;
+					}
+				} else {
+					mask.in4.s_addr = 0xffffffff;
+				}
+				if (gethost(AF_INET, s, &addr) == -1) {
+					error = "gethost failed";
+					goto parseerror;
+				}
+
+				oplist[osize++] = addr.in4.s_addr;
+				oplist[osize++] = mask.in4.s_addr;
+
+#ifdef USE_INET6
+			} else if (!strcasecmp(ops, "ip6.addr") ||
+			    !strcasecmp(ops, "ip6.src") ||
+			    !strcasecmp(ops, "ip6.dst")) {
+				i6addr_t mask, addr;
+				char *delim;
+
+				delim = strchr(s, '/');
+				if (delim != NULL) {
+					*delim++ = '\0';
+					if (genmask(AF_INET6, delim,
+						    &mask) == -1) {
+						error = "genmask failed";
+						goto parseerror;
+					}
+				} else {
+					mask.i6[0] = 0xffffffff;
+					mask.i6[1] = 0xffffffff;
+					mask.i6[2] = 0xffffffff;
+					mask.i6[3] = 0xffffffff;
+				}
+				if (gethost(AF_INET6, s, &addr) == -1) {
+					error = "gethost failed";
+					goto parseerror;
+				}
+
+				oplist[osize++] = addr.i6[0];
+				oplist[osize++] = addr.i6[1];
+				oplist[osize++] = addr.i6[2];
+				oplist[osize++] = addr.i6[3];
+				oplist[osize++] = mask.i6[0];
+				oplist[osize++] = mask.i6[1];
+				oplist[osize++] = mask.i6[2];
+				oplist[osize++] = mask.i6[3];
+#endif
+
+			} else if (!strcasecmp(ops, "ip.p")) {
+				int p;
+
+				p = getproto(s);
+				if (p == -1)
+					goto parseerror;
+				oplist[osize++] = p;
+
+			} else if (!strcasecmp(ops, "tcp.flags")) {
+				u_32_t mask, flags;
+				char *delim;
+
+				delim = strchr(s, '/');
+				if (delim != NULL) {
+					*delim++ = '\0';
+					mask = tcpflags(delim);
+				} else {
+					mask = 0xff;
+				}
+				flags = tcpflags(s);
+
+				oplist[osize++] = flags;
+				oplist[osize++] = mask;
+
+
+			} else if (!strcasecmp(ops, "tcp.port") ||
+			    !strcasecmp(ops, "tcp.sport") ||
+			    !strcasecmp(ops, "tcp.dport") ||
+			    !strcasecmp(ops, "udp.port") ||
+			    !strcasecmp(ops, "udp.sport") ||
+			    !strcasecmp(ops, "udp.dport")) {
+				char proto[4];
+				u_short port;
+
+				strncpy(proto, ops, 3);
+				proto[3] = '\0';
+				if (getport(NULL, s, &port, proto) == -1)
+					goto parseerror;
+				oplist[osize++] = port;
+
+			} else if (!strcasecmp(ops, "tcp.state")) {
+				oplist[osize++] = atoi(s);
+
+			} else {
+				error = "unknown word";
+				goto parseerror;
+			}
+		}
+	}
+
+	free(temp);
+
+	if (errorptr != NULL)
+		*errorptr = NULL;
+
+	for (i = asize; i > 0; i--)
+		oplist[i] = oplist[i - 1];
+
+	oplist[0] = asize + 2;
+	oplist[asize + 1] = IPF_EXP_END;
+
+	return oplist;
+
+parseerror:
+	if (errorptr != NULL)
+		*errorptr = error;
+	if (oplist != NULL)
+		free(oplist);
+	if (temp != NULL)
+		free(temp);
+	return NULL;
+}


Property changes on: trunk/contrib/ipfilter/lib/parseipfexpr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/parsewhoisline.c
===================================================================
--- trunk/contrib/ipfilter/lib/parsewhoisline.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/parsewhoisline.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $
+ */
+#include "ipf.h"
+
+/*
+Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255
+Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47
+ */
+int
+parsewhoisline(line, addrp, maskp)
+	char *line;
+	addrfamily_t *addrp;
+	addrfamily_t *maskp;
+{
+	struct in_addr a1, a2;
+	char *src = line;
+	char *s = NULL;
+
+	if (line == NULL)
+		return -1;
+
+	while (*src != '\0') {
+		s = strchr(src, '(');
+		if (s == NULL)
+			break;
+
+		if (strncmp(s, "(NET", 4)) {
+			src = s + 1;
+		}
+		break;
+	}
+
+	if (s == NULL)
+		return -1;
+
+	memset(addrp, 0x00, sizeof(*maskp));
+	memset(maskp, 0x00, sizeof(*maskp));
+
+	if (*(s + 4) == '6') {
+#ifdef USE_INET6
+		i6addr_t a61, a62;
+
+		s = strchr(s, ')');
+		if (s == NULL || *++s != ' ')
+			return -1;
+		/*
+		 * Parse the IPv6
+		 */
+		if (inet_pton(AF_INET6, s, &a61.in6) != 1)
+			return -1;
+
+		s = strchr(s, ' ');
+		if (s == NULL || strncmp(s, " - ", 3))
+			return -1;
+
+		s += 3;
+		if (inet_pton(AF_INET6, s, &a62) != 1)
+			return -1;
+
+		addrp->adf_addr = a61;
+		addrp->adf_family = AF_INET6;
+		addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
+				 sizeof(struct in6_addr);
+
+		maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]);
+		maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]);
+		maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]);
+		maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]);
+
+		/*
+		 * If the mask that's been generated isn't a consecutive mask
+		 * then we can't add it into a pool.
+		 */
+		if (count6bits(maskp->adf_addr.i6) == -1)
+			return -1;
+
+		maskp->adf_family = AF_INET6;
+		maskp->adf_len = addrp->adf_len;
+
+		if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6,
+				&addrp->adf_addr.in6)) {
+			return -1;
+		}
+		return 0;
+#else
+		return -1;
+#endif
+	}
+
+	s = strchr(s, ')');
+	if (s == NULL || *++s != ' ')
+		return -1;
+
+	s++;
+
+	if (inet_aton(s, &a1) != 1)
+		return -1;
+
+	s = strchr(s, ' ');
+	if (s == NULL || strncmp(s, " - ", 3))
+		return -1;
+
+	s += 3;
+	if (inet_aton(s, &a2) != 1)
+		return -1;
+
+	addrp->adf_addr.in4 = a1;
+	addrp->adf_family = AF_INET;
+	addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
+			 sizeof(struct in_addr);
+	maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr);
+
+	/*
+	 * If the mask that's been generated isn't a consecutive mask then
+	 * we can't add it into a pool.
+	 */
+	if (count4bits(maskp->adf_addr.in4.s_addr) == -1)
+		return -1;
+
+	maskp->adf_family = AF_INET;
+	maskp->adf_len = addrp->adf_len;
+	bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len);
+	if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) !=
+	    addrp->adf_addr.in4.s_addr)
+		return -1;
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/parsewhoisline.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/poolio.c
===================================================================
--- trunk/contrib/ipfilter/lib/poolio.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/poolio.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: poolio.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "ipf.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_pool.h"
+
+static int poolfd = -1;
+
+
+int
+pool_open()
+{
+
+	if ((opts & OPT_DONTOPEN) != 0)
+		return 0;
+
+	if (poolfd == -1)
+		poolfd = open(IPLOOKUP_NAME, O_RDWR);
+	return poolfd;
+}
+
+int
+pool_ioctl(iocfunc, cmd, ptr)
+	ioctlfunc_t iocfunc;
+	ioctlcmd_t cmd;
+	void *ptr;
+{
+	return (*iocfunc)(poolfd, cmd, ptr);
+}
+
+
+void
+pool_close()
+{
+	if (poolfd != -1) {
+		close(poolfd);
+		poolfd = -1;
+	}
+}
+
+int
+pool_fd()
+{
+	return poolfd;
+}


Property changes on: trunk/contrib/ipfilter/lib/poolio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/prependmbt.c
===================================================================
--- trunk/contrib/ipfilter/lib/prependmbt.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/prependmbt.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: prependmbt.c,v 1.3.2.3 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+int prependmbt(fin, m)
+	fr_info_t *fin;
+	mb_t *m;
+{
+	m->mb_next = *fin->fin_mp;
+	*fin->fin_mp = m;
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/prependmbt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printactiveaddr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printactiveaddr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printactiveaddr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * Added redirect stuff and a variety of bug fixes. (mcn at EnGarde.com)
+ */
+
+#include "ipf.h"
+
+
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: printactiveaddr.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $";
+#endif
+
+
+void
+printactiveaddress(v, fmt, addr, ifname)
+	int v;
+	char *fmt, *ifname;
+	i6addr_t *addr;
+{
+	switch (v)
+	{
+	case 4 :
+		PRINTF(fmt, inet_ntoa(addr->in4));
+		break;
+#ifdef USE_INET6
+	case 6 :
+		printaddr(AF_INET6, FRI_NORMAL, ifname, 0,
+			  (u_32_t *)&addr->in6, NULL);
+		break;
+#endif
+	default :
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printactiveaddr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printaddr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printaddr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printaddr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+
+#include "ipf.h"
+
+void
+printaddr(family, type, base, ifidx, addr, mask)
+	int family, type, ifidx;
+	char *base;
+	u_32_t *addr, *mask;
+{
+	char *suffix;
+
+	switch (type)
+	{
+	case FRI_BROADCAST :
+		suffix = "bcast";
+		break;
+
+	case FRI_DYNAMIC :
+		PRINTF("%s", base + ifidx);
+		printmask(family, mask);
+		suffix = NULL;
+		break;
+
+	case FRI_NETWORK :
+		suffix = "net";
+		break;
+
+	case FRI_NETMASKED :
+		suffix = "netmasked";
+		break;
+
+	case FRI_PEERADDR :
+		suffix = "peer";
+		break;
+
+	case FRI_LOOKUP :
+		suffix = NULL;
+		printlookup(base, (i6addr_t *)addr, (i6addr_t *)mask);
+		break;
+
+	case FRI_NONE :
+	case FRI_NORMAL :
+		printhostmask(family, addr, mask);
+		suffix = NULL;
+		break;
+	case FRI_RANGE :
+		printhost(family, addr);
+		putchar('-');
+		printhost(family, mask);
+		suffix = NULL;
+		break;
+	case FRI_SPLIT :
+		printhost(family, addr);
+		putchar(',');
+		printhost(family, mask);
+		suffix = NULL;
+		break;
+	default :
+		PRINTF("<%d>", type);
+		printmask(family, mask);
+		suffix = NULL;
+		break;
+	}
+
+	if (suffix != NULL) {
+		PRINTF("%s/%s", base + ifidx, suffix);
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printaddr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printdstl_live.c
===================================================================
--- trunk/contrib/ipfilter/lib/printdstl_live.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printdstl_live.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include <sys/ioctl.h>
+#include "ipf.h"
+#include "netinet/ipl.h"
+
+
+/*
+ * Because the ipf_dstnode_t can vary in size because of the interface name,
+ * the size may be larger than just sizeof().
+ */
+ippool_dst_t *
+printdstl_live(d, fd, name, opts, fields)
+	ippool_dst_t *d;
+	int fd;
+	char *name;
+	int opts;
+	wordtab_t *fields;
+{
+	ipf_dstnode_t *entry, *zero;
+	ipflookupiter_t iter;
+	int printed, last;
+	ipfobj_t obj;
+
+	if ((name != NULL) && strncmp(name, d->ipld_name, FR_GROUPLEN))
+		return d->ipld_next;
+
+	entry = calloc(1, sizeof(*entry) + 64);
+	if (entry == NULL)
+		return d->ipld_next;
+	zero = calloc(1, sizeof(*zero) + 64);
+	if (zero == NULL) {
+		free(entry);
+		return d->ipld_next;
+	}
+
+	if (fields == NULL)
+		printdstlistdata(d, opts);
+
+	if ((d->ipld_flags & IPHASH_DELETE) != 0)
+		PRINTF("# ");
+
+	if ((opts & OPT_DEBUG) == 0)
+		PRINTF("\t{");
+
+	obj.ipfo_rev = IPFILTER_VERSION;
+	obj.ipfo_type = IPFOBJ_LOOKUPITER;
+	obj.ipfo_ptr = &iter;
+	obj.ipfo_size = sizeof(iter);
+
+	iter.ili_data = entry;
+	iter.ili_type = IPLT_DSTLIST;
+	iter.ili_otype = IPFLOOKUPITER_NODE;
+	iter.ili_ival = IPFGENITER_LOOKUP;
+	iter.ili_unit = d->ipld_unit;
+	strncpy(iter.ili_name, d->ipld_name, FR_GROUPLEN);
+
+	last = 0;
+	printed = 0;
+
+	while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) {
+		if (entry->ipfd_next == NULL)
+			last = 1;
+		if (bcmp((char *)zero, (char *)entry, sizeof(*zero)) == 0)
+			break;
+		(void) printdstlistnode(entry, bcopywrap, opts, fields);
+		printed++;
+	}
+
+	(void) ioctl(fd, SIOCIPFDELTOK, &iter.ili_key);
+	free(entry);
+	free(zero);
+
+	if (printed == 0)
+		putchar(';');
+
+	if ((opts & OPT_DEBUG) == 0)
+		PRINTF(" };\n");
+	return d->ipld_next;
+}


Property changes on: trunk/contrib/ipfilter/lib/printdstl_live.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printdstlist.c
===================================================================
--- trunk/contrib/ipfilter/lib/printdstlist.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printdstlist.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+
+ippool_dst_t *
+printdstlist(pp, copyfunc, name, opts, nodes, fields)
+	ippool_dst_t *pp;
+	copyfunc_t copyfunc;
+	char *name;
+	int opts;
+	ipf_dstnode_t *nodes;
+	wordtab_t *fields;
+{
+	ipf_dstnode_t *node;
+	ippool_dst_t dst;
+
+	if ((*copyfunc)(pp, &dst, sizeof(dst)))
+		return NULL;
+
+	if ((name != NULL) && strncmp(name, dst.ipld_name, FR_GROUPLEN))
+		return dst.ipld_next;
+
+	if (fields == NULL)
+		printdstlistdata(&dst, opts);
+
+	if ((dst.ipld_flags & IPDST_DELETE) != 0)
+		PRINTF("# ");
+	if ((opts & OPT_DEBUG) == 0)
+		PRINTF("\t{");
+
+	if (nodes == NULL) {
+		putchar(';');
+	} else {
+		for (node = nodes; node != NULL; ) {
+			ipf_dstnode_t *n;
+
+			n = calloc(1, node->ipfd_size);
+			if (n == NULL)
+				break;
+			if ((*copyfunc)(node, n, node->ipfd_size)) {
+				free(n);
+				return NULL;
+			}
+
+			node = printdstlistnode(n, bcopywrap, opts, fields);
+
+			free(n);
+		}
+	}
+
+	if ((opts & OPT_DEBUG) == 0)
+		PRINTF(" };\n");
+
+	return dst.ipld_next;
+}


Property changes on: trunk/contrib/ipfilter/lib/printdstlist.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printdstlistdata.c
===================================================================
--- trunk/contrib/ipfilter/lib/printdstlistdata.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printdstlistdata.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+#include <ctype.h>
+
+
+void
+printdstlistdata(pool, opts)
+	ippool_dst_t *pool;
+	int opts;
+{
+
+	if ((opts & OPT_DEBUG) == 0) {
+		if ((pool->ipld_flags & IPDST_DELETE) != 0)
+			PRINTF("# ");
+		PRINTF("pool ");
+	} else {
+		if ((pool->ipld_flags & IPDST_DELETE) != 0)
+			PRINTF("# ");
+		PRINTF("Name: %s\tRole: ", pool->ipld_name);
+	}
+
+	printunit(pool->ipld_unit);
+
+	if ((opts & OPT_DEBUG) == 0) {
+		PRINTF("/dstlist (name %s;", pool->ipld_name);
+		if (pool->ipld_policy != IPLDP_NONE) {
+			PRINTF(" policy ");
+			printdstlistpolicy(pool->ipld_policy);
+			putchar(';');
+		}
+		PRINTF(")\n");
+	} else {
+		putchar(' ');
+
+		PRINTF("\tReferences: %d\n", pool->ipld_ref);
+		if ((pool->ipld_flags & IPDST_DELETE) != 0)
+			PRINTF("# ");
+		PRINTF("Policy: \n");
+		printdstlistpolicy(pool->ipld_policy);
+		PRINTF("\n\tNodes Starting at %p\n", pool->ipld_dests);
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printdstlistdata.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printdstlistnode.c
===================================================================
--- trunk/contrib/ipfilter/lib/printdstlistnode.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printdstlistnode.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+
+ipf_dstnode_t *
+printdstlistnode(inp, copyfunc, opts, fields)
+	ipf_dstnode_t *inp;
+	copyfunc_t copyfunc;
+	int opts;
+	wordtab_t *fields;
+{
+	ipf_dstnode_t node, *np;
+	int i;
+#ifdef USE_INET6
+	char buf[INET6_ADDRSTRLEN+1];
+	const char *str;
+#endif
+
+	if ((*copyfunc)(inp, &node, sizeof(node)))
+		return NULL;
+
+	np = calloc(1, node.ipfd_size);
+	if (np == NULL)
+		return node.ipfd_next;
+	if ((*copyfunc)(inp, np, node.ipfd_size))
+		return NULL;
+
+	if (fields != NULL) {
+		for (i = 0; fields[i].w_value != 0; i++) {
+			printpoolfield(np, IPLT_DSTLIST, i);
+			if (fields[i + 1].w_value != 0)
+				printf("\t");
+		}
+		printf("\n");
+	} else if ((opts & OPT_DEBUG) == 0) {
+		putchar(' ');
+		if (np->ipfd_dest.fd_name >= 0)
+			PRINTF("%s:", np->ipfd_names);
+		if (np->ipfd_dest.fd_addr.adf_family == AF_INET) {
+			printip(AF_INET, (u_32_t *)&np->ipfd_dest.fd_ip);
+		} else {
+#ifdef USE_INET6
+			str = inet_ntop(AF_INET6, &np->ipfd_dest.fd_ip6,
+					buf, sizeof(buf) - 1);
+			if (str != NULL)
+				PRINTF("%s", str);
+#endif
+		}
+		putchar(';');
+	} else {
+		PRINTF("Interface: [%s]/%d\n", np->ipfd_names,
+		       np->ipfd_dest.fd_name);
+#ifdef USE_INET6
+		str = inet_ntop(np->ipfd_dest.fd_addr.adf_family,
+				&np->ipfd_dest.fd_ip6, buf, sizeof(buf) - 1);
+		if (str != NULL) {
+			PRINTF("\tAddress: %s\n", str);
+		}
+#else
+		PRINTF("\tAddress: %s\n", inet_ntoa(np->ipfd_dest.fd_ip));
+#endif
+		PRINTF(
+#ifdef USE_QUAD_T
+		       "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n",
+#else
+		       "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n",
+#endif
+		       np->ipfd_states, np->ipfd_ref,
+		       np->ipfd_names, np->ipfd_uid);
+	}
+	free(np);
+	return node.ipfd_next;
+}


Property changes on: trunk/contrib/ipfilter/lib/printdstlistnode.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printdstlistpolicy.c
===================================================================
--- trunk/contrib/ipfilter/lib/printdstlistpolicy.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printdstlistpolicy.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+
+void
+printdstlistpolicy(policy)
+	ippool_policy_t policy;
+{
+	switch (policy)
+	{
+	case IPLDP_NONE :
+		PRINTF("none");
+		break;
+	case IPLDP_ROUNDROBIN :
+		PRINTF("round-robin");
+		break;
+	case IPLDP_CONNECTION :
+		PRINTF("weighting connection");
+		break;
+	case IPLDP_RANDOM :
+		PRINTF("random");
+		break;
+	default :
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printdstlistpolicy.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printfieldhdr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printfieldhdr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printfieldhdr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printfieldhdr.c,v 1.5.2.3 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+#include <ctype.h>
+
+
+void
+printfieldhdr(words, field)
+	wordtab_t *words, *field;
+{
+	wordtab_t *w;
+	char *s, *t;
+	int i;
+
+	if (field->w_value == -2) {
+		for (i = 0, w = words; w->w_word != NULL; ) {
+			if (w->w_value > 0) {
+				printfieldhdr(words, w);
+				w++;
+				if (w->w_value > 0)
+					putchar('\t');
+			} else {
+				w++;
+			}
+		}
+		return;
+	}
+
+	for (w = words; w->w_word != NULL; w++) {
+		if (w->w_value == field->w_value) {
+			if (w->w_word == field->w_word) {
+				s = strdup(w->w_word);
+			} else {
+				s = NULL;
+			}
+
+			if ((w->w_word != field->w_word) || (s == NULL)) {
+				PRINTF("%s", field->w_word);
+			} else {
+				for (t = s; *t != '\0'; t++) {
+					if (ISALPHA(*t) && ISLOWER(*t))
+						*t = TOUPPER(*t);
+				}
+				PRINTF("%s", s);
+				free(s);
+			}
+		}
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printfieldhdr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printhost.c
===================================================================
--- trunk/contrib/ipfilter/lib/printhost.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printhost.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printhost.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+
+void
+printhost(family, addr)
+	int	family;
+	u_32_t	*addr;
+{
+#ifdef  USE_INET6
+	char ipbuf[64];
+#else
+	struct in_addr ipa;
+#endif
+
+	if ((family == -1) || !*addr)
+		PRINTF("any");
+	else {
+#ifdef  USE_INET6
+		void *ptr = addr;
+
+		PRINTF("%s", inet_ntop(family, ptr, ipbuf, sizeof(ipbuf)));
+#else
+		ipa.s_addr = *addr;
+		PRINTF("%s", inet_ntoa(ipa));
+#endif
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printhost.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printipfexpr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printipfexpr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printipfexpr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,199 @@
+#include "ipf.h"
+
+static void printport __P((int *));
+static void printhosts __P((int *));
+static void printsingle __P((int *));
+#ifdef USE_INET6
+static void printhostsv6 __P((int *));
+#endif
+
+void
+printipfexpr(array)
+	int *array;
+{
+	int i, nelems, j, not;
+	ipfexp_t *ipfe;
+
+	nelems = array[0];
+
+	for (i = 1; i < nelems; ) {
+		ipfe = (ipfexp_t *)(array + i);
+		if (ipfe->ipfe_cmd == IPF_EXP_END)
+			break;
+
+		not = ipfe->ipfe_not;
+
+		switch (ipfe->ipfe_cmd)
+		{
+		case IPF_EXP_IP_ADDR :
+			PRINTF("ip.addr %s= ", not ? "!" : "");
+			printhosts(array + i);
+			break;
+
+		case IPF_EXP_IP_PR :
+			PRINTF("ip.p %s= ", not ? "!" : "");
+			printsingle(array + i);
+			break;
+
+		case IPF_EXP_IP_SRCADDR :
+			PRINTF("ip.src %s= ", not ? "!" : "");
+			printhosts(array + i);
+			break;
+
+		case IPF_EXP_IP_DSTADDR :
+			PRINTF("ip.dst %s= ", not ? "!" : "");
+			printhosts(array + i);
+			break;
+
+		case IPF_EXP_TCP_PORT :
+			PRINTF("tcp.port %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_TCP_DPORT :
+			PRINTF("tcp.dport %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_TCP_SPORT :
+			PRINTF("tcp.sport %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_TCP_FLAGS :
+			PRINTF("tcp.flags %s= ", not ? "!" : "");
+
+			for (j = 0; j < ipfe->ipfe_narg; ) {
+				printtcpflags(array[i + 4], array[i + 5]);
+				j += 2;
+				if (j < array[4])
+					putchar(',');
+			}
+			break;
+
+		case IPF_EXP_UDP_PORT :
+			PRINTF("udp.port %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_UDP_DPORT :
+			PRINTF("udp.dport %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_UDP_SPORT :
+			PRINTF("udp.sport %s= ", not ? "!" : "");
+			printport(array + i);
+			break;
+
+		case IPF_EXP_IDLE_GT :
+			PRINTF("idle-gt %s= ", not ? "!" : "");
+			printsingle(array + i);
+			break;
+
+		case IPF_EXP_TCP_STATE :
+			PRINTF("tcp-state %s= ", not ? "!" : "");
+			printsingle(array + i);
+			break;
+
+#ifdef USE_INET6
+		case IPF_EXP_IP6_ADDR :
+			PRINTF("ip6.addr %s= ", not ? "!" : "");
+			printhostsv6(array + i);
+			break;
+
+		case IPF_EXP_IP6_SRCADDR :
+			PRINTF("ip6.src %s= ", not ? "!" : "");
+			printhostsv6(array + i);
+			break;
+
+		case IPF_EXP_IP6_DSTADDR :
+			PRINTF("ip6.dst %s= ", not ? "!" : "");
+			printhostsv6(array + i);
+			break;
+#endif
+
+		case IPF_EXP_END :
+			break;
+
+		default :
+			PRINTF("#%#x,len=%d;",
+			       ipfe->ipfe_cmd, ipfe->ipfe_narg);
+		}
+
+		if (array[i] != IPF_EXP_END)
+			putchar(';');
+
+		i += ipfe->ipfe_size;
+		if (array[i] != IPF_EXP_END)
+			putchar(' ');
+	}
+}
+
+
+static void
+printsingle(array)
+	int *array;
+{
+	ipfexp_t *ipfe = (ipfexp_t *)array;
+	int i;
+
+	for (i = 0; i < ipfe->ipfe_narg; ) {
+		PRINTF("%d", array[i + 4]);
+		i++;
+		if (i < ipfe->ipfe_narg)
+			putchar(',');
+	}
+}
+
+
+static void
+printport(array)
+	int *array;
+{
+	ipfexp_t *ipfe = (ipfexp_t *)array;
+	int i;
+
+	for (i = 0; i < ipfe->ipfe_narg; ) {
+		PRINTF("%d", ntohs(array[i + 4]));
+		i++;
+		if (i < ipfe->ipfe_narg)
+			putchar(',');
+	}
+}
+
+
+static void
+printhosts(array)
+	int *array;
+{
+	ipfexp_t *ipfe = (ipfexp_t *)array;
+	int i, j;
+
+	for (i = 0, j = 0; i < ipfe->ipfe_narg; j++) {
+		printhostmask(AF_INET, (u_32_t *)ipfe->ipfe_arg0 + j * 2,
+			      (u_32_t *)ipfe->ipfe_arg0 + j * 2 + 1);
+		i += 2;
+		if (i < ipfe->ipfe_narg)
+			putchar(',');
+	}
+}
+
+
+#ifdef USE_INET6
+static void
+printhostsv6(array)
+	int *array;
+{
+	ipfexp_t *ipfe = (ipfexp_t *)array;
+	int i, j;
+
+	for (i = 4, j= 0; i < ipfe->ipfe_size; j++) {
+		printhostmask(AF_INET6, (u_32_t *)ipfe->ipfe_arg0 + j * 8,
+			      (u_32_t *)ipfe->ipfe_arg0 + j * 8 + 4);
+		i += 8;
+		if (i < ipfe->ipfe_size)
+			putchar(',');
+	}
+}
+#endif


Property changes on: trunk/contrib/ipfilter/lib/printipfexpr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printiphdr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printiphdr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printiphdr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C)  by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printiphdr.c,v 1.1 2009/03/01 12:48:32 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+
+void
+printiphdr(ip)
+	ip_t *ip;
+{
+	PRINTF("ip(v=%d,hl=%d,len=%d,tos=%#x,off=%#x,sum=%#x,src=%#x,dst=%#x",
+	       ip->ip_v, ip->ip_hl, ntohs(ip->ip_len), ip->ip_tos,
+	       ntohs(ip->ip_off), ntohs(ip->ip_sum), ntohl(ip->ip_src.s_addr),
+	       ntohl(ip->ip_dst.s_addr));
+}


Property changes on: trunk/contrib/ipfilter/lib/printiphdr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printlookup.c
===================================================================
--- trunk/contrib/ipfilter/lib/printlookup.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printlookup.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id$
+ */
+
+#include "ipf.h"
+
+
+void
+printlookup(base, addr, mask)
+	char *base;
+	i6addr_t *addr, *mask;
+{
+	char name[32];
+
+	switch (addr->iplookuptype)
+	{
+	case IPLT_POOL :
+		PRINTF("pool/");
+		break;
+	case IPLT_HASH :
+		PRINTF("hash/");
+		break;
+	case IPLT_DSTLIST :
+		PRINTF("dstlist/");
+		break;
+	default :
+		PRINTF("lookup(%x)=", addr->iplookuptype);
+		break;
+	}
+
+	if (addr->iplookupsubtype == 0)
+		PRINTF("%u", addr->iplookupnum);
+	else if (addr->iplookupsubtype == 1) {
+		strncpy(name, base + addr->iplookupname, sizeof(name));
+		name[sizeof(name) - 1] = '\0';
+		PRINTF("%s", name);
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printlookup.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printnataddr.c
===================================================================
--- trunk/contrib/ipfilter/lib/printnataddr.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printnataddr.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * Added redirect stuff and a variety of bug fixes. (mcn at EnGarde.com)
+ */
+
+#include "ipf.h"
+#include "kmem.h"
+
+
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: printnataddr.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $";
+#endif
+
+
+void
+printnataddr(v, base, addr, ifidx)
+	int v;
+	char *base;
+	nat_addr_t *addr;
+	int ifidx;
+{
+	switch (v)
+	{
+	case 4 :
+		if (addr->na_atype == FRI_NORMAL &&
+		    addr->na_addr[0].in4.s_addr == 0) {
+			PRINTF("0/%d", count4bits(addr->na_addr[1].in4.s_addr));
+		} else {
+			printaddr(AF_INET, addr->na_atype, base, ifidx,
+				  (u_32_t *)&addr->na_addr[0].in4.s_addr,
+				  (u_32_t *)&addr->na_addr[1].in4.s_addr);
+		}
+		break;
+#ifdef USE_INET6
+	case 6 :
+		printaddr(AF_INET6, addr->na_atype, base, ifidx,
+			  (u_32_t *)&addr->na_addr[0].in6,
+			  (u_32_t *)&addr->na_addr[1].in6);
+		break;
+#endif
+	default :
+		printf("{v=%d}", v);
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printnataddr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printnatfield.c
===================================================================
--- trunk/contrib/ipfilter/lib/printnatfield.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printnatfield.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printnatfield.c,v 1.6.2.2 2012/01/26 05:44:26 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+wordtab_t natfields[] = {
+	{ "all",	-2 },
+	{ "ifp0",	1 },
+	{ "ifp1",	2 },
+	{ "mtu0",	3 },
+	{ "mtu1",	4 },
+	{ "ifname0",	5 },
+	{ "ifname1",	6 },
+	{ "sumd0",	7 },
+	{ "sumd1",	8 },
+	{ "pkts0",	9 },
+	{ "pkts1",	10 },
+	{ "bytes0",	11 },
+	{ "bytes1",	12 },
+	{ "proto0",	13 },
+	{ "proto1",	14 },
+	{ "hash0",	15 },
+	{ "hash1",	16 },
+	{ "ref",	17 },
+	{ "rev",	18 },
+	{ "v0",		19 },
+	{ "redir",	20 },
+	{ "use",	21 },
+	{ "ipsumd",	22 },
+	{ "dir",	23 },
+	{ "olddstip",	24 },
+	{ "oldsrcip",	25 },
+	{ "newdstip",	26 },
+	{ "newsrcip",	27 },
+	{ "olddport",	28 },
+	{ "oldsport",	29 },
+	{ "newdport",	30 },
+	{ "newsport",	31 },
+	{ "age",	32 },
+	{ "v1",		33 },
+	{ NULL, 0 }
+};
+
+
+void
+printnatfield(n, fieldnum)
+	nat_t *n;
+	int fieldnum;
+{
+	int i;
+
+	switch (fieldnum)
+	{
+	case -2 :
+		for (i = 1; natfields[i].w_word != NULL; i++) {
+			if (natfields[i].w_value > 0) {
+				printnatfield(n, i);
+				if (natfields[i + 1].w_value > 0)
+					putchar('\t');
+			}
+		}
+		break;
+
+	case 1:
+		PRINTF("%#lx", (u_long)n->nat_ifps[0]);
+		break;
+
+	case 2:
+		PRINTF("%#lx", (u_long)n->nat_ifps[1]);
+		break;
+
+	case 3:
+		PRINTF("%d", n->nat_mtu[0]);
+		break;
+
+	case 4:
+		PRINTF("%d", n->nat_mtu[1]);
+		break;
+
+	case 5:
+		PRINTF("%s", n->nat_ifnames[0]);
+		break;
+
+	case 6:
+		PRINTF("%s", n->nat_ifnames[1]);
+		break;
+
+	case 7:
+		PRINTF("%d", n->nat_sumd[0]);
+		break;
+
+	case 8:
+		PRINTF("%d", n->nat_sumd[1]);
+		break;
+
+	case 9:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", n->nat_pkts[0]);
+#else
+		PRINTF("%lu", n->nat_pkts[0]);
+#endif
+		break;
+
+	case 10:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", n->nat_pkts[1]);
+#else
+		PRINTF("%lu", n->nat_pkts[1]);
+#endif
+		break;
+
+	case 11:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", n->nat_bytes[0]);
+#else
+		PRINTF("%lu", n->nat_bytes[0]);
+#endif
+		break;
+
+	case 12:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", n->nat_bytes[1]);
+#else
+		PRINTF("%lu", n->nat_bytes[1]);
+#endif
+		break;
+
+	case 13:
+		PRINTF("%d", n->nat_pr[0]);
+		break;
+
+	case 14:
+		PRINTF("%d", n->nat_pr[1]);
+		break;
+
+	case 15:
+		PRINTF("%u", n->nat_hv[0]);
+		break;
+
+	case 16:
+		PRINTF("%u", n->nat_hv[1]);
+		break;
+
+	case 17:
+		PRINTF("%d", n->nat_ref);
+		break;
+
+	case 18:
+		PRINTF("%d", n->nat_rev);
+		break;
+
+	case 19:
+		PRINTF("%d", n->nat_v[0]);
+		break;
+
+	case 33:
+		PRINTF("%d", n->nat_v[0]);
+		break;
+
+	case 20:
+		PRINTF("%d", n->nat_redir);
+		break;
+
+	case 21:
+		PRINTF("%d", n->nat_use);
+		break;
+
+	case 22:
+		PRINTF("%u", n->nat_ipsumd);
+		break;
+
+	case 23:
+		PRINTF("%d", n->nat_dir);
+		break;
+
+	case 24:
+		PRINTF("%s", hostname(n->nat_v[0], &n->nat_odstip));
+		break;
+
+	case 25:
+		PRINTF("%s", hostname(n->nat_v[0], &n->nat_osrcip));
+		break;
+
+	case 26:
+		PRINTF("%s", hostname(n->nat_v[1], &n->nat_ndstip));
+		break;
+
+	case 27:
+		PRINTF("%s", hostname(n->nat_v[1], &n->nat_nsrcip));
+		break;
+
+	case 28:
+		PRINTF("%hu", ntohs(n->nat_odport));
+		break;
+
+	case 29:
+		PRINTF("%hu", ntohs(n->nat_osport));
+		break;
+
+	case 30:
+		PRINTF("%hu", ntohs(n->nat_ndport));
+		break;
+
+	case 31:
+		PRINTF("%hu", ntohs(n->nat_nsport));
+		break;
+
+	case 32:
+		PRINTF("%u", n->nat_age);
+		break;
+
+	default:
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printnatfield.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printnatside.c
===================================================================
--- trunk/contrib/ipfilter/lib/printnatside.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printnatside.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printnatside.c,v 1.2.2.6 2012/07/22 08:04:24 darren_r Exp $
+ */
+#include "ipf.h"
+
+void
+printnatside(side, ns)
+	char *side;
+	nat_stat_side_t *ns;
+{
+	PRINTF("%lu\tproxy create fail %s\n", ns->ns_appr_fail, side);
+	PRINTF("%lu\tproxy fail %s\n", ns->ns_ipf_proxy_fail, side);
+	PRINTF("%lu\tbad nat %s\n", ns->ns_badnat, side);
+	PRINTF("%lu\tbad nat new %s\n", ns->ns_badnatnew, side);
+	PRINTF("%lu\tbad next addr %s\n", ns->ns_badnextaddr, side);
+	PRINTF("%lu\tbucket max %s\n", ns->ns_bucket_max, side);
+	PRINTF("%lu\tclone nomem %s\n", ns->ns_clone_nomem, side);
+	PRINTF("%lu\tdecap bad %s\n", ns->ns_decap_bad, side);
+	PRINTF("%lu\tdecap fail %s\n", ns->ns_decap_fail, side);
+	PRINTF("%lu\tdecap pullup %s\n", ns->ns_decap_pullup, side);
+	PRINTF("%lu\tdivert dup %s\n", ns->ns_divert_dup, side);
+	PRINTF("%lu\tdivert exist %s\n", ns->ns_divert_exist, side);
+	PRINTF("%lu\tdrop %s\n", ns->ns_drop, side);
+	PRINTF("%lu\texhausted %s\n", ns->ns_exhausted, side);
+	PRINTF("%lu\ticmp address %s\n", ns->ns_icmp_address, side);
+	PRINTF("%lu\ticmp basic %s\n", ns->ns_icmp_basic, side);
+	PRINTF("%lu\tinuse %s\n", ns->ns_inuse, side);
+	PRINTF("%lu\ticmp mbuf wrong size %s\n", ns->ns_icmp_mbuf, side);
+	PRINTF("%lu\ticmp header unmatched %s\n", ns->ns_icmp_notfound, side);
+	PRINTF("%lu\ticmp rebuild failures %s\n", ns->ns_icmp_rebuild, side);
+	PRINTF("%lu\ticmp short %s\n", ns->ns_icmp_short, side);
+	PRINTF("%lu\ticmp packet size wrong %s\n", ns->ns_icmp_size, side);
+	PRINTF("%lu\tIFP address fetch failures %s\n",
+		ns->ns_ifpaddrfail, side);
+	PRINTF("%lu\tpackets untranslated %s\n", ns->ns_ignored, side);
+	PRINTF("%lu\tNAT insert failures %s\n", ns->ns_insert_fail, side);
+	PRINTF("%lu\tNAT lookup misses %s\n", ns->ns_lookup_miss, side);
+	PRINTF("%lu\tNAT lookup nowild %s\n", ns->ns_lookup_nowild, side);
+	PRINTF("%lu\tnew ifpaddr failed %s\n", ns->ns_new_ifpaddr, side);
+	PRINTF("%lu\tmemory requests failed %s\n", ns->ns_memfail, side);
+	PRINTF("%lu\ttable max reached %s\n", ns->ns_table_max, side);
+	PRINTF("%lu\tpackets translated %s\n", ns->ns_translated, side);
+	PRINTF("%lu\tfinalised failed %s\n", ns->ns_unfinalised, side);
+	PRINTF("%lu\tsearch wraps %s\n", ns->ns_wrap, side);
+	PRINTF("%lu\tnull translations %s\n", ns->ns_xlate_null, side);
+	PRINTF("%lu\ttranslation exists %s\n", ns->ns_xlate_exists, side);
+	PRINTF("%lu\tno memory %s\n", ns->ns_memfail, side);
+
+	if (opts & OPT_VERBOSE)
+		PRINTF("%p table %s\n", ns->ns_table, side);
+}


Property changes on: trunk/contrib/ipfilter/lib/printnatside.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printpoolfield.c
===================================================================
--- trunk/contrib/ipfilter/lib/printpoolfield.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printpoolfield.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printpoolfield.c,v 1.1.2.4 2012/01/26 05:44:26 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+wordtab_t poolfields[] = {
+	{ "all",	-2 },
+	{ "address",	1 },
+	{ "mask",	2 },
+	{ "ifname",	3 },
+	{ "pkts",	4 },
+	{ "bytes",	5 },
+	{ "family",	6 },
+	{ NULL, 0 }
+};
+
+
+void
+printpoolfield(p, ptype, fieldnum)
+	void *p;
+	int ptype;
+	int fieldnum;
+{
+	addrfamily_t *a;
+	char abuf[80];
+	int i;
+
+	switch (fieldnum)
+	{
+	case -2 :
+		for (i = 1; poolfields[i].w_word != NULL; i++) {
+			if (poolfields[i].w_value > 0) {
+				printpoolfield(p, ptype, i);
+				if (poolfields[i + 1].w_value > 0)
+					putchar('\t');
+			}
+		}
+		break;
+
+	case 1:
+		if (ptype == IPLT_POOL) {
+			ip_pool_node_t *node = (ip_pool_node_t *)p;
+
+			if (node->ipn_info)
+				PRINTF("!");
+			a = &node->ipn_addr;
+			PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr,
+					       abuf, sizeof(abuf)));
+		} else if (ptype == IPLT_HASH) {
+			iphtent_t *node = (iphtent_t *)p;
+
+			PRINTF("%s", inet_ntop(node->ipe_family,
+					       &node->ipe_addr,
+					       abuf, sizeof(abuf)));
+		} else if (ptype == IPLT_DSTLIST) {
+			ipf_dstnode_t *node = (ipf_dstnode_t *)p;
+
+			a = &node->ipfd_dest.fd_addr;
+			PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr,
+					       abuf, sizeof(abuf)));
+		}
+		break;
+
+	case 2:
+		if (ptype == IPLT_POOL) {
+			ip_pool_node_t *node = (ip_pool_node_t *)p;
+
+			a = &node->ipn_mask;
+			PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr,
+					       abuf, sizeof(abuf)));
+		} else if (ptype == IPLT_HASH) {
+			iphtent_t *node = (iphtent_t *)p;
+
+			PRINTF("%s", inet_ntop(node->ipe_family,
+					       &node->ipe_mask,
+					       abuf, sizeof(abuf)));
+		} else if (ptype == IPLT_DSTLIST) {
+			PRINTF("%s", "");
+		}
+		break;
+
+	case 3:
+		if (ptype == IPLT_POOL) {
+			PRINTF("%s", "");
+		} else if (ptype == IPLT_HASH) {
+			PRINTF("%s", "");
+		} else if (ptype == IPLT_DSTLIST) {
+			ipf_dstnode_t *node = (ipf_dstnode_t *)p;
+
+			if (node->ipfd_dest.fd_name == -1) {
+				PRINTF("%s", "");
+			} else {
+				PRINTF("%s", node->ipfd_names +
+				       node->ipfd_dest.fd_name);
+			}
+		}
+		break;
+
+	case 4:
+		if (ptype == IPLT_POOL) {
+			ip_pool_node_t *node = (ip_pool_node_t *)p;
+
+#ifdef USE_QUAD_T
+			PRINTF("%"PRIu64"", node->ipn_hits);
+#else
+			PRINTF("%lu", node->ipn_hits);
+#endif
+		} else if (ptype == IPLT_HASH) {
+			iphtent_t *node = (iphtent_t *)p;
+
+#ifdef USE_QUAD_T
+			PRINTF("%"PRIu64"", node->ipe_hits);
+#else
+			PRINTF("%lu", node->ipe_hits);
+#endif
+		} else if (ptype == IPLT_DSTLIST) {
+			printf("0");
+		}
+		break;
+
+	case 5:
+		if (ptype == IPLT_POOL) {
+			ip_pool_node_t *node = (ip_pool_node_t *)p;
+
+#ifdef USE_QUAD_T
+			PRINTF("%"PRIu64"", node->ipn_bytes);
+#else
+			PRINTF("%lu", node->ipn_bytes);
+#endif
+		} else if (ptype == IPLT_HASH) {
+			iphtent_t *node = (iphtent_t *)p;
+
+#ifdef USE_QUAD_T
+			PRINTF("%"PRIu64"", node->ipe_bytes);
+#else
+			PRINTF("%lu", node->ipe_bytes);
+#endif
+		} else if (ptype == IPLT_DSTLIST) {
+			printf("0");
+		}
+		break;
+
+	case 6:
+		if (ptype == IPLT_POOL) {
+			ip_pool_node_t *node = (ip_pool_node_t *)p;
+
+			PRINTF("%s", familyname(node->ipn_addr.adf_family));
+		} else if (ptype == IPLT_HASH) {
+			iphtent_t *node = (iphtent_t *)p;
+
+			PRINTF("%s", familyname(node->ipe_family));
+		} else if (ptype == IPLT_DSTLIST) {
+			ipf_dstnode_t *node = (ipf_dstnode_t *)p;
+
+			a = &node->ipfd_dest.fd_addr;
+			PRINTF("%s", familyname(a->adf_family));
+		}
+		break;
+
+	default :
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printpoolfield.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printstatefields.c
===================================================================
--- trunk/contrib/ipfilter/lib/printstatefields.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printstatefields.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printstatefields.c,v 1.4.2.2 2012/01/26 05:44:26 darren_r Exp $
+ */
+
+#include "ipf.h"
+
+wordtab_t statefields[] = {
+	{ "all",	-2 },
+	{ "ifp0",	1 },
+	{ "ifp1",	2 },
+	{ "ifp2",	3 },
+	{ "ifp3",	4 },
+	{ "ifname0",	5 },
+	{ "ifname1",	6 },
+	{ "ifname2",	7 },
+	{ "ifname3",	8 },
+	{ "pkts0",	9 },
+	{ "pkts1",	10 },
+	{ "pkts2",	11 },
+	{ "pkts3",	12 },
+	{ "bytes0",	13 },
+	{ "bytes1",	14 },
+	{ "bytes2",	15 },
+	{ "bytes3",	16 },
+	{ "state0",	17 },
+	{ "state1",	18 },
+	{ "age0",	19 },
+	{ "age1",	20 },
+	{ "ref",	21 },
+	{ "isn0",	22 },
+	{ "isn1",	23 },
+	{ "sumd0",	24 },
+	{ "sumd1",	25 },
+	{ "src",	26 },
+	{ "dst",	27 },
+	{ "sport",	28 },
+	{ "dport",	29 },
+	{ "icmptype",	30 },
+	{ "-",		31 },
+	{ "pass",	32 },
+	{ "proto",	33 },
+	{ "version",	34 },
+	{ "hash",	35 },
+	{ "tag",	36 },
+	{ "flags",	37 },
+	{ "rulen",	38 },
+	{ "group",	39 },
+	{ "flx0",	40 },
+	{ "flx1",	41 },
+	{ "flx2",	42 },
+	{ "flx3",	43 },
+	{ "opt0",	44 },
+	{ "opt1",	45 },
+	{ "optmsk0",	46 },
+	{ "optmsk1",	47 },
+	{ "sec",	48 },
+	{ "secmsk",	49 },
+	{ "auth",	50 },
+	{ "authmsk",	51 },
+	{ "icmppkts0",	52 },
+	{ "icmppkts1",	53 },
+	{ "icmppkts2",	54 },
+	{ "icmppkts3",	55 },
+	{ NULL, 0 }
+};
+
+
+void
+printstatefield(sp, fieldnum)
+	ipstate_t *sp;
+	int fieldnum;
+{
+	int i;
+
+	switch (fieldnum)
+	{
+	case -2 :
+		for (i = 1; statefields[i].w_word != NULL; i++) {
+			if (statefields[i].w_value > 0) {
+				printstatefield(sp, i);
+				if (statefields[i + 1].w_value > 0)
+					putchar('\t');
+			}
+		}
+		break;
+
+	case 1:
+		PRINTF("%#lx", (u_long)sp->is_ifp[0]);
+		break;
+
+	case 2:
+		PRINTF("%#lx", (u_long)sp->is_ifp[1]);
+		break;
+
+	case 3:
+		PRINTF("%#lx", (u_long)sp->is_ifp[2]);
+		break;
+
+	case 4:
+		PRINTF("%#lx", (u_long)sp->is_ifp[3]);
+		break;
+
+	case 5:
+		PRINTF("%s", sp->is_ifname[0]);
+		break;
+
+	case 6:
+		PRINTF("%s", sp->is_ifname[1]);
+		break;
+
+	case 7:
+		PRINTF("%s", sp->is_ifname[2]);
+		break;
+
+	case 8:
+		PRINTF("%s", sp->is_ifname[3]);
+		break;
+
+	case 9:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_pkts[0]);
+#else
+		PRINTF("%lu", sp->is_pkts[0]);
+#endif
+		break;
+
+	case 10:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_pkts[1]);
+#else
+		PRINTF("%lu", sp->is_pkts[1]);
+#endif
+		break;
+
+	case 11:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_pkts[2]);
+#else
+		PRINTF("%lu", sp->is_pkts[2]);
+#endif
+		break;
+
+	case 12:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_pkts[3]);
+#else
+		PRINTF("%lu", sp->is_pkts[3]);
+#endif
+		break;
+
+	case 13:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_bytes[0]);
+#else
+		PRINTF("%lu", sp->is_bytes[0]);
+#endif
+		break;
+
+	case 14:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_bytes[1]);
+#else
+		PRINTF("%lu", sp->is_bytes[1]);
+#endif
+		break;
+
+	case 15:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_bytes[2]);
+#else
+		PRINTF("%lu", sp->is_bytes[2]);
+#endif
+		break;
+
+	case 16:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_bytes[3]);
+#else
+		PRINTF("%lu", sp->is_bytes[3]);
+#endif
+		break;
+
+	case 17:
+		PRINTF("%d", sp->is_state[0]);
+		break;
+
+	case 18:
+		PRINTF("%d", sp->is_state[1]);
+		break;
+
+	case 19:
+		PRINTF("%d", sp->is_frage[0]);
+		break;
+
+	case 20:
+		PRINTF("%d", sp->is_frage[1]);
+		break;
+
+	case 21:
+		PRINTF("%d", sp->is_ref);
+		break;
+
+	case 22:
+		PRINTF("%d", sp->is_isninc[0]);
+		break;
+
+	case 23:
+		PRINTF("%d", sp->is_isninc[1]);
+		break;
+
+	case 24:
+		PRINTF("%hd", sp->is_sumd[0]);
+		break;
+
+	case 25:
+		PRINTF("%hd", sp->is_sumd[1]);
+		break;
+
+	case 26:
+		PRINTF("%s", hostname(sp->is_v, &sp->is_src.in4));
+		break;
+
+	case 27:
+		PRINTF("%s", hostname(sp->is_v, &sp->is_dst.in4));
+		break;
+
+	case 28:
+		PRINTF("%hu", ntohs(sp->is_sport));
+		break;
+
+	case 29:
+		PRINTF("%hu", ntohs(sp->is_dport));
+		break;
+
+	case 30:
+		PRINTF("%d", sp->is_type);
+		break;
+
+	case 32:
+		PRINTF("%#x", sp->is_pass);
+		break;
+
+	case 33:
+		PRINTF("%d", sp->is_p);
+		break;
+
+	case 34:
+		PRINTF("%d", sp->is_v);
+		break;
+
+	case 35:
+		PRINTF("%d", sp->is_hv);
+		break;
+
+	case 36:
+		PRINTF("%d", sp->is_tag);
+		break;
+
+	case 37:
+		PRINTF("%#x", sp->is_flags);
+		break;
+
+	case 38:
+		PRINTF("%d", sp->is_rulen);
+		break;
+
+	case 39:
+		PRINTF("%s", sp->is_group);
+		break;
+
+	case 40:
+		PRINTF("%#x", sp->is_flx[0][0]);
+		break;
+
+	case 41:
+		PRINTF("%#x", sp->is_flx[0][1]);
+		break;
+
+	case 42:
+		PRINTF("%#x", sp->is_flx[1][0]);
+		break;
+
+	case 43:
+		PRINTF("%#x", sp->is_flx[1][1]);
+		break;
+
+	case 44:
+		PRINTF("%#x", sp->is_opt[0]);
+		break;
+
+	case 45:
+		PRINTF("%#x", sp->is_opt[1]);
+		break;
+
+	case 46:
+		PRINTF("%#x", sp->is_optmsk[0]);
+		break;
+
+	case 47:
+		PRINTF("%#x", sp->is_optmsk[1]);
+		break;
+
+	case 48:
+		PRINTF("%#x", sp->is_sec);
+		break;
+
+	case 49:
+		PRINTF("%#x", sp->is_secmsk);
+		break;
+
+	case 50:
+		PRINTF("%#x", sp->is_auth);
+		break;
+
+	case 51:
+		PRINTF("%#x", sp->is_authmsk);
+		break;
+
+	case 52:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_icmppkts[0]);
+#else
+		PRINTF("%lu", sp->is_icmppkts[0]);
+#endif
+		break;
+
+	case 53:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_icmppkts[1]);
+#else
+		PRINTF("%lu", sp->is_icmppkts[1]);
+#endif
+		break;
+
+	case 54:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_icmppkts[2]);
+#else
+		PRINTF("%lu", sp->is_icmppkts[2]);
+#endif
+		break;
+
+	case 55:
+#ifdef USE_QUAD_T
+		PRINTF("%"PRIu64"", sp->is_icmppkts[3]);
+#else
+		PRINTF("%lu", sp->is_icmppkts[3]);
+#endif
+		break;
+
+	default:
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printstatefields.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printtcpflags.c
===================================================================
--- trunk/contrib/ipfilter/lib/printtcpflags.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printtcpflags.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,30 @@
+#include "ipf.h"
+
+
+void
+printtcpflags(tcpf, tcpfm)
+	u_32_t tcpf, tcpfm;
+{
+	u_char *t;
+	char *s;
+
+	if (tcpf & ~TCPF_ALL) {
+		PRINTF("0x%x", tcpf);
+	} else {
+		for (s = flagset, t = flags; *s; s++, t++) {
+			if (tcpf & *t)
+				(void)putchar(*s);
+		}
+	}
+
+	if (tcpfm) {
+		(void)putchar('/');
+		if (tcpfm & ~TCPF_ALL) {
+			PRINTF("0x%x", tcpfm);
+		} else {
+			for (s = flagset, t = flags; *s; s++, t++)
+				if (tcpfm & *t)
+					(void)putchar(*s);
+		}
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printtcpflags.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/printunit.c
===================================================================
--- trunk/contrib/ipfilter/lib/printunit.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/printunit.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+
+void
+printunit(unit)
+	int unit;
+{
+
+	switch (unit)
+	{
+	case IPL_LOGIPF :
+		PRINTF("ipf");
+		break;
+	case IPL_LOGNAT :
+		PRINTF("nat");
+		break;
+	case IPL_LOGSTATE :
+		PRINTF("state");
+		break;
+	case IPL_LOGAUTH :
+		PRINTF("auth");
+		break;
+	case IPL_LOGSYNC :
+		PRINTF("sync");
+		break;
+	case IPL_LOGSCAN :
+		PRINTF("scan");
+		break;
+	case IPL_LOGLOOKUP :
+		PRINTF("lookup");
+		break;
+	case IPL_LOGCOUNT :
+		PRINTF("count");
+		break;
+	case IPL_LOGALL :
+		PRINTF("all");
+		break;
+	default :
+		PRINTF("unknown(%d)", unit);
+	}
+}


Property changes on: trunk/contrib/ipfilter/lib/printunit.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_execute.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_execute.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_execute.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,80 @@
+#include "ipf.h"
+#include "ipmon.h"
+
+static void *execute_parse __P((char **));
+static void execute_destroy __P((void *));
+static int execute_send __P((void *, ipmon_msg_t *));
+static void execute_print __P((void *));
+
+typedef struct execute_opts_s {
+	char	*path;
+} execute_opts_t;
+
+ipmon_saver_t executesaver = {
+	"execute",
+	execute_destroy,
+	NULL,			/* dup */
+	NULL,			/* match */
+	execute_parse,
+	execute_print,
+	execute_send
+};
+
+
+static void *
+execute_parse(char **strings)
+{
+	execute_opts_t *ctx;
+
+	ctx = calloc(1, sizeof(*ctx));
+
+	if (ctx != NULL && strings[0] != NULL && strings[0][0] != '\0') {
+		ctx->path = strdup(strings[0]);
+
+	} else {
+		free(ctx);
+		return NULL;
+	}
+
+	return ctx;
+}
+
+
+static void
+execute_print(ctx)
+	void *ctx;
+{
+	execute_opts_t *exe = ctx;
+
+	printf("%s", exe->path);
+}
+
+
+static void
+execute_destroy(ctx)
+	void *ctx;
+{
+	execute_opts_t *exe = ctx;
+
+	if (exe != NULL)
+		free(exe->path);
+	free(exe);
+}
+
+
+static int
+execute_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+	execute_opts_t *exe = ctx;
+	FILE *fp;
+
+	fp = popen(exe->path, "w");
+	if (fp != NULL) {
+		fwrite(msg->imm_msg, msg->imm_msglen, 1, fp);
+		pclose(fp);
+	}
+	return 0;
+}
+


Property changes on: trunk/contrib/ipfilter/lib/save_execute.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_file.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_file.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_file.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,130 @@
+#include "ipf.h"
+#include "ipmon.h"
+
+static void *file_parse __P((char **));
+static void file_destroy __P((void *));
+static int file_send __P((void *, ipmon_msg_t *));
+static void file_print __P((void *));
+static int file_match __P((void *, void *));
+static void *file_dup __P((void *));
+
+typedef struct file_opts_s {
+	FILE	*fp;
+	int	raw;
+	char	*path;
+	int	ref;
+} file_opts_t;
+
+ipmon_saver_t filesaver = {
+	"file",
+	file_destroy,
+	file_dup,
+	file_match,
+	file_parse,
+	file_print,
+	file_send
+};
+
+
+static void *
+file_parse(strings)
+	char **strings;
+{
+	file_opts_t *ctx;
+
+	ctx = calloc(1, sizeof(*ctx));
+	if (ctx == NULL)
+		return NULL;
+
+	if (strings[0] != NULL && strings[0][0] != '\0') {
+		ctx->ref = 1;
+		if (!strncmp(strings[0], "raw://", 6)) {
+			ctx->raw = 1;
+			ctx->path = strdup(strings[0] + 6);
+			ctx->fp = fopen(ctx->path, "ab");
+		} else if (!strncmp(strings[0], "file://", 7)) {
+			ctx->path = strdup(strings[0] + 7);
+			ctx->fp = fopen(ctx->path, "a");
+		} else {
+			free(ctx);
+			ctx = NULL;
+		}
+	} else {
+		free(ctx);
+		ctx = NULL;
+	}
+
+	return ctx;
+}
+
+
+static int
+file_match(ctx1, ctx2)
+	void *ctx1, *ctx2;
+{
+	file_opts_t *f1 = ctx1, *f2 = ctx2;
+
+	if (f1->raw != f2->raw)
+		return 1;
+	if (strcmp(f1->path, f2->path))
+		return 1;
+	return 0;
+}
+
+
+static void *
+file_dup(ctx)
+	void *ctx;
+{
+	file_opts_t *f = ctx;
+
+	f->ref++;
+	return f;
+}
+
+
+static void
+file_print(ctx)
+	void *ctx;
+{
+	file_opts_t *file = ctx;
+
+	if (file->raw)
+		printf("raw://");
+	else
+		printf("file://");
+	printf("%s", file->path);
+}
+
+
+static void
+file_destroy(ctx)
+	void *ctx;
+{
+	file_opts_t *file = ctx;
+
+	file->ref--;
+	if (file->ref > 0)
+		return;
+
+	if (file->path != NULL)
+		free(file->path);
+	free(file);
+}
+
+
+static int
+file_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+	file_opts_t *file = ctx;
+
+	if (file->raw) {
+		fwrite(msg->imm_data, msg->imm_dsize, 1, file->fp);
+	} else {
+		fprintf(file->fp, "%s", msg->imm_msg);
+	}
+	return 0;
+}
+


Property changes on: trunk/contrib/ipfilter/lib/save_file.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_nothing.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_nothing.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_nothing.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,62 @@
+#include "ipf.h"
+#include "ipmon.h"
+
+static void *nothing_parse __P((char **));
+static void nothing_destroy __P((void *));
+static int nothing_send __P((void *, ipmon_msg_t *));
+
+typedef struct nothing_opts_s {
+	FILE	*fp;
+	int	raw;
+	char	*path;
+} nothing_opts_t;
+
+ipmon_saver_t nothingsaver = {
+	"nothing",
+	nothing_destroy,
+	NULL,		/* dup */
+	NULL,		/* match */
+	nothing_parse,
+	NULL,		/* print */
+	nothing_send
+};
+
+
+static void *
+nothing_parse(char **strings)
+{
+	void *ctx;
+
+#if 0
+	strings = strings;	/* gcc -Wextra */
+#endif
+
+	ctx = calloc(1, sizeof(void *));
+
+	return ctx;
+}
+
+
+static void
+nothing_destroy(ctx)
+	void *ctx;
+{
+	free(ctx);
+}
+
+
+static int
+nothing_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+#if 0
+	ctx = ctx;	/* gcc -Wextra */
+	msg = msg;	/* gcc -Wextra */
+#endif
+	/*
+	 * Do nothing
+	 */
+	return 0;
+}
+


Property changes on: trunk/contrib/ipfilter/lib/save_nothing.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_syslog.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_syslog.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_syslog.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,137 @@
+#include "ipf.h"
+#include "ipmon.h"
+#include <syslog.h>
+
+static void *syslog_parse __P((char **));
+static void syslog_destroy __P((void *));
+static int syslog_send __P((void *, ipmon_msg_t *));
+static void syslog_print __P((void *));
+
+typedef struct syslog_opts_s {
+	int	facpri;
+	int	fac;
+	int	pri;
+} syslog_opts_t;
+
+ipmon_saver_t syslogsaver = {
+	"syslog",
+	syslog_destroy,
+	NULL,			/* dup */
+	NULL,			/* match */
+	syslog_parse,
+	syslog_print,
+	syslog_send
+};
+
+
+static void *
+syslog_parse(char **strings)
+{
+	syslog_opts_t *ctx;
+	char *str;
+	char *s;
+
+	ctx = calloc(1, sizeof(*ctx));
+	if (ctx == NULL)
+		return NULL;
+
+	ctx->facpri = -1;
+
+	if (strings[0] != NULL && strings[0][0] != '\0') {
+		str = strdup(*strings);
+		if (str != NULL && *str != '\0') {
+			int fac = -1, pri = -1;
+
+			s = strchr(str, '.');
+			if (s != NULL)
+				*s++ = '\0';
+
+			if (*str != '\0') {
+				fac = fac_findname(str);
+				if (fac == -1) {
+					free(str);
+					free(ctx);
+					return NULL;
+				}
+			}
+
+			if (s != NULL && *s != '\0') {
+				pri = pri_findname(s);
+				if (pri == -1) {
+					free(str);
+					free(ctx);
+					return NULL;
+				}
+			}
+			free(str);
+
+			ctx->fac = fac;
+			ctx->pri = pri;
+			if (pri == -1)
+				ctx->facpri = fac;
+			else if (fac == -1)
+				ctx->facpri = pri;
+			else
+				ctx->facpri = fac | pri;
+		} else {
+			if (str != NULL)
+				free(str);
+			free(ctx);
+			ctx = NULL;
+		}
+	}
+
+	return ctx;
+}
+
+
+static void
+syslog_print(ctx)
+	void *ctx;
+{
+	syslog_opts_t *sys = ctx;
+
+	if (sys->facpri == -1)
+		return;
+
+	if (sys->fac == -1) {
+		printf(".%s", pri_toname(sys->pri));
+	} else if (sys->pri == -1) {
+		printf("%s.", fac_toname(sys->fac));
+	} else {
+		printf("%s.%s", fac_toname(sys->facpri & LOG_FACMASK),
+		       pri_toname(sys->facpri & LOG_PRIMASK));
+	}
+}
+
+
+static void
+syslog_destroy(ctx)
+	void *ctx;
+{
+	free(ctx);
+}
+
+
+static int
+syslog_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+	syslog_opts_t *sys = ctx;
+	int facpri;
+
+	if (sys->facpri == -1) {
+		facpri = msg->imm_loglevel;
+	} else {
+		if (sys->pri == -1) {
+			facpri = sys->fac | (msg->imm_loglevel & LOG_PRIMASK);
+		} else if (sys->fac == -1) {
+			facpri = sys->pri | (msg->imm_loglevel & LOG_FACMASK);
+		} else {
+			facpri = sys->facpri;
+		}
+	}
+	syslog(facpri, "%s", msg->imm_msg);
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/save_syslog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_v1trap.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_v1trap.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_v1trap.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,463 @@
+#include "ipf.h"
+#include "netinet/ipl.h"
+#include "ipmon.h"
+#include <ctype.h>
+
+#define	IPF_ENTERPRISE	9932
+/*
+ * Enterprise number OID:
+ * 1.3.6.1.4.1.9932
+ */
+static u_char ipf_enterprise[] = { 6, 7, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c };
+static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 };
+static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 };
+
+static int writeint __P((u_char *, int));
+static int writelength __P((u_char *, u_int));
+static int maketrap_v1 __P((char *, u_char *, int, u_char *, int, u_32_t,
+			    time_t));
+static void snmpv1_destroy __P((void *));
+static void *snmpv1_dup __P((void *));
+static int snmpv1_match __P((void *, void *));
+static void *snmpv1_parse __P((char **));
+static void snmpv1_print __P((void *));
+static int snmpv1_send __P((void *, ipmon_msg_t *));
+
+typedef struct snmpv1_opts_s {
+	char			*community;
+	int			fd;
+	int			v6;
+	int			ref;
+#ifdef USE_INET6
+	struct sockaddr_in6	sin6;
+#endif
+	struct sockaddr_in	sin;
+} snmpv1_opts_t;
+
+ipmon_saver_t snmpv1saver = {
+	"snmpv1",
+	snmpv1_destroy,
+	snmpv1_dup,		/* dup */
+	snmpv1_match,		/* match */
+	snmpv1_parse,
+	snmpv1_print,
+	snmpv1_send
+};
+
+
+static int
+snmpv1_match(ctx1, ctx2)
+	void *ctx1, *ctx2;
+{
+	snmpv1_opts_t *s1 = ctx1, *s2 = ctx2;
+
+	if (s1->v6 != s2->v6)
+		return 1;
+
+	if (strcmp(s1->community, s2->community))
+		return 1;
+
+#ifdef USE_INET6
+	if (s1->v6 == 1) {
+		if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6)))
+			return 1;
+	} else
+#endif
+	{
+		if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin)))
+			return 1;
+	}
+
+	return 0;
+}
+
+
+static void *
+snmpv1_dup(ctx)
+	void *ctx;
+{
+	snmpv1_opts_t *s = ctx;
+
+	s->ref++;
+	return s;
+}
+
+
+static void
+snmpv1_print(ctx)
+	void *ctx;
+{
+	snmpv1_opts_t *snmpv1 = ctx;
+
+	printf("%s ", snmpv1->community);
+#ifdef USE_INET6
+	if (snmpv1->v6 == 1) {
+		char buf[80];
+
+		printf("%s", inet_ntop(AF_INET6, &snmpv1->sin6.sin6_addr, buf,
+				       sizeof(snmpv1->sin6.sin6_addr)));
+	} else
+#endif
+	{
+		printf("%s", inet_ntoa(snmpv1->sin.sin_addr));
+	}
+}
+
+
+static void *
+snmpv1_parse(char **strings)
+{
+	snmpv1_opts_t *ctx;
+	int result;
+	char *str;
+	char *s;
+
+	if (strings[0] == NULL || strings[0][0] == '\0')
+		return NULL;
+
+	if (strchr(*strings, ' ') == NULL)
+		return NULL;
+
+	str = strdup(*strings);
+
+	ctx = calloc(1, sizeof(*ctx));
+	if (ctx == NULL)
+		return NULL;
+
+	ctx->fd = -1;
+
+	s = strchr(str, ' ');
+	*s++ = '\0';
+	ctx->community = str;
+
+	while (ISSPACE(*s))
+		s++;
+	if (!*s) {
+		free(str);
+		free(ctx);
+		return NULL;
+	}
+
+#ifdef USE_INET6
+	if (strchr(s, ':') == NULL) {
+		result = inet_pton(AF_INET, s, &ctx->sin.sin_addr);
+		if (result == 1) {
+			ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
+			if (ctx->fd >= 0) {
+				ctx->sin.sin_family = AF_INET;
+				ctx->sin.sin_port = htons(162);
+				if (connect(ctx->fd,
+					    (struct sockaddr *)&ctx->sin,
+					    sizeof(ctx->sin)) != 0) {
+						snmpv1_destroy(ctx);
+						return NULL;
+				}
+			}
+		}
+	} else {
+		result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr);
+		if (result == 1) {
+			ctx->v6 = 1;
+			ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0);
+			if (ctx->fd >= 0) {
+				ctx->sin6.sin6_family = AF_INET6;
+				ctx->sin6.sin6_port = htons(162);
+				if (connect(ctx->fd,
+					    (struct sockaddr *)&ctx->sin6,
+					    sizeof(ctx->sin6)) != 0) {
+						snmpv1_destroy(ctx);
+						return NULL;
+				}
+			}
+		}
+	}
+#else
+	result = inet_aton(s, &ctx->sin.sin_addr);
+	if (result == 1) {
+		ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
+		if (ctx->fd >= 0) {
+			ctx->sin.sin_family = AF_INET;
+			ctx->sin.sin_port = htons(162);
+			if (connect(ctx->fd, (struct sockaddr *)&ctx->sin,
+				    sizeof(ctx->sin)) != 0) {
+					snmpv1_destroy(ctx);
+					return NULL;
+			}
+		}
+	}
+#endif
+
+	if (result != 1) {
+		free(str);
+		free(ctx);
+		return NULL;
+	}
+
+	ctx->ref = 1;
+
+	return ctx;
+}
+
+
+static void
+snmpv1_destroy(ctx)
+	void *ctx;
+{
+	snmpv1_opts_t *v1 = ctx;
+
+	v1->ref--;
+	if (v1->ref > 0)
+		return;
+
+	if (v1->community)
+		free(v1->community);
+	if (v1->fd >= 0)
+		close(v1->fd);
+	free(v1);
+}
+
+
+static int
+snmpv1_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+	snmpv1_opts_t *v1 = ctx;
+
+	return sendtrap_v1_0(v1->fd, v1->community,
+			     msg->imm_msg, msg->imm_msglen, msg->imm_when);
+}
+
+static char def_community[] = "public";	/* ublic */
+
+static int
+writelength(buffer, value)
+	u_char *buffer;
+	u_int value;
+{
+	u_int n = htonl(value);
+	int len;
+
+	if (value < 128) {
+		*buffer = value;
+		return 1;
+	}
+	if (value > 0xffffff)
+		len = 4;
+	else if (value > 0xffff)
+		len = 3;
+	else if (value > 0xff)
+		len = 2;
+	else
+		len = 1;
+
+	*buffer = 0x80 | len;
+
+	bcopy((u_char *)&n + 4 - len, buffer + 1, len);
+
+	return len + 1;
+}
+
+
+static int
+writeint(buffer, value)
+	u_char *buffer;
+	int value;
+{
+	u_char *s = buffer;
+	u_int n = value;
+
+	if (value == 0) {
+		*buffer = 0;
+		return 1;
+	}
+
+	if (n >  4194304) {
+		*s++ = 0x80 | (n / 4194304);
+		n -= 4194304 * (n / 4194304);
+	}
+	if (n >  32768) {
+		*s++ = 0x80 | (n / 32768);
+		n -= 32768 * (n / 327678);
+	}
+	if (n > 128) {
+		*s++ = 0x80 | (n / 128);
+		n -= (n / 128) * 128;
+	}
+	*s++ = (u_char)n;
+
+	return s - buffer;
+}
+
+
+
+/*
+ * First style of traps is:
+ * 1.3.6.1.4.1.9932.1.1
+ */
+static int
+maketrap_v1(community, buffer, bufsize, msg, msglen, ipaddr, when)
+	char *community;
+	u_char *buffer;
+	int bufsize;
+	u_char *msg;
+	int msglen;
+	u_32_t ipaddr;
+	time_t when;
+{
+	u_char *s = buffer, *t, *pdulen, *varlen;
+	int basesize = 73;
+	u_short len;
+	int trapmsglen;
+	int pdulensz;
+	int varlensz;
+	int baselensz;
+	int n;
+
+	if (community == NULL || *community == '\0')
+		community = def_community;
+	basesize += strlen(community) + msglen;
+
+	if (basesize + 8 > bufsize)
+		return 0;
+
+	memset(buffer, 0xff, bufsize);
+	*s++ = 0x30;		/* Sequence */
+	if (basesize - 1 >= 128) {
+		baselensz = 2;
+		basesize++;
+	} else {
+		baselensz = 1;
+	}
+	s += baselensz;
+	*s++ = 0x02;		/* Integer32 */
+	*s++ = 0x01;		/* length 1 */
+	*s++ = 0x00;		/* version 1 */
+	*s++ = 0x04;		/* octet string */
+	*s++ = strlen(community);		/* length of "public" */
+	bcopy(community, s, s[-1]);
+	s += s[-1];
+	*s++ = 0xA4;		/* PDU(4) */
+	pdulen = s++;
+	if (basesize - (s - buffer) >= 128) {
+		pdulensz = 2;
+		basesize++;
+		s++;
+	} else {
+		pdulensz = 1;
+	}
+
+	/* enterprise */
+	bcopy(ipf_enterprise, s, sizeof(ipf_enterprise));
+	s += sizeof(ipf_enterprise);
+
+	/* Agent address */
+	*s++ = 0x40;
+	*s++ = 0x4;
+	bcopy(&ipaddr, s, 4);
+	s += 4;
+
+	/* Generic Trap code */
+	*s++ = 0x2;
+	n = writeint(s + 1, 6);
+	if (n == 0)
+		return 0;
+	*s = n;
+	s += n + 1;
+
+	/* Specific Trap code */
+	*s++ = 0x2;
+	n = writeint(s + 1, 0);
+	if (n == 0)
+		return 0;
+	*s = n;
+	s += n + 1;
+
+	/* Time stamp */
+	*s++ = 0x43;			/* TimeTicks */
+	*s++ = 0x04;			/* TimeTicks */
+	s[0] = when >> 24;
+	s[1] = when >> 16;
+	s[2] = when >> 8;
+	s[3] = when & 0xff;
+	s += 4;
+
+	/*
+	 * The trap0 message is "ipfilter_version" followed by the message
+	 */
+	*s++ = 0x30;
+	varlen = s;
+	if (basesize - (s - buffer) >= 128) {
+		varlensz = 2;
+		basesize++;
+	} else {
+		varlensz = 1;
+	}
+	s += varlensz;
+
+	*s++ = 0x30;
+	t = s + 1;
+	bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1));
+	t += sizeof(ipf_trap0_1);
+
+	*t++ = 0x2;		/* Integer */
+	n = writeint(t + 1, IPFILTER_VERSION);
+	*t = n;
+	t += n + 1;
+
+	len = t - s - 1;
+	writelength(s, len);
+
+	s = t;
+	*s++ = 0x30;
+	if (basesize - (s - buffer) >= 128) {
+		trapmsglen = 2;
+		basesize++;
+	} else {
+		trapmsglen = 1;
+	}
+	t = s + trapmsglen;
+	bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2));
+	t += sizeof(ipf_trap0_2);
+
+	*t++ = 0x4;		/* Octet string */
+	n = writelength(t, msglen);
+	t += n;
+	bcopy(msg, t, msglen);
+	t += msglen;
+
+	len = t - s - trapmsglen;
+	writelength(s, len);
+
+	len = t - varlen - varlensz;
+	writelength(varlen, len);		/* pdu length */
+
+	len = t - pdulen - pdulensz;
+	writelength(pdulen, len);		/* pdu length */
+
+	len = t - buffer - baselensz - 1;
+	writelength(buffer + 1, len);	/* length of trap */
+
+	return t - buffer;
+}
+
+
+int
+sendtrap_v1_0(fd, community, msg, msglen, when)
+	int fd;
+	char *community, *msg;
+	int msglen;
+	time_t when;
+{
+
+	u_char buffer[1500];
+	int n;
+
+	n = maketrap_v1(community, buffer, sizeof(buffer),
+			(u_char *)msg, msglen, 0, when);
+	if (n > 0) {
+		return send(fd, buffer, n, 0);
+	}
+
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/save_v1trap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/save_v2trap.c
===================================================================
--- trunk/contrib/ipfilter/lib/save_v2trap.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/save_v2trap.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,461 @@
+#include "ipf.h"
+#include "netinet/ipl.h"
+#include "ipmon.h"
+#include <ctype.h>
+
+static u_char sysuptime[] = { 6, 8, 0x2b, 6, 1, 2, 1, 1, 3, 0 };
+/*
+ * Enterprise number OID:
+ * 1.3.6.1.4.1.9932
+ */
+static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 };
+static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 };
+
+static int writeint __P((u_char *, int));
+static int writelength __P((u_char *, u_int));
+static int maketrap_v2 __P((char *, u_char *, int, u_char *, int));
+static void snmpv2_destroy __P((void *));
+static void *snmpv2_dup __P((void *));
+static int snmpv2_match __P((void *, void *));
+static void *snmpv2_parse __P((char **));
+static void snmpv2_print __P((void *));
+static int snmpv2_send __P((void *, ipmon_msg_t *));
+
+
+int sendtrap_v2_0 __P((int, char *, char *, int));
+
+static char def_community[] = "public";	/* ublic */
+
+typedef struct snmpv2_opts_s {
+	char			*community;
+	char			*server;
+	int			fd;
+	int			v6;
+	int			ref;
+#ifdef USE_INET6
+	struct sockaddr_in6	sin6;
+#endif
+	struct sockaddr_in	sin;
+} snmpv2_opts_t;
+
+ipmon_saver_t snmpv2saver = {
+	"snmpv2",
+	snmpv2_destroy,
+	snmpv2_dup,		/* dup */
+	snmpv2_match,		/* match */
+	snmpv2_parse,
+	snmpv2_print,
+	snmpv2_send
+};
+
+
+static int
+snmpv2_match(ctx1, ctx2)
+	void *ctx1, *ctx2;
+{
+	snmpv2_opts_t *s1 = ctx1, *s2 = ctx2;
+
+	if (s1->v6 != s2->v6)
+		return 1;
+
+	if (strcmp(s1->community, s2->community))
+		return 1;
+
+#ifdef USE_INET6
+	if (s1->v6 == 1) {
+		if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6)))
+			return 1;
+	} else
+#endif
+	{
+		if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin)))
+			return 1;
+	}
+
+	return 0;
+}
+
+
+static void *
+snmpv2_dup(ctx)
+	void *ctx;
+{
+	snmpv2_opts_t *s = ctx;
+
+	s->ref++;
+	return s;
+}
+
+
+static void
+snmpv2_print(ctx)
+        void *ctx;
+{
+	snmpv2_opts_t *snmpv2 = ctx;
+
+	printf("%s ", snmpv2->community);
+#ifdef USE_INET6
+	if (snmpv2->v6 == 1) {
+		char buf[80];
+
+		printf("%s", inet_ntop(AF_INET6, &snmpv2->sin6.sin6_addr, buf,
+				       sizeof(snmpv2->sin6.sin6_addr)));
+	} else
+#endif
+	{
+		printf("%s", inet_ntoa(snmpv2->sin.sin_addr));
+	}
+}
+
+
+static void *
+snmpv2_parse(char **strings)
+{
+	snmpv2_opts_t *ctx;
+	int result;
+	char *str;
+	char *s;
+
+	if (strings[0] == NULL || strings[0][0] == '\0')
+		return NULL;
+	if (strchr(*strings, ' ') == NULL)
+		return NULL;
+
+	str = strdup(*strings);
+
+	ctx = calloc(1, sizeof(*ctx));
+	if (ctx == NULL) {
+		free(str);
+		return NULL;
+	}
+
+	ctx->fd = -1;
+
+	s = strchr(str, ' ');
+	*s++ = '\0';
+	ctx->community = str;
+
+	while (ISSPACE(*s))
+		s++;
+	if (!*s) {
+		free(str);
+		free(ctx);
+		return NULL;
+	}
+
+#ifdef USE_INET6
+	if (strchr(s, ':') == NULL) {
+		result = inet_pton(AF_INET, s, &ctx->sin.sin_addr);
+		if (result == 1) {
+			ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
+			if (ctx->fd >= 0) {
+				ctx->sin.sin_family = AF_INET;
+				ctx->sin.sin_port = htons(162);
+				if (connect(ctx->fd,
+					    (struct sockaddr *)&ctx->sin,
+					    sizeof(ctx->sin)) != 0) {
+						snmpv2_destroy(ctx);
+						return NULL;
+				}
+			}
+		}
+	} else {
+		result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr);
+		if (result == 1) {
+			ctx->v6 = 1;
+			ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0);
+			if (ctx->fd >= 0) {
+				ctx->sin6.sin6_family = AF_INET6;
+				ctx->sin6.sin6_port = htons(162);
+				if (connect(ctx->fd,
+					    (struct sockaddr *)&ctx->sin6,
+					    sizeof(ctx->sin6)) != 0) {
+						snmpv2_destroy(ctx);
+						return NULL;
+				}
+			}
+		}
+	}
+#else
+	result = inet_aton(s, &ctx->sin.sin_addr);
+	if (result == 1) {
+		ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
+		if (ctx->fd >= 0) {
+			ctx->sin.sin_family = AF_INET;
+			ctx->sin.sin_port = htons(162);
+			if (connect(ctx->fd, (struct sockaddr *)&ctx->sin,
+				    sizeof(ctx->sin)) != 0) {
+					snmpv2_destroy(ctx);
+					return NULL;
+			}
+		}
+	}
+#endif
+
+	if (result != 1) {
+		free(str);
+		free(ctx);
+		return NULL;
+	}
+
+	ctx->ref = 1;
+
+	return ctx;
+}
+
+
+static void
+snmpv2_destroy(ctx)
+	void *ctx;
+{
+	snmpv2_opts_t *v2 = ctx;
+
+	v2->ref--;
+	if (v2->ref > 0)
+		return;
+
+	if (v2->community)
+		free(v2->community);
+	if (v2->fd >= 0)
+		close(v2->fd);
+	free(v2);
+}
+
+
+static int
+snmpv2_send(ctx, msg)
+	void *ctx;
+	ipmon_msg_t *msg;
+{
+	snmpv2_opts_t *v2 = ctx;
+
+	return sendtrap_v2_0(v2->fd, v2->community,
+			     msg->imm_msg, msg->imm_msglen);
+}
+static int
+writelength(buffer, value)
+	u_char *buffer;
+	u_int value;
+{
+	u_int n = htonl(value);
+	int len;
+
+	if (value < 128) {
+		*buffer = value;
+		return 1;
+	}
+	if (value > 0xffffff)
+		len = 4;
+	else if (value > 0xffff)
+		len = 3;
+	else if (value > 0xff)
+		len = 2;
+	else
+		len = 1;
+
+	*buffer = 0x80 | len;
+
+	bcopy((u_char *)&n + 4 - len, buffer + 1, len);
+
+	return len + 1;
+}
+
+
+static int
+writeint(buffer, value)
+	u_char *buffer;
+	int value;
+{
+	u_char *s = buffer;
+	u_int n = value;
+
+	if (value == 0) {
+		*buffer = 0;
+		return 1;
+	}
+
+	if (n >  4194304) {
+		*s++ = 0x80 | (n / 4194304);
+		n -= 4194304 * (n / 4194304);
+	}
+	if (n >  32768) {
+		*s++ = 0x80 | (n / 32768);
+		n -= 32768 * (n / 327678);
+	}
+	if (n > 128) {
+		*s++ = 0x80 | (n / 128);
+		n -= (n / 128) * 128;
+	}
+	*s++ = (u_char)n;
+
+	return s - buffer;
+}
+
+
+
+/*
+ * First style of traps is:
+ * 1.3.6.1.4.1.9932.1.1
+ */
+static int
+maketrap_v2(community, buffer, bufsize, msg, msglen)
+	char *community;
+	u_char *buffer;
+	int bufsize;
+	u_char *msg;
+	int msglen;
+{
+	u_char *s = buffer, *t, *pdulen;
+	u_char *varlen;
+	int basesize = 77;
+	u_short len;
+	int trapmsglen;
+	int pdulensz;
+	int varlensz;
+	int baselensz;
+	int n;
+
+	if (community == NULL || *community == '\0')
+		community = def_community;
+	basesize += strlen(community) + msglen;
+
+	if (basesize + 8 > bufsize)
+		return 0;
+
+	memset(buffer, 0xff, bufsize);
+	*s++ = 0x30;		/* Sequence */
+
+	if (basesize - 1 >= 128) {
+		baselensz = 2;
+		basesize++;
+	} else {
+		baselensz = 1;
+	}
+	s += baselensz;
+	*s++ = 0x02;		/* Integer32 */
+	*s++ = 0x01;		/* length 1 */
+	*s++ = 0x01;		/* version 2 */
+	*s++ = 0x04;		/* octet string */
+	*s++ = strlen(community);		/* length of "public" */
+	bcopy(community, s, s[-1]);
+	s += s[-1];
+	*s++ = 0xA7;		/* PDU(7) */
+	pdulen = s++;
+	if (basesize - (s - buffer) >= 128) {
+		pdulensz = 2;
+		basesize++;
+		s++;
+	} else {
+		pdulensz = 1;
+	}
+	/* request id */
+	*s++ = 0x2;	/* integer */
+	*s++ = 0x4;	/* len 4 */
+	*s++ = 0x0;	/* noError */
+	*s++ = 0x0;	/* noError */
+	*s++ = 0x0;	/* noError */
+	*s++ = 0x0;	/* noError */
+
+	/* error status */
+	*s++ = 0x2;	/* integer */
+	*s++ = 0x1;	/* len 1 */
+	*s++ = 0x0;	/* noError */
+
+	/* error-index */
+	*s++ = 0x2;	/* integer */
+	*s++ = 0x1;	/* len 1 */
+	*s++ = 0x0;	/* noError */
+
+	*s++ = 0x30;	/* sequence */
+	varlen = s++;
+	if (basesize - (s - buffer) >= 128) {
+		varlensz = 2;
+		basesize++;
+		s++;
+	} else {
+		varlensz = 1;
+	}
+
+	*s++ = 0x30;	/* sequence */
+	*s++ = sizeof(sysuptime) + 6;
+
+	bcopy(sysuptime, s, sizeof(sysuptime));
+	s += sizeof(sysuptime);
+
+	*s++ = 0x43;	/* Timestamp */
+	*s++ = 0x04;	/* TimeTicks */
+	*s++ = 0x0;
+	*s++ = 0x0;
+	*s++ = 0x0;
+	*s++ = 0x0;
+
+	*s++ = 0x30;
+	t = s + 1;
+	bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1));
+	t += sizeof(ipf_trap0_1);
+
+	*t++ = 0x2;		/* Integer */
+	n = writeint(t + 1, IPFILTER_VERSION);
+	*t = n;
+	t += n + 1;
+
+	len = t - s - 1;
+	writelength(s, len);
+
+	s = t;
+	*s++ = 0x30;
+	if (msglen < 128) {
+		if (msglen + 1 + 1 + sizeof(ipf_trap0_2) >= 128)
+			trapmsglen = 2;
+		else
+			trapmsglen = 1;
+	} else {
+		if (msglen + 2 + 1 + sizeof(ipf_trap0_2) >= 128)
+			trapmsglen = 2;
+		else
+			trapmsglen = 1;
+	}
+	t = s + trapmsglen;
+	bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2));
+	t += sizeof(ipf_trap0_2);
+
+	*t++ = 0x4;		/* Octet string */
+	n = writelength(t, msglen);
+	t += n;
+	bcopy(msg, t, msglen);
+	t += msglen;
+
+	len = t - s - trapmsglen;
+	writelength(s, len);
+
+	len = t - varlen - varlensz;
+	writelength(varlen, len);		/* pdu length */
+
+	len = t - pdulen - pdulensz;
+	writelength(pdulen, len);		/* pdu length */
+
+	len = t - buffer - baselensz - 1;
+	writelength(buffer + 1, len);	/* length of trap */
+
+	return t - buffer;
+}
+
+
+int
+sendtrap_v2_0(fd, community, msg, msglen)
+	int fd;
+	char *community, *msg;
+	int msglen;
+{
+
+	u_char buffer[1500];
+	int n;
+
+	n = maketrap_v2(community, buffer, sizeof(buffer),
+			(u_char *)msg, msglen);
+	if (n > 0) {
+		return send(fd, buffer, n, 0);
+	}
+
+	return 0;
+}


Property changes on: trunk/contrib/ipfilter/lib/save_v2trap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/lib/vtof.c
===================================================================
--- trunk/contrib/ipfilter/lib/vtof.c	                        (rev 0)
+++ trunk/contrib/ipfilter/lib/vtof.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,16 @@
+#include "ipf.h"
+
+int
+vtof(version)
+	int version;
+{
+#ifdef USE_INET6
+	if (version == 6)
+		return AF_INET6;
+#endif
+	if (version == 4)
+		return AF_INET;
+	if (version == 0)
+		return AF_UNSPEC;
+	return -1;
+}


Property changes on: trunk/contrib/ipfilter/lib/vtof.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/ml_ipl.c
===================================================================
--- trunk/contrib/ipfilter/ml_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/ml_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,164 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+/*
+ * 29/12/94 Added code from Marc Huber <huber at fzi.de> to allow it to allocate
+ * its own major char number! Way cool patch!
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <sys/syslog.h>
+#include <sys/buf.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+#include <sundev/mbvar.h>
+#include <sun/autoconf.h>
+#include <sun/vddrv.h>
+#if defined(sun4c) || defined(sun4m)
+#include <sun/openprom.h>
+#endif
+
+#ifndef	IPL_NAME
+#define	IPL_NAME	"/dev/ipf"
+#endif
+
+extern	int	ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread();
+extern	int	nulldev(), ipfidentify(), errno;
+
+struct	cdevsw	ipfdevsw =
+{
+	ipfopen, ipfclose, ipfread, nulldev,
+	ipfioctl, nulldev, nulldev, nulldev,
+	0, nulldev,
+};
+
+
+struct	dev_ops	ipf_ops =
+{
+	1,
+	ipfidentify,
+	ipfattach,
+	ipfopen,
+	ipfclose,
+	ipfread,
+	NULL,		/* write */
+	NULL,		/* strategy */
+	NULL,		/* dump */
+	0,		/* psize */
+        ipfioctl,
+	NULL,		/* reset */
+	NULL		/* mmap */
+};
+
+int	ipf_major = 0;
+
+#ifdef sun4m
+struct	vdldrv	vd =
+{
+	VDMAGIC_PSEUDO,
+	"ipf",
+	&ipf_ops,
+	NULL,
+	&ipfdevsw,
+	0,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	0,
+	1,
+};
+#else /* sun4m */
+struct vdldrv vd =
+{
+	VDMAGIC_PSEUDO,	/* magic */
+	"ipf",		/* name */
+#ifdef sun4c
+	&ipf_ops,	/* dev_ops */
+#else
+	NULL,		/* struct mb_ctlr *mb_ctlr */
+	NULL,		/* struct mb_driver *mb_driver */
+	NULL,		/* struct mb_device *mb_device */
+	0,		/* num ctlrs */
+	1,		/* numdevs */
+#endif /* sun4c */
+	NULL,		/* bdevsw */
+	&ipfdevsw,	/* cdevsw */
+	0,		/* block major */
+	0,		/* char major */
+};
+#endif /* sun4m */
+
+extern int vd_unuseddev();
+extern struct cdevsw cdevsw[];
+extern int nchrdev;
+
+xxxinit(fc, vdp, vdi, vds)
+	u_int	fc;
+	struct	vddrv	*vdp;
+	caddr_t	vdi;
+	struct	vdstat	*vds;
+{
+	struct	vdlinkage *v;
+	int	i;
+
+	switch (fc)
+	{
+	case VDLOAD:
+		while (ipf_major < nchrdev &&
+		       cdevsw[ipf_major].d_open != vd_unuseddev)
+			ipf_major++;
+		if (ipf_major == nchrdev)
+			return ENODEV;
+		vd.Drv_charmajor = ipf_major;
+		vdp->vdd_vdtab = (struct vdlinkage *)&vd;
+		return ipf_attach(vdi);
+	case VDUNLOAD:
+		return unload(vdp, vdi);
+
+	case VDSTAT:
+		return 0;
+
+	default:
+		return EIO;
+	}
+}
+
+static unload(vdp, vdi)
+	struct vddrv *vdp;
+	struct vdioctl_unload  *vdi;
+{
+	int	i;
+
+	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
+	return ipfdetach();
+}
+
+
+static	int	ipf_attach(vdi)
+struct	vdioctl_load	*vdi;
+{
+	struct	vnode	*vp;
+	struct	vattr	vattr;
+	int		error = 0, fmode = S_IFCHR|0600;
+
+	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
+	vattr_null(&vattr);
+	vattr.va_type = MFTOVT(fmode);
+	vattr.va_mode = (fmode & 07777);
+	vattr.va_rdev = ipf_major<<8;
+
+	error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp);
+	if (error == 0)
+		VN_RELE(vp);
+	return ipfattach(0);
+}


Property changes on: trunk/contrib/ipfilter/ml_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mlfk_ipl.c
===================================================================
--- trunk/contrib/ipfilter/mlfk_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mlfk_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,529 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/conf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/select.h>
+#if __FreeBSD_version >= 500000
+# include <sys/selinfo.h>
+#endif
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+
+
+#include "netinet/ipl.h"
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_auth.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_sync.h"
+
+extern ipf_main_softc_t ipfmain;
+
+#if __FreeBSD_version >= 502116
+static struct cdev *ipf_devs[IPL_LOGSIZE];
+#else
+static dev_t ipf_devs[IPL_LOGSIZE];
+#endif
+
+#if 0
+static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
+#endif
+static int ipf_modload(void);
+static int ipf_modunload(void);
+
+#if (__FreeBSD_version >= 500024)
+# if (__FreeBSD_version >= 502116)
+static	int	ipfopen __P((struct cdev*, int, int, struct thread *));
+static	int	ipfclose __P((struct cdev*, int, int, struct thread *));
+# else
+static	int	ipfopen __P((dev_t, int, int, struct thread *));
+static	int	ipfclose __P((dev_t, int, int, struct thread *));
+# endif /* __FreeBSD_version >= 502116 */
+#else
+static	int	ipfopen __P((dev_t, int, int, struct proc *));
+static	int	ipfclose __P((dev_t, int, int, struct proc *));
+#endif
+#if (__FreeBSD_version >= 502116)
+static	int	ipfread __P((struct cdev*, struct uio *, int));
+static	int	ipfwrite __P((struct cdev*, struct uio *, int));
+#else
+static	int	ipfread __P((dev_t, struct uio *, int));
+static	int	ipfwrite __P((dev_t, struct uio *, int));
+#endif /* __FreeBSD_version >= 502116 */
+
+
+
+SYSCTL_DECL(_net_inet);
+#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
+	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
+		   ptr, val, sysctl_ipf_int, "I", descr);
+#define	CTLFLAG_OFF	0x00800000	/* IPFilter must be disabled */
+#define	CTLFLAG_RWO	(CTLFLAG_RW|CTLFLAG_OFF)
+SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
+#if 0
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
+	   &ipf_tcpidletimeout, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
+	   &ipf_tcphalfclosed, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
+	   &ipf_tcpclosewait, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
+	   &ipf_tcplastack, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
+	   &ipf_tcptimeout, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
+	   &ipf_tcpclosed, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
+	   &ipf_udptimeout, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
+	   &ipf_udpacktimeout, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
+	   &ipf_icmptimeout, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO,
+	   &ipf_nat_defage, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
+	   &ipf_ipfrttl, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD,
+	   &ipf_running, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO,
+	   &ipf_state_size, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO,
+	   &ipf_state_max, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO,
+	   &ipf_nat_table_sz, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO,
+	   &ipf_nat_maprules_sz, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO,
+	   &ipf_nat_rdrrules_sz, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO,
+	   &ipf_nat_hostmap_sz, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO,
+	   &ipf_auth_size, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
+	   &ipf_auth_used, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
+	   &ipf_auth_defaultage, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, "");
+#endif
+
+#define CDEV_MAJOR 79
+#include <sys/poll.h>
+#if __FreeBSD_version >= 500043
+# include <sys/select.h>
+static int ipfpoll(struct cdev *dev, int events, struct thread *td);
+
+static struct cdevsw ipf_cdevsw = {
+#if __FreeBSD_version >= 502103
+	.d_version =	D_VERSION,
+	.d_flags =	0,	/* D_NEEDGIANT - Should be SMP safe */
+#endif
+	.d_open =	ipfopen,
+	.d_close =	ipfclose,
+	.d_read =	ipfread,
+	.d_write =	ipfwrite,
+	.d_ioctl =	ipfioctl,
+	.d_poll =	ipfpoll,
+	.d_name =	"ipf",
+#if __FreeBSD_version < 600000
+	.d_maj =	CDEV_MAJOR,
+#endif
+};
+#else
+static int ipfpoll(dev_t dev, int events, struct proc *td);
+
+static struct cdevsw ipf_cdevsw = {
+	/* open */	ipfopen,
+	/* close */	ipfclose,
+	/* read */	ipfread,
+	/* write */	ipfwrite,
+	/* ioctl */	ipfioctl,
+	/* poll */	ipfpoll,
+	/* mmap */	nommap,
+	/* strategy */	nostrategy,
+	/* name */	"ipf",
+	/* maj */	CDEV_MAJOR,
+	/* dump */	nodump,
+	/* psize */	nopsize,
+	/* flags */	0,
+# if (__FreeBSD_version < 500043)
+	/* bmaj */	-1,
+# endif
+# if (__FreeBSD_version >= 430000)
+	/* kqfilter */	NULL
+# endif
+};
+#endif
+
+static char *ipf_devfiles[] = {	IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
+				IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
+
+
+static int
+ipfilter_modevent(module_t mod, int type, void *unused)
+{
+	int error = 0;
+
+	switch (type)
+	{
+	case MOD_LOAD :
+		error = ipf_modload();
+		break;
+
+	case MOD_UNLOAD :
+		error = ipf_modunload();
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	return error;
+}
+
+
+static int
+ipf_modload()
+{
+	char *defpass, *c, *str;
+	int i, j, error;
+
+	if (ipf_load_all() != 0)
+		return EIO;
+
+	if (ipf_create_all(&ipfmain) == NULL)
+		return EIO;
+
+	error = ipfattach(&ipfmain);
+	if (error)
+		return error;
+
+	for (i = 0; i < IPL_LOGSIZE; i++)
+		ipf_devs[i] = NULL;
+
+	for (i = 0; (str = ipf_devfiles[i]); i++) {
+		c = NULL;
+		for(j = strlen(str); j > 0; j--)
+			if (str[j] == '/') {
+				c = str + j + 1;
+				break;
+			}
+		if (!c)
+			c = str;
+		ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, c);
+	}
+
+	error = ipf_pfil_hook();
+	if (error != 0)
+		return error;
+	ipf_event_reg();
+
+	if (FR_ISPASS(ipfmain.ipf_pass))
+		defpass = "pass";
+	else if (FR_ISBLOCK(ipfmain.ipf_pass))
+		defpass = "block";
+	else
+		defpass = "no-match -> block";
+
+	printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+		ipfilter_version, defpass,
+#ifdef IPFILTER_LOG
+		"enabled",
+#else
+		"disabled",
+#endif
+#ifdef IPFILTER_COMPILED
+		" (COMPILED)"
+#else
+		""
+#endif
+		);
+	return 0;
+}
+
+
+static int
+ipf_modunload()
+{
+	int error, i;
+
+	if (ipfmain.ipf_refcnt)
+		return EBUSY;
+
+	error = ipf_pfil_unhook();
+	if (error != 0)
+		return error;
+
+	if (ipfmain.ipf_running >= 0) {
+		error = ipfdetach(&ipfmain);
+		if (error != 0)
+			return error;
+
+		ipf_destroy_all(&ipfmain);
+		ipf_unload_all();
+	} else
+		error = 0;
+
+	ipfmain.ipf_running = -2;
+
+	for (i = 0; ipf_devfiles[i]; i++) {
+		if (ipf_devs[i] != NULL)
+			destroy_dev(ipf_devs[i]);
+	}
+
+	printf("%s unloaded\n", ipfilter_version);
+
+	return error;
+}
+
+
+static moduledata_t ipfiltermod = {
+	"ipfilter",
+	ipfilter_modevent,
+	0
+};
+
+
+DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
+#ifdef	MODULE_VERSION
+MODULE_VERSION(ipfilter, 1);
+#endif
+
+
+#if 0
+#ifdef SYSCTL_IPF
+int
+sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
+{
+	int error = 0;
+
+	if (arg1)
+		error = SYSCTL_OUT(req, arg1, sizeof(int));
+	else
+		error = SYSCTL_OUT(req, &arg2, sizeof(int));
+
+	if (error || !req->newptr)
+		return (error);
+
+	if (!arg1)
+		error = EPERM;
+	else {
+		if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0))
+			error = EBUSY;
+		else
+			error = SYSCTL_IN(req, arg1, sizeof(int));
+	}
+	return (error);
+}
+#endif
+#endif
+
+
+static int
+#if __FreeBSD_version >= 500043
+ipfpoll(struct cdev *dev, int events, struct thread *td)
+#else
+ipfpoll(dev_t dev, int events, struct proc *td)
+#endif
+{
+	u_int unit = GET_MINOR(dev);
+	int revents;
+
+	if (unit < 0 || unit > IPL_LOGMAX)
+		return 0;
+
+	revents = 0;
+
+	switch (unit)
+	{
+	case IPL_LOGIPF :
+	case IPL_LOGNAT :
+	case IPL_LOGSTATE :
+#ifdef IPFILTER_LOG
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit))
+			revents |= events & (POLLIN | POLLRDNORM);
+#endif
+		break;
+	case IPL_LOGAUTH :
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain))
+			revents |= events & (POLLIN | POLLRDNORM);
+		break;
+	case IPL_LOGSYNC :
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain))
+			revents |= events & (POLLIN | POLLRDNORM);
+		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain))
+			revents |= events & (POLLOUT | POLLWRNORM);
+		break;
+	case IPL_LOGSCAN :
+	case IPL_LOGLOOKUP :
+	default :
+		break;
+	}
+
+	if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
+		selrecord(td, &ipfmain.ipf_selwait[unit]);
+
+	return revents;
+}
+
+
+/*
+ * routines below for saving IP headers to buffer
+ */
+static int ipfopen(dev, flags
+#if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
+, devtype, p)
+	int devtype;
+# if (__FreeBSD_version >= 500024)
+	struct thread *p;
+# else
+	struct proc *p;
+# endif /* __FreeBSD_version >= 500024 */
+#else
+)
+#endif
+#if (__FreeBSD_version >= 502116)
+	struct cdev *dev;
+#else
+	dev_t dev;
+#endif
+	int flags;
+{
+	u_int unit = GET_MINOR(dev);
+	int error;
+
+	if (IPL_LOGMAX < unit)
+		error = ENXIO;
+	else {
+		switch (unit)
+		{
+		case IPL_LOGIPF :
+		case IPL_LOGNAT :
+		case IPL_LOGSTATE :
+		case IPL_LOGAUTH :
+		case IPL_LOGLOOKUP :
+		case IPL_LOGSYNC :
+#ifdef IPFILTER_SCAN
+		case IPL_LOGSCAN :
+#endif
+			error = 0;
+			break;
+		default :
+			error = ENXIO;
+			break;
+		}
+	}
+	return error;
+}
+
+
+static int ipfclose(dev, flags
+#if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
+, devtype, p)
+	int devtype;
+# if (__FreeBSD_version >= 500024)
+	struct thread *p;
+# else
+	struct proc *p;
+# endif /* __FreeBSD_version >= 500024 */
+#else
+)
+#endif
+#if (__FreeBSD_version >= 502116)
+	struct cdev *dev;
+#else
+	dev_t dev;
+#endif
+	int flags;
+{
+	u_int	unit = GET_MINOR(dev);
+
+	if (IPL_LOGMAX < unit)
+		unit = ENXIO;
+	else
+		unit = 0;
+	return unit;
+}
+
+/*
+ * ipfread/ipflog
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+#if (BSD >= 199306)
+static int ipfread(dev, uio, ioflag)
+	int ioflag;
+#else
+static int ipfread(dev, uio)
+#endif
+#if (__FreeBSD_version >= 502116)
+	struct cdev *dev;
+#else
+	dev_t dev;
+#endif
+	struct uio *uio;
+{
+	u_int	unit = GET_MINOR(dev);
+
+	if (unit < 0)
+		return ENXIO;
+
+	if (ipfmain.ipf_running < 1)
+		return EIO;
+
+	if (unit == IPL_LOGSYNC)
+		return ipf_sync_read(&ipfmain, uio);
+
+#ifdef IPFILTER_LOG
+	return ipf_log_read(&ipfmain, unit, uio);
+#else
+	return ENXIO;
+#endif
+}
+
+
+/*
+ * ipfwrite
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+#if (BSD >= 199306)
+static int ipfwrite(dev, uio, ioflag)
+	int ioflag;
+#else
+static int ipfwrite(dev, uio)
+#endif
+#if (__FreeBSD_version >= 502116)
+	struct cdev *dev;
+#else
+	dev_t dev;
+#endif
+	struct uio *uio;
+{
+
+	if (ipfmain.ipf_running < 1)
+		return EIO;
+
+	if (GET_MINOR(dev) == IPL_LOGSYNC)
+		return ipf_sync_write(&ipfmain, uio);
+	return ENXIO;
+}


Property changes on: trunk/contrib/ipfilter/mlfk_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mli_ipl.c
===================================================================
--- trunk/contrib/ipfilter/mli_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mli_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,683 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ * (C)opyright 1997 by Marc Boucher.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+
+/* TODO: (MARCXXX)
+	- ipl_init failure -> open ENODEV or whatever
+	- prevent multiple LKM loads
+	- surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ?
+	- m != m1 problem
+*/
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#ifdef IPFILTER_LKM
+#include <sys/mload.h>
+#endif
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#ifdef IFF_DRVRLOCK /* IRIX6 */
+#include <sys/hashing.h>
+#include <netinet/in_var.h>
+#endif
+#include <sys/mbuf.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/tcpip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ipfilter.h>
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_nat.h"
+
+#ifndef	MBUF_IS_CLUSTER
+# define	MBUF_IS_CLUSTER(m)	((m)->m_flags & MCL_CLUSTER)
+#endif
+#undef	IPFDEBUG	/* #define IPFDEBUG 9 */
+
+#ifdef IPFILTER_LKM
+u_int	ipldevflag = D_MP;
+char	*iplmversion = M_VERSION;
+#else
+u_int	ipfilterdevflag = D_MP;
+char	*ipfiltermversion = M_VERSION;
+#endif
+
+ipfmutex_t	ipl_mutex, ipfi_mutex, ipf_rw, ipf_stinsert, ipf_auth_mx;
+ipfmutex_t	ipf_nat_new, ipf_natio, ipf_timeoutlock;
+ipfrwlock_t	ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
+ipfrwlock_t	ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens;
+
+int     (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **));
+
+#ifdef IPFILTER_LKM
+static int *ipff_addr;
+static int ipff_value;
+static __psunsigned_t *ipfk_addr;
+static __psunsigned_t ipfk_code[4];
+#endif
+static void nifattach();
+static void nifdetach();
+
+typedef	struct	nif	{
+	struct	nif	*nf_next;
+	struct ifnet	*nf_ifp;
+#if (IRIX < 60500)
+	int     (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *);
+#else
+	int     (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
+			     struct rtentry *);
+#endif
+	char	nf_name[LIFNAMSIZ];
+	int	nf_unit;
+} nif_t;
+
+static nif_t *nif_head;
+static int nif_interfaces = 0;
+extern int in_interfaces;
+#if IRIX >= 60500
+toid_t	ipf_timer_id;
+#endif
+
+extern ipnat_t *nat_list;
+
+#ifdef IPFDEBUG
+static void ipf_dumppacket(m)
+	struct mbuf *m;
+{
+	u_char *s;
+	char *t, line[80];
+	int len, off, i;
+
+	off = 0;
+
+	while (m != NULL) {
+		len = M_LEN(m);
+		s = mtod(m, u_char *);
+		printf("mbuf 0x%lx len %d flags %x type %d\n",
+			m, len, m->m_flags, m->m_type);
+		printf("dat 0x%lx off 0x%lx/%d s 0x%lx next 0x%lx\n",
+			m->m_dat, m->m_off, m->m_off, s, m->m_next);
+		while (len > 0) {
+			t = line;
+			for (i = 0; (i < 16) && (len > 0); len--, i++)
+				sprintf(t, " %02x", *s++), t += strlen(t);
+			*s = '\0';
+			printf("mbuf:%x:%s\n", off, line);
+			off += 16;
+		}
+		m = m->m_next;
+	}
+}
+#endif
+
+
+static int
+#if IRIX < 60500
+ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
+#else
+ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+	      struct rtentry *rt)
+#endif
+{
+#if (IPFDEBUG >= 0)
+	static unsigned int cnt = 0;
+#endif
+	nif_t *nif;
+
+	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
+	for (nif = nif_head; nif; nif = nif->nf_next)
+		if (nif->nf_ifp == ifp)
+			break;
+	MUTEX_EXIT(&ipfi_mutex);
+
+	if (nif == NULL) {
+		printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp);
+		return ENETDOWN;
+	}
+
+#if (IPFDEBUG >= 7)
+	if ((++cnt % 200) == 0)
+		printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+
+	if (ipf_checkp) {
+		struct mbuf *m1 = m;
+		struct ip *ip;
+		int hlen;
+
+		switch(m->m_type)
+		{
+		case MT_HEADER:
+			if (m->m_len == 0) {
+				if (m->m_next == NULL)
+					break;
+				m = m->m_next;
+			}
+			/* FALLTHROUGH */
+		case MT_DATA:
+			if (!MBUF_IS_CLUSTER(m) &&
+			    ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
+#if (IPFDEBUG >= 4)
+				printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+				break;
+			}
+			if (m->m_len < sizeof(char)) {
+#if (IPFDEBUG >= 3)
+				printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags);
+#endif
+				break;
+			}
+			ip = mtod(m, struct ip *);
+			if (ip->ip_v != IPVERSION) {
+#if (IPFDEBUG >= 2)
+				ipf_dumppacket(m);
+				printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+				break;
+			}
+
+			hlen = ip->ip_hl << 2;
+			if ((*ipf_checkp)(ip, hlen, ifp, 1, &m1) || (m1 == NULL))
+				return EHOSTUNREACH;
+
+			m = m1;
+			break;
+
+		default:
+#if (IPFDEBUG >= 2)
+			printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+			break;
+		}
+	}
+#if (IRIX < 60500)
+	return (*nif->nf_output)(ifp, m, dst);
+#else
+	return (*nif->nf_output)(ifp, m, dst, rt);
+#endif
+}
+
+int
+
+
+#if !defined(IPFILTER_LKM) && (IRIX >= 60500)
+ipfilter_kernel(struct ifnet *rcvif, struct mbuf *m)
+#else
+ipl_kernel(struct ifnet *rcvif, struct mbuf *m)
+#endif
+{
+#if (IPFDEBUG >= 7)
+	static unsigned int cnt = 0;
+
+	if ((++cnt % 200) == 0)
+		printf("IP Filter: ipl_kernel(rcvif=0x%lx, m=0x%lx\n",
+			rcvif, m);
+#endif
+
+	if (ipf_running <= 0)
+		return IPF_ACCEPTIT;
+
+	/*
+	 * Check if we want to allow this packet to be processed.
+	 * Consider it to be bad if not.
+	 */
+	if (ipf_checkp) {
+		struct mbuf *m1 = m;
+		struct ip *ip;
+		int hlen;
+
+		if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) {
+#if (IPFDEBUG >= 4)
+			printf("IP Filter: ipl_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+			return IPF_ACCEPTIT;
+		}
+
+		if (!MBUF_IS_CLUSTER(m) &&
+		    ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
+#if (IPFDEBUG >= 4)
+			printf("IP Filter: ipl_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off);
+#endif
+			return IPF_ACCEPTIT;
+		}
+
+		if (m->m_len < sizeof(char)) {
+#if (IPFDEBUG >= 1)
+			printf("IP Filter: ipl_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags);
+#endif
+			return IPF_ACCEPTIT;
+		}
+
+		ip = mtod(m, struct ip *);
+		if (ip->ip_v != IPVERSION) {
+#if (IPFDEBUG >= 4)
+			printf("IP Filter: ipl_kernel: bad ip_v\n");
+#endif
+			m_freem(m);
+			return IPF_DROPIT;
+		}
+
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+		hlen = ip->ip_hl << 2;
+		if ((*ipf_checkp)(ip, hlen, rcvif, 0, &m1) || !m1)
+			return IPF_DROPIT;
+		ip = mtod(m1, struct ip *);
+		ip->ip_len = ntohs(ip->ip_len);
+		ip->ip_off = ntohs(ip->ip_off);
+
+#if (IPFDEBUG >= 2)
+		if (m != m1)
+			printf("IP Filter: ipl_kernel: m != m1\n");
+#endif
+	}
+
+	return IPF_ACCEPTIT;
+}
+
+int
+ipl_ipfilter_attach(void)
+{
+#if defined(IPFILTER_LKM)
+	__psunsigned_t *addr_ff, *addr_fk;
+
+	st_findaddr("ipfilterflag", &addr_ff);
+# if (IPFDEBUG >= 1)
+	printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff);
+# endif
+	if (!addr_ff)
+		return ESRCH;
+
+	st_findaddr("ipfilter_kernel", &addr_fk);
+# if (IPFDEBUG >= 1)
+	printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk);
+# endif
+	if (!addr_fk)
+		return ESRCH;
+
+	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
+
+	ipff_addr = (int *)addr_ff;
+
+	ipff_value = *ipff_addr;
+	*ipff_addr = 0;
+
+
+	ipfk_addr = addr_fk;
+
+	bcopy(ipfk_addr, ipfk_code, sizeof(ipfk_code));
+
+	/* write a "li t4, ipl_kernel" instruction */
+	ipfk_addr[0] = 0x3c0c0000 |
+		       (((__psunsigned_t)ipl_kernel >> 16) & 0xffff);
+	ipfk_addr[1] = 0x358c0000 |
+		       ((__psunsigned_t)ipl_kernel & 0xffff);
+	/* write a "jr t4" instruction" */
+	ipfk_addr[2] = 0x01800008;
+
+	/* write a "nop" instruction */
+	ipfk_addr[3] = 0;
+
+	icache_inval(ipfk_addr, sizeof(ipfk_code));
+
+	*ipff_addr = 1; /* enable ipfilter_kernel */
+
+	MUTEX_EXIT(&ipfi_mutex);
+#else
+	extern int ipfilterflag;
+
+	ipfilterflag = 1;
+#endif
+	nif_interfaces = 0;
+	nifattach();
+
+	return 0;
+}
+
+
+/*
+ * attach the packet filter to each non-loopback interface that is running
+ */
+static void
+nifattach()
+{
+	nif_t *nif, *qf2;
+	struct ifnet *ifp;
+	struct frentry *f;
+	ipnat_t *np;
+
+	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
+
+	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+		if ((!(ifp->if_flags & IFF_RUNNING)) ||
+			(ifp->if_flags & IFF_LOOPBACK))
+			continue;
+
+		/*
+		 * Look for entry already setup for this device
+		 */
+		for (nif = nif_head; nif; nif = nif->nf_next)
+			if (nif->nf_ifp == ifp)
+				break;
+		if (nif)
+			continue;
+
+		if (ifp->if_output == ipl_if_output) {
+			printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n",
+				ifp);
+			continue;
+		}
+#if (IPFDEBUG >= 2)
+		printf("IP Filter: nifattach nif %x opt %x\n",
+		       ifp, ifp->if_output);
+#endif
+		KMALLOC(nif, nif_t *);
+		if (!nif) {
+			printf("IP Filter: malloc(%d) for nif_t failed\n",
+			       sizeof(nif_t));
+			continue;
+		}
+
+		nif->nf_ifp = ifp;
+		(void) strncpy(nif->nf_name, ifp->if_name,
+			       sizeof(nif->nf_name));
+		nif->nf_name[sizeof(nif->nf_name) - 1] = '\0';
+		nif->nf_unit = ifp->if_unit;
+
+		nif->nf_next = nif_head;
+		nif_head = nif;
+
+		/*
+		 * Activate any rules directly associated with this interface
+		 */
+		WRITE_ENTER(&ipf_mutex);
+		for (f = ipf_rules[0][0]; f; f = f->fr_next) {
+			if ((f->fr_ifa == (struct ifnet *)-1)) {
+				if (f->fr_ifname[0] &&
+				    (GETIFP(f->fr_ifname, 4) == ifp))
+					f->fr_ifa = ifp;
+			}
+		}
+		for (f = ipf_rules[1][0]; f; f = f->fr_next) {
+			if ((f->fr_ifa == (struct ifnet *)-1)) {
+				if (f->fr_ifname[0] &&
+				    (GETIFP(f->fr_ifname, 4) == ifp))
+					f->fr_ifa = ifp;
+			}
+		}
+		RWLOCK_EXIT(&ipf_mutex);
+		WRITE_ENTER(&ipf_nat);
+		for (np = nat_list; np; np = np->in_next) {
+			if ((np->in_ifps[0] == (void *)-1)) {
+				if (np->in_ifnames[0][0] &&
+				    (GETIFP(np->in_ifnames[0], 4) == ifp))
+					np->in_ifps[0] = (void *)ifp;
+			}
+			if ((np->in_ifps[1] == (void *)-1)) {
+				if (np->in_ifnames[1][0] &&
+				    (GETIFP(np->in_ifnames[1], 4) == ifp))
+					np->in_ifps[1] = (void *)ifp;
+			}
+		}
+		RWLOCK_EXIT(&ipf_nat);
+
+		nif->nf_output = ifp->if_output;
+		ifp->if_output = ipl_if_output;
+
+#if (IPFDEBUG >= 2)
+		printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n",
+			ifp, nif->nf_output, ifp->if_output);
+#endif
+
+		printf("IP Filter: attach to [%s,%d]\n",
+			nif->nf_name, ifp->if_unit);
+	}
+	if (!nif_head)
+		printf("IP Filter: not attached to any interfaces\n");
+
+	nif_interfaces = in_interfaces;
+
+	MUTEX_EXIT(&ipfi_mutex);
+
+	return;
+}
+
+
+/*
+ * unhook the IP filter from all defined interfaces with IP addresses
+ */
+static void
+nifdetach()
+{
+	nif_t *nif, *qf2, **qp;
+	struct ifnet *ifp;
+
+	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
+	/*
+	 * Make two passes, first get rid of all the unknown devices, next
+	 * unlink known devices.
+	 */
+	for (qp = &nif_head; (nif = *qp); ) {
+		for (ifp = ifnet; ifp; ifp = ifp->if_next)
+			if (nif->nf_ifp == ifp)
+				break;
+		if (ifp) {
+			qp = &nif->nf_next;
+			continue;
+		}
+		printf("IP Filter: removing [%s]\n", nif->nf_name);
+		*qp = nif->nf_next;
+		KFREE(nif);
+	}
+
+	while ((nif = nif_head)) {
+		nif_head = nif->nf_next;
+		for (ifp = ifnet; ifp; ifp = ifp->if_next)
+			if (nif->nf_ifp == ifp)
+				break;
+		if (ifp) {
+			printf("IP Filter: detaching [%s,%d]\n",
+				nif->nf_name, ifp->if_unit);
+
+#if (IPFDEBUG >= 4)
+			printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n",
+				ifp, ifp->if_output, nif->nf_output);
+#endif
+			ifp->if_output = nif->nf_output;
+		}
+		KFREE(nif);
+	}
+	MUTEX_EXIT(&ipfi_mutex);
+
+	return;
+}
+
+
+void
+ipl_ipfilter_detach(void)
+{
+#ifdef IPFILTER_LKM
+	nifdetach();
+	MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */
+
+	if (ipff_addr) {
+		*ipff_addr = 0;
+
+		if (ipfk_addr) {
+			bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code));
+			icache_inval(ipfk_addr - 16, sizeof(ipfk_code)+32);
+		}
+
+		*ipff_addr = ipff_value;
+	}
+
+	MUTEX_EXIT(&ipfi_mutex);
+#else
+	extern int ipfilterflag;
+
+	nifdetach();
+
+	ipfilterflag = 0;
+#endif
+}
+
+
+/* this function is called from ipf_slowtimer at 500ms intervals to
+   keep our interface list in sync */
+void
+ipl_ipfilter_intfsync(void)
+{
+	MUTEX_ENTER(&ipfi_mutex);
+	if (nif_interfaces != in_interfaces) {
+		/* if the number of interfaces has changed, resync */
+		MUTEX_EXIT(&ipfi_mutex);
+		ipf_sync(&ipfmain, NULL);
+	} else
+		MUTEX_EXIT(&ipfi_mutex);
+}
+
+#ifdef IPFILTER_LKM
+/* this routine should be treated as an interrupt routine and should
+   not call any routines that would cause it to sleep, such as: biowait(),
+   sleep(), psema() or delay().
+*/
+int
+iplunload(void)
+{
+	int error = 0;
+
+	if (ipf_refcnt)
+		return EBUSY;
+
+	WRITE_ENTER(&ipf_global);
+	error = ipl_detach();
+	if (error != 0) {
+		RWLOCK_EXIT(&ipf_global);
+		return error;
+	}
+	ipf_running = -2;
+
+#if (IRIX < 60500)
+	LOCK_DEALLOC(ipl_mutex.l);
+	LOCK_DEALLOC(ipf_rw.l);
+	LOCK_DEALLOC(ipf_auth.l);
+	LOCK_DEALLOC(ipf_natfrag.l);
+	LOCK_DEALLOC(ipf_ipidfrag.l);
+	LOCK_DEALLOC(ipf_tokens.l);
+	LOCK_DEALLOC(ipf_stinsert.l);
+	LOCK_DEALLOC(ipf_nat_new.l);
+	LOCK_DEALLOC(ipf_natio.l);
+	LOCK_DEALLOC(ipf_nat.l);
+	LOCK_DEALLOC(ipf_state.l);
+	LOCK_DEALLOC(ipf_frag.l);
+	LOCK_DEALLOC(ipf_auth_mx.l);
+	LOCK_DEALLOC(ipf_mutex.l);
+	LOCK_DEALLOC(ipf_frcache.l);
+	LOCK_DEALLOC(ipfi_mutex.l);
+	RWLOCK_EXIT(&ipf_global);
+	LOCK_DEALLOC(ipf_global.l);
+#else
+	MUTEX_DESTROY(&ipf_rw);
+	MUTEX_DESTROY(&ipfi_mutex);
+	MUTEX_DESTROY(&ipf_timeoutlock);
+	RW_DESTROY(&ipf_mutex);
+	RW_DESTROY(&ipf_frcache);
+	RW_DESTROY(&ipf_tokens);
+	RWLOCK_EXIT(&ipf_global);
+	delay(hz);
+	RW_DESTROY(&ipf_global);
+#endif
+
+	printf("%s unloaded\n", ipfilter_version);
+
+	delay(hz);
+
+	return 0;
+}
+#endif
+
+void
+ipfilterinit(void)
+{
+#ifdef IPFILTER_LKM
+	int error;
+#endif
+
+#if (IRIX < 60500)
+	ipfi_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ipf_frcache.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ipf_timeoutlock.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_global.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_stinsert.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_ipidfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_tokens.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+	ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+
+	if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_timeoutlock.l ||
+	    !ipf_frag.l || !ipf_state.l || !ipf_nat.l || !ipf_natfrag.l ||
+	    !ipf_auth.l || !ipf_rw.l || !ipf_ipidfrag.l || !ipl_mutex.l ||
+	    !ipf_stinsert.l || !ipf_auth_mx.l || !ipf_frcache.l ||
+	    !ipf_tokens.l)
+		panic("IP Filter: LOCK_ALLOC failed");
+#else
+	MUTEX_INIT(&ipf_rw, "ipf rw mutex");
+	MUTEX_INIT(&ipf_timeoutlock, "ipf timeout mutex");
+	RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
+	RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
+	RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
+#endif
+
+#ifdef IPFILTER_LKM
+	error = ipl_attach();
+	if (error) {
+		iplunload();
+	} else {
+		char *defpass;
+
+		if (FR_ISPASS(ipf_pass))
+			defpass = "pass";
+		else if (FR_ISBLOCK(ipf_pass))
+			defpass = "block";
+		else
+			defpass = "no-match -> block";
+
+		printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+			ipfilter_version, defpass,
+# ifdef  IPFILTER_LOG
+			"enabled",
+# else
+			"disabled",
+# endif
+# ifdef IPFILTER_COMPILED
+		" (COMPILED)"
+# else
+		""
+# endif
+		);
+	}
+#endif
+
+	return;
+}


Property changes on: trunk/contrib/ipfilter/mli_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mln_ipl.c
===================================================================
--- trunk/contrib/ipfilter/mln_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mln_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,355 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+/*
+ * 29/12/94 Added code from Marc Huber <huber at fzi.de> to allow it to allocate
+ * its own major char number! Way cool patch!
+ */
+
+
+#include <sys/param.h>
+
+/*
+ * Post NetBSD 1.2 has the PFIL interface for packet filters.  This turns
+ * on those hooks.  We don't need any special mods with this!
+ */
+#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
+    (defined(NetBSD1_2) && NetBSD1_2 > 1)
+# define NETBSD_PF
+#endif
+
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/vnode.h>
+#include <sys/namei.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/exec.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <sys/lkm.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_auth.h"
+#include "ip_state.h"
+#include "ip_nat.h"
+#include "ip_sync.h"
+
+#if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 103050000
+#define vn_lock(v,f) VOP_LOCK(v)
+#endif
+
+#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
+#define	VOP_LEASE	LEASE_CHECK
+#endif
+
+
+extern	int	lkmenodev __P((void));
+
+#if NetBSD >= 199706
+int	ipflkm_lkmentry __P((struct lkm_table *, int, int));
+#else
+int	xxxinit __P((struct lkm_table *, int, int));
+#endif
+static	int	ipf_unload __P((void));
+static	int	ipf_load __P((void));
+static	int	ipf_remove __P((void));
+static	int	ipfaction __P((struct lkm_table *, int));
+static	char	*ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
+				    IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
+				    IPLOOKUP_NAME, NULL };
+
+int				ipf_major = 0;
+extern	ipf_main_softc_t	ipfmain;
+extern	const struct cdevsw ipl_cdevsw;
+
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
+MOD_DEV(IPL_VERSION, "ipf", NULL, -1, &ipl_cdevsw, -1);
+#else
+MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
+#endif
+
+extern int vd_unuseddev __P((void));
+extern struct cdevsw cdevsw[];
+extern int nchrdev;
+
+
+int
+#if NetBSD >= 199706
+ipflkm_lkmentry(lkmtp, cmd, ver)
+#else
+xxxinit(lkmtp, cmd, ver)
+#endif
+	struct lkm_table *lkmtp;
+	int cmd, ver;
+{
+	DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction);
+}
+
+
+static int
+ipfaction(lkmtp, cmd)
+	struct lkm_table *lkmtp;
+	int cmd;
+{
+#if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000)
+	int i;
+#endif
+	struct lkm_dev *args = lkmtp->private.lkm_dev;
+	int err = 0;
+
+	switch (cmd)
+	{
+	case LKM_E_LOAD :
+		if (lkmexists(lkmtp))
+			return EEXIST;
+
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
+# if (__NetBSD_Version__ < 200000000)
+		err = devsw_attach(args->lkm_devname,
+				   args->lkm_bdev, &args->lkm_bdevmaj,
+				   args->lkm_cdev, &args->lkm_cdevmaj);
+		if (err != 0)
+			return (err);
+# endif
+		ipf_major = args->lkm_cdevmaj;
+#else
+		for (i = 0; i < nchrdev; i++)
+			if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev ||
+			    cdevsw[i].d_open == ipfopen)
+				break;
+		if (i == nchrdev) {
+			printf("IP Filter: No free cdevsw slots\n");
+			return ENODEV;
+		}
+
+		ipf_major = i;
+		args->lkm_offset = i;   /* slot in cdevsw[] */
+#endif
+		printf("IP Filter: loaded into slot %d\n", ipf_major);
+		return ipf_load();
+	case LKM_E_UNLOAD :
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
+		devsw_detach(args->lkm_bdev, args->lkm_cdev);
+		args->lkm_bdevmaj = -1;
+		args->lkm_cdevmaj = -1;
+#endif
+		err = ipf_unload();
+		if (!err)
+			printf("IP Filter: unloaded from slot %d\n",
+			       ipf_major);
+		break;
+	case LKM_E_STAT :
+		break;
+	default:
+		err = EIO;
+		break;
+	}
+	return err;
+}
+
+
+static int
+ipf_remove()
+{
+	char *name;
+	struct nameidata nd;
+	int error, i;
+
+        for (i = 0; (name = ipf_devfiles[i]); i++) {
+#if (__NetBSD_Version__ > 106009999)
+# if (__NetBSD_Version__ > 399001400)
+#  if (__NetBSD_Version__ > 499001400)
+		NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE,
+		       name);
+#  else
+		NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE,
+		       name, curlwp);
+#  endif
+# else
+		NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE,
+		       name, curproc);
+# endif
+#else
+		NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+#endif
+		if ((error = namei(&nd)))
+			return (error);
+#if (__NetBSD_Version__ > 399001400)
+# if (__NetBSD_Version__ > 399002000)
+#  if (__NetBSD_Version__ < 499001400)
+		VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_cred, LEASE_WRITE);
+#  endif
+# else
+		VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE);
+# endif
+#else
+		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+#endif
+#if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000)
+		vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
+#endif
+#if (__NetBSD_Version__ >= 399002000)
+# if (__NetBSD_Version__ < 499001400)
+		VOP_LEASE(nd.ni_vp, curlwp, curlwp->l_cred, LEASE_WRITE);
+# endif
+#else
+# if (__NetBSD_Version__ > 399001400)
+		VOP_LEASE(nd.ni_vp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE);
+# else
+		VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
+# endif
+#endif
+		(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+	}
+	return 0;
+}
+
+
+static int
+ipf_unload()
+{
+	int error = 0;
+
+	/*
+	 * Unloading - remove the filter rule check from the IP
+	 * input/output stream.
+	 */
+	if (ipfmain.ipf_refcnt)
+		error = EBUSY;
+	else if (ipfmain.ipf_running >= 0) {
+		error = ipfdetach(&ipfmain);
+		if (error == 0) {
+			ipf_destroy_all(&ipfmain);
+			ipf_unload_all();
+		}
+	}
+
+	if (error == 0) {
+		ipfmain.ipf_running = -2;
+		error = ipf_remove();
+		printf("%s unloaded\n", ipfilter_version);
+	}
+	return error;
+}
+
+
+static int
+ipf_load()
+{
+	struct nameidata nd;
+	struct vattr vattr;
+	int error = 0, fmode = S_IFCHR|0600, i;
+	char *name;
+
+	/*
+	 * XXX Remove existing device nodes prior to creating new ones
+	 * XXX using the assigned LKM device slot's major number.  In a
+	 * XXX perfect world we could use the ones specified by cdevsw[].
+	 */
+	(void)ipf_remove();
+
+	bzero((char *)&ipfmain, sizeof(ipfmain));
+        error = ipf_load_all();
+	if (error != 0)
+		return error;
+	if (ipf_create_all(&ipfmain) == NULL) {
+		ipf_unload_all();
+		return EIO;
+	}
+
+	error = ipfattach(&ipfmain);
+	if (error != 0) {
+		(void) ipf_unload();
+		return error;
+	}
+
+	for (i = 0; (error == 0) && (name = ipf_devfiles[i]); i++) {
+#if (__NetBSD_Version__ > 399001400)
+# if (__NetBSD_Version__ > 499001400)
+		NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name);
+# else
+		NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curlwp);
+# endif
+#else
+		NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+#endif
+		if ((error = namei(&nd)))
+			break;
+		if (nd.ni_vp != NULL) {
+			VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+			if (nd.ni_dvp == nd.ni_vp)
+				vrele(nd.ni_dvp);
+			else
+				vput(nd.ni_dvp);
+			vrele(nd.ni_vp);
+			error = EEXIST;
+			break;
+		}
+		VATTR_NULL(&vattr);
+		vattr.va_type = VCHR;
+		vattr.va_mode = (fmode & 07777);
+		vattr.va_rdev = (ipf_major << 8) | i;
+#if (__NetBSD_Version__ > 399001400)
+# if (__NetBSD_Version__ >= 399002000)
+#  if (__NetBSD_Version__ < 499001400)
+		VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_cred, LEASE_WRITE);
+#  endif
+# else
+		VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE);
+# endif
+#else
+		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+#endif
+		error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
+		if (error == 0)
+			vput(nd.ni_vp);
+	}
+
+	if (error == 0) {
+		char *defpass;
+
+		if (FR_ISPASS(ipfmain.ipf_pass))
+			defpass = "pass";
+		else if (FR_ISBLOCK(ipfmain.ipf_pass))
+			defpass = "block";
+		else
+			defpass = "no-match -> block";
+
+		printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+			ipfilter_version, defpass,
+#ifdef IPFILTER_LOG
+			"enabled",
+#else
+			"disabled",
+#endif
+#ifdef IPFILTER_COMPILED
+			" (COMPILED)"
+#else
+			""
+#endif
+			);
+		ipfmain.ipf_running = 1;
+	}
+	return error;
+}


Property changes on: trunk/contrib/ipfilter/mln_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mln_rule.c
===================================================================
--- trunk/contrib/ipfilter/mln_rule.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mln_rule.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/exec.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <sys/lkm.h>
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_rules.h"
+
+
+static int ipfruleaction __P((struct lkm_table *, int));
+
+#ifdef IPFILTER_LKM
+# if NetBSD >= 199706
+int	ipfrule_lkmentry __P((struct lkm_table *, int, int));
+# else
+int	xxxinit __P((struct lkm_table *, int, int));
+# endif
+
+
+MOD_MISC("IPFilter Rules");
+
+# if NetBSD >= 199706
+int ipfrule_lkmentry(lkmtp, cmd, ver)
+# else
+int xxxinit(lkmtp, cmd, ver)
+# endif
+	struct lkm_table *lkmtp;
+	int cmd, ver;
+{
+	DISPATCH(lkmtp, cmd, ver, ipfruleaction, ipfruleaction, ipfruleaction);
+}
+
+static int ipfruleaction(lkmtp, cmd)
+	struct lkm_table *lkmtp;
+	int cmd;
+{
+	int err = 0;
+
+	switch (cmd)
+	{
+	case LKM_E_LOAD :
+		if (lkmexists(lkmtp))
+			return EEXIST;
+
+		err = ipfrule_add();
+		if (!err)
+			ipf_refcnt++;
+		break;
+	case LKM_E_UNLOAD :
+		err = ipfrule_remove();
+		if (!err)
+			ipf_refcnt--;
+		break;
+	case LKM_E_STAT :
+		break;
+	default:
+		err = EIO;
+		break;
+	}
+	return err;
+}
+#endif /* IPFILTER_LKM */


Property changes on: trunk/contrib/ipfilter/mln_rule.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mlo_ipl.c
===================================================================
--- trunk/contrib/ipfilter/mlo_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mlo_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,364 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/vnode.h>
+#include <sys/namei.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/exec.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <sys/lkm.h>
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
+
+#define vn_lock(v,f) VOP_LOCK(v)
+
+#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
+#define	VOP_LEASE	LEASE_CHECK
+#endif
+
+
+extern	int	lkmenodev __P((void));
+
+#if OpenBSD >= 200311
+int	if_ipf_lkmentry __P((struct lkm_table *, int, int));
+#else
+int	if_ipf __P((struct lkm_table *, int, int));
+#endif
+static	int	ipf_unload __P((void));
+static	int	ipf_load __P((void));
+static	int	ipf_remove __P((void));
+static	int	ipfaction __P((struct lkm_table *, int));
+static	char	*ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
+				    IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
+				    IPLOOKUP_NAME, NULL };
+
+
+struct	cdevsw	ipfdevsw =
+{
+	ipfopen,		/* open */
+	ipfclose,		/* close */
+	ipfread,		/* read */
+	(void *)nullop,		/* write */
+	ipfioctl,		/* ioctl */
+	(void *)nullop,		/* stop */
+	(void *)NULL,		/* tty */
+	(void *)nullop,		/* select */
+	(void *)nullop,		/* mmap */
+	NULL			/* strategy */
+};
+
+int	ipf_major = 0;
+
+MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipfdevsw);
+
+extern int vd_unuseddev __P((void));
+extern struct cdevsw cdevsw[];
+extern int nchrdev;
+
+
+#if OpenBSD >= 200311
+int if_ipf_lkmentry (lkmtp, cmd, ver)
+#else
+int if_ipf(lkmtp, cmd, ver)
+#endif
+	struct lkm_table *lkmtp;
+	int cmd, ver;
+{
+	DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction);
+}
+
+int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */
+
+static int ipfaction(lkmtp, cmd)
+	struct lkm_table *lkmtp;
+	int cmd;
+{
+	int i;
+	struct lkm_dev *args = lkmtp->private.lkm_dev;
+	int err = 0;
+
+	switch (cmd)
+	{
+	case LKM_E_LOAD :
+		if (lkmexists(lkmtp))
+			return EEXIST;
+
+		for (i = 0; i < nchrdev; i++)
+			if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev ||
+			    cdevsw[i].d_open == ipfopen)
+				break;
+		if (i == nchrdev) {
+			printf("IP Filter: No free cdevsw slots\n");
+			return ENODEV;
+		}
+
+		ipf_major = i;
+		args->lkm_offset = i;   /* slot in cdevsw[] */
+		printf("IP Filter: loaded into slot %d\n", ipf_major);
+		return ipf_load();
+	case LKM_E_UNLOAD :
+		err = ipf_unload();
+		if (!err)
+			printf("IP Filter: unloaded from slot %d\n",
+			       ipf_major);
+		break;
+	case LKM_E_STAT :
+		break;
+	default:
+		err = EIO;
+		break;
+	}
+	return err;
+}
+
+
+static int ipf_remove()
+{
+	struct nameidata nd;
+	int error, i;
+	char *name;
+
+        for (i = 0; (name = ipf_devfiles[i]); i++) {
+#if OpenBSD >= 200311
+		NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE,
+		       name, curproc);
+#else
+		NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+#endif
+		if ((error = namei(&nd)))
+			return (error);
+		VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
+#if OpenBSD < 200311
+		VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc);
+		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+#else
+		(void)uvm_vnp_uncache(nd.ni_vp);
+
+		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+		VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
+#endif
+		(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+	}
+	return 0;
+}
+
+
+static int ipf_unload()
+{
+	int error = 0;
+
+	/*
+	 * Unloading - remove the filter rule check from the IP
+	 * input/output stream.
+	 */
+        if (ipf_refcnt)
+                error = EBUSY;
+	else if (ipf_running >= 0)
+		error = ipfdetach();
+
+	if (error == 0) {
+		ipf_running = -2;
+		error = ipf_remove();
+		printf("%s unloaded\n", ipfilter_version);
+	}
+	return error;
+}
+
+
+static int ipf_load()
+{
+	struct nameidata nd;
+	struct vattr vattr;
+	int error = 0, fmode = S_IFCHR|0600, i;
+	char *name;
+
+	/*
+	 * XXX Remove existing device nodes prior to creating new ones
+	 * XXX using the assigned LKM device slot's major number.  In a
+	 * XXX perfect world we could use the ones specified by cdevsw[].
+	 */
+	(void)ipf_remove();
+
+	error = ipfattach();
+
+	for (i = 0; (error == 0) && (name = ipf_devfiles[i]); i++) {
+		NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+		if ((error = namei(&nd)))
+			break;
+		if (nd.ni_vp != NULL) {
+			VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+			if (nd.ni_dvp == nd.ni_vp)
+				vrele(nd.ni_dvp);
+			else
+				vput(nd.ni_dvp);
+			vrele(nd.ni_vp);
+			error = EEXIST;
+			break;
+		}
+		VATTR_NULL(&vattr);
+		vattr.va_type = VCHR;
+		vattr.va_mode = (fmode & 07777);
+		vattr.va_rdev = (ipf_major << 8) | i;
+		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+		error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
+	}
+
+	if (error == 0) {
+		char *defpass;
+
+		if (FR_ISPASS(ipf_pass))
+			defpass = "pass";
+		else if (FR_ISBLOCK(ipf_pass))
+			defpass = "block";
+		else
+			defpass = "no-match -> block";
+
+		printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+			ipfilter_version, defpass,
+#ifdef IPFILTER_LOG
+			"enabled",
+#else
+			"disabled",
+#endif
+#ifdef IPFILTER_COMPILED
+			" (COMPILED)"
+#else
+			""
+#endif
+			);
+		ipf_running = 1;
+	}
+	return error;
+}
+
+
+/*
+ * routines below for saving IP headers to buffer
+ */
+int
+ipfopen(dev, flags, devtype, p)
+	dev_t dev;
+	int flags;
+	int devtype;
+	struct proc *p;
+{
+	u_int min = GET_MINOR(dev);
+	int error;
+
+	if (IPL_LOGMAX < min) {
+		error = ENXIO;
+	} else {
+		switch (unit)
+		{
+		case IPL_LOGIPF :
+		case IPL_LOGNAT :
+		case IPL_LOGSTATE :
+		case IPL_LOGAUTH :
+		case IPL_LOGLOOKUP :
+		case IPL_LOGSYNC :
+#ifdef IPFILTER_SCAN
+		case IPL_LOGSCAN :
+#endif
+			error = 0;
+			break;
+		default :
+			error = ENXIO;
+			break;
+		}
+	}
+	return error;
+}
+
+
+int
+ipfclose(dev, flags, devtype, p)
+	dev_t dev;
+	int flags;
+	int devtype;
+	struct proc *p;
+{
+	u_int   min = GET_MINOR(dev);
+
+	if (IPL_LOGMAX < min)
+		min = ENXIO;
+	else
+		min = 0;
+	return min;
+}
+
+
+/*
+ * ipfread/ipflog
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+int
+ipfread(dev, uio, ioflag)
+	dev_t dev;
+	register struct uio *uio;
+	int ioflag;
+{
+
+	if (ipf_running < 1)
+		return EIO;
+
+	if (GET_MINOR(dev) == IPL_LOGSYNC)
+		return ipfsync_read(uio);
+
+#ifdef IPFILTER_LOG
+	return ipflog_read(GET_MINOR(dev), uio);
+#else
+	return ENXIO;
+#endif
+}
+
+
+/*
+ * ipfwrite
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+int
+#if (BSD >= 199306)
+ipfwrite(dev, uio, ioflag)
+	int ioflag;
+#else
+ipfwrite(dev, uio)
+#endif
+	dev_t dev;
+	register struct uio *uio;
+{
+
+	if (ipf_running < 1)
+		return EIO;
+
+	if (GET_MINOR(dev) == IPL_LOGSYNC)
+		return ipfsync_write(uio);
+	return ENXIO;
+}


Property changes on: trunk/contrib/ipfilter/mlo_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mlo_rule.c
===================================================================
--- trunk/contrib/ipfilter/mlo_rule.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mlo_rule.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,80 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/exec.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <sys/lkm.h>
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_rules.h"
+
+
+#ifdef	IPFILTER_LKM
+
+static int ipfruleaction __P((struct lkm_table *, int));
+
+int	ipfrule __P((struct lkm_table *, int, int));
+
+
+MOD_MISC("IPFilter Rules");
+
+int ipfrule(lkmtp, cmd, ver)
+	struct lkm_table *lkmtp;
+	int cmd, ver;
+{
+	DISPATCH(lkmtp, cmd, ver, ipfruleaction, ipfruleaction, ipfruleaction);
+}
+
+int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */
+
+static int ipfruleaction(lkmtp, cmd)
+	struct lkm_table *lkmtp;
+	int cmd;
+{
+	int err = 0;
+
+	switch (cmd)
+	{
+	case LKM_E_LOAD :
+		if (lkmexists(lkmtp))
+			return EEXIST;
+
+		err = ipfrule_add();
+		if (!err)
+			ipf_refcnt++;
+		break;
+	case LKM_E_UNLOAD :
+		err = ipfrule_remove();
+		if (!err)
+			ipf_refcnt--;
+		break;
+	case LKM_E_STAT :
+		break;
+	default:
+		err = EIO;
+		break;
+	}
+	return err;
+}
+#endif	/* IPFILTER_LKM */


Property changes on: trunk/contrib/ipfilter/mlo_rule.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mls_ipl.c
===================================================================
--- trunk/contrib/ipfilter/mls_ipl.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mls_ipl.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,351 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+/*
+ * 29/12/94 Added code from Marc Huber <huber at fzi.de> to allow it to allocate
+ * its own major char number! Way cool patch!
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/conf.h>
+#include <sys/syslog.h>
+#include <sys/buf.h>
+#include <sys/mbuf.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+#include <sundev/mbvar.h>
+#include <sun/autoconf.h>
+#include <sun/vddrv.h>
+#if defined(sun4c) || defined(sun4m)
+# include <sun/openprom.h>
+#endif
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <net/if.h>
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
+
+
+#if !defined(lint)
+static const char sccsid[] = "@(#)mls_ipl.c	2.6 10/15/95 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$Id$";
+#endif
+
+extern	int	ipfdetach __P((void));
+#ifndef	IPFILTER_LOG
+#define	ipfread	nulldev
+#endif
+extern	int	nulldev __P((void));
+extern	int	errno;
+
+extern int nodev __P((void));
+
+static	int	unload __P((void));
+static	int	ipf_attach __P((void));
+int	xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *));
+static	char	*ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
+				    IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
+				    IPLOOKUP_NAME, NULL };
+static	int	ipfopen __P((dev_t, int));
+static	int	ipfclose __P((dev_t, int));
+static	int	ipfread __P((dev_t, struct uio *));
+static	int	ipfwrite __P((dev_t, struct uio *));
+
+
+struct	cdevsw	ipfdevsw =
+{
+	ipfopen, ipfclose, ipfread, nulldev,
+	ipfioctl, nulldev, nulldev, nulldev,
+	0, nulldev,
+};
+
+
+struct	dev_ops	ipf_ops =
+{
+	1,
+	ipfidentify,
+	ipfattach,
+	ipfopen,
+	ipfclose,
+	ipfread,
+	ipfwrite,
+	NULL,		/* strategy */
+	NULL,		/* dump */
+	0,		/* psize */
+        ipfioctl,
+	NULL,		/* reset */
+	NULL		/* mmap */
+};
+
+int	ipf_major = 0;
+
+#ifdef sun4m
+struct	vdldrv	vd =
+{
+	VDMAGIC_PSEUDO,
+	IPL_VERSION,
+	&ipf_ops,
+	NULL,
+	&ipfdevsw,
+	0,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	0,
+	1,
+};
+#else /* sun4m */
+struct vdldrv vd =
+{
+	VDMAGIC_PSEUDO,	/* magic */
+	IPL_VERSION,
+#ifdef sun4c
+	&ipf_ops,	/* dev_ops */
+#else
+	NULL,		/* struct mb_ctlr *mb_ctlr */
+	NULL,		/* struct mb_driver *mb_driver */
+	NULL,		/* struct mb_device *mb_device */
+	0,		/* num ctlrs */
+	1,		/* numdevs */
+#endif /* sun4c */
+	NULL,		/* bdevsw */
+	&ipfdevsw,	/* cdevsw */
+	0,		/* block major */
+	0,		/* char major */
+};
+#endif /* sun4m */
+
+extern int vd_unuseddev __P((void));
+extern struct cdevsw cdevsw[];
+extern int nchrdev;
+
+xxxinit(fc, vdp, data, vds)
+	u_int	fc;
+	struct	vddrv	*vdp;
+	caddr_t	data;
+	struct	vdstat	*vds;
+{
+	struct vdioctl_load *vdi = (struct vdioctl_load *)data;
+
+	switch (fc)
+	{
+	case VDLOAD:
+	    {
+		struct vdconf *vdc;
+		if (vdi && vdi->vdi_userconf)
+			for (vdc = vdi->vdi_userconf; vdc->vdc_type; vdc++)
+				if (vdc->vdc_type == VDCCHARMAJOR) {
+					ipf_major = vdc->vdc_data;
+					break;
+				}
+
+		if (!ipf_major) {
+			while (ipf_major < nchrdev &&
+			       cdevsw[ipf_major].d_open != vd_unuseddev)
+				ipf_major++;
+			if (ipf_major == nchrdev)
+				return ENODEV;
+		}
+		vdp->vdd_vdtab = (struct vdlinkage *)&vd;
+		vd.Drv_charmajor = ipf_major;
+		return ipf_attach();
+	    }
+	case VDUNLOAD:
+		return unload();
+	case VDSTAT:
+		return 0;
+	default:
+		return EIO;
+	}
+}
+
+
+static int
+unload()
+{
+	int err = 0, i;
+	char *name;
+
+	if (ipf_refcnt != 0)
+		err = EBUSY;
+	else if (ipf_running >= 0)
+		err = ipfdetach();
+	if (err)
+		return err;
+
+	ipf_running = -2;
+	for (i = 0; (name = ipf_devfiles[i]); i++)
+		(void) vn_remove(name, UIO_SYSSPACE, FILE);
+	printf("%s unloaded\n", ipfilter_version);
+	return 0;
+}
+
+
+static int
+ipf_attach()
+{
+	struct vnode *vp;
+	struct vattr vattr;
+	int error = 0, fmode = S_IFCHR|0600, i;
+	char *name;
+
+	error = ipfattach();
+	if (error)
+		return error;
+
+        for (i = 0; (name = ipf_devfiles[i]); i++) {
+		(void) vn_remove(name, UIO_SYSSPACE, FILE);
+		vattr_null(&vattr);
+		vattr.va_type = MFTOVT(fmode);
+		vattr.va_mode = (fmode & 07777);
+		vattr.va_rdev = (ipf_major << 8) | i;
+
+		error = vn_create(name, UIO_SYSSPACE, &vattr, EXCL, 0, &vp);
+		if (error) {
+			printf("IP Filter: vn_create(%s) = %d\n", name, error);
+			break;
+		} else {
+			VN_RELE(vp);
+		}
+	}
+
+	if (error == 0) {
+		char *defpass;
+
+		if (FR_ISPASS(ipf_pass))
+			defpass = "pass";
+		else if (FR_ISBLOCK(ipf_pass))
+			defpass = "block";
+		else
+			defpass = "no-match -> block";
+
+		printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+			ipfilter_version, defpass,
+#ifdef IPFILTER_LOG
+			"enabled",
+#else
+			"disabled",
+#endif
+#ifdef IPFILTER_COMPILED
+			" (COMPILED)"
+#else
+			""
+#endif
+			);
+		ipf_running = 1;
+	}
+	return error;
+}
+
+
+/*
+ * routines below for saving IP headers to buffer
+ */
+static int
+ipfopen(dev, flags)
+	dev_t dev;
+	int flags;
+{
+	u_int unit = GET_MINOR(dev);
+	int error;
+
+	if (IPL_LOGMAX < unit) {
+		error = ENXIO;
+	} else {
+		switch (unit)
+		{
+		case IPL_LOGIPF :
+		case IPL_LOGNAT :
+		case IPL_LOGSTATE :
+		case IPL_LOGAUTH :
+		case IPL_LOGLOOKUP :
+		case IPL_LOGSYNC :
+#ifdef IPFILTER_SCAN
+		case IPL_LOGSCAN :
+#endif
+			error = 0;
+			break;
+		default :
+			error = ENXIO;
+			break;
+		}
+	}
+	return error;
+}
+
+
+static int
+ipfclose(dev, flags)
+	dev_t dev;
+	int flags;
+{
+	u_int	unit = GET_MINOR(dev);
+
+	if (IPL_LOGMAX < unit)
+		unit = ENXIO;
+	else
+		unit = 0;
+	return unit;
+}
+
+
+/*
+ * ipfread/ipflog
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+static int
+ipfread(dev, uio)
+	dev_t dev;
+	register struct uio *uio;
+{
+
+	if (ipf_running < 1) {
+		ipfmain.ipf_interror = 130006;
+		return EIO;
+	}
+
+#ifdef IPFILTER_LOG
+	return ipflog_read(GET_MINOR(dev), uio);
+#else
+	ipfmain.ipf_interror = 130007;
+	return ENXIO;
+#endif
+}
+
+
+/*
+ * ipfwrite
+ */
+static int
+ipfwrite(dev, uio)
+	dev_t dev;
+	register struct uio *uio;
+{
+
+	if (ipf_running < 1) {
+		ipfmain.ipf_interror = 130008;
+		return EIO;
+	}
+
+	if (getminor(dev) == IPL_LOGSYNC)
+		return ipfsync_write(uio);
+	ipfmain.ipf_interror = 130009;
+	return ENXIO;
+}


Property changes on: trunk/contrib/ipfilter/mls_ipl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mls_rule.c
===================================================================
--- trunk/contrib/ipfilter/mls_rule.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mls_rule.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,116 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+/*
+ * 29/12/94 Added code from Marc Huber <huber at fzi.de> to allow it to allocate
+ * its own major char number! Way cool patch!
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/conf.h>
+#include <sys/syslog.h>
+#include <sys/buf.h>
+#include <sys/mbuf.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+#include <sundev/mbvar.h>
+#include <sun/autoconf.h>
+#include <sun/vddrv.h>
+#if defined(sun4c) || defined(sun4m)
+# include <sun/openprom.h>
+#endif
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <net/if.h>
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_rules.h"
+
+
+extern	int	errno;
+
+
+int	xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *));
+
+int	ipl_major = 0;
+
+#ifdef sun4m
+struct	vdldrv	vd =
+{
+	VDMAGIC_USER,
+	"IP Filter rules",
+	NULL,
+	NULL,
+	NULL,
+	0,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	0,
+	1,
+};
+#else /* sun4m */
+struct vdldrv vd =
+{
+	VDMAGIC_USER,	/* magic */
+	"IP Filter rules",
+#ifdef sun4c
+	NULL,	/* dev_ops */
+#else
+	NULL,		/* struct mb_ctlr *mb_ctlr */
+	NULL,		/* struct mb_driver *mb_driver */
+	NULL,		/* struct mb_device *mb_device */
+	0,		/* num ctlrs */
+	1,		/* numdevs */
+#endif /* sun4c */
+	NULL,		/* bdevsw */
+	NULL,		/* cdevsw */
+	0,		/* block major */
+	0,		/* char major */
+};
+#endif /* sun4m */
+
+
+xxxinit(fc, vdp, data, vds)
+	u_int	fc;
+	struct	vddrv	*vdp;
+	caddr_t	data;
+	struct	vdstat	*vds;
+{
+	struct vdioctl_load *vdi = (struct vdioctl_load *)data;
+	int err;
+
+	switch (fc)
+	{
+	case VDLOAD:
+		err = ipfrule_add();
+		if (!err)
+			ipf_refcnt++;
+		break;
+	case VDUNLOAD:
+		err = ipfrule_remove();
+		if (!err)
+			ipf_refcnt--;
+		break;
+	case VDSTAT:
+		err = 0;
+		break;
+	default:
+		err = EIO;
+		break;
+	}
+}


Property changes on: trunk/contrib/ipfilter/mls_rule.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/mlso_rule.c
===================================================================
--- trunk/contrib/ipfilter/mlso_rule.c	                        (rev 0)
+++ trunk/contrib/ipfilter/mlso_rule.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,130 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#pragma ident "@(#)$Id$"
+
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/modctl.h>
+#include <sys/open.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/cred.h>
+#include <sys/dditypes.h>
+#include <sys/stream.h>
+#include <sys/poll.h>
+#include <sys/autoconf.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/dlpi.h>
+#include <sys/stropts.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#if SOLARIS2 >= 6
+# include <net/if_types.h>
+#endif
+#include <net/af.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/tcpip.h>
+#include <netinet/ip_icmp.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_rules.h"
+
+char	_depends_on[] = "drv/ipf";
+
+
+extern	ipf_main_softc_t	ipfmain;
+extern	struct mod_ops		mod_miscops;
+static	struct modlmisc		ipfrulemod = {
+		&mod_miscops,
+		"IP Filter rules"
+};
+
+static	struct modlinkage	modlink1 = {
+		MODREV_1,
+		&ipfrulemod,
+		NULL
+};
+
+
+int _init()
+{
+	int ipfruleinst;
+
+	ipfruleinst = mod_install(&modlink1);
+#ifdef	IPFRULEDEBUG
+	cmn_err(CE_NOTE, "IP Filter Rules: _init() = %d", ipfruleinst);
+#endif
+
+	if (ipfruleinst == 0) {
+		if (ipfmain.ipf_running >= 0) {
+			ipfruleinst = ipfrule_add();
+			if (!ipfruleinst)
+				ipfmain.ipf_refcnt++;
+			else {
+				cmn_err(CE_NOTE,
+					"IP Filter Rules: ipfrule_add failed");
+				ipfruleinst = -1;
+			}
+		} else
+			ipfruleinst = -1;
+	}
+	if (ipfruleinst == 0)
+		cmn_err(CE_CONT, "IP Filter Rules: loaded\n");
+	return ipfruleinst;
+}
+
+
+int _fini(void)
+{
+	int ipfruleinst;
+
+	ipfruleinst = mod_remove(&modlink1);
+#ifdef	IPFRULEDEBUG
+	cmn_err(CE_NOTE, "IP Filter Rules: _fini() = %d", ipfruleinst);
+#endif
+	if (ipfruleinst == 0) {
+		ipfruleinst = ipfrule_remove();
+		if (!ipfruleinst)
+			ipfmain.ipf_refcnt--;
+		else
+			ipfruleinst = -1;
+	}
+	if (ipfruleinst == 0)
+		cmn_err(CE_CONT, "IP Filter Rules: unloaded\n");
+	return ipfruleinst;
+}
+
+
+int _info(modinfop)
+	struct modinfo *modinfop;
+{
+	int ipfruleinst;
+
+	ipfruleinst = mod_info(&modlink1, modinfop);
+#ifdef	IPFRULEDEBUG
+	cmn_err(CE_NOTE, "IP Filter Rules: _info(%x) = %x",
+		modinfop, ipfruleinst);
+#endif
+	return ipfruleinst;
+}


Property changes on: trunk/contrib/ipfilter/mlso_rule.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/radix_ipf.c
===================================================================
--- trunk/contrib/ipfilter/radix_ipf.c	                        (rev 0)
+++ trunk/contrib/ipfilter/radix_ipf.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,1528 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#if !defined(_KERNEL)
+# include <stddef.h>
+# include <stdlib.h>
+# include <strings.h>
+# include <string.h>
+#endif
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#ifdef RDX_DEBUG
+# include <arpa/inet.h>
+# include <stdlib.h>
+# include <stdio.h>
+#endif
+#include "netinet/radix_ipf.h"
+
+#define	ADF_OFF	offsetof(addrfamily_t, adf_addr)
+#define	ADF_OFF_BITS	(ADF_OFF << 3)
+
+static ipf_rdx_node_t *ipf_rx_insert __P((ipf_rdx_head_t *,
+					  ipf_rdx_node_t nodes[2], int *));
+static void ipf_rx_attach_mask __P((ipf_rdx_node_t *, ipf_rdx_mask_t *));
+static int count_mask_bits __P((addrfamily_t *, u_32_t **));
+static void buildnodes __P((addrfamily_t *, addrfamily_t *,
+			    ipf_rdx_node_t n[2]));
+static ipf_rdx_node_t *ipf_rx_find_addr __P((ipf_rdx_node_t *, u_32_t *));
+static ipf_rdx_node_t *ipf_rx_lookup __P((ipf_rdx_head_t *, addrfamily_t *,
+					  addrfamily_t *));
+static ipf_rdx_node_t *ipf_rx_match __P((ipf_rdx_head_t *, addrfamily_t *));
+
+/*
+ * Foreword.
+ * ---------
+ * The code in this file has been written to target using the addrfamily_t
+ * data structure to house the address information and no other. Thus there
+ * are certain aspects of thise code (such as offsets to the address itself)
+ * that are hard coded here whilst they might be more variable elsewhere.
+ * Similarly, this code enforces no maximum key length as that's implied by
+ * all keys needing to be stored in addrfamily_t.
+ */
+
+/* ------------------------------------------------------------------------ */
+/* Function:    count_mask_bits                                             */
+/* Returns:     number of consecutive bits starting at "mask".              */
+/*                                                                          */
+/* Count the number of bits set in the address section of addrfamily_t and  */
+/* return both that number and a pointer to the last word with a bit set if */
+/* lastp is not NULL. The bit count is performed using network byte order   */
+/* as the guide for which bit is the most significant bit.                  */
+/* ------------------------------------------------------------------------ */
+static int
+count_mask_bits(mask, lastp)
+	addrfamily_t *mask;
+	u_32_t **lastp;
+{
+	u_32_t *mp = (u_32_t *)&mask->adf_addr;
+	u_32_t m;
+	int count = 0;
+	int mlen;
+
+	mlen = mask->adf_len - offsetof(addrfamily_t, adf_addr);
+	for (; mlen > 0; mlen -= 4, mp++) {
+		if ((m = ntohl(*mp)) == 0)
+			break;
+		if (lastp != NULL)
+			*lastp = mp;
+		for (; m & 0x80000000; m <<= 1)
+			count++;
+	}
+
+	return count;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    buildnodes                                                  */
+/* Returns:     Nil                                                         */
+/* Parameters:  addr(I)  - network address for this radix node              */
+/*              mask(I)  - netmask associated with the above address        */
+/*              nodes(O) - pair of ipf_rdx_node_t's to initialise with data */
+/*                         associated with addr and mask.                   */
+/*                                                                          */
+/* Initialise the fields in a pair of radix tree nodes according to the     */
+/* data supplied in the paramters "addr" and "mask". It is expected that    */
+/* "mask" will contain a consecutive string of bits set. Masks with gaps in */
+/* the middle are not handled by this implementation.                       */
+/* ------------------------------------------------------------------------ */
+static void
+buildnodes(addr, mask, nodes)
+	addrfamily_t *addr, *mask;
+	ipf_rdx_node_t nodes[2];
+{
+	u_32_t maskbits;
+	u_32_t lastbits;
+	u_32_t lastmask;
+	u_32_t *last;
+	int masklen;
+
+	last = NULL;
+	maskbits = count_mask_bits(mask, &last);
+	if (last == NULL) {
+		masklen = 0;
+		lastmask = 0;
+	} else {
+		masklen = last - (u_32_t *)mask;
+		lastmask = *last;
+	}
+	lastbits = maskbits & 0x1f;
+
+	bzero(&nodes[0], sizeof(ipf_rdx_node_t) * 2);
+	nodes[0].maskbitcount = maskbits;
+	nodes[0].index = -1 - (ADF_OFF_BITS + maskbits);
+	nodes[0].addrkey = (u_32_t *)addr;
+	nodes[0].maskkey = (u_32_t *)mask;
+	nodes[0].addroff = nodes[0].addrkey + masklen;
+	nodes[0].maskoff = nodes[0].maskkey + masklen;
+	nodes[0].parent = &nodes[1];
+	nodes[0].offset = masklen;
+	nodes[0].lastmask = lastmask;
+	nodes[1].offset = masklen;
+	nodes[1].left = &nodes[0];
+	nodes[1].maskbitcount = maskbits;
+#ifdef RDX_DEBUG
+	(void) strcpy(nodes[0].name, "_BUILD.0");
+	(void) strcpy(nodes[1].name, "_BUILD.1");
+#endif
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_find_addr                                            */
+/* Returns:     ipf_rdx_node_t * - pointer to a node in the radix tree.     */
+/* Parameters:  tree(I)  - pointer to first right node in tree to search    */
+/*              addr(I)  - pointer to address to match                      */
+/*                                                                          */
+/* Walk the radix tree given by "tree", looking for a leaf node that is a   */
+/* match for the address given by "addr".                                   */
+/* ------------------------------------------------------------------------ */
+static ipf_rdx_node_t *
+ipf_rx_find_addr(tree, addr)
+	ipf_rdx_node_t *tree;
+	u_32_t *addr;
+{
+	ipf_rdx_node_t *cur;
+
+	for (cur = tree; cur->index >= 0;) {
+		if (cur->bitmask & addr[cur->offset]) {
+			cur = cur->right;
+		} else {
+			cur = cur->left;
+		}
+	}
+
+	return (cur);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_match                                                */
+/* Returns:     ipf_rdx_node_t * - NULL on error, else pointer to the node  */
+/*                                 added to the tree.                       */
+/* Paramters:   head(I)  - pointer to tree head to search                   */
+/*              addr(I)  - pointer to address to find                       */
+/*                                                                          */
+/* Search the radix tree for the best match to the address pointed to by    */
+/* "addr" and return a pointer to that node. This search will not match the */
+/* address information stored in either of the root leaves as neither of    */
+/* them are considered to be part of the tree of data being stored.         */
+/* ------------------------------------------------------------------------ */
+static ipf_rdx_node_t *
+ipf_rx_match(head, addr)
+	ipf_rdx_head_t *head;
+	addrfamily_t *addr;
+{
+	ipf_rdx_mask_t *masknode;
+	ipf_rdx_node_t *prev;
+	ipf_rdx_node_t *node;
+	ipf_rdx_node_t *cur;
+	u_32_t *data;
+	u_32_t *mask;
+	u_32_t *key;
+	u_32_t *end;
+	int len;
+	int i;
+
+	len = addr->adf_len;
+	end = (u_32_t *)((u_char *)addr + len);
+	node = ipf_rx_find_addr(head->root, (u_32_t *)addr);
+
+	/*
+	 * Search the dupkey list for a potential match.
+	 */
+	for (cur = node; (cur != NULL) && (cur->root == 0); cur = cur->dupkey) {
+		i = cur[0].addroff - cur[0].addrkey;
+		data = cur[0].addrkey + i;
+		mask = cur[0].maskkey + i;
+		key = (u_32_t *)addr + i;
+		for (; key < end; data++, key++, mask++)
+			if ((*key & *mask) != *data)
+				break;
+		if ((end == key) && (cur->root == 0))
+			return (cur);	/* Equal keys */
+	}
+	prev = node->parent;
+	key = (u_32_t *)addr;
+
+	for (node = prev; node->root == 0; node = node->parent) {
+		/*
+		 * We know that the node hasn't matched so therefore only
+		 * the entries in the mask list are searched, not the top
+		 * node nor the dupkey list.
+		 */
+		masknode = node->masks;
+		for (; masknode != NULL; masknode = masknode->next) {
+			if (masknode->maskbitcount > node->maskbitcount)
+				continue;
+			cur = masknode->node;
+			for (i = ADF_OFF >> 2; i <= node->offset; i++) {
+				if ((key[i] & masknode->mask[i]) ==
+				    cur->addrkey[i])
+					return (cur);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_lookup                                               */
+/* Returns:     ipf_rdx_node_t * - NULL on error, else pointer to the node  */
+/*                                 added to the tree.                       */
+/* Paramters:   head(I)  - pointer to tree head to search                   */
+/*              addr(I)  - address part of the key to match                 */
+/*              mask(I)  - netmask part of the key to match                 */
+/*                                                                          */
+/* ipf_rx_lookup searches for an exact match on (addr,mask). The intention  */
+/* is to see if a given key is in the tree, not to see if a route exists.   */
+/* ------------------------------------------------------------------------ */
+ipf_rdx_node_t *
+ipf_rx_lookup(head, addr, mask)
+	ipf_rdx_head_t *head;
+	addrfamily_t *addr, *mask;
+{
+	ipf_rdx_node_t *found;
+	ipf_rdx_node_t *node;
+	u_32_t *akey;
+	int count;
+
+	found = ipf_rx_find_addr(head->root, (u_32_t *)addr);
+	if (found->root == 1)
+		return NULL;
+
+	/*
+	 * It is possible to find a matching address in the tree but for the
+	 * netmask to not match. If the netmask does not match and there is
+	 * no list of alternatives present at dupkey, return a failure.
+	 */
+	count = count_mask_bits(mask, NULL);
+	if (count != found->maskbitcount && found->dupkey == NULL)
+		return (NULL);
+
+	akey = (u_32_t *)addr;
+	if ((found->addrkey[found->offset] & found->maskkey[found->offset]) !=
+	    akey[found->offset])
+		return NULL;
+
+	if (found->dupkey != NULL) {
+		node = found;
+		while (node != NULL && node->maskbitcount != count)
+			node = node->dupkey;
+		if (node == NULL)
+			return (NULL);
+		found = node;
+	}
+	return found;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_attach_mask                                          */
+/* Returns:     Nil                                                         */
+/* Parameters:  node(I)  - pointer to a radix tree node                     */
+/*              mask(I)  - pointer to mask structure to add                 */
+/*                                                                          */
+/* Add the netmask to the given node in an ordering where the most specific */
+/* netmask is at the top of the list.                                       */
+/* ------------------------------------------------------------------------ */
+static void
+ipf_rx_attach_mask(node, mask)
+	ipf_rdx_node_t *node;
+	ipf_rdx_mask_t *mask;
+{
+	ipf_rdx_mask_t **pm;
+	ipf_rdx_mask_t *m;
+
+	for (pm = &node->masks; (m = *pm) != NULL; pm = &m->next)
+		if (m->maskbitcount < mask->maskbitcount)
+			break;
+	mask->next = *pm;
+	*pm = mask;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_insert                                               */
+/* Returns:     ipf_rdx_node_t * - NULL on error, else pointer to the node  */
+/*                                 added to the tree.                       */
+/* Paramters:   head(I)  - pointer to tree head to add nodes to             */
+/*              nodes(I) - pointer to radix nodes to be added               */
+/*              dup(O)   - set to 1 if node is a duplicate, else 0.         */
+/*                                                                          */
+/* Add the new radix tree entry that owns nodes[] to the tree given by head.*/
+/* If there is already a matching key in the table, "dup" will be set to 1  */
+/* and the existing node pointer returned if there is a complete key match. */
+/* A complete key match is a matching of all key data that is presented by  */
+/* by the netmask.                                                          */
+/* ------------------------------------------------------------------------ */
+static ipf_rdx_node_t *
+ipf_rx_insert(head, nodes, dup)
+	ipf_rdx_head_t *head;
+	ipf_rdx_node_t nodes[2];
+	int *dup;
+{
+	ipf_rdx_mask_t **pmask;
+	ipf_rdx_node_t *node;
+	ipf_rdx_node_t *prev;
+	ipf_rdx_mask_t *mask;
+	ipf_rdx_node_t *cur;
+	u_32_t nodemask;
+	u_32_t *addr;
+	u_32_t *data;
+	int nodebits;
+	u_32_t *key;
+	u_32_t *end;
+	u_32_t bits;
+	int nodekey;
+	int nodeoff;
+	int nlen;
+	int len;
+
+	addr = nodes[0].addrkey;
+
+	node = ipf_rx_find_addr(head->root, addr);
+	len = ((addrfamily_t *)addr)->adf_len;
+	key = (u_32_t *)&((addrfamily_t *)addr)->adf_addr;
+	data= (u_32_t *)&((addrfamily_t *)node->addrkey)->adf_addr;
+	end = (u_32_t *)((u_char *)addr + len);
+	for (nlen = 0; key < end; data++, key++, nlen += 32)
+		if (*key != *data)
+			break;
+	if (end == data) {
+		*dup = 1;
+		return (node);	/* Equal keys */
+	}
+	*dup = 0;
+
+	bits = (ntohl(*data) ^ ntohl(*key));
+	for (; bits != 0; nlen++) {
+		if ((bits & 0x80000000) != 0)
+			break;
+		bits <<= 1;
+	}
+	nlen += ADF_OFF_BITS;
+	nodes[1].index = nlen;
+	nodes[1].bitmask = htonl(0x80000000 >> (nlen & 0x1f));
+	nodes[0].offset = nlen / 32;
+	nodes[1].offset = nlen / 32;
+
+	/*
+	 * Walk through the tree and look for the correct place to attach
+	 * this node. ipf_rx_fin_addr is not used here because the place
+	 * to attach this node may be an internal node (same key, different
+	 * netmask.) Additionally, the depth of the search is forcibly limited
+	 * here to not exceed the netmask, so that a short netmask will be
+	 * added higher up the tree even if there are lower branches.
+	 */
+	cur = head->root;
+	key = nodes[0].addrkey;
+	do {
+		prev = cur;
+		if (key[cur->offset] & cur->bitmask) {
+			cur = cur->right;
+		} else {
+			cur = cur->left;
+		}
+	} while (nlen > (unsigned)cur->index);
+
+	if ((key[prev->offset] & prev->bitmask) == 0) {
+		prev->left = &nodes[1];
+	} else {
+		prev->right = &nodes[1];
+	}
+	cur->parent = &nodes[1];
+	nodes[1].parent = prev;
+	if ((key[nodes[1].offset] & nodes[1].bitmask) == 0) {
+		nodes[1].right = cur;
+	} else {
+		nodes[1].right = &nodes[0];
+		nodes[1].left = cur;
+	}
+
+	nodeoff = nodes[0].offset;
+	nodekey = nodes[0].addrkey[nodeoff];
+	nodemask = nodes[0].lastmask;
+	nodebits = nodes[0].maskbitcount;
+	prev = NULL;
+	/*
+	 * Find the node up the tree with the largest pattern that still
+	 * matches the node being inserted to see if this mask can be
+	 * moved there.
+	 */
+	for (cur = nodes[1].parent; cur->root == 0; cur = cur->parent) {
+		if (cur->maskbitcount <= nodebits)
+			break;
+		if (((cur - 1)->addrkey[nodeoff] & nodemask) != nodekey)
+			break;
+		prev = cur;
+	}
+
+	KMALLOC(mask, ipf_rdx_mask_t *);
+	if (mask == NULL)
+		return NULL;
+	bzero(mask, sizeof(*mask));
+	mask->next = NULL;
+	mask->node = &nodes[0];
+	mask->maskbitcount = nodebits;
+	mask->mask = nodes[0].maskkey;
+	nodes[0].mymask = mask;
+
+	if (prev != NULL) {
+		ipf_rdx_mask_t *m;
+
+		for (pmask = &prev->masks; (m = *pmask) != NULL;
+		     pmask = &m->next) {
+			if (m->maskbitcount < nodebits)
+				break;
+		}
+	} else {
+		/*
+		 * No higher up nodes qualify, so attach mask locally.
+		 */
+		pmask = &nodes[0].masks;
+	}
+	mask->next = *pmask;
+	*pmask = mask;
+
+	/*
+	 * Search the mask list on each child to see if there are any masks
+	 * there that can be moved up to this newly inserted node.
+	 */
+	cur = nodes[1].right;
+	if (cur->root == 0) {
+		for (pmask = &cur->masks; (mask = *pmask) != NULL; ) {
+			if (mask->maskbitcount < nodebits) {
+				*pmask = mask->next;
+				ipf_rx_attach_mask(&nodes[0], mask);
+			} else {
+				pmask = &mask->next;
+			}
+		}
+	}
+	cur = nodes[1].left;
+	if (cur->root == 0 && cur != &nodes[0]) {
+		for (pmask = &cur->masks; (mask = *pmask) != NULL; ) {
+			if (mask->maskbitcount < nodebits) {
+				*pmask = mask->next;
+				ipf_rx_attach_mask(&nodes[0], mask);
+			} else {
+				pmask = &mask->next;
+			}
+		}
+	}
+	return (&nodes[0]);
+}
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_addroute                                             */
+/* Returns:     ipf_rdx_node_t * - NULL on error, else pointer to the node  */
+/*                                 added to the tree.                       */
+/* Paramters:   head(I)  - pointer to tree head to search                   */
+/*              addr(I)  - address portion of "route" to add                */
+/*              mask(I)  - netmask portion of "route" to add                */
+/*              nodes(I) - radix tree data nodes inside allocate structure  */
+/*                                                                          */
+/* Attempt to add a node to the radix tree. The key for the node is the     */
+/* (addr,mask). No memory allocation for the radix nodes themselves is      */
+/* performed here, the data structure that this radix node is being used to */
+/* find is expected to house the node data itself however the call to       */
+/* ipf_rx_insert() will attempt to allocate memory in order for netmask to  */
+/* be promoted further up the tree.                                         */
+/* In this case, the ip_pool_node_t structure from ip_pool.h contains both  */
+/* the key material (addr,mask) and the radix tree nodes[].                 */
+/*                                                                          */
+/* The mechanics of inserting the node into the tree is handled by the      */
+/* function ipf_rx_insert() above. Here, the code deals with the case       */
+/* where the data to be inserted is a duplicate.                            */
+/* ------------------------------------------------------------------------ */
+ipf_rdx_node_t *
+ipf_rx_addroute(head, addr, mask, nodes)
+	ipf_rdx_head_t *head;
+	addrfamily_t *addr, *mask;
+	ipf_rdx_node_t *nodes;
+{
+	ipf_rdx_node_t *node;
+	ipf_rdx_node_t *prev;
+	ipf_rdx_node_t *x;
+	int dup;
+
+	buildnodes(addr, mask, nodes);
+	x = ipf_rx_insert(head, nodes, &dup);
+	if (x == NULL)
+		return NULL;
+
+	if (dup == 1) {
+		node = &nodes[0];
+		prev = NULL;
+		/*
+		 * The duplicate list is kept sorted with the longest
+		 * mask at the top, meaning that the most specific entry
+		 * in the listis found first. This list thus allows for
+		 * duplicates such as 128.128.0.0/32 and 128.128.0.0/16.
+		 */
+		while ((x != NULL) && (x->maskbitcount > node->maskbitcount)) {
+			prev = x;
+			x = x->dupkey;
+		}
+
+		/*
+		 * Is it a complete duplicate? If so, return NULL and
+		 * fail the insert. Otherwise, insert it into the list
+		 * of netmasks active for this key.
+		 */
+		if ((x != NULL) && (x->maskbitcount == node->maskbitcount))
+			return (NULL);
+
+		if (prev != NULL) {
+			nodes[0].dupkey = x;
+			prev->dupkey = &nodes[0];
+			nodes[0].parent = prev;
+			if (x != NULL)
+				x->parent = &nodes[0];
+		} else {
+			nodes[0].dupkey = x->dupkey;
+			prev = x->parent;
+			nodes[0].parent = prev;
+			x->parent = &nodes[0];
+			if (prev->left == x)
+				prev->left = &nodes[0];
+			else
+				prev->right = &nodes[0];
+		}
+	}
+
+	return &nodes[0];
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_delete                                               */
+/* Returns:     ipf_rdx_node_t * - NULL on error, else node removed from    */
+/*                                 the tree.                                */
+/* Paramters:   head(I)  - pointer to tree head to search                   */
+/*              addr(I)  - pointer to the address part of the key           */
+/*              mask(I)  - pointer to the netmask part of the key           */
+/*                                                                          */
+/* Search for an entry in the radix tree that is an exact match for (addr,  */
+/* mask) and remove it if it exists. In the case where (addr,mask) is a not */
+/* a unique key, the tree structure itself is not changed - only the list   */
+/* of duplicate keys.                                                       */
+/* ------------------------------------------------------------------------ */
+ipf_rdx_node_t *
+ipf_rx_delete(head, addr, mask)
+        ipf_rdx_head_t *head;
+        addrfamily_t *addr, *mask;
+{
+	ipf_rdx_mask_t **pmask;
+	ipf_rdx_node_t *parent;
+	ipf_rdx_node_t *found;
+	ipf_rdx_node_t *prev;
+	ipf_rdx_node_t *node;
+	ipf_rdx_node_t *cur;
+	ipf_rdx_mask_t *m;
+	int count;
+
+	found = ipf_rx_find_addr(head->root, (u_32_t *)addr);
+	if (found == NULL)
+		return NULL;
+	if (found->root == 1)
+		return NULL;
+	count = count_mask_bits(mask, NULL);
+	parent = found->parent;
+	if (found->dupkey != NULL) {
+		node = found;
+		while (node != NULL && node->maskbitcount != count)
+			node = node->dupkey;
+		if (node == NULL)
+			return (NULL);
+		if (node != found) {
+			/*
+			 * Remove from the dupkey list. Here, "parent" is
+			 * the previous node on the list (rather than tree)
+			 * and "dupkey" is the next node on the list.
+			 */
+			parent = node->parent;
+			parent->dupkey = node->dupkey;
+			node->dupkey->parent = parent;
+		} else {
+			/*
+			 * 
+			 * When removing the top node of the dupkey list,
+			 * the pointers at the top of the list that point
+			 * to other tree nodes need to be preserved and
+			 * any children must have their parent updated.
+			 */
+			node = node->dupkey;
+			node->parent = found->parent;
+			node->right = found->right;
+			node->left = found->left;
+			found->right->parent = node;
+			found->left->parent = node;
+			if (parent->left == found)
+				parent->left = node;
+			else
+				parent->right= node;
+		}
+	} else {
+		if (count != found->maskbitcount)
+			return (NULL);
+		/*
+		 * Remove the node from the tree and reconnect the subtree
+		 * below.
+		 */
+		/*
+		 * If there is a tree to the left, look for something to
+		 * attach in place of "found".
+		 */
+		prev = found + 1;
+		cur = parent->parent;
+		if (parent != found + 1) {
+			if ((found + 1)->parent->right == found + 1)
+				(found + 1)->parent->right = parent;
+			else
+				(found + 1)->parent->left = parent;
+			if (cur->right == parent) {
+				if (parent->left == found) {
+					cur->right = parent->right;
+				} else if (parent->left != parent - 1) {
+					cur->right = parent->left;
+				} else {
+					cur->right = parent - 1;
+				}
+				cur->right->parent = cur;
+			} else {
+				if (parent->right == found) {
+					cur->left = parent->left;
+				} else if (parent->right != parent - 1) {
+					cur->left = parent->right;
+				} else {
+					cur->left = parent - 1;
+				}
+				cur->left->parent = cur;
+			}
+			parent->left = (found + 1)->left;
+			if ((found + 1)->right != parent)
+				parent->right = (found + 1)->right;
+			parent->left->parent = parent;
+			parent->right->parent = parent;
+			parent->parent = (found + 1)->parent;
+
+			parent->bitmask = prev->bitmask;
+			parent->offset = prev->offset;
+			parent->index = prev->index;
+		} else {
+			/*
+			 * We found an edge node.
+			 */
+			cur = parent->parent;
+			if (cur->left == parent) {
+				if (parent->left == found) {
+					cur->left = parent->right;
+					parent->right->parent = cur;
+				} else {
+					cur->left = parent->left;
+					parent->left->parent = cur;
+				}
+			} else {
+				if (parent->right != found) {
+					cur->right = parent->right;
+					parent->right->parent = cur;
+				} else {
+					cur->right = parent->left;
+					prev->left->parent = cur;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Remove mask associated with this node.
+	 */
+	for (cur = parent; cur->root == 0; cur = cur->parent) {
+		ipf_rdx_mask_t **pm;
+
+		if (cur->maskbitcount <= found->maskbitcount)
+			break;
+		if (((cur - 1)->addrkey[found->offset] & found->bitmask) !=
+		    found->addrkey[found->offset])
+			break;
+		for (pm = &cur->masks; (m = *pm) != NULL; )
+			if (m->node == cur) {
+				*pm = m->next;
+				break;
+			} else {
+				pm = &m->next;
+			}
+	}
+	KFREE(found->mymask);
+
+	/*
+	 * Masks that have been brought up to this node from below need to
+	 * be sent back down.
+	 */
+	for (pmask = &parent->masks; (m = *pmask) != NULL; ) {
+		*pmask = m->next;
+		cur = m->node;
+		if (cur == found)
+			continue;
+		if (found->addrkey[cur->offset] & cur->lastmask) {
+			ipf_rx_attach_mask(parent->right, m);
+		} else if (parent->left != found) {
+			ipf_rx_attach_mask(parent->left, m);
+		}
+	}
+
+	return (found);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_walktree                                             */
+/* Returns:     Nil                                                         */
+/* Paramters:   head(I)   - pointer to tree head to search                  */
+/*              walker(I) - function to call for each node in the tree      */
+/*              arg(I)    - parameter to pass to walker, in addition to the */
+/*                          node pointer                                    */
+/*                                                                          */
+/* A standard tree walking function except that it is iterative, rather     */
+/* than recursive and tracks the next node in case the "walker" function    */
+/* should happen to delete and free the current node. It thus goes without  */
+/* saying that the "walker" function is not permitted to cause any change   */
+/* in the validity of the data found at either the left or right child.     */
+/* ------------------------------------------------------------------------ */
+void
+ipf_rx_walktree(head, walker, arg)
+	ipf_rdx_head_t *head;
+	radix_walk_func_t walker;
+	void *arg;
+{
+	ipf_rdx_node_t *next;
+	ipf_rdx_node_t *node = head->root;
+	ipf_rdx_node_t *base;
+
+	while (node->index >= 0)
+		node = node->left;
+
+	for (;;) {
+		base = node;
+		while ((node->parent->right == node) && (node->root == 0))
+			node = node->parent;
+
+		for (node = node->parent->right; node->index >= 0; )
+			node = node->left;
+		next = node;
+
+		for (node = base; node != NULL; node = base) {
+			base = node->dupkey;
+			if (node->root == 0)
+				walker(node, arg);
+		}
+		node = next;
+		if (node->root)
+			return;
+	}
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_inithead                                             */
+/* Returns:     int       - 0 = success, else failure                       */
+/* Paramters:   softr(I)  - pointer to radix context                        */
+/*              headp(O)  - location for where to store allocated tree head */
+/*                                                                          */
+/* This function allocates and initialises a radix tree head structure.     */
+/* As a traditional radix tree, node 0 is used as the "0" sentinel and node */
+/* "2" is used as the all ones sentinel, leaving node "1" as the root from  */
+/* which the tree is hung with node "0" on its left and node "2" to the     */
+/* right. The context, "softr", is used here to provide a common source of  */
+/* the zeroes and ones data rather than have one per head.                  */
+/* ------------------------------------------------------------------------ */
+int
+ipf_rx_inithead(softr, headp)
+	radix_softc_t *softr;
+	ipf_rdx_head_t **headp;
+{
+	ipf_rdx_head_t *ptr;
+	ipf_rdx_node_t *node;
+
+	KMALLOC(ptr, ipf_rdx_head_t *);
+	*headp = ptr;
+	if (ptr == NULL)
+		return -1;
+	bzero(ptr, sizeof(*ptr));
+	node = ptr->nodes;
+	ptr->root = node + 1;
+	node[0].index = ADF_OFF_BITS;
+	node[0].index = -1 - node[0].index;
+	node[1].index = ADF_OFF_BITS;
+	node[2].index = node[0].index;
+	node[0].parent = node + 1;
+	node[1].parent = node + 1;
+	node[2].parent = node + 1;
+	node[1].bitmask = htonl(0x80000000);
+	node[0].root = 1;
+	node[1].root = 1;
+	node[2].root = 1;
+	node[0].offset = ADF_OFF_BITS >> 5;
+	node[1].offset = ADF_OFF_BITS >> 5;
+	node[2].offset = ADF_OFF_BITS >> 5;
+	node[1].left = &node[0];
+	node[1].right = &node[2];
+	node[0].addrkey = (u_32_t *)softr->zeros;
+	node[2].addrkey = (u_32_t *)softr->ones;
+#ifdef RDX_DEBUG
+	(void) strcpy(node[0].name, "0_ROOT");
+	(void) strcpy(node[1].name, "1_ROOT");
+	(void) strcpy(node[2].name, "2_ROOT");
+#endif
+
+	ptr->addaddr = ipf_rx_addroute;
+	ptr->deladdr = ipf_rx_delete;
+	ptr->lookup = ipf_rx_lookup;
+	ptr->matchaddr = ipf_rx_match;
+	ptr->walktree = ipf_rx_walktree;
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_freehead                                             */
+/* Returns:     Nil                                                         */
+/* Paramters:   head(I)  - pointer to tree head to free                     */
+/*                                                                          */
+/* This function simply free's up the radix tree head. Prior to calling     */
+/* this function, it is expected that the tree will have been emptied.      */
+/* ------------------------------------------------------------------------ */
+void
+ipf_rx_freehead(head)
+	ipf_rdx_head_t *head;
+{
+	KFREE(head);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_create                                               */
+/* Parameters:  Nil                                                         */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+void *
+ipf_rx_create()
+{
+	radix_softc_t *softr;
+
+	KMALLOC(softr, radix_softc_t *);
+	if (softr == NULL)
+		return NULL;
+	bzero((char *)softr, sizeof(*softr));
+
+	KMALLOCS(softr->zeros, u_char *, 3 * sizeof(addrfamily_t));
+	if (softr->zeros == NULL) {
+		KFREE(softr);
+		return (NULL);
+	}
+	softr->ones = softr->zeros + sizeof(addrfamily_t);
+
+	return softr;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_init                                                 */
+/* Returns:     int       - 0 = success (always)                            */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+int
+ipf_rx_init(ctx)
+	void *ctx;
+{
+	radix_softc_t *softr = ctx;
+
+	memset(softr->zeros, 0, 3 * sizeof(addrfamily_t));
+	memset(softr->ones, 0xff, sizeof(addrfamily_t));
+
+	return (0);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rx_destroy                                              */
+/* Returns:     Nil                                                         */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+void
+ipf_rx_destroy(ctx)
+	void *ctx;
+{
+	radix_softc_t *softr = ctx;
+
+	if (softr->zeros != NULL)
+		KFREES(softr->zeros, 3 * sizeof(addrfamily_t));
+	KFREE(softr);
+}
+
+/* ====================================================================== */
+
+#ifdef RDX_DEBUG
+/*
+ * To compile this file as a standalone test unit, use -DRDX_DEBUG=1
+ */
+#define	NAME(x)	((x)->index < 0 ? (x)->name : (x)->name)
+#define	GNAME(y)	((y) == NULL ? "NULL" : NAME(y))
+
+typedef struct myst {
+	struct ipf_rdx_node nodes[2];
+	addrfamily_t	dst;
+	addrfamily_t	mask;
+	struct myst	*next;
+	int		printed;
+} myst_t;
+
+typedef struct tabe_s {
+	char	*host;
+	char	*mask;
+	char	*what;
+} tabe_t;
+
+tabe_t builtin[] = {
+#if 1
+	{ "192:168:100::0",	"48",			"d" },
+	{ "192:168:100::2",	"128",			"d" },
+#else
+	{ "127.192.0.0",	"255.255.255.0",	"d" },
+	{ "127.128.0.0",	"255.255.255.0",	"d" },
+	{ "127.96.0.0",		"255.255.255.0",	"d" },
+	{ "127.80.0.0",		"255.255.255.0",	"d" },
+	{ "127.72.0.0",		"255.255.255.0",	"d" },
+	{ "127.64.0.0",		"255.255.255.0",	"d" },
+	{ "127.56.0.0",		"255.255.255.0",	"d" },
+	{ "127.48.0.0",		"255.255.255.0",	"d" },
+	{ "127.40.0.0",		"255.255.255.0",	"d" },
+	{ "127.32.0.0",		"255.255.255.0",	"d" },
+	{ "127.24.0.0",		"255.255.255.0",	"d" },
+	{ "127.16.0.0",		"255.255.255.0",	"d" },
+	{ "127.8.0.0",		"255.255.255.0",	"d" },
+	{ "124.0.0.0",		"255.0.0.0",		"d" },
+	{ "125.0.0.0",		"255.0.0.0",		"d" },
+	{ "126.0.0.0",		"255.0.0.0",		"d" },
+	{ "127.0.0.0",		"255.0.0.0",		"d" },
+	{ "10.0.0.0",		"255.0.0.0",		"d" },
+	{ "128.250.0.0",	"255.255.0.0",		"d" },
+	{ "192.168.0.0",	"255.255.0.0",		"d" },
+	{ "192.168.1.0",	"255.255.255.0",	"d" },
+#endif
+	{ NULL, NULL, NULL }
+};
+
+char *mtable[][1] = {
+#if 1
+	{ "192:168:100::2" },
+	{ "192:168:101::2" },
+#else
+	{ "9.0.0.0" },
+	{ "9.0.0.1" },
+	{ "11.0.0.0" },
+	{ "11.0.0.1" },
+	{ "127.0.0.1" },
+	{ "127.0.1.0" },
+	{ "255.255.255.0" },
+	{ "126.0.0.1" },
+	{ "128.251.0.0" },
+	{ "128.251.0.1" },
+	{ "128.251.255.255" },
+	{ "129.250.0.0" },
+	{ "129.250.0.1" },
+	{ "192.168.255.255" },
+#endif
+	{ NULL }
+};
+
+
+int forder[22] = {
+	14, 13, 12,  5, 10,  3, 19,  7,  4, 20,  8,
+	 2, 17,  9, 16, 11, 15,  1,  6, 18,  0, 21
+};
+
+static int nodecount = 0;
+myst_t *myst_top = NULL;
+tabe_t *ttable = NULL;
+
+void add_addr(ipf_rdx_head_t *, int , int);
+void checktree(ipf_rdx_head_t *);
+void delete_addr(ipf_rdx_head_t *rnh, int item);
+void dumptree(ipf_rdx_head_t *rnh);
+void nodeprinter(ipf_rdx_node_t *, void *);
+void printroots(ipf_rdx_head_t *);
+void random_add(ipf_rdx_head_t *);
+void random_delete(ipf_rdx_head_t *);
+void test_addr(ipf_rdx_head_t *rnh, int pref, addrfamily_t *, int);
+
+
+static void
+ipf_rx_freenode(node, arg)
+	ipf_rdx_node_t *node;
+	void *arg;
+{
+	ipf_rdx_head_t *head = arg;
+	ipf_rdx_node_t *rv;
+	myst_t *stp;
+
+	stp = (myst_t *)node;
+	rv = ipf_rx_delete(head, &stp->dst, &stp->mask);
+	if (rv != NULL) {
+		free(rv);
+	}
+}
+
+
+const char *
+addrname(ap)
+	addrfamily_t *ap;
+{
+	static char name[80];
+	const char *txt;
+
+	bzero((char *)name, sizeof(name));
+	txt =  inet_ntop(ap->adf_family, &ap->adf_addr, name,
+			 sizeof(name));
+	return txt;
+}
+
+
+void
+fill6bits(bits, msk)
+	int bits;
+	u_int *msk;
+{
+	if (bits == 0) {
+		msk[0] = 0;
+		msk[1] = 0;
+		msk[2] = 0;
+		msk[3] = 0;
+		return;
+	}
+
+	msk[0] = 0xffffffff;
+	msk[1] = 0xffffffff;
+	msk[2] = 0xffffffff;
+	msk[3] = 0xffffffff;
+
+	if (bits == 128)
+		return;
+	if (bits > 96) {
+		msk[3] = htonl(msk[3] << (128 - bits));
+	} else if (bits > 64) {
+		msk[3] = 0;
+		msk[2] = htonl(msk[2] << (96 - bits));
+	} else if (bits > 32) {
+		msk[3] = 0;
+		msk[2] = 0;
+		msk[1] = htonl(msk[1] << (64 - bits));
+	} else {
+		msk[3] = 0;
+		msk[2] = 0;
+		msk[1] = 0;
+		msk[0] = htonl(msk[0] << (32 - bits));
+	}
+}
+
+
+void
+setaddr(afp, str)
+	addrfamily_t *afp;
+	char *str;
+{
+
+	bzero((char *)afp, sizeof(*afp));
+
+	if (strchr(str, ':') == NULL) {
+		afp->adf_family = AF_INET;
+		afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4;
+	} else {
+		afp->adf_family = AF_INET6;
+		afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16;
+	}
+	inet_pton(afp->adf_family, str, &afp->adf_addr);
+}
+
+
+void
+setmask(afp, str)
+	addrfamily_t *afp;
+	char *str;
+{
+	if (strchr(str, '.') != NULL) {
+		afp->adf_addr.in4.s_addr = inet_addr(str);
+		afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4;
+	} else if (afp->adf_family == AF_INET) {
+		afp->adf_addr.i6[0] = htonl(0xffffffff << (32 - atoi(str)));
+		afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4;
+	} else if (afp->adf_family == AF_INET6) {
+		fill6bits(atoi(str), afp->adf_addr.i6);
+		afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16;
+	}
+}
+
+
+void
+nodeprinter(node, arg)
+	ipf_rdx_node_t *node;
+	void *arg;
+{
+	myst_t *stp = (myst_t *)node;
+
+	printf("Node %-9.9s L %-9.9s R %-9.9s P %9.9s/%-9.9s %s/%d\n",
+		node[0].name,
+		GNAME(node[1].left), GNAME(node[1].right),
+		GNAME(node[0].parent), GNAME(node[1].parent),
+		addrname(&stp->dst), node[0].maskbitcount);
+	if (stp->printed == -1)
+		printf("!!! %d\n", stp->printed);
+	else
+		stp->printed = 1;
+}
+
+
+void
+printnode(stp)
+	myst_t *stp;
+{
+	ipf_rdx_node_t *node = &stp->nodes[0];
+
+	if (stp->nodes[0].index > 0)
+		stp = (myst_t *)&stp->nodes[-1];
+
+	printf("Node %-9.9s ", node[0].name);
+	printf("L %-9.9s ", GNAME(node[1].left));
+	printf("R %-9.9s ", GNAME(node[1].right));
+	printf("P %9.9s", GNAME(node[0].parent));
+	printf("/%-9.9s ", GNAME(node[1].parent));
+	printf("%s P%d\n", addrname(&stp->dst), stp->printed);
+}
+
+
+void
+buildtab(void)
+{
+	char line[80], *s;
+	tabe_t *tab;
+	int lines;
+	FILE *fp;
+
+	lines = 0;
+	fp = fopen("hosts", "r");
+
+	while (fgets(line, sizeof(line), fp) != NULL) {
+		s = strchr(line, '\n');
+		if (s != NULL)
+			*s = '\0';
+		lines++;
+		if (lines == 1)
+			tab = malloc(sizeof(*tab) * 2);
+		else
+			tab = realloc(tab, (lines + 1) * sizeof(*tab));
+		tab[lines - 1].host = strdup(line);
+		s = strchr(tab[lines - 1].host, '/');
+		*s++ = '\0';
+		tab[lines - 1].mask = s;
+		tab[lines - 1].what = "d";
+	}
+	fclose(fp);
+
+	tab[lines].host = NULL;
+	tab[lines].mask = NULL;
+	tab[lines].what = NULL;
+	ttable = tab;
+}
+
+
+void
+printroots(rnh)
+	ipf_rdx_head_t *rnh;
+{
+	printf("Root.0.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n",
+		GNAME(&rnh->nodes[0]),
+		rnh->nodes[0].index, GNAME(rnh->nodes[0].parent),
+		GNAME(rnh->nodes[0].left), GNAME(rnh->nodes[0].right));
+	printf("Root.1.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n",
+		GNAME(&rnh->nodes[1]),
+		rnh->nodes[1].index, GNAME(rnh->nodes[1].parent),
+		GNAME(rnh->nodes[1].left), GNAME(rnh->nodes[1].right));
+	printf("Root.2.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n",
+		GNAME(&rnh->nodes[2]),
+		rnh->nodes[2].index, GNAME(rnh->nodes[2].parent),
+		GNAME(rnh->nodes[2].left), GNAME(rnh->nodes[2].right));
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	addrfamily_t af;
+	ipf_rdx_head_t *rnh;
+	radix_softc_t *ctx;
+	int j;
+	int i;
+
+	rnh = NULL;
+
+	buildtab();
+	ctx = ipf_rx_create();
+	ipf_rx_init(ctx);
+	ipf_rx_inithead(ctx, &rnh);
+
+	printf("=== ADD-0 ===\n");
+	for (i = 0; ttable[i].host != NULL; i++) {
+		add_addr(rnh, i, i);
+		checktree(rnh);
+	}
+	printroots(rnh);
+	ipf_rx_walktree(rnh, nodeprinter, NULL);
+	printf("=== DELETE-0 ===\n");
+	for (i = 0; ttable[i].host != NULL; i++) {
+		delete_addr(rnh, i);
+		printroots(rnh);
+		ipf_rx_walktree(rnh, nodeprinter, NULL);
+	}
+	printf("=== ADD-1 ===\n");
+	for (i = 0; ttable[i].host != NULL; i++) {
+		setaddr(&af, ttable[i].host);
+		add_addr(rnh, i, i); /*forder[i]); */
+		checktree(rnh);
+	}
+	dumptree(rnh);
+	ipf_rx_walktree(rnh, nodeprinter, NULL);
+	printf("=== TEST-1 ===\n");
+	for (i = 0; ttable[i].host != NULL; i++) {
+		setaddr(&af, ttable[i].host);
+		test_addr(rnh, i, &af, -1);
+	}
+
+	printf("=== TEST-2 ===\n");
+	for (i = 0; mtable[i][0] != NULL; i++) {
+		setaddr(&af, mtable[i][0]);
+		test_addr(rnh, i, &af, -1);
+	}
+	printf("=== DELETE-1 ===\n");
+	for (i = 0; ttable[i].host != NULL; i++) {
+		if (ttable[i].what[0] != 'd')
+			continue;
+		delete_addr(rnh, i);
+		for (j = 0; ttable[j].host != NULL; j++) {
+			setaddr(&af, ttable[j].host);
+			test_addr(rnh, i, &af, 3);
+		}
+		printroots(rnh);
+		ipf_rx_walktree(rnh, nodeprinter, NULL);
+	}
+
+	dumptree(rnh);
+
+	printf("=== ADD-2 ===\n");
+	random_add(rnh);
+	checktree(rnh);
+	dumptree(rnh);
+	ipf_rx_walktree(rnh, nodeprinter, NULL);
+	printf("=== DELETE-2 ===\n");
+	random_delete(rnh);
+	checktree(rnh);
+	dumptree(rnh);
+
+	ipf_rx_walktree(rnh, ipf_rx_freenode, rnh);
+
+	return 0;
+}
+
+
+void
+dumptree(rnh)
+	ipf_rdx_head_t *rnh;
+{
+	myst_t *stp;
+
+	printf("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n");
+	printroots(rnh);
+	for (stp = myst_top; stp; stp = stp->next)
+		printnode(stp);
+	printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+}
+
+
+void
+test_addr(rnh, pref, addr, limit)
+	ipf_rdx_head_t *rnh;
+	int pref;
+	addrfamily_t *addr;
+{
+	static int extras[14] = { 0, -1, 1, 3, 5, 8, 9,
+				  15, 16, 19, 255, 256, 65535, 65536
+	};
+	ipf_rdx_node_t *rn;
+	addrfamily_t af;
+	char name[80];
+	myst_t *stp;
+	int i;
+
+	memset(&af, 0, sizeof(af));
+#if 0
+	if (limit < 0 || limit > 14)
+		limit = 14;
+
+	for (i = 0; i < limit; i++) {
+		if (ttable[i].host == NULL)
+			break;
+		setaddr(&af, ttable[i].host);
+		printf("%d.%d.LOOKUP(%s)", pref, i, addrname(&af));
+		rn = ipf_rx_match(rnh, &af);
+		stp = (myst_t *)rn;
+		printf(" = %s (%s/%d)\n", GNAME(rn),
+			rn ? addrname(&stp->dst) : "NULL",
+			rn ? rn->maskbitcount : 0);
+	}
+#else
+	printf("%d.%d.LOOKUP(%s)", pref, -1, addrname(addr));
+	rn = ipf_rx_match(rnh, addr);
+	stp = (myst_t *)rn;
+	printf(" = %s (%s/%d)\n", GNAME(rn),
+		rn ? addrname(&stp->dst) : "NULL", rn ? rn->maskbitcount : 0);
+#endif
+}
+
+
+void
+delete_addr(rnh, item)
+	ipf_rdx_head_t *rnh;
+	int item;
+{
+	ipf_rdx_node_t *rn;
+	addrfamily_t mask;
+	addrfamily_t af;
+	myst_t **pstp;
+	myst_t *stp;
+
+	memset(&af, 0, sizeof(af));
+	memset(&mask, 0, sizeof(mask));
+	setaddr(&af, ttable[item].host);
+	mask.adf_family = af.adf_family;
+	setmask(&mask, ttable[item].mask);
+
+	printf("DELETE(%s)\n", addrname(&af));
+	rn = ipf_rx_delete(rnh, &af, &mask);
+	if (rn == NULL) {
+		printf("FAIL LOOKUP DELETE\n");
+		checktree(rnh);
+		for (stp = myst_top; stp != NULL; stp = stp->next)
+			if (stp->printed != -1)
+				stp->printed = -2;
+		ipf_rx_walktree(rnh, nodeprinter, NULL);
+		dumptree(rnh);
+		abort();
+	}
+	printf("%d.delete(%s) = %s\n", item, addrname(&af), GNAME(rn));
+
+	for (pstp = &myst_top; (stp = *pstp) != NULL; pstp = &stp->next)
+		if (stp == (myst_t *)rn)
+			break;
+	stp->printed = -1;
+	stp->nodes[0].parent = &stp->nodes[0];
+	stp->nodes[1].parent = &stp->nodes[1];
+	*pstp = stp->next;
+	free(stp);
+	nodecount--;
+	checktree(rnh);
+}
+
+
+void
+add_addr(rnh, n, item)
+	ipf_rdx_head_t *rnh;
+	int n, item;
+{
+	ipf_rdx_node_t *rn;
+	myst_t *stp;
+
+	stp = calloc(1, sizeof(*stp));
+	rn = (ipf_rdx_node_t *)stp;
+	setaddr(&stp->dst, ttable[item].host);
+	stp->mask.adf_family = stp->dst.adf_family;
+	setmask(&stp->mask, ttable[item].mask);
+	stp->next = myst_top;
+	myst_top = stp;
+	(void) sprintf(rn[0].name, "_BORN.0");
+	(void) sprintf(rn[1].name, "_BORN.1");
+	rn = ipf_rx_addroute(rnh, &stp->dst, &stp->mask, stp->nodes);
+	(void) sprintf(rn[0].name, "%d_NODE.0", item);
+	(void) sprintf(rn[1].name, "%d_NODE.1", item);
+	printf("ADD %d/%d %s/%s\n", n, item, rn[0].name, rn[1].name);
+	nodecount++;
+	checktree(rnh);
+}
+
+
+void
+checktree(ipf_rdx_head_t *head)
+{
+	myst_t *s1;
+	ipf_rdx_node_t *rn;
+
+	if (nodecount <= 1)
+		return;
+
+	for (s1 = myst_top; s1 != NULL; s1 = s1->next) {
+		int fault = 0;
+		if (s1->printed == -1)
+			continue;
+		rn = &s1->nodes[1];
+		if (rn->right->parent != rn)
+			fault |= 1;
+		if (rn->left->parent != rn)
+			fault |= 2;
+		if (rn->parent->left != rn && rn->parent->right != rn)
+			fault |= 4;
+		if (fault != 0) {
+			printf("FAULT %#x %s\n", fault, rn->name);
+			dumptree(head);
+			ipf_rx_walktree(head, nodeprinter, NULL);
+			fflush(stdout);
+			fflush(stderr);
+			printf("--\n");
+			abort();
+		}
+	}
+}
+
+
+int *
+randomize(int *pnitems)
+{
+	int *order;
+	int nitems;
+	int choice;
+	int j;
+	int i;
+
+	nitems = sizeof(ttable) / sizeof(ttable[0]);
+	*pnitems = nitems;
+	order = calloc(nitems, sizeof(*order));
+	srandom(getpid() * time(NULL));
+	memset(order, 0xff, nitems * sizeof(*order));
+	order[21] = 21;
+	for (i = 0; i < nitems - 1; i++) {
+		do {
+			choice = rand() % (nitems - 1);
+			for (j = 0; j < nitems; j++)
+				if (order[j] == choice)
+					break;
+		} while (j != nitems);
+		order[i] = choice;
+	}
+
+	return order;
+}
+
+
+void
+random_add(rnh)
+	ipf_rdx_head_t *rnh;
+{
+	int *order;
+	int nitems;
+	int i;
+
+	order = randomize(&nitems);
+
+	for (i = 0; i < nitems - 1; i++) {
+		add_addr(rnh, i, order[i]);
+		checktree(rnh);
+	}
+}
+
+
+void
+random_delete(rnh)
+	ipf_rdx_head_t *rnh;
+{
+	int *order;
+	int nitems;
+	int i;
+
+	order = randomize(&nitems);
+
+	for (i = 0; i < nitems - 1; i++) {
+		delete_addr(rnh, i);
+		checktree(rnh);
+	}
+}
+#endif /* RDX_DEBUG */


Property changes on: trunk/contrib/ipfilter/radix_ipf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/sys/tree.h
===================================================================
--- trunk/contrib/ipfilter/sys/tree.h	                        (rev 0)
+++ trunk/contrib/ipfilter/sys/tree.h	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,750 @@
+/*	$NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $	*/
+/*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
+/* $FreeBSD: src/sys/sys/tree.h,v 1.7 2007/12/28 07:03:26 jasone Exp $ */
+
+/*-
+ * Copyright 2002 Niels Provos <provos at citi.umich.edu>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef	_SYS_TREE_H_
+#define	_SYS_TREE_H_
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure.  Every operation
+ * on the tree causes a splay to happen.  The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree.  On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n).  The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute.  It fulfills a set of conditions:
+ *	- every search path from the root to a leaf consists of the
+ *	  same number of black nodes,
+ *	- each red node (except for the root) has a black parent,
+ *	- each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type)						\
+struct name {								\
+	struct type *sph_root; /* root of the tree */			\
+}
+
+#define SPLAY_INITIALIZER(root)						\
+	{ NULL }
+
+#define SPLAY_INIT(root) do {						\
+	(root)->sph_root = NULL;					\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ENTRY(type)						\
+struct {								\
+	struct type *spe_left; /* left element */			\
+	struct type *spe_right; /* right element */			\
+}
+
+#define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
+#define SPLAY_ROOT(head)		(head)->sph_root
+#define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do {				\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do {				\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
+	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
+	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp)				\
+void name##_SPLAY(struct name *, struct type *);			\
+void name##_SPLAY_MINMAX(struct name *, int);				\
+struct type *name##_SPLAY_INSERT(struct name *, struct type *);		\
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *);		\
+									\
+/* Finds the node with the same key as elm */				\
+static __inline struct type *						\
+name##_SPLAY_FIND(struct name *head, struct type *elm)			\
+{									\
+	if (SPLAY_EMPTY(head))						\
+		return(NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0)				\
+		return (head->sph_root);				\
+	return (NULL);							\
+}									\
+									\
+static __inline struct type *						\
+name##_SPLAY_NEXT(struct name *head, struct type *elm)			\
+{									\
+	name##_SPLAY(head, elm);					\
+	if (SPLAY_RIGHT(elm, field) != NULL) {				\
+		elm = SPLAY_RIGHT(elm, field);				\
+		while (SPLAY_LEFT(elm, field) != NULL) {		\
+			elm = SPLAY_LEFT(elm, field);			\
+		}							\
+	} else								\
+		elm = NULL;						\
+	return (elm);							\
+}									\
+									\
+static __inline struct type *						\
+name##_SPLAY_MIN_MAX(struct name *head, int val)			\
+{									\
+	name##_SPLAY_MINMAX(head, val);					\
+        return (SPLAY_ROOT(head));					\
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp)				\
+struct type *								\
+name##_SPLAY_INSERT(struct name *head, struct type *elm)		\
+{									\
+    if (SPLAY_EMPTY(head)) {						\
+	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
+    } else {								\
+	    int __comp;							\
+	    name##_SPLAY(head, elm);					\
+	    __comp = (cmp)(elm, (head)->sph_root);			\
+	    if(__comp < 0) {						\
+		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
+		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
+		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
+	    } else if (__comp > 0) {					\
+		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
+		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
+		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
+	    } else							\
+		    return ((head)->sph_root);				\
+    }									\
+    (head)->sph_root = (elm);						\
+    return (NULL);							\
+}									\
+									\
+struct type *								\
+name##_SPLAY_REMOVE(struct name *head, struct type *elm)		\
+{									\
+	struct type *__tmp;						\
+	if (SPLAY_EMPTY(head))						\
+		return (NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0) {			\
+		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
+			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
+		} else {						\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
+			name##_SPLAY(head, elm);			\
+			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
+		}							\
+		return (elm);						\
+	}								\
+	return (NULL);							\
+}									\
+									\
+void									\
+name##_SPLAY(struct name *head, struct type *elm)			\
+{									\
+	struct type __node, *__left, *__right, *__tmp;			\
+	int __comp;							\
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {		\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) < 0){			\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) > 0){			\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}									\
+									\
+/* Splay with either the minimum or the maximum element			\
+ * Used to find minimum or maximum element in tree.			\
+ */									\
+void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+{									\
+	struct type __node, *__left, *__right, *__tmp;			\
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while (1) {							\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp < 0){				\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp > 0) {				\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}
+
+#define SPLAY_NEGINF	-1
+#define SPLAY_INF	1
+
+#define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head)					\
+	for ((x) = SPLAY_MIN(name, head);				\
+	     (x) != NULL;						\
+	     (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type)						\
+struct name {								\
+	struct type *rbh_root; /* root of the tree */			\
+}
+
+#define RB_INITIALIZER(root)						\
+	{ NULL }
+
+#define RB_INIT(root) do {						\
+	(root)->rbh_root = NULL;					\
+} while (/*CONSTCOND*/ 0)
+
+/*
+ * Undef for Linux
+ */
+#undef	RB_BLACK
+#undef	RB_RED
+#undef	RB_ROOT
+
+#define RB_BLACK	0
+#define RB_RED		1
+#define RB_ENTRY(type)							\
+struct {								\
+	struct type *rbe_left;		/* left element */		\
+	struct type *rbe_right;		/* right element */		\
+	struct type *rbe_parent;	/* parent element */		\
+	int rbe_color;			/* node color */		\
+}
+
+#define RB_LEFT(elm, field)		(elm)->field.rbe_left
+#define RB_RIGHT(elm, field)		(elm)->field.rbe_right
+#define RB_PARENT(elm, field)		(elm)->field.rbe_parent
+#define RB_COLOR(elm, field)		(elm)->field.rbe_color
+#define RB_ROOT(head)			(head)->rbh_root
+#define RB_EMPTY(head)			(RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do {					\
+	RB_PARENT(elm, field) = parent;					\
+	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
+	RB_COLOR(elm, field) = RB_RED;					\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_SET_BLACKRED(black, red, field) do {				\
+	RB_COLOR(black, field) = RB_BLACK;				\
+	RB_COLOR(red, field) = RB_RED;					\
+} while (/*CONSTCOND*/ 0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)	do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
+	(tmp) = RB_RIGHT(elm, field);					\
+	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {	\
+		RB_PARENT(RB_LEFT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_LEFT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
+	(tmp) = RB_LEFT(elm, field);					\
+	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {	\
+		RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_RIGHT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+#define	RB_PROTOTYPE(name, type, field, cmp)				\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define	RB_PROTOTYPE_STATIC(name, type, field, cmp)			\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)		\
+attr void name##_RB_INSERT_COLOR(struct name *, struct type *);		\
+attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+attr struct type *name##_RB_REMOVE(struct name *, struct type *);	\
+attr struct type *name##_RB_INSERT(struct name *, struct type *);	\
+attr struct type *name##_RB_FIND(struct name *, struct type *);		\
+attr struct type *name##_RB_NFIND(struct name *, struct type *);	\
+attr struct type *name##_RB_NEXT(struct type *);			\
+attr struct type *name##_RB_PREV(struct type *);			\
+attr struct type *name##_RB_MINMAX(struct name *, int);			\
+									\
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define	RB_GENERATE(name, type, field, cmp)				\
+	RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define	RB_GENERATE_STATIC(name, type, field, cmp)			\
+	RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)		\
+attr void								\
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
+{									\
+	struct type *parent, *gparent, *tmp;				\
+	while ((parent = RB_PARENT(elm, field)) != NULL &&		\
+	    RB_COLOR(parent, field) == RB_RED) {			\
+		gparent = RB_PARENT(parent, field);			\
+		if (parent == RB_LEFT(gparent, field)) {		\
+			tmp = RB_RIGHT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_RIGHT(parent, field) == elm) {		\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_RIGHT(head, gparent, tmp, field);	\
+		} else {						\
+			tmp = RB_LEFT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_LEFT(parent, field) == elm) {		\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_LEFT(head, gparent, tmp, field);	\
+		}							\
+	}								\
+	RB_COLOR(head->rbh_root, field) = RB_BLACK;			\
+}									\
+									\
+attr void								\
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
+{									\
+	struct type *tmp;						\
+	while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&	\
+	    elm != RB_ROOT(head)) {					\
+		if (RB_LEFT(parent, field) == elm) {			\
+			tmp = RB_RIGHT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = RB_RIGHT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_RIGHT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
+					struct type *oleft;		\
+					if ((oleft = RB_LEFT(tmp, field)) \
+					    != NULL)			\
+						RB_COLOR(oleft, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_RIGHT(head, tmp, oleft, field);\
+					tmp = RB_RIGHT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_RIGHT(tmp, field))		\
+					RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				elm = RB_ROOT(head);			\
+				break;					\
+			}						\
+		} else {						\
+			tmp = RB_LEFT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = RB_LEFT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_LEFT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
+					struct type *oright;		\
+					if ((oright = RB_RIGHT(tmp, field)) \
+					    != NULL)			\
+						RB_COLOR(oright, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_LEFT(head, tmp, oright, field);\
+					tmp = RB_LEFT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_LEFT(tmp, field))		\
+					RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				elm = RB_ROOT(head);			\
+				break;					\
+			}						\
+		}							\
+	}								\
+	if (elm)							\
+		RB_COLOR(elm, field) = RB_BLACK;			\
+}									\
+									\
+attr struct type *							\
+name##_RB_REMOVE(struct name *head, struct type *elm)			\
+{									\
+	struct type *child, *parent, *old = elm;			\
+	int color;							\
+	if (RB_LEFT(elm, field) == NULL)				\
+		child = RB_RIGHT(elm, field);				\
+	else if (RB_RIGHT(elm, field) == NULL)				\
+		child = RB_LEFT(elm, field);				\
+	else {								\
+		struct type *left;					\
+		elm = RB_RIGHT(elm, field);				\
+		while ((left = RB_LEFT(elm, field)) != NULL)		\
+			elm = left;					\
+		child = RB_RIGHT(elm, field);				\
+		parent = RB_PARENT(elm, field);				\
+		color = RB_COLOR(elm, field);				\
+		if (child)						\
+			RB_PARENT(child, field) = parent;		\
+		if (parent) {						\
+			if (RB_LEFT(parent, field) == elm)		\
+				RB_LEFT(parent, field) = child;		\
+			else						\
+				RB_RIGHT(parent, field) = child;	\
+			RB_AUGMENT(parent);				\
+		} else							\
+			RB_ROOT(head) = child;				\
+		if (RB_PARENT(elm, field) == old)			\
+			parent = elm;					\
+		(elm)->field = (old)->field;				\
+		if (RB_PARENT(old, field)) {				\
+			if (RB_LEFT(RB_PARENT(old, field), field) == old)\
+				RB_LEFT(RB_PARENT(old, field), field) = elm;\
+			else						\
+				RB_RIGHT(RB_PARENT(old, field), field) = elm;\
+			RB_AUGMENT(RB_PARENT(old, field));		\
+		} else							\
+			RB_ROOT(head) = elm;				\
+		RB_PARENT(RB_LEFT(old, field), field) = elm;		\
+		if (RB_RIGHT(old, field))				\
+			RB_PARENT(RB_RIGHT(old, field), field) = elm;	\
+		if (parent) {						\
+			left = parent;					\
+			do {						\
+				RB_AUGMENT(left);			\
+			} while ((left = RB_PARENT(left, field)) != NULL); \
+		}							\
+		goto color;						\
+	}								\
+	parent = RB_PARENT(elm, field);					\
+	color = RB_COLOR(elm, field);					\
+	if (child)							\
+		RB_PARENT(child, field) = parent;			\
+	if (parent) {							\
+		if (RB_LEFT(parent, field) == elm)			\
+			RB_LEFT(parent, field) = child;			\
+		else							\
+			RB_RIGHT(parent, field) = child;		\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT(head) = child;					\
+color:									\
+	if (color == RB_BLACK)						\
+		name##_RB_REMOVE_COLOR(head, parent, child);		\
+	return (old);							\
+}									\
+									\
+/* Inserts a node into the RB tree */					\
+attr struct type *							\
+name##_RB_INSERT(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp;						\
+	struct type *parent = NULL;					\
+	int comp = 0;							\
+	tmp = RB_ROOT(head);						\
+	while (tmp) {							\
+		parent = tmp;						\
+		comp = (cmp)(elm, parent);				\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	RB_SET(elm, parent, field);					\
+	if (parent != NULL) {						\
+		if (comp < 0)						\
+			RB_LEFT(parent, field) = elm;			\
+		else							\
+			RB_RIGHT(parent, field) = elm;			\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT(head) = elm;					\
+	name##_RB_INSERT_COLOR(head, elm);				\
+	return (NULL);							\
+}									\
+									\
+/* Finds the node with the same key as elm */				\
+attr struct type *							\
+name##_RB_FIND(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (NULL);							\
+}									\
+									\
+/* Finds the first node greater than or equal to the search key */	\
+attr struct type *							\
+name##_RB_NFIND(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	struct type *res = NULL;					\
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0) {						\
+			res = tmp;					\
+			tmp = RB_LEFT(tmp, field);			\
+		}							\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (res);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr struct type *							\
+name##_RB_NEXT(struct type *elm)					\
+{									\
+	if (RB_RIGHT(elm, field)) {					\
+		elm = RB_RIGHT(elm, field);				\
+		while (RB_LEFT(elm, field))				\
+			elm = RB_LEFT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr struct type *							\
+name##_RB_PREV(struct type *elm)					\
+{									\
+	if (RB_LEFT(elm, field)) {					\
+		elm = RB_LEFT(elm, field);				\
+		while (RB_RIGHT(elm, field))				\
+			elm = RB_RIGHT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+attr struct type *							\
+name##_RB_MINMAX(struct name *head, int val)				\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	struct type *parent = NULL;					\
+	while (tmp) {							\
+		parent = tmp;						\
+		if (val < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else							\
+			tmp = RB_RIGHT(tmp, field);			\
+	}								\
+	return (parent);						\
+}
+
+#define RB_NEGINF	-1
+#define RB_INF	1
+
+#define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y)	name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
+#define RB_PREV(name, x, y)	name##_RB_PREV(y)
+#define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head)					\
+	for ((x) = RB_MIN(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_REVERSE(x, name, head)				\
+	for ((x) = RB_MAX(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_PREV(x))
+
+#endif	/* _SYS_TREE_H_ */


Property changes on: trunk/contrib/ipfilter/sys/tree.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/contrib/ipfilter/tools/ipfsyncd.c
===================================================================
--- trunk/contrib/ipfilter/tools/ipfsyncd.c	                        (rev 0)
+++ trunk/contrib/ipfilter/tools/ipfsyncd.c	2018-07-01 23:55:17 UTC (rev 11254)
@@ -0,0 +1,671 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipfsyncd.c,v 1.1.2.2 2012/07/22 08:04:24 darren_r Exp $";
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#include <sys/errno.h>
+
+#include <netinet/in.h>
+#include <net/if.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+
+#include "ipf.h"
+#include "opts.h"
+
+
+#define	R_IO_ERROR	-1
+#define	R_OKAY		0
+#define	R_MORE		1
+#define	R_SKIP		2
+#if	defined(sun) && !defined(SOLARIS2)
+# define	STRERROR(x)     sys_errlist[x]
+extern  char    *sys_errlist[];
+#else
+# define	STRERROR(x)     strerror(x)
+#endif
+
+
+int	main __P((int, char *[]));
+void	usage __P((char *));
+void	printsynchdr __P((synchdr_t *));
+void	printtable __P((int));
+void	printsmcproto __P((char *));
+void	printcommand __P((int));
+int	do_kbuff __P((int, char *, int *));
+int	do_packet __P((int, char *));
+int	buildsocket __P((char *, struct sockaddr_in *));
+void	do_io __P((void));
+void	handleterm __P((int));
+
+int	terminate = 0;
+int	igmpfd = -1;
+int	nfd = -1;
+int	lfd = -1;
+int	opts = 0;
+
+void
+usage(progname)
+	char *progname;
+{
+	fprintf(stderr,
+		"Usage: %s [-d] [-p port] [-i address] -I <interface>\n",
+		progname);
+}
+
+void
+handleterm(sig)
+	int sig;
+{
+	terminate = sig;
+}
+
+
+/* should be large enough to hold header + any datatype */
+#define BUFFERLEN 1400
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	struct sockaddr_in sin;
+	char *interface;
+	char *progname;
+	int opt, tries;
+
+	progname = strrchr(argv[0], '/');
+	if (progname) {
+		progname++;
+	} else {
+		progname = argv[0];
+	}
+
+	opts = 0;
+	tries = 0;
+	interface = NULL;
+
+	bzero((char *)&sin, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(0xaf6c);
+	sin.sin_addr.s_addr = htonl(INADDR_UNSPEC_GROUP | 0x697066);
+
+	while ((opt = getopt(argc, argv, "di:I:p:")) != -1)
+		switch (opt)
+		{
+		case 'd' :
+			debuglevel++;
+			break;
+		case 'I' :
+			interface = optarg;
+			break;
+		case 'i' :
+			sin.sin_addr.s_addr = inet_addr(optarg);
+			break;
+		case 'p' :
+			sin.sin_port = htons(atoi(optarg));
+			break;
+		}
+
+	if (interface == NULL) {
+		usage(progname);
+		exit(1);
+	}
+
+	if (!debuglevel) {
+
+#if BSD >= 199306
+		daemon(0, 0);
+#else
+		int fd = open("/dev/null", O_RDWR);
+
+		switch (fork())
+		{
+		case 0 :
+			break;
+
+		case -1 :
+			fprintf(stderr, "%s: fork() failed: %s\n",
+				argv[0], STRERROR(errno));
+			exit(1);
+			/* NOTREACHED */
+
+		default :
+			exit(0);
+			/* NOTREACHED */
+		}
+
+		dup2(fd, 0);
+		dup2(fd, 1);
+		dup2(fd, 2);
+		close(fd);
+
+		setsid();
+#endif
+	}
+
+       	signal(SIGHUP, handleterm);
+       	signal(SIGINT, handleterm);
+       	signal(SIGTERM, handleterm);
+
+	openlog(progname, LOG_PID, LOG_SECURITY);
+
+	while (!terminate) {
+		if (lfd != -1) {
+			close(lfd);
+			lfd = -1;
+		}
+		if (nfd != -1) {
+			close(nfd);
+			nfd = -1;
+		}
+		if (igmpfd != -1) {
+			close(igmpfd);
+			igmpfd = -1;
+		}
+
+		if (buildsocket(interface, &sin) == -1)
+			goto tryagain;
+
+		lfd = open(IPSYNC_NAME, O_RDWR);
+		if (lfd == -1) {
+			syslog(LOG_ERR, "open(%s):%m", IPSYNC_NAME);
+			debug(1, "open(%s): %s\n", IPSYNC_NAME,
+			      STRERROR(errno));
+			goto tryagain;
+		}
+
+		tries = -1;
+		do_io();
+tryagain:
+		tries++;
+		syslog(LOG_INFO, "retry in %d seconds", 1 << tries);
+		debug(1, "wait %d seconds\n", 1 << tries);
+		sleep(1 << tries);
+	}
+
+
+	/* terminate */
+	if (lfd != -1)
+		close(lfd);
+	if (nfd != -1)
+		close(nfd);
+
+	syslog(LOG_ERR, "signal %d received, exiting...", terminate);
+	debug(1, "signal %d received, exiting...", terminate);
+
+	exit(1);
+}
+
+
+void
+do_io()
+{
+	char nbuff[BUFFERLEN];
+	char buff[BUFFERLEN];
+	fd_set mrd, rd;
+	int maxfd;
+	int inbuf;
+	int n1;
+	int left;
+
+	FD_ZERO(&mrd);
+	FD_SET(lfd, &mrd);
+	FD_SET(nfd, &mrd);
+	maxfd = nfd;
+	if (lfd > maxfd)
+		maxfd = lfd;
+	debug(2, "nfd %d lfd %d maxfd %d\n", nfd, lfd, maxfd);
+
+	inbuf = 0;
+	/*
+	 * A threaded approach to this loop would have one thread
+	 * work on reading lfd (only) all the time and another thread
+	 * working on reading nfd all the time.
+	 */
+	while (!terminate) {
+		int n;
+
+		rd = mrd;
+
+		n = select(maxfd + 1, &rd, NULL, NULL, NULL);
+		if (n < 0) {
+			switch (errno)
+			{
+			case EINTR :
+				continue;
+			default :
+				syslog(LOG_ERR, "select error: %m");
+				debug(1, "select error: %s\n", STRERROR(errno));
+				return;
+			}
+		}
+
+		if (FD_ISSET(lfd, &rd)) {
+			n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf);
+
+			debug(3, "read(K):%d\n", n1);
+
+			if (n1 <= 0) {
+				syslog(LOG_ERR, "read error (k-header): %m");
+				debug(1, "read error (k-header): %s\n",
+				      STRERROR(errno));
+				return;
+			}
+
+			left = 0;
+
+			switch (do_kbuff(n1, buff, &left))
+			{
+			case R_IO_ERROR :
+				return;
+			case R_MORE :
+				inbuf += left;
+				break;
+			default :
+				inbuf = 0;
+				break;
+			}
+		}
+
+		if (FD_ISSET(nfd, &rd)) {
+			n1 = recv(nfd, nbuff, sizeof(nbuff), 0);
+
+			debug(3, "read(N):%d\n", n1);
+
+			if (n1 <= 0) {
+				syslog(LOG_ERR, "read error (n-header): %m");
+				debug(1, "read error (n-header): %s\n",
+				      STRERROR(errno));
+				return;
+			}
+
+			switch (do_packet(n1, nbuff))
+			{
+			case R_IO_ERROR :
+				return;
+			default :
+				break;
+			}
+		}
+	}
+}
+
+
+int
+buildsocket(nicname, sinp)
+	char *nicname;
+	struct sockaddr_in *sinp;
+{
+	struct sockaddr_in *reqip;
+	struct ifreq req;
+	char opt;
+
+	debug(2, "binding to %s:%s\n", nicname, inet_ntoa(sinp->sin_addr));
+
+	if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+		struct in_addr addr;
+		struct ip_mreq mreq;
+
+		igmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
+		if (igmpfd == -1) {
+			syslog(LOG_ERR, "socket:%m");
+			debug(1, "socket:%s\n", STRERROR(errno));
+			return -1;
+		}
+
+		bzero((char *)&req, sizeof(req));
+		strncpy(req.ifr_name, nicname, sizeof(req.ifr_name));
+		req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
+		if (ioctl(igmpfd, SIOCGIFADDR, &req) == -1) {
+			syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m");
+			debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno));
+			close(igmpfd);
+			igmpfd = -1;
+			return -1;
+		}
+		reqip = (struct sockaddr_in *)&req.ifr_addr;
+
+		addr = reqip->sin_addr;
+		if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_IF,
+			       (char *)&addr, sizeof(addr)) == -1) {
+			syslog(LOG_ERR, "setsockopt(IP_MULTICAST_IF(%s)):%m",
+			       inet_ntoa(addr));
+			debug(1, "setsockopt(IP_MULTICAST_IF(%s)):%s\n",
+			      inet_ntoa(addr), STRERROR(errno));
+			close(igmpfd);
+			igmpfd = -1;
+			return -1;
+		}
+
+		opt = 0;
+		if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_LOOP,
+			       (char *)&opt, sizeof(opt)) == -1) {
+			syslog(LOG_ERR, "setsockopt(IP_MULTICAST_LOOP=0):%m");
+			debug(1, "setsockopt(IP_MULTICAST_LOOP=0):%s\n",
+			      STRERROR(errno));
+			close(igmpfd);
+			igmpfd = -1;
+			return -1;
+		}
+
+		opt = 63;
+		if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_TTL,
+			       (char *)&opt, sizeof(opt)) == -1) {
+			syslog(LOG_ERR, "setsockopt(IP_MULTICAST_TTL=%d):%m",
+			       opt);
+			debug(1, "setsockopt(IP_MULTICAST_TTL=%d):%s\n", opt,
+			      STRERROR(errno));
+			close(igmpfd);
+			igmpfd = -1;
+			return -1;
+		}
+
+		mreq.imr_multiaddr.s_addr = sinp->sin_addr.s_addr;
+		mreq.imr_interface.s_addr = reqip->sin_addr.s_addr;
+
+		if (setsockopt(igmpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+			       (char *)&mreq, sizeof(mreq)) == -1) {
+			char buffer[80];
+
+			sprintf(buffer, "%s,", inet_ntoa(sinp->sin_addr));
+			strcat(buffer, inet_ntoa(reqip->sin_addr));
+
+			syslog(LOG_ERR,
+			       "setsockpt(IP_ADD_MEMBERSHIP,%s):%m", buffer);
+			debug(1, "setsockpt(IP_ADD_MEMBERSHIP,%s):%s\n",
+			      buffer, STRERROR(errno));
+			close(igmpfd);
+			igmpfd = -1;
+			return -1;
+		}
+	}
+	nfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (nfd == -1) {
+		syslog(LOG_ERR, "socket:%m");
+		if (igmpfd != -1) {
+			close(igmpfd);
+			igmpfd = -1;
+		}
+		return -1;
+	}
+	bzero((char *)&req, sizeof(req));
+	strncpy(req.ifr_name, nicname, sizeof(req.ifr_name));
+	req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
+	if (ioctl(nfd, SIOCGIFADDR, &req) == -1) {
+		syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m");
+		debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno));
+		close(igmpfd);
+		igmpfd = -1;
+		return -1;
+	}
+
+	if (bind(nfd, (struct sockaddr *)&req.ifr_addr,
+		 sizeof(req.ifr_addr)) == -1) {
+		syslog(LOG_ERR, "bind:%m");
+		debug(1, "bind:%s\n", STRERROR(errno));
+		close(nfd);
+		if (igmpfd != -1) {
+			close(igmpfd);
+			igmpfd = -1;
+		}
+		nfd = -1;
+		return -1;
+	}
+
+	if (connect(nfd, (struct sockaddr *)sinp, sizeof(*sinp)) == -1) {
+		syslog(LOG_ERR, "connect:%m");
+		debug(1, "connect:%s\n", STRERROR(errno));
+		close(nfd);
+		if (igmpfd != -1) {
+			close(igmpfd);
+			igmpfd = -1;
+		}
+		nfd = -1;
+		return -1;
+	}
+	syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sinp->sin_addr));
+	debug(3, "Sending data to %s\n", inet_ntoa(sinp->sin_addr));
+
+	return nfd;
+}
+
+
+int
+do_packet(pklen, buff)
+	int pklen;
+	char *buff;
+{
+	synchdr_t *sh;
+	u_32_t magic;
+	int len;
+	int n2;
+	int n3;
+
+	while (pklen > 0) {
+		if (pklen < sizeof(*sh)) {
+			syslog(LOG_ERR, "packet length too short:%d", pklen);
+			debug(2, "packet length too short:%d\n", pklen);
+			return R_SKIP;
+		}
+
+		sh = (synchdr_t *)buff;
+		len = ntohl(sh->sm_len);
+		magic = ntohl(sh->sm_magic);
+
+		if (magic != SYNHDRMAGIC) {
+			syslog(LOG_ERR, "invalid header magic %x", magic);
+			debug(2, "invalid header magic %x\n", magic);
+			return R_SKIP;
+		}
+
+		if (pklen < len + sizeof(*sh)) {
+			syslog(LOG_ERR, "packet length too short:%d", pklen);
+			debug(2, "packet length too short:%d\n", pklen);
+			return R_SKIP;
+		}
+
+		if (debuglevel > 3) {
+			printsynchdr(sh);
+			printcommand(sh->sm_cmd);
+			printtable(sh->sm_table);
+			printsmcproto(buff);
+		}
+
+		n2 = sizeof(*sh) + len;
+
+		do {
+			n3 = write(lfd, buff, n2);
+			if (n3 <= 0) {
+				syslog(LOG_ERR, "write error: %m");
+				debug(1, "write error: %s\n", STRERROR(errno));
+				return R_IO_ERROR;
+			}
+
+			n2 -= n3;
+			buff += n3;
+			pklen -= n3;
+		} while (n3 != 0);
+	}
+
+	return R_OKAY;
+}
+
+
+
+int
+do_kbuff(inbuf, buf, left)
+	int inbuf, *left;
+	char *buf;
+{
+	synchdr_t *sh;
+	u_32_t magic;
+	int complete;
+	int sendlen;
+	int error;
+	int bytes;
+	int len;
+	int n2;
+	int n3;
+
+	sendlen = 0;
+	bytes = inbuf;
+	error = R_OKAY;
+	sh = (synchdr_t *)buf;
+
+	for (complete = 0; bytes > 0; complete++) {
+		len = ntohl(sh->sm_len);
+		magic = ntohl(sh->sm_magic);
+
+		if (magic != SYNHDRMAGIC) {
+			syslog(LOG_ERR,
+			       "read invalid header magic 0x%x, flushing",
+			       magic);
+			debug(2, "read invalid header magic 0x%x, flushing\n",
+			       magic);
+			n2 = SMC_RLOG;
+			(void) ioctl(lfd, SIOCIPFFL, &n2);
+			break;
+		}
+
+		if (debuglevel > 3) {
+			printsynchdr(sh);
+			printcommand(sh->sm_cmd);
+			printtable(sh->sm_table);
+			putchar('\n');
+		}
+
+		if (bytes < sizeof(*sh) + len) {
+			debug(3, "Not enough bytes %d < %d\n", bytes,
+			      sizeof(*sh) + len);
+			error = R_MORE;
+			break;
+		}
+
+		if (debuglevel > 3) {
+			printsmcproto(buf);
+		}
+
+		sendlen += len + sizeof(*sh);
+		sh = (synchdr_t *)(buf + sendlen);
+		bytes -= sendlen;
+	}
+
+	if (complete) {
+		n3 = send(nfd, buf, sendlen, 0);
+		if (n3 <= 0) {
+			syslog(LOG_ERR, "write error: %m");
+			debug(1, "write error: %s\n", STRERROR(errno));
+			return R_IO_ERROR;
+		}
+		debug(3, "send on %d len %d = %d\n", nfd, sendlen, n3);
+		error = R_OKAY;
+	}
+
+	/* move buffer to the front,we might need to make
+	 * this more efficient, by using a rolling pointer
+	 * over the buffer and only copying it, when
+	 * we are reaching the end
+	 */
+	if (bytes > 0) {
+		bcopy(buf + bytes, buf, bytes);
+		error = R_MORE;
+	}
+	debug(4, "complete %d bytes %d error %d\n", complete, bytes, error);
+
+	*left = bytes;
+
+	return error;
+}
+
+
+void
+printcommand(cmd)
+	int cmd;
+{
+
+	switch (cmd)
+	{
+	case SMC_CREATE :
+		printf(" cmd:CREATE");
+		break;
+	case SMC_UPDATE :
+		printf(" cmd:UPDATE");
+		break;
+	default :
+		printf(" cmd:Unknown(%d)", cmd);
+		break;
+	}
+}
+
+
+void
+printtable(table)
+	int table;
+{
+	switch (table)
+	{
+	case SMC_NAT :
+		printf(" table:NAT");
+		break;
+	case SMC_STATE :
+		printf(" table:STATE");
+		break;
+	default :
+		printf(" table:Unknown(%d)", table);
+		break;
+	}
+}
+
+
+void
+printsmcproto(buff)
+	char *buff;
+{
+	syncupdent_t *su;
+	synchdr_t *sh;
+
+	sh = (synchdr_t *)buff;
+
+	if (sh->sm_cmd == SMC_CREATE) {
+		;
+
+	} else if (sh->sm_cmd == SMC_UPDATE) {
+		su = (syncupdent_t *)buff;
+		if (sh->sm_p == IPPROTO_TCP) {
+			printf(" TCP Update: age %lu state %d/%d\n",
+				su->sup_tcp.stu_age,
+				su->sup_tcp.stu_state[0],
+				su->sup_tcp.stu_state[1]);
+		}
+	} else {
+		printf("Unknown command\n");
+	}
+}
+
+
+void
+printsynchdr(sh)
+	synchdr_t *sh;
+{
+
+	printf("v:%d p:%d num:%d len:%d magic:%x", sh->sm_v, sh->sm_p,
+	       ntohl(sh->sm_num), ntohl(sh->sm_len), ntohl(sh->sm_magic));
+}


Property changes on: trunk/contrib/ipfilter/tools/ipfsyncd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list