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