Module Name:    src
Committed By:   darrenr
Date:           Sat Apr 17 21:00:44 UTC 2010

Modified Files:
        src/sys/dist/ipf/netinet: fil.c ip_auth.c ip_compat.h ip_fil.h
            ip_fil_netbsd.c ip_lookup.c ip_nat.c ip_state.c ip_sync.c ipl.h

Log Message:
Commit IPFilter 4.1.34 to HEAD


To generate a diff of this commit:
cvs rdiff -u -r1.45 -r1.46 src/sys/dist/ipf/netinet/fil.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dist/ipf/netinet/ip_auth.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dist/ipf/netinet/ip_compat.h
cvs rdiff -u -r1.18 -r1.19 src/sys/dist/ipf/netinet/ip_fil.h
cvs rdiff -u -r1.53 -r1.54 src/sys/dist/ipf/netinet/ip_fil_netbsd.c
cvs rdiff -u -r1.15 -r1.16 src/sys/dist/ipf/netinet/ip_lookup.c
cvs rdiff -u -r1.40 -r1.41 src/sys/dist/ipf/netinet/ip_nat.c
cvs rdiff -u -r1.35 -r1.36 src/sys/dist/ipf/netinet/ip_state.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dist/ipf/netinet/ip_sync.c \
    src/sys/dist/ipf/netinet/ipl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dist/ipf/netinet/fil.c
diff -u src/sys/dist/ipf/netinet/fil.c:1.45 src/sys/dist/ipf/netinet/fil.c:1.46
--- src/sys/dist/ipf/netinet/fil.c:1.45	Wed Aug 19 08:36:10 2009
+++ src/sys/dist/ipf/netinet/fil.c	Sat Apr 17 21:00:44 2010
@@ -1,7 +1,7 @@
-/*	$NetBSD: fil.c,v 1.45 2009/08/19 08:36:10 darrenr Exp $	*/
+/*	$NetBSD: fil.c,v 1.46 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
- * Copyright (C) 1993-2003 by Darren Reed.
+ * Copyright (C) 1993-2010 by Darren Reed.
  *
  * See the IPFILTER.LICENCE file for details on licencing.
  *
@@ -157,10 +157,10 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.45 2009/08/19 08:36:10 darrenr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.46 2010/04/17 21:00:44 darrenr Exp $");
 #else
 static const char sccsid[] = "@(#)fil.c	1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.147 2009/07/21 22:25:28 darrenr Exp";
+static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.154 2010/02/24 10:07:57 darrenr Exp";
 #endif
 #endif
 
@@ -240,6 +240,7 @@
 static	ipfunc_t	fr_findfunc __P((ipfunc_t));
 static	frentry_t	*fr_firewall __P((fr_info_t *, u_32_t *));
 static	int		fr_funcinit __P((frentry_t *fr));
+static	void		fr_getstat __P((struct friostat *, int));
 static	INLINE void	frpr_ah __P((fr_info_t *));
 static	INLINE void	frpr_esp __P((fr_info_t *));
 static	INLINE void	frpr_gre __P((fr_info_t *));
@@ -525,7 +526,7 @@
 /*                                                                          */
 /* IPv6 Only                                                                */
 /* This function expects to find an IPv6 extension header at fin_dp.        */
-/* There must be at least 8 bytes of data at fin_dp for there to be a valid */
+/* There must be at least 8 Bytes of data at fin_dp for there to be a valid */
 /* extension header present. If a good one is found, fin_dp is advanced to  */
 /* point at the first piece of data after the extension header, fin_exthdr  */
 /* points to the start of the extension header and the "protocol" of the    */
@@ -2270,6 +2271,12 @@
 		if (fin->fin_fr != NULL)
 			pass = fr_scanlist(fin, fr_pass);
 
+		fr = fin->fin_fr;
+		if ((fr != NULL) && (fr->fr_type == FR_T_IPF) &&
+		    ((fr->fr_satype == FRI_LOOKUP) ||
+		     (fr->fr_datype == FRI_LOOKUP)))
+			fin->fin_flx |= FI_DONTCACHE;
+
 		if (((pass & FR_KEEPSTATE) == 0) &&
 		    ((fin->fin_flx & FI_DONTCACHE) == 0)) {
 			WRITE_ENTER(&ipf_frcache);
@@ -2279,7 +2286,6 @@
 		if ((pass & FR_NOMATCH)) {
 			ATOMIC_INCL(frstats[out].fr_nom);
 		}
-		fr = fin->fin_fr;
 	}
 
 	/*
@@ -3201,7 +3207,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
- * Id: fil.c,v 2.243.2.147 2009/07/21 22:25:28 darrenr Exp
+ * Id: fil.c,v 2.243.2.154 2010/02/24 10:07:57 darrenr Exp
  */
 /*
  * Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -3724,7 +3730,7 @@
 			fr->fr_ifas[i] = fr_resolvenic(fr->fr_ifnames[i], v);
 		}
 
-		if (fr->fr_type == FR_T_IPF) {
+		if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) {
 			if (fr->fr_satype != FRI_NORMAL &&
 			    fr->fr_satype != FRI_LOOKUP) {
 				(void)fr_ifpaddr(v, fr->fr_satype,
@@ -3758,15 +3764,15 @@
 		}
 
 #ifdef	IPFILTER_LOOKUP
-		if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP &&
-		    fr->fr_srcptr == NULL) {
+		if (((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) &&
+		    (fr->fr_satype == FRI_LOOKUP) && (fr->fr_srcptr == NULL)) {
 			fr->fr_srcptr = fr_resolvelookup(fr->fr_srctype,
 							 fr->fr_srcsubtype,
 							 &fr->fr_slookup,
 							 &fr->fr_srcfunc);
 		}
-		if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP &&
-		    fr->fr_dstptr == NULL) {
+		if (((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) &&
+		    (fr->fr_datype == FRI_LOOKUP) && (fr->fr_dstptr == NULL)) {
 			fr->fr_dstptr = fr_resolvelookup(fr->fr_dsttype,
 							 fr->fr_dstsubtype,
 							 &fr->fr_dlookup,
@@ -3914,12 +3920,18 @@
 /* Function:    fr_getstat                                                  */
 /* Returns:     Nil                                                         */
 /* Parameters:  fiop(I)  - pointer to ipfilter stats structure              */
+/*              rev(I)   - version of program doing ioctl                   */
 /*                                                                          */
 /* Stores a copy of current pointers, counters, etc, in the friostat        */
 /* structure.                                                               */
+/* If IPFILTER_COMPAT is compiled, we pretend to be whatever version the    */
+/* program is looking for. This ensure that validation of the version it    */
+/* expects will always succeed. Thus kernels with IPFILTER_COMPAT will      */
+/* allow older binaries to work but kernels without it will not.            */
 /* ------------------------------------------------------------------------ */
-void fr_getstat(fiop)
+static void fr_getstat(fiop, rev)
 friostat_t *fiop;
+int rev;
 {
 	int i, j;
 
@@ -3954,8 +3966,18 @@
 #endif
 	fiop->f_defpass = fr_pass;
 	fiop->f_features = fr_features;
+
+
+#ifdef IPFILTER_COMPAT
+	sprintf(fiop->f_version, "IP Filter: v%d.%d.%d",
+		       (rev / 1000000) % 100,
+		       (rev / 10000) % 100,
+		       (rev / 100) % 100);
+#else
+	rev = rev;
 	(void) strncpy(fiop->f_version, ipfilter_version,
 		       sizeof(fiop->f_version));
+#endif
 }
 
 
