[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