summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2007-10-18 21:52:14 +0000
committerdarrenr <darrenr@FreeBSD.org>2007-10-18 21:52:14 +0000
commitfd172ed3272b523c5499832d7098b6766bac7e4f (patch)
tree7eb0ed562f560c2289c5b113e742797727d126db
parent6f755e940898e80d77f95031600e671c36e0a7a6 (diff)
downloadFreeBSD-src-fd172ed3272b523c5499832d7098b6766bac7e4f.zip
FreeBSD-src-fd172ed3272b523c5499832d7098b6766bac7e4f.tar.gz
Pullup IPFilter 4.1.28 from the vendor branch into HEAD.
MFC after: 7 days
-rw-r--r--contrib/ipfilter/Makefile19
-rw-r--r--contrib/ipfilter/ip_fil.c9
-rw-r--r--contrib/ipfilter/ipsend/iptests.c8
-rw-r--r--contrib/ipfilter/ipsend/sock.c8
-rw-r--r--contrib/ipfilter/l4check/l4check.c43
-rw-r--r--contrib/ipfilter/lib/ipft_tx.c37
-rw-r--r--contrib/ipfilter/lib/printnat.c13
-rw-r--r--contrib/ipfilter/lib/printpacket.c4
-rw-r--r--contrib/ipfilter/lib/printstate.c4
-rw-r--r--contrib/ipfilter/man/ippool.52
-rw-r--r--contrib/ipfilter/md5.h2
-rw-r--r--contrib/ipfilter/radix.c6
-rw-r--r--contrib/ipfilter/radix_ipf.h4
-rw-r--r--contrib/ipfilter/tools/ipf_y.y24
-rw-r--r--contrib/ipfilter/tools/ipfstat.c6
-rw-r--r--contrib/ipfilter/tools/ipmon.c35
-rw-r--r--contrib/ipfilter/tools/ipnat.c65
-rw-r--r--contrib/ipfilter/tools/ipnat_y.y1
-rw-r--r--contrib/ipfilter/tools/lexer.c55
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c285
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h182
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h51
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c283
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c14
-rw-r--r--sys/contrib/ipfilter/netinet/ip_htable.c90
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c254
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c10
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c172
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.c10
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h6
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c9
35 files changed, 1127 insertions, 666 deletions
diff --git a/contrib/ipfilter/Makefile b/contrib/ipfilter/Makefile
index 9b4673e..334cd45 100644
--- a/contrib/ipfilter/Makefile
+++ b/contrib/ipfilter/Makefile
@@ -6,7 +6,7 @@
# to the original author and the contributors.
#
# $FreeBSD$
-# Id: Makefile,v 2.76.2.19 2006/03/17 10:38:38 darrenr Exp $
+# Id: Makefile,v 2.76.2.24 2007/09/26 10:04:03 darrenr Exp $
#
SHELL=/bin/sh
BINDEST=/usr/local/bin
@@ -132,10 +132,7 @@ all:
@echo "openbsd - compile for OpenBSD"
@echo "freebsd20 - compile for FreeBSD 2.0, 2.1 or earlier"
@echo "freebsd22 - compile for FreeBSD-2.2 or greater"
- @echo "freebsd3 - compile for FreeBSD-3.x"
- @echo "freebsd4 - compile for FreeBSD-4.x"
- @echo "freebsd5 - compile for FreeBSD-5.x"
- @echo "freebsd6 - compile for FreeBSD-6.x"
+ @echo "freebsd - compile for all other versions of FreeBSD"
@echo "bsd - compile for generic 4.4BSD systems"
@echo "bsdi - compile for BSD/OS"
@echo "irix - compile for SGI IRIX"
@@ -152,6 +149,7 @@ retest:
else echo test directory not present, sorry; fi
include:
+ -mkdir -p net netinet
if [ ! -f netinet/done ] ; then \
(cd netinet; ln -s ../*.h .; ln -s ../ip_*_pxy.c .;); \
(cd netinet; ln -s ../ipsend/tcpip.h tcpip.h); \
@@ -167,6 +165,9 @@ sunos solaris: include
MAKE="$(MAKE)" MAKEFLAGS="$(MAKEFLAGS)" BPFILTER=$(BPFILTER) \
CC="$(CC)" DEBUG="$(DEBUG)" ./buildsunos
+freebsd:
+ make freebsd`uname -r|cut -c1`
+
freebsd22: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
-rm -f BSD/$(CPUDIR)/ioconf.h
@@ -351,13 +352,9 @@ sunos4 solaris1:
(cd SunOS4; make -f Makefile.ipsend build "CC=$(CC)" TOP=.. $(DEST) $(MFLAGS); cd ..)
sunos5 solaris2: null
- (cd SunOS5/$(CPUDIR); $(MAKE) build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
+ (cd SunOS5/$(CPUDIR); $(MAKE) build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)"; cd ..)
(cd SunOS5/$(CPUDIR); $(MAKE) -f Makefile.ipsend build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
-sunos5x86 solaris2x86: null
- (cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
- (cd SunOS5/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
-
linux: include
(cd Linux; make build LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) LINUXKERNEL=$(LINUXKERNEL); cd ..)
(cd Linux; make ipflkm LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) LINUXKERNEL=$(LINUXKERNEL) WORKDIR=`pwd`; cd ..)
@@ -374,7 +371,7 @@ install-sunos4: solaris
(cd SunOS4; $(MAKE) CPU=$(CPU) TOP=.. install)
install-sunos5: solaris null
- (cd SunOS5; $(MAKE) CPU=$(CPU) TOP=.. install)
+ (cd SunOS5; $(MAKE) TOP=.. install)
install-aix:
(cd AIX/`AIX/cpurev`; make install "TOP=../.." $(MFLAGS); cd ..)
diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c
index 45bbf94..a3efa87 100644
--- a/contrib/ipfilter/ip_fil.c
+++ b/contrib/ipfilter/ip_fil.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.16 2007/05/28 11:56:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.18 2007/09/09 11:32:05 darrenr Exp $";
#endif
#ifndef SOLARIS
@@ -81,7 +81,7 @@ struct file;
#include <sys/hashing.h>
# endif
#endif
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(SOLARIS2)
# include "radix_ipf.h"
#endif
#ifndef __osf__
@@ -390,7 +390,7 @@ int v;
*addr++ = '\0';
for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
- COPYIFNAME(ifp, ifname);
+ COPYIFNAME(v, ifp, ifname);
if (!strcmp(name, ifname)) {
if (addr != NULL)
fr_setifpaddr(ifp, addr);
@@ -429,6 +429,9 @@ int v;
}
ifp = ifneta[nifs - 1];
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ TAILQ_INIT(&ifp->if_addrlist);
+#endif
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c
index a58131d..0dd96b8 100644
--- a/contrib/ipfilter/ipsend/iptests.c
+++ b/contrib/ipfilter/ipsend/iptests.c
@@ -8,7 +8,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: iptests.c,v 2.8.2.8 2007/02/17 12:41:51 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: iptests.c,v 2.8.2.9 2007/09/13 07:19:34 darrenr Exp $";
#endif
#include <sys/param.h>
#include <sys/types.h>
@@ -22,6 +22,9 @@ typedef int boolean_t;
#endif
#include <sys/time.h>
#if !defined(__osf__)
+# ifdef __NetBSD__
+# include <machine/lock.h>
+# endif
# define _KERNEL
# define KERNEL
# if !defined(solaris) && !defined(linux) && !defined(__sgi) && !defined(hpux)
@@ -1097,7 +1100,8 @@ int ptest;
struct tcpcb *tcbp, tcb;
struct tcpiphdr ti;
struct sockaddr_in sin;
- int fd, slen;
+ int fd;
+ socklen_t slen;
bzero((char *)&sin, sizeof(sin));
diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c
index 7aac448..9a2cfc3 100644
--- a/contrib/ipfilter/ipsend/sock.c
+++ b/contrib/ipfilter/ipsend/sock.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: sock.c,v 2.8.4.6 2007/02/17 12:41:51 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: sock.c,v 2.8.4.7 2007/09/13 07:19:34 darrenr Exp $";
#endif
#include <sys/param.h>
#include <sys/types.h>
@@ -30,6 +30,9 @@ typedef int boolean_t;
# include <sys/dir.h>
#endif
#if !defined(__osf__)
+# ifdef __NetBSD__
+# include <machine/lock.h>
+# endif
# define _KERNEL
# define KERNEL
# ifdef ultrix
@@ -385,7 +388,8 @@ struct in_addr gwip;
{
struct sockaddr_in rsin, lsin;
struct tcpcb *t, tcb;
- int fd, nfd, len;
+ int fd, nfd;
+ socklen_t len;
printf("Dest. Port: %d\n", ti->ti_dport);
diff --git a/contrib/ipfilter/l4check/l4check.c b/contrib/ipfilter/l4check/l4check.c
index 5c44a37..fd2753e 100644
--- a/contrib/ipfilter/l4check/l4check.c
+++ b/contrib/ipfilter/l4check/l4check.c
@@ -27,6 +27,7 @@
#include "ip_compat.h"
#include "ip_fil.h"
#include "ip_nat.h"
+#include "ipl.h"
#include "ipf.h"
@@ -98,13 +99,21 @@ char *dst, *src;
void addnat(l4)
l4cfg_t *l4;
{
+
ipnat_t *ipn = &l4->l4_nat;
- printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0]),
+ printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0].in4),
ipn->in_outmsk, ntohs(ipn->in_pmin));
- printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ntohs(ipn->in_pnext));
+ printf("%s,%u\n", inet_ntoa(ipn->in_in[0].in4), ntohs(ipn->in_pnext));
if (!(opts & OPT_DONOTHING)) {
- if (ioctl(natfd, SIOCADNAT, &ipn) == -1)
+ ipfobj_t obj;
+
+ bzero(&obj, sizeof(obj));
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = sizeof(*ipn);
+ obj.ipfo_ptr = ipn;
+
+ if (ioctl(natfd, SIOCADNAT, &obj) == -1)
perror("ioctl(SIOCADNAT)");
}
}
@@ -116,9 +125,16 @@ l4cfg_t *l4;
ipnat_t *ipn = &l4->l4_nat;
printf("Remove NAT rule for %s/%#x,%u -> ",
- inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin);
- printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ipn->in_pnext);
+ inet_ntoa(ipn->in_out[0].in4), ipn->in_outmsk, ipn->in_pmin);
+ printf("%s,%u\n", inet_ntoa(ipn->in_in[0].in4), ipn->in_pnext);
if (!(opts & OPT_DONOTHING)) {
+ ipfobj_t obj;
+
+ bzero(&obj, sizeof(obj));
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = sizeof(*ipn);
+ obj.ipfo_ptr = ipn;
+
if (ioctl(natfd, SIOCRMNAT, &ipn) == -1)
perror("ioctl(SIOCRMNAT)");
}
@@ -178,7 +194,6 @@ l4cfg_t *l4;
void writefd(l4)
l4cfg_t *l4;
{
- char buf[80], *ptr;
int n, i, fd;
fd = l4->l4_fd;
@@ -410,7 +425,6 @@ u_short *portp;
struct servent *sp;
struct hostent *hp;
char *host, *port;
- struct in_addr ip;
host = str;
port = strchr(host, ',');
@@ -555,7 +569,8 @@ char *filename;
break;
}
- strncpy(ipn->in_ifname, s, sizeof(ipn->in_ifname));
+ strncpy(ipn->in_ifnames[0], s, LIFNAMSIZ);
+ strncpy(ipn->in_ifnames[1], s, LIFNAMSIZ);
if (!gethostport(t, num, &ipn->in_outip,
&ipn->in_pmin)) {
errtxt = line;
@@ -567,11 +582,11 @@ char *filename;
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Interface %s %s/%#x port %u\n",
- ipn->in_ifname,
- inet_ntoa(ipn->in_out[0]),
+ ipn->in_ifnames[0],
+ inet_ntoa(ipn->in_out[0].in4),
ipn->in_outmsk, ipn->in_pmin);
} else if (!strcasecmp(t, "remote")) {
- if (!*ipn->in_ifname) {
+ if (!*ipn->in_ifnames[0]) {
fprintf(stderr,
"%d: ifname not set prior to remote\n",
num);
@@ -606,7 +621,7 @@ char *filename;
break;
}
bcopy((char *)&template, (char *)l4, sizeof(*l4));
- l4->l4_sin.sin_addr = ipn->in_in[0];
+ l4->l4_sin.sin_addr = ipn->in_in[0].in4;
l4->l4_sin.sin_port = ipn->in_pnext;
l4->l4_next = l4list;
l4list = l4;
@@ -793,7 +808,7 @@ char *argv[];
}
if (!(opts & OPT_DONOTHING)) {
- natfd = open(IPL_NAT, O_RDWR);
+ natfd = open(IPNAT_NAME, O_RDWR);
if (natfd == -1) {
perror("open(IPL_NAT)");
exit(1);
@@ -804,4 +819,6 @@ char *argv[];
fprintf(stderr, "Starting...\n");
while (runconfig() == 0)
;
+
+ exit(1);
}
diff --git a/contrib/ipfilter/lib/ipft_tx.c b/contrib/ipfilter/lib/ipft_tx.c
index c613d6b..f4475e3 100644
--- a/contrib/ipfilter/lib/ipft_tx.c
+++ b/contrib/ipfilter/lib/ipft_tx.c
@@ -5,11 +5,11 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ipft_tx.c,v 1.15.2.9 2006/06/16 17:21:04 darrenr Exp $
+ * $Id: ipft_tx.c,v 1.15.2.10 2007/09/03 21:54:44 darrenr Exp $
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.9 2006/06/16 17:21:04 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.10 2007/09/03 21:54:44 darrenr Exp $";
#endif
#include <ctype.h>
@@ -259,19 +259,30 @@ int *out;
}
ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);
cpp++;
- if (*cpp && ip->ip_p == IPPROTO_TCP) {
- char *s, *t;
-
- tcp->th_flags = 0;
- for (s = *cpp; *s; s++)
- if ((t = strchr(myflagset, *s)))
- tcp->th_flags |= myflags[t - myflagset];
- if (tcp->th_flags)
- cpp++;
- if (tcp->th_flags == 0)
- abort();
+ if (ip->ip_p == IPPROTO_TCP) {
+ if (*cpp != NULL) {
+ char *s, *t;
+
+ tcp->th_flags = 0;
+ for (s = *cpp; *s; s++)
+ if ((t = strchr(myflagset, *s)))
+ tcp->th_flags |= myflags[t-myflagset];
+ if (tcp->th_flags)
+ cpp++;
+ }
+
if (tcp->th_flags & TH_URG)
tcp->th_urp = htons(1);
+
+ if (*cpp && !strncasecmp(*cpp, "seq=", 4)) {
+ tcp->th_seq = htonl(atoi(*cpp + 4));
+ cpp++;
+ }
+
+ if (*cpp && !strncasecmp(*cpp, "ack=", 4)) {
+ tcp->th_ack = htonl(atoi(*cpp + 4));
+ cpp++;
+ }
} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {
extern char *tx_icmptypes[];
char **s, *t;
diff --git a/contrib/ipfilter/lib/printnat.c b/contrib/ipfilter/lib/printnat.c
index 06ed9a3..62942ce 100644
--- a/contrib/ipfilter/lib/printnat.c
+++ b/contrib/ipfilter/lib/printnat.c
@@ -13,7 +13,7 @@
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.13 2006/12/09 10:37:47 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.14 2007/09/06 16:40:11 darrenr Exp $";
#endif
/*
@@ -136,6 +136,8 @@ int opts;
if (opts & OPT_DEBUG)
printf("\tpmax %u\n", np->in_pmax);
} else {
+ int protoprinted = 0;
+
if (!(np->in_flags & IPN_FILTER)) {
printf("%s/", inet_ntoa(np->in_in[0].in4));
bits = count4bits(np->in_inmsk);
@@ -172,6 +174,7 @@ int opts;
printf(" %.*s/", (int)sizeof(np->in_plabel),
np->in_plabel);
printproto(pr, np->in_p, NULL);
+ protoprinted = 1;
} else if (np->in_redir == NAT_MAPBLK) {
if ((np->in_pmin == 0) &&
(np->in_flags & IPN_AUTOPORTMAP))
@@ -187,6 +190,7 @@ int opts;
printf(" portmap ");
}
printproto(pr, np->in_p, np);
+ protoprinted = 1;
if (np->in_flags & IPN_AUTOPORTMAP) {
printf(" auto");
if (opts & OPT_DEBUG)
@@ -198,9 +202,6 @@ int opts;
printf(" %d:%d", ntohs(np->in_pmin),
ntohs(np->in_pmax));
}
- } else if (np->in_flags & IPN_TCPUDP || np->in_p) {
- putchar(' ');
- printproto(pr, np->in_p, np);
}
if (np->in_flags & IPN_FRAG)
@@ -212,6 +213,10 @@ int opts;
printf(" mssclamp %d", np->in_mssclamp);
if (np->in_tag.ipt_tag[0] != '\0')
printf(" tag %s", np->in_tag.ipt_tag);
+ if (!protoprinted && (np->in_flags & IPN_TCPUDP || np->in_p)) {
+ putchar(' ');
+ printproto(pr, np->in_p, np);
+ }
printf("\n");
if (opts & OPT_DEBUG) {
struct in_addr nip;
diff --git a/contrib/ipfilter/lib/printpacket.c b/contrib/ipfilter/lib/printpacket.c
index cff13eb..25a4d5a 100644
--- a/contrib/ipfilter/lib/printpacket.c
+++ b/contrib/ipfilter/lib/printpacket.c
@@ -5,7 +5,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: printpacket.c,v 1.12.4.4 2006/09/30 21:44:43 darrenr Exp $
+ * $Id: printpacket.c,v 1.12.4.5 2007/09/09 22:15:30 darrenr Exp $
*/
#include "ipf.h"
@@ -56,7 +56,7 @@ struct ip *ip;
printf("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len),
IP_HL(ip) << 2, ip->ip_p);
if (off & IP_OFFMASK)
- printf(" @%d", off << 3);
+ printf(" @%d", (off & IP_OFFMASK) << 3);
printf(" %s", inet_ntoa(ip->ip_src));
if (!(off & IP_OFFMASK))
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
diff --git a/contrib/ipfilter/lib/printstate.c b/contrib/ipfilter/lib/printstate.c
index 43621ef..a8777b2 100644
--- a/contrib/ipfilter/lib/printstate.c
+++ b/contrib/ipfilter/lib/printstate.c
@@ -35,8 +35,8 @@ u_long now;
sp->is_send, sp->is_dend,
sp->is_maxswin, sp->is_swinscale,
sp->is_maxdwin, sp->is_dwinscale);
- PRINTF("\tcmsk %04x smsk %04x isc %p s0 %08x/%08x\n",
- sp->is_smsk[0], sp->is_smsk[1], sp->is_isc,
+ PRINTF("\tcmsk %04x smsk %04x s0 %08x/%08x\n",
+ sp->is_smsk[0], sp->is_smsk[1],
sp->is_s0[0], sp->is_s0[1]);
PRINTF("\tFWD:ISN inc %x sumd %x\n",
sp->is_isninc[0], sp->is_sumd[0]);
diff --git a/contrib/ipfilter/man/ippool.5 b/contrib/ipfilter/man/ippool.5
index 974a0e8..367eb8d 100644
--- a/contrib/ipfilter/man/ippool.5
+++ b/contrib/ipfilter/man/ippool.5
@@ -94,7 +94,7 @@ to use the tree data storage type with
configuration entries.
.SH POOL ROLES
.PP
-When a pool is defined in the configruation file, it must have an associated
+When a pool is defined in the configuration file, it must have an associated
role. At present the only supported role is
.B ipf.
Future development will see futher expansion of their use by other sections
diff --git a/contrib/ipfilter/md5.h b/contrib/ipfilter/md5.h
index 8270531..914df74 100644
--- a/contrib/ipfilter/md5.h
+++ b/contrib/ipfilter/md5.h
@@ -39,7 +39,7 @@
***********************************************************************
*/
-#ifndef __MD5_INCLUDE__
+#if !defined(__MD5_INCLUDE__) && !defined(_SYS_MD5_H)
#ifndef __P
# ifdef __STDC__
diff --git a/contrib/ipfilter/radix.c b/contrib/ipfilter/radix.c
index e0c69ed..8c67562 100644
--- a/contrib/ipfilter/radix.c
+++ b/contrib/ipfilter/radix.c
@@ -76,8 +76,14 @@ void panic __P((char *str));
#include <netinet/in.h>
#include <sys/socket.h>
#include <net/if.h>
+#ifdef SOLARIS2
+# define _RADIX_H_
+#endif
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
+#ifdef SOLARIS2
+# undef _RADIX_H_
+#endif
/* END OF INCLUDES */
#include "radix_ipf.h"
#ifndef min
diff --git a/contrib/ipfilter/radix_ipf.h b/contrib/ipfilter/radix_ipf.h
index 220a389..11e4ba7 100644
--- a/contrib/ipfilter/radix_ipf.h
+++ b/contrib/ipfilter/radix_ipf.h
@@ -42,7 +42,7 @@
# endif
#endif
-#if defined(__sgi) || defined(__osf__)
+#if defined(__sgi) || defined(__osf__) || defined(sun)
# define radix_mask ipf_radix_mask
# define radix_node ipf_radix_node
# define radix_node_head ipf_radix_node_head
@@ -163,7 +163,7 @@ struct radix_node_head {
#define FreeS(p, z) KFREES(p, z)
#define Free(p) KFREE(p)
-#if (defined(__osf__) || defined(AIX) || (IRIX >= 60516)) && defined(_KERNEL)
+#if (defined(__osf__) || defined(AIX) || (IRIX >= 60516) || defined(sun)) && defined(_KERNEL)
# define rn_init ipf_rn_init
# define rn_fini ipf_rn_fini
# define rn_inithead ipf_rn_inithead
diff --git a/contrib/ipfilter/tools/ipf_y.y b/contrib/ipfilter/tools/ipf_y.y
index e8789e0..2ce4291 100644
--- a/contrib/ipfilter/tools/ipf_y.y
+++ b/contrib/ipfilter/tools/ipf_y.y
@@ -772,8 +772,20 @@ fromport:
srcportlist:
portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) }
+ | portnum ':' portnum
+ { DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $1; \
+ fr->fr_stop = $3;) }
+ | portnum YY_RANGE_IN portnum
+ { DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $1; \
+ fr->fr_stop = $3;) }
| srcportlist lmore portnum
{ DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) }
+ | srcportlist lmore portnum ':' portnum
+ { DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $3; \
+ fr->fr_stop = $5;) }
+ | srcportlist lmore portnum YY_RANGE_IN portnum
+ { DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $3; \
+ fr->fr_stop = $5;) }
;
dstobject:
@@ -838,8 +850,20 @@ toport:
dstportlist:
portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) }
+ | portnum ':' portnum
+ { DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $1; \
+ fr->fr_dtop = $3;) }
+ | portnum YY_RANGE_IN portnum
+ { DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $1; \
+ fr->fr_dtop = $3;) }
| dstportlist lmore portnum
{ DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) }
+ | dstportlist lmore portnum ':' portnum
+ { DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $3; \
+ fr->fr_dtop = $5;) }
+ | dstportlist lmore portnum YY_RANGE_IN portnum
+ { DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $3; \
+ fr->fr_dtop = $5;) }
;
addr: pool '/' YY_NUMBER { pooled = 1;
diff --git a/contrib/ipfilter/tools/ipfstat.c b/contrib/ipfilter/tools/ipfstat.c
index 481282a..3c5bfdd 100644
--- a/contrib/ipfilter/tools/ipfstat.c
+++ b/contrib/ipfilter/tools/ipfstat.c
@@ -71,7 +71,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.23 2007/05/31 13:13:02 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.25 2007/06/30 09:48:50 darrenr Exp $";
#endif
#ifdef __hpux
@@ -1120,7 +1120,7 @@ ips_stat_t *ipsp;
PRINTF("\t%u%% hash efficiency\n", ipsp->iss_active ?
(u_int)(ipsp->iss_inuse * 100 / ipsp->iss_active) : 0);
- minlen = ipsp->iss_max;
+ minlen = ipsp->iss_inuse;
totallen = 0;
maxlen = 0;
@@ -1128,7 +1128,7 @@ ips_stat_t *ipsp;
if (buckets[i] > maxlen)
maxlen = buckets[i];
if (buckets[i] < minlen)
- minlen = buckets[i];
+ minlen = buckets[i];
totallen += buckets[i];
}
diff --git a/contrib/ipfilter/tools/ipmon.c b/contrib/ipfilter/tools/ipmon.c
index f651f86..ceaed82 100644
--- a/contrib/ipfilter/tools/ipmon.c
+++ b/contrib/ipfilter/tools/ipmon.c
@@ -78,7 +78,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.18 2007/05/27 11:12:12 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.20 2007/09/20 12:51:56 darrenr Exp $";
#endif
@@ -752,6 +752,8 @@ int blen;
strcpy(t, "NAT:MAPBLOCK ");
else if (nl->nl_type == NL_CLONE)
strcpy(t, "NAT:CLONE ");
+ else if (nl->nl_type == NL_DESTROY)
+ strcpy(t, "NAT:DESTROY ");
else
sprintf(t, "Type: %d ", nl->nl_type);
t += strlen(t);
@@ -764,8 +766,9 @@ int blen;
(void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip),
portname(res, proto, (u_int)nl->nl_outport));
t += strlen(t);
- (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip),
- portname(res, proto, (u_int)nl->nl_origport));
+ (void) sprintf(t, "[%s,%s PR %s]", HOSTNAME_V4(res, nl->nl_origip),
+ portname(res, proto, (u_int)nl->nl_origport),
+ getproto(nl->nl_p));
t += strlen(t);
if (nl->nl_type == NL_EXPIRE) {
#ifdef USE_QUAD_T
@@ -1002,7 +1005,10 @@ int blen;
ipflog_t *ipf;
iplog_t *ipl;
#ifdef USE_INET6
+ struct ip6_ext *ehp;
+ u_short ehl;
ip6_t *ip6;
+ int go;
#endif
ipl = (iplog_t *)buf;
@@ -1111,6 +1117,29 @@ int blen;
s = (u_32_t *)&ip6->ip6_src;
d = (u_32_t *)&ip6->ip6_dst;
plen = hl + ntohs(ip6->ip6_plen);
+ go = 1;
+ ehp = (struct ip6_ext *)((char *)ip6 + hl);
+ while (go == 1) {
+ switch (p)
+ {
+ case IPPROTO_HOPOPTS :
+ case IPPROTO_MOBILITY :
+ case IPPROTO_DSTOPTS :
+ case IPPROTO_ROUTING :
+ case IPPROTO_AH :
+ p = ehp->ip6e_nxt;
+ ehl = 8 + (ehp->ip6e_len << 3);
+ hl += ehl;
+ ehp = (struct ip6_ext *)((char *)ehp + ehl);
+ break;
+ case IPPROTO_FRAGMENT :
+ hl += sizeof(struct ip6_frag);
+ /* FALLTHROUGH */
+ default :
+ go = 0;
+ break;
+ }
+ }
#else
sprintf(t, "ipv6");
goto printipflog;
diff --git a/contrib/ipfilter/tools/ipnat.c b/contrib/ipfilter/tools/ipnat.c
index c9954ab..28e29ec 100644
--- a/contrib/ipfilter/tools/ipnat.c
+++ b/contrib/ipfilter/tools/ipnat.c
@@ -67,7 +67,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.6 2007/05/11 11:16:55 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.11 2007/09/25 08:27:34 darrenr Exp $";
#endif
@@ -80,6 +80,7 @@ char thishost[MAXHOSTNAMELEN];
extern char *optarg;
void dostats __P((int, natstat_t *, int, int));
+void dotable __P((natstat_t *, int, int));
void flushtable __P((int, int));
void usage __P((char *));
int main __P((int, char*[]));
@@ -359,9 +360,10 @@ int fd, opts, alive;
nsp->ns_added, nsp->ns_expire);
printf("no memory\t%lu\tbad nat\t%lu\n",
nsp->ns_memfail, nsp->ns_badnat);
- printf("inuse\t%lu\nrules\t%lu\n",
- nsp->ns_inuse, nsp->ns_rules);
+ printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n",
+ nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules);
printf("wilds\t%u\n", nsp->ns_wilds);
+ dotable(nsp, fd, alive);
if (opts & OPT_VERBOSE)
printf("table %p list %p\n",
nsp->ns_table, nsp->ns_list);
@@ -378,6 +380,63 @@ int fd, opts, alive;
}
+void dotable(nsp, fd, alive)
+natstat_t *nsp;
+int fd, alive;
+{
+ int sz, i, used, totallen, maxlen, minlen;
+ ipftable_t table;
+ u_long *buckets;
+ ipfobj_t obj;
+
+ sz = sizeof(*buckets) * nsp->ns_nattab_sz;
+ buckets = (u_long *)malloc(sz);
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_GTABLE;
+ obj.ipfo_size = sizeof(table);
+ obj.ipfo_ptr = &table;
+
+ table.ita_type = IPFTABLE_BUCKETS_NATIN;
+ table.ita_table = buckets;
+
+ if (alive) {
+ if (ioctl(fd, SIOCGTABL, &obj) != 0) {
+ free(buckets);
+ return;
+ }
+ } else {
+ if (kmemcpy((char *)buckets, (u_long)nsp->ns_nattab_sz, sz)) {
+ free(buckets);
+ return;
+ }
+ }
+
+ totallen = 0;
+ maxlen = 0;
+ minlen = nsp->ns_inuse;
+ used = 0;
+
+ for (i = 0; i < nsp->ns_nattab_sz; i++) {
+ if (buckets[i] > maxlen)
+ maxlen = buckets[i];
+ if (buckets[i] < minlen)
+ minlen = buckets[i];
+ if (buckets[i] != 0)
+ used++;
+ totallen += buckets[i];
+ }
+
+ printf("hash efficiency\t%2.2f%%\n",
+ totallen ? ((float)used / totallen) * 100.0 : 0.0);
+ printf("bucket usage\t%2.2f%%\n",
+ ((float)used / nsp->ns_nattab_sz) * 100.0);
+ printf("minimal length\t%d\n", minlen);
+ printf("maximal length\t%d\n", maxlen);
+ printf("average length\t%.3f\n", used ? (float)totallen / used : 0.0);
+}
+
+
/*
* Display NAT statistics.
*/
diff --git a/contrib/ipfilter/tools/ipnat_y.y b/contrib/ipfilter/tools/ipnat_y.y
index 1857219..cce717d 100644
--- a/contrib/ipfilter/tools/ipnat_y.y
+++ b/contrib/ipfilter/tools/ipnat_y.y
@@ -611,6 +611,7 @@ compare:
range:
YY_RANGE_OUT { $$ = FR_OUTRANGE; }
| YY_RANGE_IN { $$ = FR_INRANGE; }
+ | ':' { $$ = FR_INCRANGE; }
;
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
diff --git a/contrib/ipfilter/tools/lexer.c b/contrib/ipfilter/tools/lexer.c
index 2969f86..989643c 100644
--- a/contrib/ipfilter/tools/lexer.c
+++ b/contrib/ipfilter/tools/lexer.c
@@ -38,6 +38,7 @@ extern int yydebug;
char *yystr = NULL;
int yytext[YYBUFSIZ+1];
+char yychars[YYBUFSIZ+1];
int yylineNum = 1;
int yypos = 0;
int yylast = -1;
@@ -51,13 +52,15 @@ wordtab_t *yysavewords[30];
static wordtab_t *yyfindkey __P((char *));
-static int yygetc __P((void));
+static int yygetc __P((int));
static void yyunputc __P((int));
static int yyswallow __P((int));
static char *yytexttostr __P((int, int));
static void yystrtotext __P((char *));
+static char *yytexttochar __P((void));
-static int yygetc()
+static int yygetc(docont)
+int docont;
{
int c;
@@ -76,6 +79,13 @@ static int yygetc()
yypos++;
} else {
c = fgetc(yyin);
+ if (docont && (c == '\\')) {
+ c = fgetc(yyin);
+ if (c == '\n') {
+ yylineNum++;
+ c = fgetc(yyin);
+ }
+ }
}
if (c == '\n')
yylineNum++;
@@ -101,7 +111,7 @@ int last;
{
int c;
- while (((c = yygetc()) > '\0') && (c != last))
+ while (((c = yygetc(0)) > '\0') && (c != last))
;
if (c != EOF)
@@ -112,6 +122,17 @@ int last;
}
+static char *yytexttochar()
+{
+ int i;
+
+ for (i = 0; i < yypos; i++)
+ yychars[i] = (char)(yytext[i] & 0xff);
+ yychars[i] = '\0';
+ return yychars;
+}
+
+
static void yystrtotext(str)
char *str;
{
@@ -167,7 +188,9 @@ int yylex()
}
nextchar:
- c = yygetc();
+ c = yygetc(0);
+ if (yydebug > 1)
+ printf("yygetc = (%x) %c [%*.*s]\n", c, c, yypos, yypos, yytexttochar());
switch (c)
{
@@ -230,20 +253,20 @@ nextchar:
yyunputc(c);
goto done;
}
- n = yygetc();
+ n = yygetc(0);
if (n == '{') {
if (yyswallow('}') == -1) {
rval = -2;
goto done;
}
- (void) yygetc();
+ (void) yygetc(0);
} else {
if (!ISALPHA(n)) {
yyunputc(n);
break;
}
do {
- n = yygetc();
+ n = yygetc(1);
} while (ISALPHA(n) || ISDIGIT(n) || n == '_');
yyunputc(n);
}
@@ -275,7 +298,7 @@ nextchar:
goto done;
}
do {
- n = yygetc();
+ n = yygetc(1);
if (n == EOF || n == TOOLONG) {
rval = -2;
goto done;
@@ -325,7 +348,7 @@ nextchar:
break;
if (isbuilding == 1)
break;
- n = yygetc();
+ n = yygetc(0);
if (n == '>') {
isbuilding = 1;
goto done;
@@ -339,7 +362,7 @@ nextchar:
yyunputc(c);
goto done;
}
- n = yygetc();
+ n = yygetc(0);
if (n == '=') {
rval = YY_CMP_NE;
goto done;
@@ -355,7 +378,7 @@ nextchar:
yyunputc(c);
goto done;
}
- n = yygetc();
+ n = yygetc(0);
if (n == '=') {
rval = YY_CMP_LE;
goto done;
@@ -375,7 +398,7 @@ nextchar:
yyunputc(c);
goto done;
}
- n = yygetc();
+ n = yygetc(0);
if (n == '=') {
rval = YY_CMP_GE;
goto done;
@@ -412,7 +435,7 @@ nextchar:
*/
do {
*s++ = c;
- c = yygetc();
+ c = yygetc(1);
} while ((ishex(c) || c == ':' || c == '.') &&
(s - ipv6buf < 46));
yyunputc(c);
@@ -438,10 +461,10 @@ nextchar:
}
if (isbuilding == 0 && c == '0') {
- n = yygetc();
+ n = yygetc(0);
if (n == 'x') {
do {
- n = yygetc();
+ n = yygetc(1);
} while (ishex(n));
yyunputc(n);
rval = YY_HEX;
@@ -455,7 +478,7 @@ nextchar:
*/
if (isbuilding == 0 && ISDIGIT(c)) {
do {
- n = yygetc();
+ n = yygetc(1);
} while (ISDIGIT(n));
yyunputc(n);
rval = YY_NUMBER;
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index 014fb0f..5a083a4 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -82,7 +82,7 @@ struct file;
#ifdef sun
# include <net/af.h>
#endif
-#if !defined(_KERNEL) && defined(__FreeBSD__)
+#if !defined(_KERNEL) && (defined(__FreeBSD__) || defined(SOLARIS2))
# if (__FreeBSD_version >= 504000)
# undef _RADIX_H_
# endif
@@ -156,7 +156,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $"; */
+/* static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $"; */
#endif
#ifndef _KERNEL
@@ -362,7 +362,7 @@ static INLINE int frpr_hopopts6 __P((fr_info_t *));
static INLINE int frpr_mobility6 __P((fr_info_t *));
static INLINE int frpr_routing6 __P((fr_info_t *));
static INLINE int frpr_dstopts6 __P((fr_info_t *));
-static INLINE void frpr_fragment6 __P((fr_info_t *));
+static INLINE int frpr_fragment6 __P((fr_info_t *));
static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int));
@@ -480,8 +480,9 @@ fr_info_t *fin;
break;
case IPPROTO_FRAGMENT :
- frpr_fragment6(fin);
- go = 0;
+ p = frpr_fragment6(fin);
+ if (fin->fin_off != 0)
+ go = 0;
break;
default :
@@ -652,7 +653,7 @@ fr_info_t *fin;
/* ------------------------------------------------------------------------ */
/* Function: frpr_fragment6 */
-/* Returns: void */
+/* Returns: int - value of the next header or IPPROTO_NONE if error */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* IPv6 Only */
@@ -664,7 +665,7 @@ fr_info_t *fin;
/* upper layer header has been seen (or where it ends) and thus we are not */
/* able to continue processing beyond this header with any confidence. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_fragment6(fin)
+static INLINE int frpr_fragment6(fin)
fr_info_t *fin;
{
struct ip6_frag *frag;
@@ -673,12 +674,12 @@ fr_info_t *fin;
fin->fin_flx |= FI_FRAG;
if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE)
- return;
+ return IPPROTO_NONE;
extoff = (char *)fin->fin_exthdr - (char *)fin->fin_dp;
if (frpr_pullup(fin, sizeof(*frag)) == -1)
- return;
+ return IPPROTO_NONE;
fin->fin_exthdr = (char *)fin->fin_dp + extoff;
frag = fin->fin_exthdr;
@@ -687,16 +688,18 @@ fr_info_t *fin;
*/
if (frag->ip6f_offlg == 0) {
fin->fin_flx |= FI_BAD;
- return;
+ return IPPROTO_NONE;
}
- fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
+ fin->fin_off = ntohs(frag->ip6f_offlg & IP6F_OFF_MASK);
fin->fin_off <<= 3;
if (fin->fin_off != 0)
fin->fin_flx |= FI_FRAGBODY;
fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
fin->fin_dlen -= sizeof(*frag);
+
+ return frag->ip6f_nxt;
}
@@ -752,15 +755,15 @@ fr_info_t *fin;
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
fin->fin_flx |= FI_ICMPERR;
- if ((fin->fin_m != NULL) &&
- (M_LEN(fin->fin_m) < fin->fin_plen)) {
+ minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
+ if (fin->fin_plen < ICMP6ERR_IPICMPHLEN)
+ break;
+
+ if (M_LEN(fin->fin_m) < fin->fin_plen) {
if (fr_coalesce(fin) != 1)
return;
}
- if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN) == -1)
- return;
-
/*
* If the destination of this packet doesn't match the
* source of the original packet then this packet is
@@ -772,7 +775,6 @@ fr_info_t *fin;
(i6addr_t *)&ip6->ip6_src))
fin->fin_flx |= FI_BAD;
- minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
break;
default :
break;
@@ -913,6 +915,14 @@ fr_info_t *fin;
/* Short inline function to cut down on code duplication to perform a call */
/* to fr_pullup to ensure there is the required amount of data, */
/* consecutively in the packet buffer. */
+/* */
+/* This function pulls up 'extra' data at the location of fin_dp. fin_dp */
+/* points to the first byte after the complete layer 3 header, which will */
+/* include all of the known extension headers for IPv6 or options for IPv4. */
+/* */
+/* Since fr_pullup() expects the total length of bytes to be pulled up, it */
+/* is necessary to add those we can already assume to be pulled up (fin_dp */
+/* - fin_ip) to what is passed through. */
/* ------------------------------------------------------------------------ */
static INLINE int frpr_pullup(fin, plen)
fr_info_t *fin;
@@ -1001,6 +1011,9 @@ fr_info_t *fin;
fin->fin_data[0] = *(u_short *)icmp;
+ if (fin->fin_dlen >= 6) /* ID field */
+ fin->fin_data[1] = icmp->icmp_id;
+
switch (icmp->icmp_type)
{
case ICMP_ECHOREPLY :
@@ -1071,14 +1084,12 @@ fr_info_t *fin;
default :
break;
}
-
- if (fin->fin_dlen >= 6) /* ID field */
- fin->fin_data[1] = icmp->icmp_id;
}
frpr_short(fin, minicmpsz);
- fr_checkv4sum(fin);
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
}
@@ -1194,6 +1205,7 @@ fr_info_t *fin;
return -1;
#if 0
+ tcp = fin->fin_dp;
ip = fin->fin_ip;
s = (u_char *)(tcp + 1);
off = IP_HL(ip) << 2;
@@ -1281,8 +1293,10 @@ fr_info_t *fin;
frpr_short(fin, sizeof(tcphdr_t));
- if (frpr_tcpcommon(fin) == 0)
- fr_checkv4sum(fin);
+ if (frpr_tcpcommon(fin) == 0) {
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
+ }
}
@@ -1300,8 +1314,10 @@ fr_info_t *fin;
frpr_short(fin, sizeof(udphdr_t));
- if (frpr_udpcommon(fin) == 0)
- fr_checkv4sum(fin);
+ if (frpr_udpcommon(fin) == 0) {
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
+ }
}
@@ -1951,7 +1967,7 @@ int fr_scanlist(fin, pass)
fr_info_t *fin;
u_32_t pass;
{
- int rulen, portcmp, off, logged, skip;
+ int rulen, portcmp, off, skip;
struct frentry *fr, *fnext;
u_32_t passt, passo;
@@ -1970,7 +1986,6 @@ u_32_t pass;
return pass;
skip = 0;
- logged = 0;
portcmp = 0;
fin->fin_depth++;
fin->fin_fr = NULL;
@@ -2104,7 +2119,7 @@ u_32_t pass;
ATOMIC_INCL(frstats[fin->fin_out].fr_skip);
}
ATOMIC_INCL(frstats[fin->fin_out].fr_pkl);
- logged = 1;
+ fin->fin_flx |= FI_DONTCACHE;
}
#endif /* IPFILTER_LOG */
fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
@@ -2129,8 +2144,6 @@ u_32_t pass;
fin->fin_fr = fr;
passt = pass;
}
- if (fin->fin_flx & FI_DONTCACHE)
- logged = 1;
pass = passt;
}
@@ -2158,8 +2171,6 @@ u_32_t pass;
break;
}
}
- if (logged)
- fin->fin_flx |= FI_DONTCACHE;
fin->fin_depth--;
return pass;
}
@@ -2410,8 +2421,10 @@ int out;
# ifdef MENTAT
qpktinfo_t *qpi = qif;
+# if !defined(_INET_IP_STACK_H)
if ((u_int)ip & 0x3)
return 2;
+# endif
# else
SPL_INT(s);
# endif
@@ -2564,11 +2577,20 @@ int out;
if (!out)
(void) fr_acctpkt(fin, NULL);
- if (fr == NULL)
- if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG)
+ if (fr == NULL) {
+ if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) {
fr = fr_knownfrag(fin, &pass);
- if (fr == NULL)
- fr = fr_checkstate(fin, &pass);
+ /*
+ * Reset the keep state flag here so that we don't
+ * try and add a new state entry because of it, leading
+ * to a blocked packet because the add will fail.
+ */
+ if (fr != NULL)
+ pass &= ~FR_KEEPSTATE;
+ }
+ if (fr == NULL)
+ fr = fr_checkstate(fin, &pass);
+ }
if ((pass & FR_NOMATCH) || (fr == NULL))
fr = fr_firewall(fin, &pass);
@@ -2631,7 +2653,14 @@ filterdone:
}
if (fin->fin_nat != NULL) {
- fr_natderef((nat_t **)&fin->fin_nat);
+ if (FR_ISBLOCK(pass) && (fin->fin_flx & FI_NEWNAT)) {
+ WRITE_ENTER(&ipf_nat);
+ nat_delete((nat_t *)fin->fin_nat, NL_DESTROY);
+ RWLOCK_EXIT(&ipf_nat);
+ fin->fin_nat = NULL;
+ } else {
+ fr_natderef((nat_t **)&fin->fin_nat);
+ }
}
/*
@@ -3071,8 +3100,8 @@ void *l4hdr;
* In case we had to copy the IP & TCP header out of mbufs,
* skip over the mbuf bits which are the header
*/
- if ((caddr_t)ip != mtod(m, caddr_t)) {
- hlen = (caddr_t)sp - (caddr_t)ip;
+ if ((char *)ip != mtod(m, char *)) {
+ hlen = (char *)sp - (char *)ip;
while (hlen) {
add = MIN(hlen, m->m_len);
sp = (u_short *)(mtod(m, caddr_t) + add);
@@ -3095,12 +3124,12 @@ void *l4hdr;
goto nodata;
while (len > 1) {
- if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) {
+ if (((char *)sp - mtod(m, char *)) >= m->m_len) {
m = m->m_next;
PANIC((!m),("fr_cksum(2): not enough data"));
sp = mtod(m, u_short *);
}
- if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) {
+ if (((char *)(sp + 1) - mtod(m, char *)) > m->m_len) {
bytes.c[0] = *(u_char *)sp;
m = m->m_next;
PANIC((!m),("fr_cksum(3): not enough data"));
@@ -3178,7 +3207,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp $
+ * $Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -3484,7 +3513,7 @@ minor_t unit;
int *nfreedp;
frentry_t **listp;
{
- int freed = 0, i;
+ int freed = 0;
frentry_t *fp;
while ((fp = *listp) != NULL) {
@@ -3495,8 +3524,7 @@ frentry_t **listp;
}
*listp = fp->fr_next;
if (fp->fr_grp != NULL) {
- i = frflushlist(set, unit, nfreedp, fp->fr_grp);
- fp->fr_ref -= i;
+ (void) frflushlist(set, unit, nfreedp, fp->fr_grp);
}
if (fp->fr_grhead != NULL) {
@@ -3852,7 +3880,7 @@ size_t size;
int error;
# if SOLARIS
- error = COPYIN(src, (caddr_t)&ca, sizeof(ca));
+ error = COPYIN(src, &ca, sizeof(ca));
if (error != 0)
return error;
# else
@@ -3894,22 +3922,27 @@ size_t size;
/* ------------------------------------------------------------------------ */
/* Function: fr_lock */
-/* Returns: (void) */
+/* Returns: int - 0 = success, else error */
/* Parameters: data(I) - pointer to lock value to set */
/* lockp(O) - pointer to location to store old lock value */
/* */
/* Get the new value for the lock integer, set it and return the old value */
/* in *lockp. */
/* ------------------------------------------------------------------------ */
-void fr_lock(data, lockp)
+int fr_lock(data, lockp)
caddr_t data;
int *lockp;
{
- int arg;
+ int arg, err;
- BCOPYIN(data, (caddr_t)&arg, sizeof(arg));
- BCOPYOUT((caddr_t)lockp, data, sizeof(*lockp));
+ err = BCOPYIN(data, &arg, sizeof(arg));
+ if (err != 0)
+ return EFAULT;
+ err = BCOPYOUT(lockp, data, sizeof(*lockp));
+ if (err != 0)
+ return EFAULT;
*lockp = arg;
+ return 0;
}
@@ -4548,7 +4581,7 @@ caddr_t data;
/*
* Return EBUSY if the rule is being reference by
- * something else (eg state information.
+ * something else (eg state information.)
*/
if (f->fr_ref > 1) {
error = EBUSY;
@@ -4559,8 +4592,6 @@ caddr_t data;
(f->fr_isc != (struct ipscan *)-1))
ipsc_detachfr(f);
#endif
- if ((fg != NULL) && (fg->fg_head != NULL))
- fg->fg_head->fr_ref--;
if (unit == IPL_LOGAUTH) {
error = fr_preauthcmd(req, f, ftail);
goto done;
@@ -4588,8 +4619,6 @@ caddr_t data;
} else
f = fp;
if (f != NULL) {
- if (fg != NULL && fg->fg_head != NULL)
- fg->fg_head->fr_ref++;
if (fp != f)
bcopy((char *)fp, (char *)f,
sizeof(*f));
@@ -4689,8 +4718,11 @@ int fr_resolvefunc(data)
void *data;
{
ipfunc_resolve_t res, *ft;
+ int err;
- BCOPYIN(data, &res, sizeof(res));
+ err = BCOPYIN(data, &res, sizeof(res));
+ if (err != 0)
+ return EFAULT;
if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') {
for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++)
@@ -5459,7 +5491,9 @@ int type;
if ((type < 0) || (type >= IPFOBJ_COUNT))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5485,11 +5519,9 @@ int type;
#endif
if ((fr_objbytes[type][0] & 1) != 0) {
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
- fr_objbytes[type][1]);
+ error = COPYIN(obj.ipfo_ptr, ptr, fr_objbytes[type][1]);
} else {
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
- obj.ipfo_size);
+ error = COPYIN(obj.ipfo_ptr, ptr, obj.ipfo_size);
}
if (error != 0)
error = EFAULT;
@@ -5524,7 +5556,9 @@ int type, sz;
if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1]))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5541,7 +5575,7 @@ int type, sz;
return EINVAL;
#endif
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, sz);
+ error = COPYIN(obj.ipfo_ptr, ptr, sz);
if (error != 0)
error = EFAULT;
return error;
@@ -5570,12 +5604,14 @@ int type, sz;
ipfobj_t obj;
int error;
- if ((type < 0) || (type > IPFOBJ_COUNT) ||
+ if ((type < 0) || (type >= IPFOBJ_COUNT) ||
((fr_objbytes[type][0] & 1) == 0) ||
(sz < fr_objbytes[type][1]))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5592,7 +5628,7 @@ int type, sz;
return EINVAL;
#endif
- error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, sz);
+ error = COPYOUT(ptr, obj.ipfo_ptr, sz);
if (error != 0)
error = EFAULT;
return error;
@@ -5618,10 +5654,12 @@ int type;
ipfobj_t obj;
int error;
- if ((type < 0) || (type > IPFOBJ_COUNT))
+ if ((type < 0) || (type >= IPFOBJ_COUNT))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5645,7 +5683,7 @@ int type;
return EINVAL;
#endif
- error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, obj.ipfo_size);
+ error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size);
if (error != 0)
error = EFAULT;
return error;
@@ -5671,6 +5709,12 @@ fr_info_t *fin;
if ((fin->fin_flx & FI_NOCKSUM) != 0)
return 0;
+ if (fin->fin_cksum == 1)
+ return 0;
+
+ if (fin->fin_cksum == -1)
+ return -1;
+
/*
* If the TCP packet isn't a fragment, isn't too short and otherwise
* isn't already considered "bad", then validate the checksum. If
@@ -5733,8 +5777,11 @@ fr_info_t *fin;
FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum));
}
#endif
- if (hdrsum == sum)
+ if (hdrsum == sum) {
+ fin->fin_cksum = 1;
return 0;
+ }
+ fin->fin_cksum = -1;
return -1;
}
@@ -5987,7 +6034,7 @@ ipftuneable_t ipf_tuneables[] = {
{ { &ipf_hostmap_sz }, "ipf_hostmap_sz", 1, 0x7fffffff,
sizeof(ipf_hostmap_sz), IPFT_WRDISABLED, NULL },
{ { &fr_nat_maxbucket }, "fr_nat_maxbucket", 1, 0x7fffffff,
- sizeof(fr_nat_maxbucket), IPFT_WRDISABLED, NULL },
+ sizeof(fr_nat_maxbucket), 0, NULL },
{ { &fr_nat_maxbucket_reset }, "fr_nat_maxbucket_reset", 0, 1,
sizeof(fr_nat_maxbucket_reset), IPFT_WRDISABLED, NULL },
{ { &nat_logging }, "nat_logging", 0, 1,
@@ -6430,7 +6477,7 @@ void fr_deinitialise()
/* the copyout may result in paging (ie network activity.) */
/* ------------------------------------------------------------------------ */
int fr_zerostats(data)
-caddr_t data;
+void *data;
{
friostat_t fio;
int error;
@@ -6536,15 +6583,12 @@ ipftoken_t *ipftokenhead = NULL, **ipftokentail = &ipftokenhead;
void ipf_expiretokens()
{
ipftoken_t *it;
- void *data;
WRITE_ENTER(&ipf_tokens);
while ((it = ipftokenhead) != NULL) {
if (it->ipt_die > fr_ticks)
break;
- data = it->ipt_data;
-
ipf_freetoken(it);
}
RWLOCK_EXIT(&ipf_tokens);
@@ -6721,7 +6765,9 @@ ipftoken_t *token;
#endif
break;
case IPFGENITER_HOSTMAP :
+ WRITE_ENTER(&ipf_nat);
fr_hostmapdel((hostmap_t **)datap);
+ RWLOCK_EXIT(&ipf_nat);
break;
default :
#ifdef IPFILTER_LOOKUP
@@ -6800,30 +6846,27 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr)
}
dst = (char *)it.iri_rule;
+ count = it.iri_nrules;
/*
* The ipfruleiter may ask for more than 1 rule at a time to be
* copied out, so long as that many exist in the list to start with!
*/
- for (count = it.iri_nrules; count > 0; count--) {
+ for (;;) {
if (next != NULL) {
- MUTEX_ENTER(&next->fr_lock);
- next->fr_ref++;
- MUTEX_EXIT(&next->fr_lock);
- t->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->fr_lock);
+ next->fr_ref++;
+ MUTEX_EXIT(&next->fr_lock);
+ t->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- ipf_freetoken(t);
- fr = NULL;
- t = NULL;
count = 1;
+ t->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_mutex);
- if (fr != NULL) {
- (void) fr_derefrule(&fr);
- }
-
error = COPYOUT(next, dst, sizeof(*next));
if (error != 0)
return EFAULT;
@@ -6837,12 +6880,17 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr)
dst += next->fr_dsize;
}
- if ((count == 1) || (next->fr_next == NULL) || (error != 0))
+ if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_mutex);
- fr = next;
- next = fr->fr_next;
+ next = next->fr_next;
+ }
+
+ if (fr != NULL) {
+ (void) fr_derefrule(&fr);
}
return error;
@@ -6970,8 +7018,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error != 0) {
error = EFAULT;
break;
@@ -7011,16 +7058,14 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&fr_flags,
- sizeof(fr_flags));
+ error = BCOPYIN(data, &fr_flags, sizeof(fr_flags));
if (error != 0)
error = EFAULT;
}
break;
case SIOCGETFF :
- error = BCOPYOUT((caddr_t)&fr_flags, (caddr_t)data,
- sizeof(fr_flags));
+ error = BCOPYOUT(&fr_flags, data, sizeof(fr_flags));
if (error != 0)
error = EFAULT;
break;
@@ -7036,8 +7081,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data,
- fr_active, 1);
+ error = frrequest(IPL_LOGIPF, cmd, data, fr_active, 1);
break;
case SIOCINIFR :
@@ -7046,7 +7090,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data,
+ error = frrequest(IPL_LOGIPF, cmd, data,
1 - fr_active, 1);
break;
@@ -7056,8 +7100,7 @@ void *ctx;
else {
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
- error = BCOPYOUT((caddr_t)&fr_active, (caddr_t)data,
- sizeof(fr_active));
+ error = BCOPYOUT(&fr_active, data, sizeof(fr_active));
if (error != 0)
error = EFAULT;
else
@@ -7075,19 +7118,17 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = fr_zerostats((caddr_t)data);
+ error = fr_zerostats(data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (!error) {
tmp = frflush(IPL_LOGIPF, 4, tmp);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error != 0)
error = EFAULT;
} else
@@ -7100,12 +7141,10 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (!error) {
tmp = frflush(IPL_LOGIPF, 6, tmp);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error != 0)
error = EFAULT;
} else
@@ -7115,7 +7154,7 @@ void *ctx;
#endif
case SIOCSTLCK :
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error == 0) {
fr_state_lock = tmp;
fr_nat_lock = tmp;
@@ -7131,8 +7170,7 @@ void *ctx;
error = EPERM;
else {
tmp = ipflog_clear(IPL_LOGIPF);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error)
error = EFAULT;
}
@@ -7164,7 +7202,7 @@ void *ctx;
case FIONREAD :
tmp = (int)iplused[IPL_LOGIPF];
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
break;
#endif
@@ -7179,16 +7217,14 @@ void *ctx;
error = ipf_genericiter(data, uid, ctx);
SPL_X(s);
break;
- break;
case SIOCIPFDELTOK :
SPL_SCHED(s);
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error == 0)
error = ipf_deltoken(tmp, uid, ctx);
SPL_X(s);
break;
- break;
default :
error = EINVAL;
@@ -7264,15 +7300,16 @@ ipftq_t *ipfqs, *userqs;
return 0;
}
if (istart > fr_ticks) {
- istart = (fr_ticks / interval) * interval;
+ if (fr_ticks - interval < interval)
+ istart = interval;
+ else
+ istart = (fr_ticks / interval) * interval;
}
iend = fr_ticks - interval;
- if (istart > iend)
- istart = iend - interval;
removed = 0;
- while (removed == 0) {
+ for (;;) {
u_long try;
try = fr_ticks - istart;
@@ -7299,8 +7336,9 @@ ipftq_t *ipfqs, *userqs;
}
}
- istart -= interval;
if (try >= iend) {
+ if (removed > 0)
+ break;
if (interval == IPF_TTLVAL(43200)) {
interval = IPF_TTLVAL(1800);
} else if (interval == IPF_TTLVAL(1800)) {
@@ -7313,6 +7351,7 @@ ipftq_t *ipfqs, *userqs;
iend = fr_ticks - interval;
}
+ istart -= interval;
}
return removed;
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index e6d3d50..6884110 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -121,7 +121,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#if !defined(lint)
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.13 2006/03/29 11:19:55 darrenr Exp $"; */
+/* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.24 2007/09/09 11:32:04 darrenr Exp $"; */
#endif
@@ -328,16 +328,10 @@ fr_info_t *fin;
return 0;
WRITE_ENTER(&ipf_auth);
- if (fr_authstart > fr_authend) {
+ if (((fr_authend + 1) % fr_authsize) == fr_authstart) {
fr_authstats.fas_nospace++;
RWLOCK_EXIT(&ipf_auth);
return 0;
- } else {
- if (fr_authused == fr_authsize) {
- fr_authstats.fas_nospace++;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
- }
}
fr_authstats.fas_added++;
@@ -374,10 +368,12 @@ fr_info_t *fin;
}
#endif
#if SOLARIS && defined(_KERNEL)
- COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname);
+ COPYIFNAME(fin->fin_v, fin->fin_ifp, fra->fra_info.fin_ifname);
m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
+# if !defined(_INET_IP_STACK_H)
fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
+# endif
fra->fra_m = *fin->fin_mp;
fra->fra_info.fin_mp = &fra->fra_m;
cv_signal(&ipfauthwait);
@@ -448,7 +444,7 @@ void *ctx;
error = EPERM;
break;
}
- fr_lock(data, &fr_auth_lock);
+ error = fr_lock(data, &fr_auth_lock);
break;
case SIOCATHST:
@@ -716,15 +712,15 @@ int fr_authflush()
/* ------------------------------------------------------------------------ */
/* Function: fr_auth_waiting */
-/* Returns: int - number of packets in the auth queue */
+/* Returns: int - 0 = no pakcets wiating, 1 = packets waiting. */
/* Parameters: None */
/* */
-/* Returns the numbers of packets queued up, waiting to be processed with */
-/* a pair of SIOCAUTHW and SIOCAUTHR calls. */
+/* Simple truth check to see if there are any packets waiting in the auth */
+/* queue. */
/* ------------------------------------------------------------------------ */
int fr_auth_waiting()
{
- return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext];
+ return (fr_authused != 0);
}
@@ -861,7 +857,13 @@ fr_authioctlloop:
* is a packet waiting to be delt with in the fr_authpkts array. We
* copy as much of that out to user space as requested.
*/
- if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
+ if (fr_authused > 0) {
+ while (fr_authpkts[fr_authnext] == NULL) {
+ fr_authnext++;
+ if (fr_authnext == fr_authsize)
+ fr_authnext = 0;
+ }
+
error = fr_outobj(data, &fr_auth[fr_authnext], IPFOBJ_FRAUTH);
if (error != 0)
return error;
@@ -888,8 +890,6 @@ fr_authioctlloop:
}
}
RWLOCK_EXIT(&ipf_auth);
- if (error != 0)
- return error;
SPL_NET(s);
WRITE_ENTER(&ipf_auth);
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 93ac208..b653007 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -5,7 +5,7 @@
*
* @(#)ip_compat.h 1.8 1/14/96
* $FreeBSD$
- * Id: ip_compat.h,v 2.142.2.36 2006/03/26 05:50:29 darrenr Exp $
+ * Id: ip_compat.h,v 2.142.2.57 2007/10/10 09:51:42 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -169,6 +169,11 @@ struct file;
# ifdef i386
# define _SYS_PROMIF_H
# endif
+# ifndef _KERNEL
+# include "radix_ipf.h"
+# else
+# include "radix_ipf_local.h"
+# endif
# include <inet/ip.h>
# undef COPYOUT
# include <inet/ip_ire.h>
@@ -201,9 +206,29 @@ typedef unsigned int u_32_t;
# ifdef _KERNEL
# define KRWLOCK_T krwlock_t
# define KMUTEX_T kmutex_t
-# include "qif.h"
-# include "pfil.h"
-# if defined(SOLARIS2) && SOLARIS2 >= 6
+
+# if !defined(FW_HOOKS)
+# include "qif.h"
+# include "pfil.h"
+# else
+# include <sys/neti.h>
+
+extern net_data_t ipfipv4;
+extern net_data_t ipfipv6;
+
+typedef struct qpktinfo {
+ void *qpi_data;
+ mblk_t **qpi_mp;
+ mblk_t *qpi_m;
+ uintptr_t qpi_real;
+ int qpi_flags;
+ int qpi_num;
+ int qpi_off;
+} qpktinfo_t;
+# define QF_GROUP 0x01
+# endif
+
+# if SOLARIS2 >= 6
# if SOLARIS2 == 6
# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1)
# define ATOMIC_DECL(x) atomic_add_long((uint32_t*)&(x), -1)
@@ -260,10 +285,24 @@ typedef unsigned int u_32_t;
# define GET_MINOR(x) getminor(x)
extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x) ((qif_t *)x)->qf_name
-# define COPYIFNAME(x, b) \
+# if defined(_INET_IP_STACK_H)
+# define COPYIFNAME(v, x, b) \
+ do { \
+ if ((v) == 4) { \
+ (void) net_getifname(ipfipv4,\
+ (uintptr_t)x, b, \
+ LIFNAMSIZ); \
+ } else { \
+ (void) net_getifname(ipfipv6,\
+ (uintptr_t)x, b, \
+ LIFNAMSIZ); \
+ } \
+ } while (0)
+# else
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, ((qif_t *)x)->qf_name, \
LIFNAMSIZ)
+# endif
# define GETKTIME(x) uniqtime((struct timeval *)x)
# define MSGDSIZE(x) msgdsize(x)
# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr)
@@ -272,7 +311,11 @@ extern void *get_unit __P((char *, int));
# define MTYPE(m) ((m)->b_datap->db_type)
# define FREE_MB_T(m) freemsg(m)
# define m_next b_cont
-# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
+# if !defined(_INET_IP_STACK_H)
+# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
+# else
+# define CACHE_HASH(x) ((uintptr_t)(x)->fin_ifp & 7)
+# endif
# define IPF_PANIC(x,y) if (x) { printf y; cmn_err(CE_PANIC, "ipf_panic"); }
typedef mblk_t mb_t;
# endif /* _KERNEL */
@@ -424,8 +467,7 @@ typedef struct iplog_select_s {
# define SPL_X(x) ;
extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x, b) ((ill_t *)x)->ill_name
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, ((qif_t *)x)->qf_name, \
LIFNAMSIZ)
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
@@ -593,6 +635,7 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x) microtime((struct timeval *)x)
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -669,6 +712,7 @@ typedef struct mbuf mb_t;
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x) microtime((struct timeval *)x)
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -752,12 +796,13 @@ typedef struct mbuf mb_t;
# endif /* _KERNEL */
# if (NetBSD <= 1991011) && (NetBSD >= 199606)
# define IFNAME(x) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -810,24 +855,66 @@ typedef u_int32_t u_32_t;
# if (__FreeBSD_version >= 500043)
# include <sys/mutex.h>
-# include <sys/sx.h>
+# if (__FreeBSD_version > 700014)
+# include <sys/rwlock.h>
+# define KRWLOCK_T struct rwlock
+# ifdef _KERNEL
+# define READ_ENTER(x) rw_rlock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) rw_wlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk)
+# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y))
+# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk)
+# define RWLOCK_EXIT(x) do { \
+ if (rw_wowned(&(x)->ipf_lk)) \
+ rw_wunlock(&(x)->ipf_lk); \
+ else \
+ rw_runlock(&(x)->ipf_lk); \
+ } while (0)
+# endif
+# else
+# include <sys/sx.h>
/*
* Whilst the sx(9) locks on FreeBSD have the right semantics and interface
* for what we want to use them for, despite testing showing they work -
* with a WITNESS kernel, it generates LOR messages.
*/
-# define KMUTEX_T struct mtx
-# if (__FreeBSD_version < 700000)
-# define KRWLOCK_T struct mtx
-# else
-# define KRWLOCK_T struct sx
+# ifdef _KERNEL
+# if (__FreeBSD_version < 700000)
+# define KRWLOCK_T struct mtx
+# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk)
+# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\
+ MTX_DEF)
+# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
+# else
+# define KRWLOCK_T struct sx
+# define READ_ENTER(x) sx_slock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk)
+# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y))
+# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk)
+# ifdef sx_unlock
+# define RWLOCK_EXIT(x) sx_unlock(&(x)->ipf_lk)
+# else
+# define RWLOCK_EXIT(x) do { \
+ if ((x)->ipf_lk.sx_cnt < 0) \
+ sx_xunlock(&(x)->ipf_lk); \
+ else \
+ sx_sunlock(&(x)->ipf_lk); \
+ } while (0)
+# endif
+# endif
+# endif
# endif
+# define KMUTEX_T struct mtx
# endif
# if (__FreeBSD_version >= 501113)
# include <net/if_var.h>
# define IFNAME(x) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
@@ -835,6 +922,7 @@ typedef u_int32_t u_32_t;
# if (__FreeBSD_version >= 500043)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7)
# else
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -856,36 +944,6 @@ typedef u_int32_t u_32_t;
MTX_DEF)
# define MUTEX_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
-/*
- * Whilst the sx(9) locks on FreeBSD have the right semantics and interface
- * for what we want to use them for, despite testing showing they work -
- * with a WITNESS kernel, it generates LOR messages.
- */
-# if (__FreeBSD_version < 700000)
-# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk)
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\
- MTX_DEF)
-# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
-# else
-# define READ_ENTER(x) sx_slock(&(x)->ipf_lk)
-# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk)
-# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk)
-# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y))
-# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk)
-# ifdef sx_unlock
-# define RWLOCK_EXIT(x) sx_unlock(&(x)->ipf_lk)
-# else
-# define RWLOCK_EXIT(x) do { \
- if ((x)->ipf_lk.sx_cnt < 0) \
- sx_xunlock(&(x)->ipf_lk); \
- else \
- sx_sunlock(&(x)->ipf_lk); \
- } while (0)
-# endif
-# endif
# include <machine/atomic.h>
# define ATOMIC_INC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)++; \
mtx_unlock(&ipf_rw.ipf_lk); }
@@ -904,6 +962,8 @@ typedef u_int32_t u_32_t;
# define SPL_IMP(x) ;
# define SPL_SCHED(x) ;
extern int in_cksum __P((struct mbuf *, int));
+# else
+# define SPL_SCHED(x) x = splhigh()
# endif /* __FreeBSD_version >= 500043 */
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
@@ -969,12 +1029,13 @@ typedef struct mbuf mb_t;
# endif /* _KERNEL */
# if (OpenBSD >= 199603)
# define IFNAME(x, b) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -1002,6 +1063,7 @@ typedef u_int32_t u_32_t;
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
typedef struct mbuf mb_t;
@@ -1028,6 +1090,7 @@ typedef u_int32_t u_32_t;
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define GETIFP(n, v) ifunit(n, IFNAMSIZ)
@@ -1085,7 +1148,7 @@ struct ip6_ext {
# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
# endif
# define WAKEUP(x,y) wake_up(x##_linux + y)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define USE_MUTEXES
# define KRWLOCK_T rwlock_t
# define KMUTEX_T spinlock_t
@@ -1179,7 +1242,7 @@ struct ifnet {
# endif /* _KERNEL */
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
@@ -1289,6 +1352,7 @@ extern void* getifp __P((char *, int));
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y)
@@ -1460,7 +1524,7 @@ typedef struct mb_s {
# define COPYBACK(m, o, l, b) bcopy((b), \
MTOD((mb_t *)m, char *) + (o), \
(l))
-# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
+# define UIOMOVE(a,b,c,d) ipfuiomove((caddr_t)a,b,c,d)
extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
extern int bcopywrap __P((void *, void *, size_t));
@@ -1590,7 +1654,7 @@ MALLOC_DECLARE(M_IPFILTER);
# endif
# define KFREE(x) FREE((x), _M_IPF)
# define KFREES(x,s) FREE((x), _M_IPF)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) selwakeup(ipfselwait+x)
@@ -1605,7 +1669,9 @@ MALLOC_DECLARE(M_IPFILTER);
# define SPL_IMP(x) x = splimp()
# define SPL_NET(x) x = splnet()
# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
-# define SPL_SCHED(x) x = splsched()
+# if !defined(SPL_SCHED)
+# define SPL_SCHED(x) x = splsched()
+# endif
# define SPL_X(x) (void) splx(x)
# endif /* !USE_MUTEXES */
@@ -1634,18 +1700,22 @@ MALLOC_DECLARE(M_IPFILTER);
# define PANIC(x,y) if (x) panic y
#endif /* _KERNEL */
-#ifndef IFNAME
+#if !defined(IFNAME) && !defined(_KERNEL)
# define IFNAME(x) ((struct ifnet *)x)->if_name
#endif
#ifndef COPYIFNAME
# define NEED_FRGETIFNAME
extern char *fr_getifname __P((struct ifnet *, char *));
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
fr_getifname((struct ifnet *)x, b)
#endif
#ifndef ASSERT
-# define ASSERT(x)
+# ifdef _KERNEL
+# define ASSERT(x)
+# else
+# define ASSERT(x) do { if (!(x)) abort(); } while (0)
+# endif
#endif
#ifndef BCOPYIN
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index dc5a473..353328c 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -5,7 +5,7 @@
*
* @(#)ip_fil.h 1.35 6/5/96
* $FreeBSD$
- * Id: ip_fil.h,v 2.170.2.29 2006/03/29 11:19:55 darrenr Exp $
+ * Id: ip_fil.h,v 2.170.2.51 2007/10/10 09:48:03 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -157,14 +157,14 @@ typedef union i6addr {
#define iplookupptr vptr[0]
#define iplookupfunc lptr[1]
-#define I60(x) (((i6addr_t *)(x))->i6[0])
-#define I61(x) (((i6addr_t *)(x))->i6[1])
-#define I62(x) (((i6addr_t *)(x))->i6[2])
-#define I63(x) (((i6addr_t *)(x))->i6[3])
-#define HI60(x) ntohl(((i6addr_t *)(x))->i6[0])
-#define HI61(x) ntohl(((i6addr_t *)(x))->i6[1])
-#define HI62(x) ntohl(((i6addr_t *)(x))->i6[2])
-#define HI63(x) ntohl(((i6addr_t *)(x))->i6[3])
+#define I60(x) (((u_32_t *)(x))[0])
+#define I61(x) (((u_32_t *)(x))[1])
+#define I62(x) (((u_32_t *)(x))[2])
+#define I63(x) (((u_32_t *)(x))[3])
+#define HI60(x) ntohl(((u_32_t *)(x))[0])
+#define HI61(x) ntohl(((u_32_t *)(x))[1])
+#define HI62(x) ntohl(((u_32_t *)(x))[2])
+#define HI63(x) ntohl(((u_32_t *)(x))[3])
#define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \
(I61(a) == I61(b)) && (I60(a) == I60(b)))
@@ -182,14 +182,14 @@ typedef union i6addr {
HI63(a) < HI63(b)))))))
#define NLADD(n,x) htonl(ntohl(n) + (x))
#define IP6_INC(a) \
- { i6addr_t *_i6 = (i6addr_t *)(a); \
- _i6->i6[0] = NLADD(_i6->i6[0], 1); \
- if (_i6->i6[0] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[1], 1); \
- if (_i6->i6[1] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[2], 1); \
- if (_i6->i6[2] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[3], 1); \
+ { u_32_t *_i6 = (u_32_t *)(a); \
+ _i6[3] = NLADD(_i6[3], 1); \
+ if (_i6[3] == 0) { \
+ _i6[2] = NLADD(_i6[2], 1); \
+ if (_i6[2] == 0) { \
+ _i6[1] = NLADD(_i6[1], 1); \
+ if (_i6[1] == 0) { \
+ _i6[0] = NLADD(_i6[0], 1); \
} \
} \
} \
@@ -263,11 +263,12 @@ typedef struct fr_ip {
#define FI_FRAGBODY 0x2000
#define FI_BADSRC 0x4000
#define FI_LOWTTL 0x8000
-#define FI_CMP 0xcfe3 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL */
+#define FI_CMP 0xcf03 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL,broadcast */
#define FI_ICMPCMP 0x0003 /* Flags we can check for ICMP error packets */
#define FI_WITH 0xeffe /* Not FI_TCPUDP */
#define FI_V6EXTHDR 0x10000
#define FI_COALESCE 0x20000
+#define FI_NEWNAT 0x40000
#define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */
#define FI_DONTCACHE 0x40000000 /* don't cache the result */
#define FI_IGNORE 0x80000000
@@ -327,6 +328,7 @@ typedef struct fr_info {
u_short fin_off;
int fin_depth; /* Group nesting depth */
int fin_error; /* Error code to return */
+ int fin_cksum; /* -1 bad, 1 good, 0 not done */
void *fin_nat;
void *fin_state;
void *fin_nattag;
@@ -1204,6 +1206,8 @@ typedef struct ipftable {
} ipftable_t;
#define IPFTABLE_BUCKETS 1
+#define IPFTABLE_BUCKETS_NATIN 2
+#define IPFTABLE_BUCKETS_NATOUT 3
/*
@@ -1405,6 +1409,13 @@ extern int iplwrite __P((dev_t, struct uio *));
# endif /* __ sgi */
# endif /* MENTAT */
+# if defined(__FreeBSD_version)
+extern int ipf_pfil_hook __P((void));
+extern int ipf_pfil_unhook __P((void));
+extern void ipf_event_reg __P((void));
+extern void ipf_event_dereg __P((void));
+# endif
+
#endif /* #ifndef _KERNEL */
extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
@@ -1491,7 +1502,7 @@ 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));
-extern void fr_lock __P((caddr_t, int *));
+extern int fr_lock __P((caddr_t, int *));
extern int fr_makefrip __P((int, ip_t *, fr_info_t *));
extern int fr_matchtag __P((ipftag_t *, ipftag_t *));
extern int fr_matchicmpqueryreply __P((int, icmpinfo_t *,
@@ -1504,7 +1515,7 @@ extern int fr_scanlist __P((fr_info_t *, u_32_t));
extern frentry_t *fr_srcgrpmap __P((fr_info_t *, u_32_t *));
extern int fr_tcpudpchk __P((fr_info_t *, frtuc_t *));
extern int fr_verifysrc __P((fr_info_t *fin));
-extern int fr_zerostats __P((char *));
+extern int fr_zerostats __P((void *));
extern ipftoken_t *ipf_findtoken __P((int, int, void *));
extern int ipf_getnextrule __P((ipftoken_t *, void *));
extern void ipf_expiretokens __P((void));
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index aeefb03..84281ab 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.46 2007/05/11 13:41:53 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12:51:50 darrenr Exp $";
#endif
#if defined(KERNEL) || defined(_KERNEL)
@@ -205,15 +205,6 @@ int ipfattach()
#ifdef USE_SPL
int s;
#endif
-#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
- int error = 0;
-# if __FreeBSD_version >= 501108
- struct pfil_head *ph_inet;
-# ifdef USE_INET6
- struct pfil_head *ph_inet6;
-# endif
-# endif
-#endif
SPL_NET(s);
if (fr_running > 0) {
@@ -233,77 +224,6 @@ int ipfattach()
}
-# ifdef NETBSD_PF
-# if __FreeBSD_version >= 500011
-# if __FreeBSD_version >= 501108
- ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
-# ifdef USE_INET6
- ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
-# endif
- if (ph_inet == NULL
-# ifdef USE_INET6
- && ph_inet6 == NULL
-# endif
- )
- return ENODEV;
-
- if (ph_inet != NULL)
- error = pfil_add_hook((void *)fr_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT, ph_inet);
- else
- error = 0;
-# else
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
- if (error) {
-# ifdef USE_INET6
- goto pfil_error;
-# else
- fr_deinitialise();
- SPL_X(s);
- return error;
-# endif
- }
-# else
- pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
-# if __FreeBSD_version >= 501108
- if (ph_inet6 != NULL)
- error = pfil_add_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
- else
- error = 0;
- if (error) {
- pfil_remove_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
-# else
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
- if (error) {
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
-pfil_error:
- fr_deinitialise();
- SPL_X(s);
- return error;
- }
-# endif
-# endif
-
-#if (__FreeBSD_version >= 502103)
- ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
- ipf_ifevent, NULL, \
- EVENTHANDLER_PRI_ANY);
- ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
- ipf_ifevent, NULL, \
- EVENTHANDLER_PRI_ANY);
- ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
- NULL, EVENTHANDLER_PRI_ANY);
-#endif
-
if (fr_checkp != fr_check) {
fr_savep = fr_checkp;
fr_checkp = fr_check;
@@ -336,31 +256,9 @@ int ipfdetach()
#ifdef USE_SPL
int s;
#endif
-#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
- int error = 0;
-# if __FreeBSD_version >= 501108
- struct pfil_head *ph_inet;
-# ifdef USE_INET6
- struct pfil_head *ph_inet6;
-# endif
-# endif
-#endif
-
if (fr_control_forwarding & 2)
ipforwarding = 0;
-#if (__FreeBSD_version >= 502103)
- if (ipf_arrivetag != NULL) {
- EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag);
- }
- if (ipf_departtag != NULL) {
- EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipf_departtag);
- }
- if (ipf_clonetag != NULL) {
- EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag);
- }
-#endif
-
SPL_NET(s);
#if (__FreeBSD_version >= 300000)
@@ -377,44 +275,6 @@ int ipfdetach()
fr_savep = NULL;
#endif
-#ifdef NETBSD_PF
-# if (__FreeBSD_version >= 500011)
-# if (__FreeBSD_version >= 501108)
- ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
- if (ph_inet != NULL)
- error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT, ph_inet);
- else
- error = 0;
-# else
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
- if (error) {
- SPL_X(s);
- return error;
- }
-# else
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
-# if (__FreeBSD_version >= 501108)
- ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
- if (ph_inet6 != NULL)
- error = pfil_remove_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
- else
- error = 0;
-# else
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
-# endif
- if (error) {
- SPL_X(s);
- return error;
- }
-# endif
-#endif
fr_deinitialise();
fr_running = -2;
@@ -692,10 +552,8 @@ fr_info_t *fin;
if (tcp->th_flags & TH_RST)
return -1; /* feedback loop */
-#ifndef IPFILTER_CKSUM
if (fr_checkl4sum(fin) == -1)
return -1;
-#endif
tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
@@ -854,7 +712,7 @@ int dst;
#endif
ip_t *ip, *ip2;
- if ((type < 0) || (type > ICMP_MAXTYPE))
+ if ((type < 0) || (type >= ICMP_MAXTYPE))
return -1;
code = fin->fin_icode;
@@ -863,10 +721,8 @@ int dst;
return -1;
#endif
-#ifndef IPFILTER_CKSUM
if (fr_checkl4sum(fin) == -1)
return -1;
-#endif
#ifdef MGETHDR
MGETHDR(m, M_DONTWAIT, MT_HEADER);
#else
@@ -1470,6 +1326,9 @@ fr_info_t *fin;
if ((fin->fin_flx & FI_NOCKSUM) != 0)
return;
+ if (fin->fin_cksum != 0)
+ return;
+
m = fin->fin_m;
if (m == NULL) {
manual = 1;
@@ -1485,8 +1344,12 @@ fr_info_t *fin;
htonl(m->m_pkthdr.csum_data +
fin->fin_ip->ip_len + fin->fin_p));
sum ^= 0xffff;
- if (sum != 0)
+ if (sum != 0) {
fin->fin_flx |= FI_BAD;
+ fin->fin_cksum = -1;
+ } else {
+ fin->fin_cksum = 1;
+ }
} else
manual = 1;
skipauto:
@@ -1598,11 +1461,16 @@ int len;
m = m_pullup(m, len);
}
*fin->fin_mp = m;
- fin->fin_m = m;
if (m == NULL) {
+ fin->fin_m = NULL;
ATOMIC_INCL(frstats[out].fr_pull[1]);
return NULL;
}
+
+ while (M_LEN(m) == 0) {
+ m = m->m_next;
+ }
+ fin->fin_m = m;
ip = MTOD(m, char *) + ipoff;
}
@@ -1658,3 +1526,122 @@ mb_t *m;
return error;
}
+
+int ipf_pfil_unhook(void) {
+#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
+# if __FreeBSD_version >= 501108
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+# endif
+#endif
+
+#ifdef NETBSD_PF
+# if (__FreeBSD_version >= 500011)
+# if (__FreeBSD_version >= 501108)
+ ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+ if (ph_inet != NULL)
+ pfil_remove_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK);
+# endif
+# ifdef USE_INET6
+# if (__FreeBSD_version >= 501108)
+ ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+ if (ph_inet6 != NULL)
+ pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
+# endif
+#endif
+
+ return (0);
+}
+
+int ipf_pfil_hook(void) {
+#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
+# if __FreeBSD_version >= 501108
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+# endif
+#endif
+
+# ifdef NETBSD_PF
+# if __FreeBSD_version >= 500011
+# if __FreeBSD_version >= 501108
+ ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+# ifdef USE_INET6
+ ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+# endif
+ if (ph_inet == NULL
+# ifdef USE_INET6
+ && ph_inet6 == NULL
+# endif
+ )
+ return ENODEV;
+
+ if (ph_inet != NULL)
+ pfil_add_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK);
+# endif
+# ifdef USE_INET6
+# if __FreeBSD_version >= 501108
+ if (ph_inet6 != NULL)
+ pfil_add_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
+# endif
+# endif
+ return (0);
+}
+
+void
+ipf_event_reg(void)
+{
+#if (__FreeBSD_version >= 502103)
+ ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
+ NULL, EVENTHANDLER_PRI_ANY);
+#endif
+}
+
+void
+ipf_event_dereg(void)
+{
+#if (__FreeBSD_version >= 502103)
+ if (ipf_arrivetag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag);
+ }
+ if (ipf_departtag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipf_departtag);
+ }
+ if (ipf_clonetag != NULL) {
+ EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag);
+ }
+#endif
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index 02e7bd1..fb21bd1 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -103,7 +103,7 @@ extern struct timeout fr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.5 2006/02/26 08:26:54 darrenr Exp $";*/
+/* static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.12 2007/09/20 12:51:51 darrenr Exp $"; */
#endif
@@ -939,16 +939,16 @@ ipfrwlock_t *lock;
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(lock);
if (frag != NULL) {
- WRITE_ENTER(lock);
- frag->ipfr_ref--;
- if (frag->ipfr_ref <= 0)
- fr_fragfree(frag);
- RWLOCK_EXIT(lock);
+#ifdef USE_MUTEXES
+ fr_fragderef(&frag, lock);
+#else
+ fr_fragderef(&frag);
+#endif
}
error = COPYOUT(next, itp->igi_data, sizeof(*next));
diff --git a/sys/contrib/ipfilter/netinet/ip_htable.c b/sys/contrib/ipfilter/netinet/ip_htable.c
index 3882156..fc521d8 100644
--- a/sys/contrib/ipfilter/netinet/ip_htable.c
+++ b/sys/contrib/ipfilter/netinet/ip_htable.c
@@ -53,7 +53,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.9 2007/02/02 23:06:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.11 2007/09/20 12:51:51 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -104,31 +104,29 @@ iplookupop_t *op;
int err, i, unit;
unit = op->iplo_unit;
- if ((op->iplo_arg & IPHASH_ANON) == 0)
+ if ((op->iplo_arg & IPHASH_ANON) == 0) {
iph = fr_existshtable(unit, op->iplo_name);
- else
- iph = NULL;
+ if (iph != NULL) {
+ if ((iph->iph_flags & IPHASH_DELETE) == 0)
+ return EEXIST;
+ iph->iph_flags &= ~IPHASH_DELETE;
+ return 0;
+ }
+ }
+ KMALLOC(iph, iphtable_t *);
if (iph == NULL) {
- KMALLOC(iph, iphtable_t *);
- if (iph == NULL) {
- ipht_nomem[op->iplo_unit]++;
- return ENOMEM;
- }
- err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
- if (err != 0) {
- KFREE(iph);
- return EFAULT;
- }
- } else {
- if ((iph->iph_flags & IPHASH_DELETE) == 0)
- return EEXIST;
+ ipht_nomem[op->iplo_unit]++;
+ return ENOMEM;
+ }
+ err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
+ if (err != 0) {
+ KFREE(iph);
+ return EFAULT;
}
if (iph->iph_unit != unit) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
+ KFREE(iph);
return EINVAL;
}
@@ -153,33 +151,25 @@ iplookupop_t *op;
iph->iph_type |= IPHASH_ANON;
}
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KMALLOCS(iph->iph_table, iphtent_t **,
- iph->iph_size * sizeof(*iph->iph_table));
- if (iph->iph_table == NULL) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
- ipht_nomem[unit]++;
- return ENOMEM;
- }
-
- bzero((char *)iph->iph_table,
- iph->iph_size * sizeof(*iph->iph_table));
- iph->iph_masks = 0;
- iph->iph_list = NULL;
-
- iph->iph_ref = 1;
- iph->iph_next = ipf_htables[unit];
- iph->iph_pnext = &ipf_htables[unit];
- if (ipf_htables[unit] != NULL)
- ipf_htables[unit]->iph_pnext = &iph->iph_next;
- ipf_htables[unit] = iph;
-
- ipf_nhtables[unit]++;
+ KMALLOCS(iph->iph_table, iphtent_t **,
+ iph->iph_size * sizeof(*iph->iph_table));
+ if (iph->iph_table == NULL) {
+ KFREE(iph);
+ ipht_nomem[unit]++;
+ return ENOMEM;
}
- iph->iph_flags &= ~IPHASH_DELETE;
+ bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
+ iph->iph_masks = 0;
+ iph->iph_list = NULL;
+
+ iph->iph_ref = 1;
+ iph->iph_next = ipf_htables[unit];
+ iph->iph_pnext = &ipf_htables[unit];
+ if (ipf_htables[unit] != NULL)
+ ipf_htables[unit]->iph_pnext = &iph->iph_next;
+ ipf_htables[unit] = iph;
+ ipf_nhtables[unit]++;
return 0;
}
@@ -551,11 +541,11 @@ ipflookupiter_t *ilp;
if (nextiph != NULL) {
ATOMIC_INC(nextiph->iph_ref);
- if (nextiph->iph_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextiph;
} else {
bzero((char *)&zp, sizeof(zp));
nextiph = &zp;
+ token->ipt_data = NULL;
}
break;
@@ -574,11 +564,11 @@ ipflookupiter_t *ilp;
if (nextnode != NULL) {
ATOMIC_INC(nextnode->ipe_ref);
- if (nextnode->ipe_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextnode;
} else {
bzero((char *)&zn, sizeof(zn));
nextnode = &zn;
+ token->ipt_data = NULL;
}
break;
default :
@@ -598,7 +588,6 @@ ipflookupiter_t *ilp;
fr_derefhtable(iph);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextiph;
err = COPYOUT(nextiph, ilp->ili_data, sizeof(*nextiph));
if (err != 0)
err = EFAULT;
@@ -610,7 +599,6 @@ ipflookupiter_t *ilp;
fr_derefhtent(node);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextnode;
err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode));
if (err != 0)
err = EFAULT;
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 83454f0..583eb63 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* $FreeBSD$
- * Id: ip_log.c,v 2.75.2.11 2006/03/26 13:50:47 darrenr Exp $
+ * Id: ip_log.c,v 2.75.2.19 2007/09/09 11:32:06 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL)
@@ -261,7 +261,8 @@ u_int flags;
ipflog_t ipfl;
u_char p;
mb_t *m;
-# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \
+ !defined(_INET_IP_STACK_H)
qif_t *ifp;
# else
struct ifnet *ifp;
@@ -273,7 +274,10 @@ u_int flags;
ipfl.fl_nattag.ipt_num[0] = 0;
ifp = fin->fin_ifp;
- hlen = fin->fin_hlen;
+ if (fin->fin_exthdr != NULL)
+ hlen = (char *)fin->fin_dp - (char *)fin->fin_ip;
+ else
+ hlen = fin->fin_hlen;
/*
* calculate header size.
*/
@@ -334,14 +338,16 @@ u_int flags;
* Get the interface number and name to which this packet is
* currently associated.
*/
-# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \
+ !defined(_INET_IP_STACK_H)
ipfl.fl_unit = (u_int)ifp->qf_ppa;
- COPYIFNAME(ifp, ipfl.fl_ifname);
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
# else
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
- (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
- COPYIFNAME(ifp, ipfl.fl_ifname);
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \
+ (SOLARIS && defined(_INET_IP_STACK_H))
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
# else
ipfl.fl_unit = (u_int)ifp->if_unit;
# if defined(_KERNEL)
@@ -350,7 +356,7 @@ u_int flags;
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
ipfl.fl_ifname[3] = ifp->if_name[3];
# else
- (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname));
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0';
# endif
# endif
@@ -426,7 +432,7 @@ void **items;
size_t *itemsz;
int *types, cnt;
{
- caddr_t buf, ptr;
+ u_char *buf, *ptr;
iplog_t *ipl;
size_t len;
int i;
@@ -463,7 +469,7 @@ int *types, cnt;
* check that we have space to record this information and can
* allocate that much.
*/
- KMALLOCS(buf, caddr_t, len);
+ KMALLOCS(buf, u_char *, len);
if (buf == NULL)
return -1;
SPL_NET(s);
@@ -502,7 +508,7 @@ int *types, cnt;
if (types[i] == 0) {
bcopy(items[i], ptr, itemsz[i]);
} else if (types[i] == 1) {
- COPYDATA(items[i], 0, itemsz[i], ptr);
+ COPYDATA(items[i], 0, itemsz[i], (char *)ptr);
}
ptr += itemsz[i];
}
@@ -627,7 +633,7 @@ struct uio *uio;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
- error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
+ error = UIOMOVE(ipl, dlen, UIO_READ, uio);
if (error) {
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
@@ -637,7 +643,7 @@ struct uio *uio;
break;
}
MUTEX_ENTER(&ipl_mutex);
- KFREES((caddr_t)ipl, dlen);
+ KFREES(ipl, dlen);
SPL_NET(s);
}
if (!iplt[unit]) {
@@ -670,7 +676,7 @@ minor_t unit;
MUTEX_ENTER(&ipl_mutex);
while ((ipl = iplt[unit]) != NULL) {
iplt[unit] = ipl->ipl_next;
- KFREES((caddr_t)ipl, ipl->ipl_dsize);
+ KFREES(ipl, ipl->ipl_dsize);
}
iplh[unit] = &iplt[unit];
ipll[unit] = NULL;
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index a6a77dc..23cb579 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -118,7 +118,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.56 2006/04/01 10:15:34 darrenr Exp $";*/
+/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.102 2007/10/16 10:08:10 darrenr Exp $"; */
#endif
@@ -179,7 +179,7 @@ u_long fr_defnatage = DEF_NAT_AGE,
natstat_t nat_stats;
int fr_nat_lock = 0;
int fr_nat_init = 0;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
extern int pfil_delayed_copy;
#endif
@@ -188,13 +188,13 @@ static int nat_flushtable __P((void));
static int nat_clearlist __P((void));
static void nat_addnat __P((struct ipnat *));
static void nat_addrdr __P((struct ipnat *));
-static void nat_delete __P((struct nat *, int));
static void nat_delrdr __P((struct ipnat *));
static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t, int));
static int nat_extraflush __P((int));
+static int nat_gettable __P((char *));
static void nat_tabmove __P((nat_t *));
static int nat_match __P((fr_info_t *, ipnat_t *));
static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *));
@@ -874,7 +874,7 @@ void *ctx;
if (!(mode & FWRITE)) {
error = EPERM;
} else {
- fr_lock(data, &fr_nat_lock);
+ error = fr_lock(data, &fr_nat_lock);
}
break;
@@ -945,6 +945,10 @@ void *ctx;
error = fr_outobj(data, nat_tqb, IPFOBJ_STATETQTAB);
break;
+ case SIOCGTABL :
+ error = nat_gettable(data);
+ break;
+
default :
error = EINVAL;
break;
@@ -1082,7 +1086,7 @@ int getlock;
n = NULL;
nat_stats.ns_rules++;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 0;
#endif
if (getlock) {
@@ -1170,9 +1174,10 @@ int getlock;
if (n->in_use == 0) {
if (n->in_apr)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -1646,22 +1651,23 @@ junkput:
/* Delete a nat entry from the various lists and table. If NAT logging is */
/* enabled then generate a NAT log record for this event. */
/* ------------------------------------------------------------------------ */
-static void nat_delete(nat, logtype)
+void nat_delete(nat, logtype)
struct nat *nat;
int logtype;
{
struct ipnat *ipn;
+ int removed = 0;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
- MUTEX_ENTER(&ipf_nat_new);
-
/*
* Take it as a general indication that all the pointers are set if
* nat_pnext is set.
*/
if (nat->nat_pnext != NULL) {
+ removed = 1;
+
nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--;
nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--;
@@ -1701,15 +1707,35 @@ int logtype;
if (logtype == NL_EXPIRE)
nat_stats.ns_expire++;
- nat->nat_ref--;
- if (nat->nat_ref > 0) {
- MUTEX_EXIT(&ipf_nat_new);
+ MUTEX_ENTER(&nat->nat_lock);
+ /*
+ * NL_DESTROY should only be passed in when we've got nat_ref >= 2.
+ * This happens when a nat'd packet is blocked and we want to throw
+ * away the NAT session.
+ */
+ if (logtype == NL_DESTROY) {
+ if (nat->nat_ref > 2) {
+ nat->nat_ref -= 2;
+ MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
+ return;
+ }
+ } else if (nat->nat_ref > 1) {
+ nat->nat_ref--;
+ MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
return;
}
+ MUTEX_EXIT(&nat->nat_lock);
/*
- * At this point, nat_ref can be either 0 or -1
+ * At this point, nat_ref is 1, doing "--" would make it 0..
*/
+ nat->nat_ref = 0;
+ if (!removed)
+ nat_stats.ns_orphans--;
#ifdef IPFILTER_SYNC
if (nat->nat_sync)
@@ -1736,7 +1762,6 @@ int logtype;
aps_free(nat->nat_aps);
nat_stats.ns_inuse--;
- MUTEX_EXIT(&ipf_nat_new);
/*
* If there's a fragment table entry too for this nat entry, then
@@ -1810,6 +1835,7 @@ static int nat_clearlist()
if (n->in_use == 0) {
if (n->in_apr != NULL)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
} else {
@@ -1818,7 +1844,7 @@ static int nat_clearlist()
}
i++;
}
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 1;
#endif
nat_masks = 0;
@@ -2482,10 +2508,12 @@ int direction;
}
if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) {
+ fr_nat_doflush = 1;
goto badnat;
}
if (flags & SI_WILDP)
nat_stats.ns_wilds++;
+ fin->fin_flx |= FI_NEWNAT;
goto done;
badnat:
nat_stats.ns_badnat++;
@@ -2528,10 +2556,10 @@ int direction;
np = ni->nai_np;
if (np->in_ifps[0] != NULL) {
- COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]);
+ COPYIFNAME(4, np->in_ifps[0], nat->nat_ifnames[0]);
}
if (np->in_ifps[1] != NULL) {
- COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]);
+ COPYIFNAME(4, np->in_ifps[1], nat->nat_ifnames[1]);
}
#ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0)
@@ -2545,6 +2573,8 @@ int direction;
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
+ if (nat->nat_p == IPPROTO_TCP)
+ nat->nat_seqnext[0] = ntohl(tcp->th_seq);
if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0))
if (appr_new(fin, nat) == -1)
@@ -2992,10 +3022,22 @@ int dir;
}
if (sumd2 != 0) {
+ ipnat_t *np;
+
+ np = nat->nat_ptr;
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- fix_incksum(fin, &icmp->icmp_cksum, sumd2);
+
+ if ((odst == 0) && (dir == NAT_OUTBOUND) &&
+ (fin->fin_rev == 0) && (np != NULL) &&
+ (np->in_redir & NAT_REDIRECT)) {
+ fix_outcksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ } else {
+ fix_incksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ }
}
}
} else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) {
@@ -3622,6 +3664,26 @@ ipnat_t *np;
ifq2 = NULL;
if (nat->nat_p == IPPROTO_TCP && ifq2 == NULL) {
+ u_32_t end, ack;
+ u_char tcpflags;
+ tcphdr_t *tcp;
+ int dsize;
+
+ tcp = fin->fin_dp;
+ tcpflags = tcp->th_flags;
+ dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
+ ((tcpflags & TH_SYN) ? 1 : 0) +
+ ((tcpflags & TH_FIN) ? 1 : 0);
+
+ ack = ntohl(tcp->th_ack);
+ end = ntohl(tcp->th_seq) + dsize;
+
+ if (SEQ_GT(ack, nat->nat_seqnext[1 - fin->fin_rev]))
+ nat->nat_seqnext[1 - fin->fin_rev] = ack;
+
+ if (nat->nat_seqnext[fin->fin_rev] == 0)
+ nat->nat_seqnext[fin->fin_rev] = end;
+
(void) fr_tcp_age(&nat->nat_tqe, fin, nat_tqb, 0);
} else {
if (ifq2 == NULL) {
@@ -4643,9 +4705,10 @@ ipnat_t **inp;
if (in->in_use == 0 && (in->in_flags & IPN_DELETE)) {
if (in->in_apr)
appr_free(in->in_apr);
+ MUTEX_DESTROY(&in->in_lock);
KFREE(in);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -4660,6 +4723,14 @@ ipnat_t **inp;
/* */
/* Decrement the reference counter for this NAT table entry and free it if */
/* there are no more things using it. */
+/* */
+/* IF nat_ref == 1 when this function is called, then we have an orphan nat */
+/* structure *because* it only gets called on paths _after_ nat_ref has been*/
+/* incremented. If nat_ref == 1 then we shouldn't decrement it here */
+/* because nat_delete() will do that and send nat_ref to -1. */
+/* */
+/* Holding the lock on nat_lock is required to serialise nat_delete() being */
+/* called from a NAT flush ioctl with a deref happening because of a packet.*/
/* ------------------------------------------------------------------------ */
void fr_natderef(natp)
nat_t **natp;
@@ -4668,10 +4739,17 @@ nat_t **natp;
nat = *natp;
*natp = NULL;
+
+ MUTEX_ENTER(&nat->nat_lock);
+ if (nat->nat_ref > 1) {
+ nat->nat_ref--;
+ MUTEX_EXIT(&nat->nat_lock);
+ return;
+ }
+ MUTEX_EXIT(&nat->nat_lock);
+
WRITE_ENTER(&ipf_nat);
- nat->nat_ref--;
- if (nat->nat_ref == 0)
- nat_delete(nat, NL_EXPIRE);
+ nat_delete(nat, NL_EXPIRE);
RWLOCK_EXIT(&ipf_nat);
}
@@ -4957,10 +5035,11 @@ ipfgeniter_t *itp;
ipnat_t *ipn, *nextipnat = NULL, zeroipn;
nat_t *nat, *nextnat = NULL, zeronat;
int error = 0, count;
- ipftoken_t *freet;
char *dst;
- freet = NULL;
+ count = itp->igi_nitems;
+ if (count < 1)
+ return ENOSPC;
READ_ENTER(&ipf_nat);
@@ -4998,61 +5077,52 @@ ipfgeniter_t *itp;
}
dst = itp->igi_data;
- for (count = itp->igi_nitems; count > 0; count--) {
+ for (;;) {
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
if (nexthm != NULL) {
- if (nexthm->hm_next == NULL) {
- freet = t;
- count = 1;
- hm = NULL;
- }
if (count == 1) {
ATOMIC_INC32(nexthm->hm_ref);
+ t->ipt_data = nexthm;
}
} else {
bzero(&zerohm, sizeof(zerohm));
nexthm = &zerohm;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_IPNAT :
if (nextipnat != NULL) {
- if (nextipnat->in_next == NULL) {
- freet = t;
- count = 1;
- ipn = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextipnat->in_lock);
nextipnat->in_use++;
MUTEX_EXIT(&nextipnat->in_lock);
+ t->ipt_data = nextipnat;
}
} else {
bzero(&zeroipn, sizeof(zeroipn));
nextipnat = &zeroipn;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_NAT :
if (nextnat != NULL) {
- if (nextnat->nat_next == NULL) {
- count = 1;
- freet = t;
- nat = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextnat->nat_lock);
nextnat->nat_ref++;
MUTEX_EXIT(&nextnat->nat_lock);
+ t->ipt_data = nextnat;
}
} else {
bzero(&zeronat, sizeof(zeronat));
nextnat = &zeronat;
count = 1;
+ t->ipt_data = NULL;
}
break;
default :
@@ -5060,20 +5130,12 @@ ipfgeniter_t *itp;
}
RWLOCK_EXIT(&ipf_nat);
- if (freet != NULL) {
- ipf_freetoken(freet);
- freet = NULL;
- }
-
+ /*
+ * Copying out to user space needs to be done without the lock.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- if (hm != NULL) {
- WRITE_ENTER(&ipf_nat);
- fr_hostmapdel(&hm);
- RWLOCK_EXIT(&ipf_nat);
- }
- t->ipt_data = nexthm;
error = COPYOUT(nexthm, dst, sizeof(*nexthm));
if (error != 0)
error = EFAULT;
@@ -5082,9 +5144,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_IPNAT :
- if (ipn != NULL)
- fr_ipnatderef(&ipn);
- t->ipt_data = nextipnat;
error = COPYOUT(nextipnat, dst, sizeof(*nextipnat));
if (error != 0)
error = EFAULT;
@@ -5093,9 +5152,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_NAT :
- if (nat != NULL)
- fr_natderef(&nat);
- t->ipt_data = nextnat;
error = COPYOUT(nextnat, dst, sizeof(*nextnat));
if (error != 0)
error = EFAULT;
@@ -5107,29 +5163,52 @@ ipfgeniter_t *itp;
if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_nat);
+ /*
+ * We need to have the lock again here to make sure that
+ * using _next is consistent.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- hm = nexthm;
- nexthm = hm->hm_next;
+ nexthm = nexthm->hm_next;
break;
-
case IPFGENITER_IPNAT :
- ipn = nextipnat;
- nextipnat = ipn->in_next;
+ nextipnat = nextipnat->in_next;
break;
-
case IPFGENITER_NAT :
- nat = nextnat;
- nextnat = nat->nat_next;
- break;
- default :
+ nextnat = nextnat->nat_next;
break;
}
}
+
+ switch (itp->igi_type)
+ {
+ case IPFGENITER_HOSTMAP :
+ if (hm != NULL) {
+ WRITE_ENTER(&ipf_nat);
+ fr_hostmapdel(&hm);
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ break;
+ case IPFGENITER_IPNAT :
+ if (ipn != NULL) {
+ fr_ipnatderef(&ipn);
+ }
+ break;
+ case IPFGENITER_NAT :
+ if (nat != NULL) {
+ fr_natderef(&nat);
+ }
+ break;
+ default :
+ break;
+ }
+
return error;
}
@@ -5338,3 +5417,44 @@ void *entry;
nat_delete(entry, NL_FLUSH);
return 0;
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: nat_gettable */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to ioctl data */
+/* */
+/* This function handles ioctl requests for tables of nat information. */
+/* At present the only table it deals with is the hash bucket statistics. */
+/* ------------------------------------------------------------------------ */
+static int nat_gettable(data)
+char *data;
+{
+ ipftable_t table;
+ int error;
+
+ error = fr_inobj(data, &table, IPFOBJ_GTABLE);
+ if (error != 0)
+ return error;
+
+ switch (table.ita_type)
+ {
+ case IPFTABLE_BUCKETS_NATIN :
+ error = COPYOUT(nat_stats.ns_bucketlen[0], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ case IPFTABLE_BUCKETS_NATOUT :
+ error = COPYOUT(nat_stats.ns_bucketlen[1], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ default :
+ return EINVAL;
+ }
+
+ if (error != 0) {
+ error = EFAULT;
+ }
+ return error;
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 5484eac..3020eb6 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -7,7 +7,7 @@
*
* @(#)ip_nat.h 1.5 2/4/96
* $FreeBSD$
- * Id: ip_nat.h,v 2.90.2.9 2005/03/28 11:09:55 darrenr Exp
+ * Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -125,6 +125,7 @@ typedef struct nat {
char nat_ifnames[2][LIFNAMSIZ];
int nat_rev; /* 0 = forward, 1 = reverse */
int nat_redir; /* copy of in_redir */
+ u_32_t nat_seqnext[2];
} nat_t;
#define nat_inip nat_inip6.in4
@@ -363,6 +364,7 @@ typedef struct natstat {
hostmap_t *ns_maplist;
u_long *ns_bucketlen[2];
u_long ns_ticks;
+ u_int ns_orphans;
} natstat_t;
typedef struct natlog {
@@ -384,6 +386,7 @@ typedef struct natlog {
#define NL_NEWRDR NAT_REDIRECT
#define NL_NEWBIMAP NAT_BIMAP
#define NL_NEWBLOCK NAT_MAPBLK
+#define NL_DESTROY 0xfffc
#define NL_CLONE 0xfffd
#define NL_FLUSH 0xfffe
#define NL_EXPIRE 0xffff
@@ -447,6 +450,7 @@ extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int));
extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int));
+extern void nat_delete __P((struct nat *, int));
extern int nat_insert __P((nat_t *, int));
extern int fr_checknatout __P((fr_info_t *, u_32_t *));
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index b04331e..b0490a1 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -104,7 +104,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.20 2007/05/31 12:27:36 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.21 2007/06/02 21:22:28 darrenr Exp $";
#endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
@@ -296,7 +296,7 @@ int mode;
void *ctx;
{
ap_ctl_t ctl;
- caddr_t ptr;
+ u_char *ptr;
int error;
mode = mode; /* LINT */
@@ -304,11 +304,13 @@ void *ctx;
switch (cmd)
{
case SIOCPROXY :
- BCOPYIN(data, &ctl, sizeof(ctl));
+ error = BCOPYIN(data, &ctl, sizeof(ctl));
+ if (error != 0)
+ return EFAULT;
ptr = NULL;
if (ctl.apc_dsize > 0) {
- KMALLOCS(ptr, caddr_t, ctl.apc_dsize);
+ KMALLOCS(ptr, u_char *, ctl.apc_dsize);
if (ptr == NULL)
error = ENOMEM;
else {
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 39a094a..cfb7974 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -113,7 +113,7 @@ struct file;
#if !defined(lint)
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.69 2007/05/26 13:05:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.80 2007/10/16 09:33:23 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@@ -550,7 +550,7 @@ void *ctx;
if (!(mode & FWRITE)) {
error = EPERM;
} else {
- fr_lock(data, &fr_state_lock);
+ error = fr_lock(data, &fr_state_lock);
}
break;
@@ -652,8 +652,8 @@ caddr_t data;
int error;
error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
+ if (error != 0)
+ return error;
isn = ips.ips_next;
if (isn == NULL) {
@@ -682,9 +682,7 @@ caddr_t data;
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
error = fr_outobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
- return 0;
+ return error;
}
@@ -993,6 +991,16 @@ u_int flags;
hv += is->is_src.i6[3];
}
#endif
+ if ((fin->fin_v == 4) &&
+ (fin->fin_flx & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST))) {
+ if (fin->fin_out == 0) {
+ flags |= SI_W_DADDR|SI_CLONE;
+ hv -= is->is_daddr;
+ } else {
+ flags |= SI_W_SADDR|SI_CLONE;
+ hv -= is->is_saddr;
+ }
+ }
switch (is->is_p)
{
@@ -1190,7 +1198,8 @@ u_int flags;
sizeof(fr->fr_ifnames[0]));
} else {
is->is_ifp[out << 1] = fin->fin_ifp;
- COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
+ COPYIFNAME(is->is_v, fin->fin_ifp,
+ is->is_ifname[out << 1]);
}
is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1];
@@ -1210,7 +1219,8 @@ u_int flags;
if (fin->fin_ifp != NULL) {
is->is_ifp[out << 1] = fin->fin_ifp;
- COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
+ COPYIFNAME(is->is_v, fin->fin_ifp,
+ is->is_ifname[out << 1]);
}
}
@@ -1439,12 +1449,13 @@ ipstate_t *is;
is->is_state[!source] = IPF_TCPS_CLOSED;
fr_movequeue(&is->is_sti, is->is_sti.tqe_ifq,
&ips_deletetq);
- MUTEX_ENTER(&is->is_lock);
+ MUTEX_EXIT(&is->is_lock);
return 0;
}
}
- if (fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags)) {
+ ret = fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags);
+ if (ret > 0) {
#ifdef IPFILTER_SCAN
if (is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER)) {
ipsc_packet(fin, is);
@@ -1540,7 +1551,8 @@ ipstate_t *is;
/* ------------------------------------------------------------------------ */
/* Function: fr_tcpinwindow */
-/* Returns: int - 1 == packet inside TCP "window", 0 == not inside. */
+/* Returns: int - 1 == packet inside TCP "window", 0 == not inside, */
+/* 2 == packet seq number matches next expected */
/* Parameters: fin(I) - pointer to packet information */
/* fdata(I) - pointer to tcp state informatio (forward) */
/* tdata(I) - pointer to tcp state informatio (reverse) */
@@ -1624,14 +1636,12 @@ int flags;
/*
* Strict sequencing only allows in-order delivery.
*/
- if ((flags & IS_STRICT) != 0) {
- if (seq != fdata->td_end) {
+ if (seq != fdata->td_end) {
+ if ((flags & IS_STRICT) != 0) {
return 0;
}
}
-#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
-#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
inseq = 0;
if ((SEQ_GE(fdata->td_maxend, end)) &&
(SEQ_GE(seq, fdata->td_end - maxwin)) &&
@@ -2028,7 +2038,7 @@ u_32_t cmask;
if (is->is_ifp[idx] == NULL &&
(*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) {
is->is_ifp[idx] = ifp;
- COPYIFNAME(ifp, is->is_ifname[idx]);
+ COPYIFNAME(is->is_v, ifp, is->is_ifname[idx]);
}
fin->fin_rev = rev;
return is;
@@ -2299,8 +2309,6 @@ u_int hv;
ipstate_t **isp;
u_int hvm;
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
hvm = is->is_hv;
/*
* Remove the hash from the old location...
@@ -2383,6 +2391,14 @@ ipftq_t **ifqp;
}
}
#endif
+ if ((v == 4) &&
+ (fin->fin_flx & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST))) {
+ if (fin->fin_out == 0) {
+ hv -= src.in4.s_addr;
+ } else {
+ hv -= dst.in4.s_addr;
+ }
+ }
/*
* Search the hash table for matching packet header info.
@@ -2531,12 +2547,31 @@ retry_tcpudp:
}
RWLOCK_EXIT(&ipf_state);
- if (!tryagain && ips_stats.iss_wild) {
- hv -= dport;
- hv -= sport;
- tryagain = 1;
- WRITE_ENTER(&ipf_state);
- goto retry_tcpudp;
+ if (ips_stats.iss_wild) {
+ if (tryagain == 0) {
+ hv -= dport;
+ hv -= sport;
+ } else if (tryagain == 1) {
+ hv = fin->fin_fi.fi_p;
+ /*
+ * If we try to pretend this is a reply to a
+ * multicast/broadcast packet then we need to
+ * exclude part of the address from the hash
+ * calculation.
+ */
+ if (fin->fin_out == 0) {
+ hv += src.in4.s_addr;
+ } else {
+ hv += dst.in4.s_addr;
+ }
+ hv += dport;
+ hv += sport;
+ }
+ tryagain++;
+ if (tryagain <= 2) {
+ WRITE_ENTER(&ipf_state);
+ goto retry_tcpudp;
+ }
}
fin->fin_flx |= oow;
break;
@@ -2888,8 +2923,6 @@ ipstate_t *is;
int why;
{
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
/*
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
@@ -2937,9 +2970,15 @@ int why;
* entry (such as ipfstat), it'll do the deref path that'll bring
* us back here to do the real delete & free.
*/
- is->is_ref--;
- if (is->is_ref > 0)
+ MUTEX_ENTER(&is->is_lock);
+ if (is->is_ref > 1) {
+ is->is_ref--;
+ MUTEX_EXIT(&is->is_lock);
return is->is_ref;
+ }
+ MUTEX_EXIT(&is->is_lock);
+
+ is->is_ref = 0;
if (is->is_tqehead[0] != NULL) {
if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0)
@@ -3536,7 +3575,7 @@ int flags;
if ((tcpflags & (TH_FIN|TH_ACK)) == TH_ACK) {
nstate = IPF_TCPS_TIME_WAIT;
}
- rval = 1;
+ rval = 2;
break;
case IPF_TCPS_LAST_ACK: /* 8 */
@@ -3560,24 +3599,14 @@ int flags;
case IPF_TCPS_FIN_WAIT_2: /* 9 */
/* NOT USED */
-#if 0
- rval = 1;
- if ((tcpflags & TH_OPENING) == TH_OPENING) {
- nstate = IPF_TCPS_SYN_RECEIVED;
- } else if (tcpflags & TH_SYN) {
- nstate = IPF_TCPS_SYN_SENT;
- } else if ((tcpflags & (TH_FIN|TH_ACK)) != 0) {
- nstate = IPF_TCPS_TIME_WAIT;
- }
-#endif
break;
case IPF_TCPS_TIME_WAIT: /* 10 */
/* we're in 2MSL timeout now */
- rval = 2;
if (ostate == IPF_TCPS_LAST_ACK) {
nstate = IPF_TCPS_CLOSED;
}
+ rval = 1;
break;
case IPF_TCPS_CLOSED: /* 11 */
@@ -3932,6 +3961,14 @@ ipftq_t *tqp;
/* Decrement the reference counter for this state table entry and free it */
/* if there are no more things using it. */
/* */
+/* This function is only called when cleaning up after increasing is_ref by */
+/* one earlier in the 'code path' so if is_ref is 1 when entering, we do */
+/* have an orphan, otherwise not. However there is a possible race between */
+/* the entry being deleted via flushing with an ioctl call (that calls the */
+/* delete function directly) and the tail end of packet processing so we */
+/* need to grab is_lock before doing the check to synchronise the two code */
+/* paths. */
+/* */
/* When operating in userland (ipftest), we have no timers to clear a state */
/* entry. Therefore, we make a few simple tests before deleting an entry */
/* outright. We compare states on each side looking for a combination of */
@@ -3954,17 +3991,23 @@ ipstate_t **isp;
is = *isp;
*isp = NULL;
- WRITE_ENTER(&ipf_state);
- is->is_ref--;
- if (is->is_ref == 0) {
- is->is_ref++; /* To counter ref-- in fr_delstate() */
- fr_delstate(is, ISL_EXPIRE);
+
+ MUTEX_ENTER(&is->is_lock);
+ if (is->is_ref > 1) {
+ is->is_ref--;
+ MUTEX_EXIT(&is->is_lock);
#ifndef _KERNEL
- } else if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
+ if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
(is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) {
- fr_delstate(is, ISL_ORPHAN);
+ fr_delstate(is, ISL_ORPHAN);
+ }
#endif
+ return;
}
+ MUTEX_EXIT(&is->is_lock);
+
+ WRITE_ENTER(&ipf_state);
+ fr_delstate(is, ISL_EXPIRE);
RWLOCK_EXIT(&ipf_state);
}
@@ -4058,7 +4101,7 @@ ipfgeniter_t *itp;
if (itp->igi_data == NULL)
return EFAULT;
- if (itp->igi_nitems == 0)
+ if (itp->igi_nitems < 1)
return ENOSPC;
if (itp->igi_type != IPFGENITER_STATE)
@@ -4080,33 +4123,29 @@ ipfgeniter_t *itp;
next = is->is_next;
}
- for (count = itp->igi_nitems; count > 0; count--) {
+ count = itp->igi_nitems;
+ for (;;) {
if (next != NULL) {
/*
* If we find a state entry to use, bump its
* reference count so that it can be used for
* is_next when we come back.
*/
- MUTEX_ENTER(&next->is_lock);
- next->is_ref++;
- MUTEX_EXIT(&next->is_lock);
- token->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->is_lock);
+ next->is_ref++;
+ MUTEX_EXIT(&next->is_lock);
+ token->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
count = 1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_state);
/*
- * If we had a prior pointer to a state entry, release it.
- */
- if (is != NULL) {
- fr_statederef(&is);
- }
-
- /*
* This should arguably be via fr_outobj() so that the state
* structure can (if required) be massaged going out.
*/
@@ -4117,9 +4156,14 @@ ipfgeniter_t *itp;
break;
dst += sizeof(*next);
+ count--;
+
READ_ENTER(&ipf_state);
- is = next;
- next = is->is_next;
+ next = next->is_next;
+ }
+
+ if (is != NULL) {
+ fr_statederef(&is);
}
return error;
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index ca7e454..9c4e814 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.h
+++ b/sys/contrib/ipfilter/netinet/ip_state.h
@@ -7,7 +7,7 @@
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* $FreeBSD$
- * Id: ip_state.h,v 2.68.2.3 2005/03/03 14:24:11 darrenr Exp
+ * Id: ip_state.h,v 2.68.2.10 2007/10/16 09:33:24 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -27,10 +27,8 @@ struct ipscan;
# define IPSTATE_MAX 4013 /* Maximum number of states held */
#endif
-#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
- (((s1) == (d2)) && ((d1) == (s2))))
-#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
- (s2).s_addr, (d2).s_addr)
+#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
+#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
typedef struct ipstate {
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.c b/sys/contrib/ipfilter/netinet/ip_sync.c
index 6b277ae..a72f50f 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.c
+++ b/sys/contrib/ipfilter/netinet/ip_sync.c
@@ -98,7 +98,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.8 2006/07/14 06:12:20 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.9 2007/06/02 21:22:28 darrenr Exp $";
#endif
#define SYNC_STATETABSZ 256
@@ -301,7 +301,7 @@ struct uio *uio;
if (uio->uio_resid >= sizeof(sh)) {
- err = UIOMOVE((caddr_t)&sh, sizeof(sh), UIO_WRITE, uio);
+ err = UIOMOVE(&sh, sizeof(sh), UIO_WRITE, uio);
if (err) {
if (ipf_sync_debug > 2)
@@ -373,7 +373,7 @@ struct uio *uio;
if (uio->uio_resid >= sh.sm_len) {
- err = UIOMOVE((caddr_t)data, sh.sm_len, UIO_WRITE, uio);
+ err = UIOMOVE(data, sh.sm_len, UIO_WRITE, uio);
if (err) {
if (ipf_sync_debug > 2)
@@ -473,7 +473,7 @@ struct uio *uio;
READ_ENTER(&ipf_syncstate);
while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) {
sl = synclog + sl_tail++;
- err = UIOMOVE((caddr_t)sl, sizeof(*sl), UIO_READ, uio);
+ err = UIOMOVE(sl, sizeof(*sl), UIO_READ, uio);
if (err != 0)
break;
}
@@ -481,7 +481,7 @@ struct uio *uio;
while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) {
su = syncupd + su_tail;
su_tail++;
- err = UIOMOVE((caddr_t)su, sizeof(*su), UIO_READ, uio);
+ err = UIOMOVE(su, sizeof(*su), UIO_READ, uio);
if (err != 0)
break;
if (su->sup_hdr.sm_sl != NULL)
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 22b8d51..4f2f122 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -7,14 +7,14 @@
*
* @(#)ipl.h 1.21 6/5/96
* $FreeBSD$
- * Id: ipl.h,v 2.52.2.14 2006/04/01 20:09:42 darrenr Exp $
+ * Id: ipl.h,v 2.52.2.30 2007/10/16 09:41:00 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v4.1.23"
+#define IPL_VERSION "IP Filter: v4.1.28"
-#define IPFILTER_VERSION 4012300
+#define IPFILTER_VERSION 4012800
#endif
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 9166712..36048e4 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -207,6 +207,11 @@ ipf_modload()
ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, c);
}
+ error = ipf_pfil_hook();
+ if (error != 0)
+ return error;
+ ipf_event_reg();
+
if (FR_ISPASS(fr_pass))
defpass = "pass";
else if (FR_ISBLOCK(fr_pass))
@@ -240,7 +245,11 @@ ipf_modunload()
return EBUSY;
if (fr_running >= 0) {
+ ipf_pfil_unhook();
+ ipf_event_dereg();
+ WRITE_ENTER(&ipf_global);
error = ipfdetach();
+ RWLOCK_EXIT(&ipf_global);
if (error != 0)
return error;
} else
OpenPOWER on IntegriCloud