@@ -4161,7 +4183,7 @@
 void *data;
 {
 	frentry_t frd, *fp, *f, **fprev, **ftail;
-	int error = 0, in, v;
+	int error = 0, in, v, need_free = 0;
 	void *ptr, *uptr;
 	u_int *p, *pp;
 	frgroup_t *fg;
@@ -4170,10 +4192,10 @@
 	fg = NULL;
 	fp = &frd;
 	if (makecopy != 0) {
-		error = fr_inobj(data, fp, IPFOBJ_FRENTRY);
+		error = fr_inobj(data, NULL, fp, IPFOBJ_FRENTRY);
 		if (error)
 			return EFAULT;
-		if ((fp->fr_flags & FR_T_BUILTIN) != 0)
+		if ((fp->fr_type & FR_T_BUILTIN) != 0)
 			return EINVAL;
 		fp->fr_ref = 0;
 		fp->fr_flags |= FR_COPIED;
@@ -4283,7 +4305,6 @@
 				error = EFAULT;
 		} else {
 			ptr = uptr;
-			error = 0;
 		}
 		if (error != 0) {
 			KFREES(ptr, fp->fr_dsize);
@@ -4295,24 +4316,20 @@
 
 	/*
 	 * Perform per-rule type sanity checks of their members.
+	 * All code after this needs to be aware that allocated memory
+	 * may need to be free'd before exiting.
 	 */
 	switch (fp->fr_type & ~FR_T_BUILTIN)
 	{
 #if defined(IPFILTER_BPF)
 	case FR_T_BPFOPC :
-		if (fp->fr_dsize == 0)
-			return EINVAL;
-		if (!bpf_validate(ptr, fp->fr_dsize/sizeof(struct bpf_insn))) {
-			if (makecopy && fp->fr_data != NULL) {
-				KFREES(fp->fr_data, fp->fr_dsize);
-			}
-			return EINVAL;
-		}
+		if (!bpf_validate(ptr, fp->fr_dsize/sizeof(struct bpf_insn)))
+			goto exit_INVAL_free;
 		break;
 #endif
 	case FR_T_IPF :
 		if (fp->fr_dsize != sizeof(fripf_t))
-			return EINVAL;
+			goto exit_INVAL_free;
 
 		/*
 		 * Allowing a rule with both "keep state" and "with oow" is
@@ -4320,7 +4337,7 @@
 		 * fail with the out of window (oow) flag set.
 		 */
 		if ((fp->fr_flags & FR_KEEPSTATE) && (fp->fr_flx & FI_OOW))
-			return EINVAL;
+			goto exit_INVAL_free;
 
 		switch (fp->fr_satype)
 		{
@@ -4329,12 +4346,8 @@
 		case FRI_NETWORK :
 		case FRI_NETMASKED :
 		case FRI_PEERADDR :
-			if (fp->fr_sifpidx < 0 || fp->fr_sifpidx > 3) {
-				if (makecopy && fp->fr_data != NULL) {
-					KFREES(fp->fr_data, fp->fr_dsize);
-				}
-				return EINVAL;
-			}
+			if (fp->fr_sifpidx < 0 || fp->fr_sifpidx > 3)
+				goto exit_INVAL_free;
 			break;
 #ifdef	IPFILTER_LOOKUP
 		case FRI_LOOKUP :
@@ -4342,8 +4355,10 @@
 							 fp->fr_srcsubtype,
 							 &fp->fr_slookup,
 							 &fp->fr_srcfunc);
-			if (fp->fr_srcptr == NULL)
-				return ESRCH;
+			if (fp->fr_srcptr == NULL) {
+				error = ESRCH;
+				goto exit_free;
+			}
 			break;
 #endif
 		default :
@@ -4357,12 +4372,8 @@
 		case FRI_NETWORK :
 		case FRI_NETMASKED :
 		case FRI_PEERADDR :
-			if (fp->fr_difpidx < 0 || fp->fr_difpidx > 3) {
-				if (makecopy && fp->fr_data != NULL) {
-					KFREES(fp->fr_data, fp->fr_dsize);
-				}
-				return EINVAL;
-			}
+			if (fp->fr_difpidx < 0 || fp->fr_difpidx > 3)
+				goto exit_INVAL_free;
 			break;
 #ifdef	IPFILTER_LOOKUP
 		case FRI_LOOKUP :
@@ -4370,8 +4381,10 @@
 							 fp->fr_dstsubtype,
 							 &fp->fr_dlookup,
 							 &fp->fr_dstfunc);
-			if (fp->fr_dstptr == NULL)
-				return ESRCH;
+			if (fp->fr_dstptr == NULL) {
+				error = ESRCH;
+				goto exit_free;
+			}
 			break;
 #endif
 		default :
@@ -4379,16 +4392,19 @@
 		}
 		break;
 	case FR_T_NONE :
-		break;
 	case FR_T_CALLFUNC :
-		break;
 	case FR_T_COMPIPF :
 		break;
 	default :
+exit_INVAL_free:
+		error = EINVAL;
+#ifdef IPFILTER_LOOKUP
+exit_free:
+#endif
 		if (makecopy && fp->fr_data != NULL) {
 			KFREES(fp->fr_data, fp->fr_dsize);
 		}
-		return EINVAL;
+		return error;
 	}
 
 	/*
@@ -4478,11 +4494,8 @@
 			}
 		}
 
-		if ((ptr != NULL) && (makecopy != 0)) {
-			KFREES(ptr, fp->fr_dsize);
-		}
-		RWLOCK_EXIT(&ipf_mutex);
-		return error;
+		need_free = 1;
+		goto done;
 	}
 
 	if (!f) {
@@ -4503,7 +4516,6 @@
 			}
 			f = NULL;
 			ptr = NULL;
-			error = 0;
 		} else if (req == (ioctlcmd_t)SIOCINAFR ||
 			   req == (ioctlcmd_t)SIOCINIFR) {
 			while ((f = *fprev) != NULL) {
@@ -4523,7 +4535,6 @@
 			}
 			f = NULL;
 			ptr = NULL;
-			error = 0;
 		}
 	}
 
@@ -4556,6 +4567,7 @@
 			    (f->fr_isc != (struct ipscan *)-1))
 				ipsc_detachfr(f);
 #endif
+			need_free = 1;
 			if (unit == IPL_LOGAUTH) {
 				error = fr_preauthcmd(req, f, ftail);
 				goto done;
@@ -4615,8 +4627,18 @@
 	}
 done:
 	RWLOCK_EXIT(&ipf_mutex);
-	if ((ptr != NULL) && (error != 0) && (makecopy != 0)) {
-		KFREES(ptr, fp->fr_dsize);
+	if (error != 0 || need_free != 0) {
+		if ((ptr != NULL) && (makecopy != 0)) {
+			KFREES(ptr, fp->fr_dsize);
+		}
+#ifdef IPFILTER_LOOKUP
+		if ((fp->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) {
+			if (fp->fr_satype == FRI_LOOKUP)
+				ip_lookup_deref(fp->fr_srctype, fp->fr_srcptr);
+			if (fp->fr_datype == FRI_LOOKUP)
+				ip_lookup_deref(fp->fr_dsttype, fp->fr_dstptr);
+		}
+#endif
 	}
 	return (error);
 }
@@ -4789,9 +4811,11 @@
 		MUTEX_DESTROY(&fr->fr_lock);
 
 #ifdef IPFILTER_LOOKUP
-		if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP)
+		if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF &&
+		    fr->fr_satype == FRI_LOOKUP)
 			ip_lookup_deref(fr->fr_srctype, fr->fr_srcptr);
-		if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP)
+		if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF &&
+		    fr->fr_datype == FRI_LOOKUP)
 			ip_lookup_deref(fr->fr_dsttype, fr->fr_dstptr);
 #endif
 
@@ -5429,28 +5453,32 @@
 
 /*
  * This array defines the expected size of objects coming into the kernel
- * for the various recognised object types.
+ * for the various recognised object types. The first column is flags (see
+ * below), 2nd column is current size, 3rd column is the version number of
+ * when the current size became current.
+ * Flags:
+ * 1 = minimum size, not absolute size
  */
-static	int	fr_objbytes[IPFOBJ_COUNT][2] = {
-	{ 1,	sizeof(struct frentry) },		/* frentry */
-	{ 0,	sizeof(struct friostat) },
-	{ 0,	sizeof(struct fr_info) },
-	{ 0,	sizeof(struct fr_authstat) },
-	{ 0,	sizeof(struct ipfrstat) },
-	{ 0,	sizeof(struct ipnat) },
-	{ 0,	sizeof(struct natstat) },
-	{ 0,	sizeof(struct ipstate_save) },
-	{ 1,	sizeof(struct nat_save) },		/* nat_save */
-	{ 0,	sizeof(struct natlookup) },
-	{ 1,	sizeof(struct ipstate) },		/* ipstate */
-	{ 0,	sizeof(struct ips_stat) },
-	{ 0,	sizeof(struct frauth) },
-	{ 0,	sizeof(struct ipftune) },
-	{ 0,	sizeof(struct nat) },			/* nat_t */
-	{ 0,	sizeof(struct ipfruleiter) },
-	{ 0,	sizeof(struct ipfgeniter) },
-	{ 0,	sizeof(struct ipftable) },
-	{ 0,	sizeof(struct ipflookupiter) },
+static	int	fr_objbytes[IPFOBJ_COUNT][3] = {
+	{ 1,	sizeof(struct frentry),		4013400 },
+	{ 0,	sizeof(struct friostat),	4013300 },
+	{ 0,	sizeof(struct fr_info),		4013200 },
+	{ 0,	sizeof(struct fr_authstat),	4010100 },
+	{ 0,	sizeof(struct ipfrstat),	4010100 },
+	{ 0,	sizeof(struct ipnat),		4011400 },
+	{ 0,	sizeof(struct natstat),		4013200 },
+	{ 0,	sizeof(struct ipstate_save),	4013400 },
+	{ 1,	sizeof(struct nat_save),	4013400 },
+	{ 0,	sizeof(struct natlookup),	4010100 },
+	{ 1,	sizeof(struct ipstate),		4011600 },
+	{ 0,	sizeof(struct ips_stat),	4012100 },
+	{ 0,	sizeof(struct frauth),		4013200 },
+	{ 0,	sizeof(struct ipftune),		4010100 },
+	{ 0,	sizeof(struct nat),		4012500 },	/* nat_t */
+	{ 0,	sizeof(struct ipfruleiter),	4011400 },	/* Added. */
+	{ 0,	sizeof(struct ipfgeniter),	4011400 },	/* Added. */
+	{ 0,	sizeof(struct ipftable),	4011400 },	/* Added. */
+	{ 0,	sizeof(struct ipflookupiter),	4011400 },	/* Added. */
 	{ 0,	sizeof(struct ipftq) * IPF_TCP_NSTATES },
 };
 
@@ -5459,58 +5487,59 @@
 /* Function:    fr_inobj                                                    */
 /* Returns:     int     - 0 = success, else failure                         */
 /* Parameters:  data(I) - pointer to ioctl data                             */
+/*              objp(O) - where to store ipfobj_t data                      */
 /*              ptr(I)  - pointer to store real data in                     */
 /*              type(I) - type of structure being moved                     */
 /*                                                                          */
 /* Copy in the contents of what the ipfobj_t points to.  In future, we      */
 /* add things to check for version numbers, sizes, etc, to make it backward */
 /* compatible at the ABI for user land.                                     */
+/* Provision of objp is supported to provide the means by which the version */
+/* number from the incoming request can be returned and then used when      */
+/* copying out data. This is essential for IPFILTER_COMPAT when dealing     */
+/* programs compiled against older header files.                            */
 /* ------------------------------------------------------------------------ */
-int fr_inobj(data, ptr, type)
+int fr_inobj(data, objp, ptr, type)
 void *data;
+ipfobj_t *objp;
 void *ptr;
 int type;
 {
 	ipfobj_t obj;
 	int error = 0;
+	int size;
 
 	if ((type < 0) || (type >= IPFOBJ_COUNT))
 		return EINVAL;
 
-	error = BCOPYIN(data, &obj, sizeof(obj));
+	if (objp == NULL)
+		objp = &obj;
+	error = BCOPYIN(data, objp, sizeof(*objp));
 	if (error != 0)
 		return EFAULT;
 
-	if (obj.ipfo_type != type)
+	if (objp->ipfo_type != type)
 		return EINVAL;
 
-#ifndef	IPFILTER_COMPAT
-	if ((fr_objbytes[type][0] & 1) != 0) {
-		if (obj.ipfo_size < fr_objbytes[type][1])
+	if (objp->ipfo_rev >= fr_objbytes[type][2]) {
+		if ((fr_objbytes[type][0] & 1) != 0) {
+			if (objp->ipfo_size < fr_objbytes[type][1])
+				return EINVAL;
+			size =  fr_objbytes[type][1];
+		} else if (objp->ipfo_size == fr_objbytes[type][1]) {
+			size =  objp->ipfo_size;
+		} else {
 			return EINVAL;
-	} else if (obj.ipfo_size != fr_objbytes[type][1]) {
-		return EINVAL;
-	}
+		}
+		error = COPYIN(objp->ipfo_ptr, ptr, size);
+	} else {
+#ifdef	IPFILTER_COMPAT
+		error = fr_in_compat(objp, ptr);
 #else
-	if (obj.ipfo_rev != IPFILTER_VERSION)
-		/* XXX compatibility hook here */
-		;
-	if ((fr_objbytes[type][0] & 1) != 0) {
-		if (obj.ipfo_size < fr_objbytes[type][1])
-			/* XXX compatibility hook here */
-			return EINVAL;
-	} else if (obj.ipfo_size != fr_objbytes[type][1])
-		/* XXX compatibility hook here */
 		return EINVAL;
 #endif
-
-	if ((fr_objbytes[type][0] & 1) != 0) {
-		error = COPYIN((void *)obj.ipfo_ptr, (void *)ptr,
-				fr_objbytes[type][1]);
-	} else {
-		error = COPYIN((void *)obj.ipfo_ptr, (void *)ptr,
-				obj.ipfo_size);
 	}
+
 	if (error != 0)
 		error = EFAULT;
 	return error;
@@ -5541,8 +5570,6 @@
 
 	if ((type < 0) || (type >= IPFOBJ_COUNT))
 		return EINVAL;
-	if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1]))
-		return EINVAL;
 
 	error = BCOPYIN(data, &obj, sizeof(obj));
 	if (error != 0)
@@ -5551,19 +5578,20 @@
 	if (obj.ipfo_type != type)
 		return EINVAL;
 
-#ifndef	IPFILTER_COMPAT
-	if (obj.ipfo_size != sz)
-		return EINVAL;
+	if (obj.ipfo_rev >= fr_objbytes[type][2]) {
+		if (((fr_objbytes[type][0] & 1) == 0) ||
+		    (sz < fr_objbytes[type][1]))
+			return EINVAL;
+
+		error = COPYIN(obj.ipfo_ptr, ptr, sz);
+	} else {
+#ifdef	IPFILTER_COMPAT
+		error = fr_in_compat(&obj, ptr);
 #else
-	if (obj.ipfo_rev != IPFILTER_VERSION)
-		/* XXX compatibility hook here */
-		;
-	if (obj.ipfo_size != sz)
-		/* XXX compatibility hook here */
-		return EINVAL;
+		error = EINVAL;
 #endif
+	}
 
-	error = COPYIN((void *)obj.ipfo_ptr, (void *)ptr, sz);
 	if (error != 0)
 		error = EFAULT;
 	return error;
@@ -5592,9 +5620,7 @@
 	ipfobj_t obj;
 	int error;
 
-	if ((type < 0) || (type >= IPFOBJ_COUNT) ||
-	    ((fr_objbytes[type][0] & 1) == 0) ||
-	    (sz < fr_objbytes[type][1]))
+	if ((type < 0) || (type >= IPFOBJ_COUNT))
 		return EINVAL;
 
 	error = BCOPYIN(data, &obj, sizeof(obj));
@@ -5604,19 +5630,20 @@
 	if (obj.ipfo_type != type)
 		return EINVAL;
 
-#ifndef	IPFILTER_COMPAT
-	if (obj.ipfo_size != sz)
-		return EINVAL;
+	if (obj.ipfo_rev >= fr_objbytes[type][2]) {
+		if (((fr_objbytes[type][0] & 1) == 0) ||
+		    (sz < fr_objbytes[type][1]))
+			return EINVAL;
+
+		error = COPYOUT(ptr, obj.ipfo_ptr, sz);
+	} else {
+#ifdef	IPFILTER_COMPAT
+		error = fr_out_compat(&obj, ptr);
 #else
-	if (obj.ipfo_rev != IPFILTER_VERSION)
-		/* XXX compatibility hook here */
-		;
-	if (obj.ipfo_size != sz)
-		/* XXX compatibility hook here */
 		return EINVAL;
 #endif
+	}
 
-	error = COPYOUT((void *)ptr, (void *)obj.ipfo_ptr, sz);
 	if (error != 0)
 		error = EFAULT;
 	return error;
@@ -5627,7 +5654,7 @@
 /* Function:    fr_outobj                                                   */
 /* Returns:     int     - 0 = success, else failure                         */
 /* Parameters:  data(I) - pointer to ioctl data                             */
-/*              ptr(I)  - pointer to store real data in                     */
+/*              ptr(I)  - pointer to data to copy out                       */
 /*              type(I) - type of structure being moved                     */
 /*                                                                          */
 /* Copy out the contents of what ptr is to where ipfobj points to.  In      */
@@ -5652,28 +5679,70 @@
 	if (obj.ipfo_type != type)
 		return EINVAL;
 
-#ifndef	IPFILTER_COMPAT
-	if ((fr_objbytes[type][0] & 1) != 0) {
-		if (obj.ipfo_size < fr_objbytes[type][1])
+	if (obj.ipfo_rev >= fr_objbytes[type][2]) {
+		if ((fr_objbytes[type][0] & 1) != 0) {
+			if (obj.ipfo_size < fr_objbytes[type][1])
+				return EINVAL;
+		} else if (obj.ipfo_size != fr_objbytes[type][1]) {
 			return EINVAL;
-	} else if (obj.ipfo_size != fr_objbytes[type][1])
-		return EINVAL;
+		}
+
+		error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size);
+		if (error != 0)
+			error = EFAULT;
+	} else {
+#ifdef	IPFILTER_COMPAT
+		error = fr_out_compat(&obj, ptr);
 #else
-	if (obj.ipfo_rev != IPFILTER_VERSION)
-		/* XXX compatibility hook here */
-		;
-	if ((fr_objbytes[type][0] & 1) != 0) {
-		if (obj.ipfo_size < fr_objbytes[type][1])
-			/* XXX compatibility hook here */
-			return EINVAL;
-	} else if (obj.ipfo_size != fr_objbytes[type][1])
-		/* XXX compatibility hook here */
-		return EINVAL;
+		error = EINVAL;
 #endif
+	}
+	return error;
+}
 
-	error = COPYOUT((void *)ptr, (void *)obj.ipfo_ptr, obj.ipfo_size);
-	if (error != 0)
-		error = EFAULT;
+
+/* ------------------------------------------------------------------------ */
+/* Function:    fr_outobjk                                                  */
+/* Returns:     int     - 0 = success, else failure                         */
+/* Parameters:  obj(I)  - pointer to data description structure             */
+/*              ptr(I)  - pointer to kernel data to copy out                */
+/*                                                                          */
+/* In the above functions, the ipfobj_t structure is copied into the kernel,*/
+/* telling ipfilter how to copy out data. In this instance, the ipfobj_t is */
+/* already populated with information and now we just need to use it.       */
+/* There is no need for this function to have a "type" parameter as there   */
+/* is no point in validating information that comes from the kernel with    */
+/* itself.                                                                  */
+/* ------------------------------------------------------------------------ */
+int fr_outobjk(obj, ptr)
+ipfobj_t *obj;
+void *ptr;
+{
+	int type = obj->ipfo_type;
+	int error;
+
+	if ((type < 0) || (type >= IPFOBJ_COUNT))
+		return EINVAL;
+
+	if (obj->ipfo_rev >= fr_objbytes[type][2]) {
+		if ((fr_objbytes[type][0] & 1) != 0) {
+			if (obj->ipfo_size < fr_objbytes[type][1])
+				return EINVAL;
+
+		} else if (obj->ipfo_size != fr_objbytes[type][1]) {
+			return EINVAL;
+		}
+
+		error = COPYOUT(ptr, obj->ipfo_ptr, obj->ipfo_size);
+		if (error != 0)
+			error = EFAULT;
+	} else {
+#ifdef	IPFILTER_COMPAT
+		error = fr_out_compat(obj, ptr);
+#else
+		error = EINVAL;
+#endif
+	}
 	return error;
 }
 
@@ -6219,7 +6288,7 @@
 	void *cookie;
 	int error;
 
-	error = fr_inobj(data, &tu, IPFOBJ_TUNEABLE);
+	error = fr_inobj(data, NULL, &tu, IPFOBJ_TUNEABLE);
 	if (error != 0)
 		return error;
 
@@ -6474,12 +6543,16 @@
 void	*data;
 {
 	friostat_t fio;
+	ipfobj_t obj;
 	int error;
 
-	fr_getstat(&fio);
+	error = fr_inobj(data, &obj, &fio, IPFOBJ_IPFSTAT);
+	if (error)
+		return error;
+	fr_getstat(&fio, obj.ipfo_rev);
 	error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT);
 	if (error)
-		return EFAULT;
+		return error;
 
 	WRITE_ENTER(&ipf_mutex);
 	bzero(&frstats, sizeof(frstats));
@@ -6815,11 +6888,12 @@
 	int error, count, out;
 	ipfruleiter_t it;
 	frgroup_t *fg;
+	ipfobj_t obj;
 	char *dst;
 
 	if (t == NULL || ptr == NULL)
 		return EFAULT;
-	error = fr_inobj(ptr, &it, IPFOBJ_IPFITER);
+	error = fr_inobj(ptr, &obj, &it, IPFOBJ_IPFITER);
 	if (error != 0)
 		return error;
 	if ((it.iri_inout < 0) || (it.iri_inout > 3))
@@ -6863,6 +6937,8 @@
 		next = fr->fr_next;
 	}
 
+	obj.ipfo_type = IPFOBJ_FRENTRY;
+	obj.ipfo_size = 0;
 	dst = (char *)it.iri_rule;
 	/*
 	 * The ipfruleiter may ask for more than 1 rule at a time to be
@@ -6892,7 +6968,9 @@
 		/*
 		 * Copy out data and clean up references and token as needed.
 		 */
-		error = COPYOUT(next, dst, sizeof(*next));
+		obj.ipfo_size = sizeof(frentry_t);
+		obj.ipfo_ptr = dst;
+		error = fr_outobjk(&obj, next);
 		if (error != 0)
 			return EFAULT;
 		if (t->ipt_data == NULL) {
@@ -6901,7 +6979,7 @@
 			if (fr != NULL)
 				(void) fr_derefrule(&fr);
 			if (next->fr_data != NULL) {
-				dst += sizeof(*next);
+				dst += obj.ipfo_size;
 				error = COPYOUT(next->fr_data, dst,
 						next->fr_dsize);
 				if (error != 0)
@@ -7009,7 +7087,7 @@
 	ipfgeniter_t iter;
 	int error;
 
-	error = fr_inobj(data, &iter, IPFOBJ_GENITER);
+	error = fr_inobj(data, NULL, &iter, IPFOBJ_GENITER);
 	if (error != 0)
 		return error;
 
@@ -7051,6 +7129,7 @@
 {
 	friostat_t fio;
 	int error, tmp;
+	ipfobj_t obj;
 	SPL_INT(s);
 
 	switch (cmd)
@@ -7151,7 +7230,10 @@
 		break;
 
 	case SIOCGETFS :
-		fr_getstat(&fio);
+		error = fr_inobj((void *)data, &obj, &fio, IPFOBJ_IPFSTAT);
+		if (error != 0)
+			break;
+		fr_getstat(&fio, obj.ipfo_rev);
 		error = fr_outobj((void *)data, &fio, IPFOBJ_IPFSTAT);
 		break;
 

Index: src/sys/dist/ipf/netinet/ip_auth.c
diff -u src/sys/dist/ipf/netinet/ip_auth.c:1.13 src/sys/dist/ipf/netinet/ip_auth.c:1.14
--- src/sys/dist/ipf/netinet/ip_auth.c:1.13	Wed Aug 19 08:36:10 2009
+++ src/sys/dist/ipf/netinet/ip_auth.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_auth.c,v 1.13 2009/08/19 08:36:10 darrenr Exp $	*/
+/*	$NetBSD: ip_auth.c,v 1.14 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij.
@@ -124,9 +124,9 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.13 2009/08/19 08:36:10 darrenr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.14 2010/04/17 21:00:44 darrenr Exp $");
 #else
-static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.33 2009/05/13 18:31:14 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.34 2010/01/31 16:22:54 darrenr Exp";
 #endif
 #endif
 
@@ -154,7 +154,7 @@
 		*fr_authlist = NULL;
 
 void fr_authderef __P((frauthent_t **));
-int fr_authgeniter __P((ipftoken_t *, ipfgeniter_t *));
+int fr_authgeniter __P((ipftoken_t *, ipfgeniter_t *, ipfobj_t *));
 int fr_authreply __P((char *));
 int fr_authwait __P((char *));
 
@@ -426,15 +426,16 @@
 	    {
 		ipftoken_t *token;
 		ipfgeniter_t iter;
+		ipfobj_t obj;
 
-		error = fr_inobj(data, &iter, IPFOBJ_GENITER);
+		error = fr_inobj(data, &obj, &iter, IPFOBJ_GENITER);
 		if (error != 0)
 			break;
 
 		SPL_SCHED(s);
 		token = ipf_findtoken(IPFGENITER_AUTH, uid, ctx);
 		if (token != NULL) {
-			error = fr_authgeniter(token, &iter);
+			error = fr_authgeniter(token, &iter, &obj);
 			WRITE_ENTER(&ipf_tokens);
 			if (token->ipt_data == NULL)
 				ipf_freetoken(token);
@@ -757,9 +758,10 @@
 /*              itp(I)   - pointer to ipfgeniter structure                  */
 /*                                                                          */
 /* ------------------------------------------------------------------------ */
-int fr_authgeniter(token, itp)
+int fr_authgeniter(token, itp, obj)
 ipftoken_t *token;
 ipfgeniter_t *itp;
+ipfobj_t *obj;
 {
 	frauthent_t *fae, *next, zero;
 	int error;
@@ -770,6 +772,10 @@
 	if (itp->igi_type != IPFGENITER_AUTH)
 		return EINVAL;
 
+	obj->ipfo_type = IPFOBJ_FRAUTH;
+	obj->ipfo_ptr = itp->igi_data;
+	obj->ipfo_size = sizeof(frauth_t);
+
 	READ_ENTER(&ipf_auth);
 
 	/*
@@ -803,7 +809,7 @@
 	/*
 	 * Copy out the data and clean up references and token as needed.
 	 */
-	error = COPYOUT(next, itp->igi_data, sizeof(*next));
+	error = fr_outobjk(obj, next);
 	if (error != 0)
 		error = EFAULT;
 
@@ -869,7 +875,7 @@
 	SPL_INT(s);
 
 fr_authioctlloop:
-	error = fr_inobj(data, au, IPFOBJ_FRAUTH);
+	error = fr_inobj(data, NULL, au, IPFOBJ_FRAUTH);
 	if (error != 0)
 		return error;
 
@@ -991,7 +997,7 @@
 	mb_t *m;
 	SPL_INT(s);
 
-	error = fr_inobj(data, &auth, IPFOBJ_FRAUTH);
+	error = fr_inobj(data, NULL, &auth, IPFOBJ_FRAUTH);
 	if (error != 0)
 		return error;
 

Index: src/sys/dist/ipf/netinet/ip_compat.h
diff -u src/sys/dist/ipf/netinet/ip_compat.h:1.27 src/sys/dist/ipf/netinet/ip_compat.h:1.28
--- src/sys/dist/ipf/netinet/ip_compat.h:1.27	Tue Jan 19 22:08:00 2010
+++ src/sys/dist/ipf/netinet/ip_compat.h	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_compat.h,v 1.27 2010/01/19 22:08:00 pooka Exp $	*/
+/*	$NetBSD: ip_compat.h,v 1.28 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1993-2001, 2003 by Darren Reed.
@@ -6,7 +6,7 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * @(#)ip_compat.h	1.8 1/14/96
- * Id: ip_compat.h,v 2.142.2.77 2009/08/16 07:03:04 darrenr Exp
+ * Id: ip_compat.h,v 2.142.2.79 2010/01/31 16:22:54 darrenr Exp
  */
 
 #ifndef _NETINET_IP_COMPAT_H_
@@ -894,6 +894,18 @@
 # endif
 
 # if defined(_KERNEL)
+#  if (__FreeBSD_version >= 500024)
+#   if (__FreeBSD_version >= 500043)
+#    define     p_cred  td_ucred
+#    define     p_uid   td_ucred->cr_ruid
+#   else
+#    define     p_cred  t_proc->p_cred
+#    define     p_uid   t_proc->p_cred->p_ruid
+#   endif
+#  else
+#   define      p_uid   p_cred->p_ruid
+#  endif /* __FreeBSD_version >= 500024 */
+
 #  if (__FreeBSD_version >= 400000)
 #   define	ipf_random	arc4random
 /*
@@ -1025,6 +1037,9 @@
 #  else
 #   define	SPL_SCHED(x)	x = splhigh()
 #  endif /* __FreeBSD_version >= 500043 */
+#  if (__FreeBSD_version >= 500024)
+#   define	GET_MINOR		dev2unit
+#  endif
 #  define	MSGDSIZE(x)	mbufchainlen(x)
 #  define	M_LEN(x)	(x)->m_len
 #  define	M_DUPLICATE(x)	m_copy((x), 0, M_COPYALL)

Index: src/sys/dist/ipf/netinet/ip_fil.h
diff -u src/sys/dist/ipf/netinet/ip_fil.h:1.18 src/sys/dist/ipf/netinet/ip_fil.h:1.19
--- src/sys/dist/ipf/netinet/ip_fil.h:1.18	Wed Aug 19 08:36:10 2009
+++ src/sys/dist/ipf/netinet/ip_fil.h	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil.h,v 1.18 2009/08/19 08:36:10 darrenr Exp $	*/
+/*	$NetBSD: ip_fil.h,v 1.19 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1993-2001, 2003 by Darren Reed.
@@ -6,7 +6,7 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * @(#)ip_fil.h	1.35 6/5/96
- * Id: ip_fil.h,v 2.170.2.62 2009/07/22 01:46:42 darrenr Exp
+ * Id: ip_fil.h,v 2.170.2.63 2010/01/31 16:22:55 darrenr Exp
  */
 
 #ifndef _NETINET_IP_FIL_H_
@@ -523,8 +523,13 @@
 
 	/*
 	 * For PPS rate limiting
+	 * fr_lpu is used to always have the same size for this field,
+	 * allocating 64bits for seconds and 32bits for milliseconds.
 	 */
-	struct timeval	fr_lastpkt;
+	union {
+		struct timeval	frp_lastpkt;
+		char	frp_bytes[12];
+	} fr_lpu;
 	int		fr_curpps;
 
 	union	{
@@ -563,6 +568,7 @@
 	u_int	fr_cksum;	/* checksum on filter rules for performance */
 } frentry_t;
 
+#define	fr_lastpkt	fr_lpu.frp_lastpkt
 #define	fr_caddr	fr_dun.fru_caddr
 #define	fr_data		fr_dun.fru_data
 #define	fr_dfunc	fr_dun.fru_func
@@ -1432,12 +1438,13 @@
 extern	int	copyinptr __P((void *, void *, size_t));
 extern	int	copyoutptr __P((void *, void *, size_t));
 extern	int	fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *));
-extern	int	fr_inobj __P((void *, void *, int));
+extern	int	fr_inobj __P((void *, ipfobj_t *, void *, int));
 extern	int	fr_inobjsz __P((void *, void *, int, int));
 extern	int	fr_ioctlswitch __P((int, void *, ioctlcmd_t, int, int, void *));
 extern	int	fr_ipf_ioctl __P((void *, ioctlcmd_t, int, int, void *));
 extern	int	fr_ipftune __P((ioctlcmd_t, void *));
 extern	int	fr_outobj __P((void *, void *, int));
+extern	int	fr_outobjk __P((ipfobj_t *, void *));
 extern	int	fr_outobjsz __P((void *, void *, int, int));
 extern	void	*fr_pullup __P((mb_t *, fr_info_t *, int));
 extern	void	fr_resolvedest __P((struct frdest *, int));
@@ -1497,7 +1504,6 @@
 extern	void		fr_fixskip __P((frentry_t **, frentry_t *, int));
 extern	void		fr_forgetifp __P((void *));
 extern	frentry_t 	*fr_getrulen __P((int, char *, u_32_t));
-extern	void		fr_getstat __P((struct friostat *));
 extern	int		fr_ifpaddr __P((int, int, void *,
 				struct in_addr *, struct in_addr *));
 extern	int		fr_initialise __P((void));
@@ -1557,6 +1563,10 @@
 extern	int	icmptoicmp6unreach[ICMP_MAX_UNREACH];
 extern	int	icmpreplytype6[ICMP6_MAXTYPE + 1];
 #endif
+#ifdef	IPFILTER_COMPAT
+extern	int	fr_in_compat __P((ipfobj_t *, void *));
+extern	int	fr_out_compat __P((ipfobj_t *, void *));
+#endif
 extern	int	icmpreplytype4[ICMP_MAXTYPE + 1];
 extern	struct frgroup *ipfgroups[IPL_LOGSIZE][2];
 extern	struct filterstats frstats[];

Index: src/sys/dist/ipf/netinet/ip_fil_netbsd.c
diff -u src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.53 src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.54
--- src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.53	Mon Oct  5 03:44:01 2009
+++ src/sys/dist/ipf/netinet/ip_fil_netbsd.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil_netbsd.c,v 1.53 2009/10/05 03:44:01 elad Exp $	*/
+/*	$NetBSD: ip_fil_netbsd.c,v 1.54 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1993-2003 by Darren Reed.
@@ -8,10 +8,10 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.53 2009/10/05 03:44:01 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.54 2010/04/17 21:00:44 darrenr Exp $");
 #else
 static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 2.55.2.66 2009/05/17 17:45:26 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 2.55.2.67 2009/12/19 05:41:08 darrenr Exp";
 #endif
 #endif
 
@@ -999,6 +999,14 @@
 	fnew.fin_dp = (char *)ip + hlen;
 	(void) fr_makefrip(hlen, ip, &fnew);
 
+	if (fin->fin_fr != NULL && fin->fin_fr->fr_type == FR_T_IPF) {
+		frdest_t *fdp = &fin->fin_fr->fr_rif;
+
+		if ((fdp->fd_ifp != NULL) &&
+		    (fdp->fd_ifp != (struct ifnet *)-1))
+			return fr_fastroute(m, mpp, &fnew, fdp);
+	}
+
 	return fr_fastroute(m, mpp, &fnew, NULL);
 }
 

Index: src/sys/dist/ipf/netinet/ip_lookup.c
diff -u src/sys/dist/ipf/netinet/ip_lookup.c:1.15 src/sys/dist/ipf/netinet/ip_lookup.c:1.16
--- src/sys/dist/ipf/netinet/ip_lookup.c:1.15	Wed Aug 19 08:36:11 2009
+++ src/sys/dist/ipf/netinet/ip_lookup.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_lookup.c,v 1.15 2009/08/19 08:36:11 darrenr Exp $	*/
+/*	$NetBSD: ip_lookup.c,v 1.16 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 2002-2003 by Darren Reed.
@@ -67,9 +67,9 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_lookup.c,v 1.15 2009/08/19 08:36:11 darrenr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_lookup.c,v 1.16 2010/04/17 21:00:44 darrenr Exp $");
 #else
-static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.21 2009/05/13 18:31:15 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.22 2010/01/31 16:22:55 darrenr Exp";
 #endif
 #endif
 
@@ -595,7 +595,7 @@
 	int err;
 	SPL_INT(s);
 
-	err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER);
+	err = fr_inobj(data, NULL, &iter, IPFOBJ_LOOKUPITER);
 	if (err != 0)
 		return err;
 

Index: src/sys/dist/ipf/netinet/ip_nat.c
diff -u src/sys/dist/ipf/netinet/ip_nat.c:1.40 src/sys/dist/ipf/netinet/ip_nat.c:1.41
--- src/sys/dist/ipf/netinet/ip_nat.c:1.40	Wed Aug 19 08:36:11 2009
+++ src/sys/dist/ipf/netinet/ip_nat.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_nat.c,v 1.40 2009/08/19 08:36:11 darrenr Exp $	*/
+/*	$NetBSD: ip_nat.c,v 1.41 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1995-2003 by Darren Reed.
@@ -105,6 +105,7 @@
 #include "netinet/ip_frag.h"
 #include "netinet/ip_state.h"
 #include "netinet/ip_proxy.h"
+#include "netinet/ipl.h"
 #ifdef	IPFILTER_SYNC
 #include "netinet/ip_sync.h"
 #endif
@@ -119,10 +120,10 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.40 2009/08/19 08:36:11 darrenr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.41 2010/04/17 21:00:44 darrenr Exp $");
 #else
 static const char sccsid[] = "@(#)ip_nat.c	1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.127 2009/07/21 09:40:55 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.130 2010/03/16 02:24:52 darrenr Exp";
 #endif
 #endif
 
@@ -215,8 +216,8 @@
 static	nat_t	*fr_natclone __P((fr_info_t *, nat_t *));
 static	void	nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
 static	int	nat_wildok __P((nat_t *, int, int, int, int));
-static	int	nat_getnext __P((ipftoken_t *, ipfgeniter_t *));
-static	int	nat_iterator __P((ipftoken_t *, ipfgeniter_t *));
+static	int	nat_getnext __P((ipftoken_t *, ipfgeniter_t *, ipfobj_t *));
+static	int	nat_iterator __P((ipftoken_t *, ipfgeniter_t *, ipfobj_t *));
 
 
 /* ------------------------------------------------------------------------ */
@@ -667,8 +668,12 @@
 		return EPERM;
 	}
 # else
-	if ((securelevel >= 2) && (mode & FWRITE)) {
-		return EPERM;
+#  if defined(__FreeBSD_version) && (__FreeBSD_version >= 500034)
+        if (securelevel_ge(curthread->td_ucred, 3) && (mode & FWRITE)) {
+#  else
+        if ((securelevel >= 3) && (mode & FWRITE)) {
+#  endif
+                return EPERM;
 	}
 # endif
 #endif
@@ -691,7 +696,7 @@
 			bcopy(data, (char *)&natd, sizeof(natd));
 			error = 0;
 		} else {
-			error = fr_inobj(data, &natd, IPFOBJ_IPNAT);
+			error = fr_inobj(data, NULL, &natd, IPFOBJ_IPNAT);
 		}
 	}
 
@@ -825,7 +830,7 @@
 	    {
 		natlookup_t nl;
 
-		error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP);
+		error = fr_inobj(data, NULL, &nl, IPFOBJ_NATLOOKUP);
 		if (error == 0) {
 			void *ptr;
 
@@ -912,13 +917,14 @@
 	    {
 		ipfgeniter_t iter;
 		ipftoken_t *token;
+		ipfobj_t obj;
 
 		SPL_SCHED(s);
-		error = fr_inobj(data, &iter, IPFOBJ_GENITER);
+		error = fr_inobj(data, &obj, &iter, IPFOBJ_GENITER);
 		if (error == 0) {
 			token = ipf_findtoken(iter.igi_type, uid, ctx);
 			if (token != NULL) {
-				error = nat_iterator(token, &iter);
+				error = nat_iterator(token, &iter, &obj);
 				WRITE_ENTER(&ipf_tokens);
 				if (token->ipt_data == NULL)
 					ipf_freetoken(token);
@@ -1289,7 +1295,7 @@
 	nat_save_t *ipn, ipns;
 	nat_t *n, *nat;
 
-	error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE);
+	error = fr_inobj(data, NULL, &ipns, IPFOBJ_NATSAVE);
 	if (error != 0)
 		return error;
 
@@ -1416,6 +1422,10 @@
 	ipnat_t *in;
 	int error;
 
+	error = fr_inobj(data, NULL, &ipn, IPFOBJ_NATSAVE);
+	if (error != 0)
+		return error;
+
 	/*
 	 * Initialise early because of code at junkput label.
 	 */
@@ -1426,13 +1436,6 @@
 	fin = NULL;
 	fr = NULL;
 
-	KMALLOC(ipn, nat_save_t *);
-	if (ipn == NULL)
-		return ENOMEM;
-	error = fr_inobj(data, ipn, IPFOBJ_NATSAVE);
-	if (error != 0)
-		goto junkput;
-
 	/*
 	 * New entry, copy in the rest of the NAT entry if it's size is more
 	 * than just the nat_t structure.
@@ -4128,7 +4131,7 @@
 	if (((fin->fin_flx & FI_ICMPERR) != 0) &&
 	    (nat = nat_icmperror(fin, &nflags, NAT_INBOUND)))
 		/*EMPTY*/;
-	else if ((fin->fin_flx & FI_FRAG) && 
+	else if ((fin->fin_flx & FI_FRAG) &&
 		 (nat = fr_nat_knownfrag(fin)))
 		natadd = 0;
 	else if ((nat = nat_inlookup(fin, nflags|NAT_SEARCH, (u_int)fin->fin_p,
@@ -5086,9 +5089,10 @@
 /* copy it out to the storage space pointed to by itp.  The next item       */
 /* in the list to look at is put back in the ipftoken struture.             */
 /* ------------------------------------------------------------------------ */
-static int nat_getnext(t, itp)
+static int nat_getnext(t, itp, obj)
 ipftoken_t *t;
 ipfgeniter_t *itp;
+ipfobj_t *obj;
 {
 	hostmap_t *hm = NULL, *nexthm = NULL, zerohm;
 	ipnat_t *ipn = NULL, *nextipnat = NULL, zeroipn;
@@ -5213,7 +5217,10 @@
 			break;
 
 		case IPFGENITER_IPNAT :
-			error = COPYOUT(nextipnat, dst, sizeof(*nextipnat));
+			obj->ipfo_size = sizeof(ipnat_t);
+			obj->ipfo_ptr = dst;
+			obj->ipfo_type = IPFOBJ_IPNAT;
+			error = fr_outobjk(obj, nextipnat);
 			if (error != 0)
 				error = EFAULT;
 			if (ipn != NULL) {
@@ -5233,7 +5240,10 @@
 			break;
 
 		case IPFGENITER_NAT :
-			error = COPYOUT(nextnat, dst, sizeof(*nextnat));
+			obj->ipfo_size = sizeof(nat_t);
+			obj->ipfo_ptr = dst;
+			obj->ipfo_type = IPFOBJ_NAT;
+			error = fr_outobjk(obj, nextnat);
 			if (error != 0)
 				error = EFAULT;
 			if (nat != NULL) {
@@ -5243,7 +5253,7 @@
 				if (nextnat->nat_next == NULL) {
 					t->ipt_data = NULL;
 					break;
-				}	
+				}
 				dst += sizeof(*nextnat);
 				nat = nextnat;
 				nextnat = nextnat->nat_next;
@@ -5272,9 +5282,10 @@
 /* linked lists of NAT related information to go through: NAT rules, active */
 /* NAT mappings and the NAT fragment cache.                                 */
 /* ------------------------------------------------------------------------ */
-static int nat_iterator(token, itp)
+static int nat_iterator(token, itp, obj)
 ipftoken_t *token;
 ipfgeniter_t *itp;
+ipfobj_t *obj;
 {
 	int error;
 
@@ -5288,7 +5299,7 @@
 	case IPFGENITER_HOSTMAP :
 	case IPFGENITER_IPNAT :
 	case IPFGENITER_NAT :
-		error = nat_getnext(token, itp);
+		error = nat_getnext(token, itp, obj);
 		break;
 
 	case IPFGENITER_NATFRAG :
@@ -5481,7 +5492,7 @@
 	ipftable_t table;
 	int error;
 
-	error = fr_inobj(data, &table, IPFOBJ_GTABLE);
+	error = fr_inobj(data, NULL, &table, IPFOBJ_GTABLE);
 	if (error != 0)
 		return error;
 

Index: src/sys/dist/ipf/netinet/ip_state.c
diff -u src/sys/dist/ipf/netinet/ip_state.c:1.35 src/sys/dist/ipf/netinet/ip_state.c:1.36
--- src/sys/dist/ipf/netinet/ip_state.c:1.35	Sun Nov 22 19:09:16 2009
+++ src/sys/dist/ipf/netinet/ip_state.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_state.c,v 1.35 2009/11/22 19:09:16 mbalmer Exp $	*/
+/*	$NetBSD: ip_state.c,v 1.36 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1995-2003 by Darren Reed.
@@ -115,10 +115,10 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.35 2009/11/22 19:09:16 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.36 2010/04/17 21:00:44 darrenr Exp $");
 #else
 static const char sccsid[] = "@(#)ip_state.c	1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.98 2009/07/21 09:40:56 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.100 2010/01/31 16:22:55 darrenr Exp";
 #endif
 #endif
 
@@ -151,7 +151,7 @@
 static void fr_fixinisn __P((fr_info_t *, ipstate_t *));
 static void fr_fixoutisn __P((fr_info_t *, ipstate_t *));
 static void fr_checknewisn __P((fr_info_t *, ipstate_t *));
-static int fr_stateiter __P((ipftoken_t *, ipfgeniter_t *));
+static int fr_stateiter __P((ipftoken_t *, ipfgeniter_t *, ipfobj_t *));
 static int fr_stgettable __P((char *));
 
 int fr_stputent __P((void *));
@@ -423,7 +423,7 @@
 	int error;
 
 	sp = &st;
-	error = fr_inobj(data, &st, IPFOBJ_IPSTATE);
+	error = fr_inobj(data, NULL, &st, IPFOBJ_IPSTATE);
 	if (error)
 		return EFAULT;
 
@@ -611,15 +611,16 @@
 	    {
 		ipftoken_t *token;
 		ipfgeniter_t iter;
+		ipfobj_t obj;
 
-		error = fr_inobj(data, &iter, IPFOBJ_GENITER);
+		error = fr_inobj(data, &obj, &iter, IPFOBJ_GENITER);
 		if (error != 0)
 			break;
 
 		SPL_SCHED(s);
 		token = ipf_findtoken(IPFGENITER_STATE, uid, ctx);
 		if (token != NULL) {
-			error = fr_stateiter(token, &iter);
+			error = fr_stateiter(token, &iter, &obj);
 			WRITE_ENTER(&ipf_tokens);
 			if (token->ipt_data == NULL)
 				ipf_freetoken(token);
@@ -678,7 +679,7 @@
 	ipstate_save_t ips;
 	int error;
 
-	error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
+	error = fr_inobj(data, NULL, &ips, IPFOBJ_STATESAVE);
 	if (error != 0)
 		return error;
 
@@ -737,7 +738,7 @@
 	frentry_t *fr;
 	char *name;
 
-	error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
+	error = fr_inobj(data, NULL, &ips, IPFOBJ_STATESAVE);
 	if (error)
 		return EFAULT;
 
@@ -932,7 +933,7 @@
 
 	if (is1->is_saddr == is2->is_saddr && is1->is_daddr == is2->is_daddr)
 		rv = 2;
-	else if (is1->is_saddr == is2->is_daddr && 
+	else if (is1->is_saddr == is2->is_daddr &&
 	    is1->is_daddr == is2->is_saddr) {
 		/* force strong match for ICMP protocol */
 		rv = (is1->is_p == IPPROTO_ICMP) ? 2 : 1;
@@ -959,8 +960,8 @@
 {
 	int	rv;
 
-	if (IP6_EQ(&is1->is_src, &is2->is_src) && 
-	    IP6_EQ(&is1->is_dst, &is2->is_dst))  
+	if (IP6_EQ(&is1->is_src, &is2->is_src) &&
+	    IP6_EQ(&is1->is_dst, &is2->is_dst))
 		rv = 2;
 	else if (IP6_EQ(&is1->is_src, &is2->is_dst) &&
 	    IP6_EQ(&is1->is_dst, &is2->is_src)) {
@@ -1028,10 +1029,10 @@
 {
 	int	rv;
 
-	if (ppairs1->us_sport == ppairs2->us_sport && 
+	if (ppairs1->us_sport == ppairs2->us_sport &&
 	    ppairs1->us_dport == ppairs2->us_dport)
 		rv = 2;
-	else if (ppairs1->us_sport == ppairs2->us_dport && 
+	else if (ppairs1->us_sport == ppairs2->us_dport &&
 		    ppairs1->us_dport == ppairs2->us_sport)
 		rv = 1;
 	else
@@ -1993,7 +1994,7 @@
 	/*
 	 * It has not yet been placed on any timeout queue, so make sure
 	 * all of that data is zero'd out.
-	 */     
+	 */
 	clone->is_sti.tqe_pnext = NULL;
 	clone->is_sti.tqe_next = NULL;
 	clone->is_sti.tqe_ifq = NULL;
@@ -3004,10 +3005,14 @@
 	fr = is->is_rule;
 	if (fr != NULL) {
 		if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) {
-			if (fin->fin_nattag == NULL)
+			if (fin->fin_nattag == NULL) {
+				RWLOCK_EXIT(&ipf_state);
 				return NULL;
-			if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0)
+			}
+			if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0) {
+				RWLOCK_EXIT(&ipf_state);
 				return NULL;
+			}
 		}
 		(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
 		fin->fin_icode = fr->fr_icode;
@@ -4324,9 +4329,10 @@
 /* This function handles the SIOCGENITER ioctl for the state tables and     */
 /* walks through the list of entries in the state table list (ips_list.)    */
 /* ------------------------------------------------------------------------ */
-static int fr_stateiter(token, itp)
+static int fr_stateiter(token, itp, obj)
 ipftoken_t *token;
 ipfgeniter_t *itp;
+ipfobj_t *obj;
 {
 	ipstate_t *is, *next, zero;
 	int error, count;
@@ -4342,6 +4348,8 @@
 		return EINVAL;
 
 	error = 0;
+	obj->ipfo_type = IPFOBJ_IPSTATE;
+	obj->ipfo_size = sizeof(ipstate_t);
 
 	READ_ENTER(&ipf_state);
 
@@ -4378,10 +4386,11 @@
 		 */
 		RWLOCK_EXIT(&ipf_state);
 
+		obj->ipfo_ptr = dst;
 		/*
 		 * Copy out data and clean up references and tokens.
 		 */
-		error = COPYOUT(next, dst, sizeof(*next));
+		error = fr_outobjk(obj, next);
 		if (error != 0)
 			error = EFAULT;
 
@@ -4424,7 +4433,7 @@
 	ipftable_t table;
 	int error;
 
-	error = fr_inobj(data, &table, IPFOBJ_GTABLE);
+	error = fr_inobj(data, NULL, &table, IPFOBJ_GTABLE);
 	if (error != 0)
 		return error;
 

Index: src/sys/dist/ipf/netinet/ip_sync.c
diff -u src/sys/dist/ipf/netinet/ip_sync.c:1.12 src/sys/dist/ipf/netinet/ip_sync.c:1.13
--- src/sys/dist/ipf/netinet/ip_sync.c:1.12	Wed Aug 19 08:36:13 2009
+++ src/sys/dist/ipf/netinet/ip_sync.c	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_sync.c,v 1.12 2009/08/19 08:36:13 darrenr Exp $	*/
+/*	$NetBSD: ip_sync.c,v 1.13 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1995-1998 by Darren Reed.
@@ -103,9 +103,9 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_sync.c,v 1.12 2009/08/19 08:36:13 darrenr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_sync.c,v 1.13 2010/04/17 21:00:44 darrenr Exp $");
 #else
-static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.16 2009/01/27 08:33:23 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.17 2009/12/27 06:55:22 darrenr Exp";
 #endif
 #endif
 
@@ -115,7 +115,7 @@
 #ifdef	IPFILTER_SYNC
 # if SOLARIS && defined(_KERNEL)
 extern	struct pollhead	iplpollhead[IPL_LOGSIZE];
-# endif 
+# endif
 
 ipfmutex_t	ipf_syncadd, ipsl_mutex;
 ipfrwlock_t	ipf_syncstate, ipf_syncnat;
Index: src/sys/dist/ipf/netinet/ipl.h
diff -u src/sys/dist/ipf/netinet/ipl.h:1.12 src/sys/dist/ipf/netinet/ipl.h:1.13
--- src/sys/dist/ipf/netinet/ipl.h:1.12	Wed Aug 19 08:36:14 2009
+++ src/sys/dist/ipf/netinet/ipl.h	Sat Apr 17 21:00:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipl.h,v 1.12 2009/08/19 08:36:14 darrenr Exp $	*/
+/*	$NetBSD: ipl.h,v 1.13 2010/04/17 21:00:44 darrenr Exp $	*/
 
 /*
  * Copyright (C) 1993-2001, 2003 by Darren Reed.
@@ -6,14 +6,14 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * @(#)ipl.h	1.21 6/5/96
- * Id: ipl.h,v 2.52.2.36 2009/08/16 07:04:14 darrenr Exp
+ * Id: ipl.h,v 2.52.2.37 2010/01/31 16:22:55 darrenr Exp
  */
 
 #ifndef	__IPL_H__
 #define	__IPL_H__
 
-#define	IPL_VERSION	"IP Filter: v4.1.33"
+#define	IPL_VERSION	"IP Filter: v4.1.34"
 
-#define	IPFILTER_VERSION	4013300
+#define	IPFILTER_VERSION	4013400
 
 #endif

Reply via email to