summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/Makefile2
-rw-r--r--usr/src/cmd/ipf/Makefile.ipf6
-rw-r--r--usr/src/cmd/ipf/lib/Makefile.com26
-rw-r--r--usr/src/cmd/ipf/lib/common/addicmp.c10
-rw-r--r--usr/src/cmd/ipf/lib/common/checkrev.c10
-rw-r--r--usr/src/cmd/ipf/lib/common/facpri.c6
-rw-r--r--usr/src/cmd/ipf/lib/common/genmask.c2
-rw-r--r--usr/src/cmd/ipf/lib/common/gethost.c17
-rw-r--r--usr/src/cmd/ipf/lib/common/getifname.c39
-rw-r--r--usr/src/cmd/ipf/lib/common/getnattype.c7
-rw-r--r--usr/src/cmd/ipf/lib/common/getport.c24
-rw-r--r--usr/src/cmd/ipf/lib/common/getportproto.c30
-rw-r--r--usr/src/cmd/ipf/lib/common/getproto.c15
-rw-r--r--usr/src/cmd/ipf/lib/common/hostname.c36
-rw-r--r--usr/src/cmd/ipf/lib/common/hostnum.c19
-rw-r--r--usr/src/cmd/ipf/lib/common/icmpcode.c6
-rw-r--r--usr/src/cmd/ipf/lib/common/inet_addr.c50
-rw-r--r--usr/src/cmd/ipf/lib/common/ipf_dotuning.c67
-rw-r--r--usr/src/cmd/ipf/lib/common/ipft_ef.c9
-rw-r--r--usr/src/cmd/ipf/lib/common/ipft_hx.c8
-rw-r--r--usr/src/cmd/ipf/lib/common/ipft_pc.c7
-rw-r--r--usr/src/cmd/ipf/lib/common/ipft_td.c10
-rw-r--r--usr/src/cmd/ipf/lib/common/ipft_tx.c56
-rw-r--r--usr/src/cmd/ipf/lib/common/kmem.c50
-rw-r--r--usr/src/cmd/ipf/lib/common/load_hash.c39
-rw-r--r--usr/src/cmd/ipf/lib/common/load_hashnode.c20
-rw-r--r--usr/src/cmd/ipf/lib/common/load_pool.c28
-rw-r--r--usr/src/cmd/ipf/lib/common/load_poolnode.c18
-rw-r--r--usr/src/cmd/ipf/lib/common/natparse.c10
-rw-r--r--usr/src/cmd/ipf/lib/common/portname.c34
-rw-r--r--usr/src/cmd/ipf/lib/common/portnum.c4
-rw-r--r--usr/src/cmd/ipf/lib/common/ports.c4
-rw-r--r--usr/src/cmd/ipf/lib/common/print_toif.c4
-rw-r--r--usr/src/cmd/ipf/lib/common/printactivenat.c83
-rw-r--r--usr/src/cmd/ipf/lib/common/printaps.c2
-rw-r--r--usr/src/cmd/ipf/lib/common/printbuf.c4
-rw-r--r--usr/src/cmd/ipf/lib/common/printfr.c418
-rw-r--r--usr/src/cmd/ipf/lib/common/printfraginfo.c27
-rw-r--r--usr/src/cmd/ipf/lib/common/printhash.c16
-rw-r--r--usr/src/cmd/ipf/lib/common/printhashnode.c12
-rw-r--r--usr/src/cmd/ipf/lib/common/printnat.c184
-rw-r--r--usr/src/cmd/ipf/lib/common/printpacket.c18
-rw-r--r--usr/src/cmd/ipf/lib/common/printpool.c25
-rw-r--r--usr/src/cmd/ipf/lib/common/printproto.c51
-rw-r--r--usr/src/cmd/ipf/lib/common/printsbuf.c7
-rw-r--r--usr/src/cmd/ipf/lib/common/printstate.c44
-rw-r--r--usr/src/cmd/ipf/lib/common/printtunable.c24
-rw-r--r--usr/src/cmd/ipf/lib/common/remove_hash.c6
-rw-r--r--usr/src/cmd/ipf/lib/common/remove_hashnode.c6
-rw-r--r--usr/src/cmd/ipf/lib/common/remove_pool.c6
-rw-r--r--usr/src/cmd/ipf/lib/common/remove_poolnode.c10
-rw-r--r--usr/src/cmd/ipf/lib/common/v6ionames.c4
-rw-r--r--usr/src/cmd/ipf/lib/common/var.c14
-rw-r--r--usr/src/cmd/ipf/tools/Makefile.tools22
-rw-r--r--usr/src/cmd/ipf/tools/ip_fil.c289
-rw-r--r--usr/src/cmd/ipf/tools/ipf.c210
-rw-r--r--usr/src/cmd/ipf/tools/ipf_y.y632
-rw-r--r--usr/src/cmd/ipf/tools/ipfcomp.c49
-rw-r--r--usr/src/cmd/ipf/tools/ipfs.c108
-rw-r--r--usr/src/cmd/ipf/tools/ipfstat.c626
-rw-r--r--usr/src/cmd/ipf/tools/ipftest.c181
-rw-r--r--usr/src/cmd/ipf/tools/ipmon.c212
-rw-r--r--usr/src/cmd/ipf/tools/ipmon_y.y326
-rw-r--r--usr/src/cmd/ipf/tools/ipnat.c23
-rw-r--r--usr/src/cmd/ipf/tools/ipnat_y.y214
-rw-r--r--usr/src/cmd/ipf/tools/ippool.c56
-rw-r--r--usr/src/cmd/ipf/tools/ippool_y.y120
-rw-r--r--usr/src/cmd/ipf/tools/lexer.c32
-rw-r--r--usr/src/common/ipf/ipl.h18
-rw-r--r--usr/src/common/ipf/solaris.c1122
-rw-r--r--usr/src/uts/common/Makefile.rules12
-rw-r--r--usr/src/uts/common/inet/ipf/bpf-ipf.h (renamed from usr/src/common/ipf/bpf-ipf.h)0
-rw-r--r--usr/src/uts/common/inet/ipf/fil.c (renamed from usr/src/common/ipf/fil.c)2492
-rw-r--r--usr/src/uts/common/inet/ipf/ip_auth.c (renamed from usr/src/common/ipf/ip_auth.c)133
-rw-r--r--usr/src/uts/common/inet/ipf/ip_fil_solaris.c (renamed from usr/src/common/ipf/ip_fil_solaris.c)894
-rw-r--r--usr/src/uts/common/inet/ipf/ip_frag.c (renamed from usr/src/common/ipf/ip_frag.c)76
-rw-r--r--usr/src/uts/common/inet/ipf/ip_htable.c (renamed from usr/src/common/ipf/ip_htable.c)119
-rw-r--r--usr/src/uts/common/inet/ipf/ip_log.c (renamed from usr/src/common/ipf/ip_log.c)355
-rw-r--r--usr/src/uts/common/inet/ipf/ip_lookup.c (renamed from usr/src/common/ipf/ip_lookup.c)216
-rw-r--r--usr/src/uts/common/inet/ipf/ip_nat.c (renamed from usr/src/common/ipf/ip_nat.c)1622
-rw-r--r--usr/src/uts/common/inet/ipf/ip_pool.c (renamed from usr/src/common/ipf/ip_pool.c)132
-rw-r--r--usr/src/uts/common/inet/ipf/ip_proxy.c (renamed from usr/src/common/ipf/ip_proxy.c)294
-rw-r--r--usr/src/uts/common/inet/ipf/ip_state.c (renamed from usr/src/common/ipf/ip_state.c)958
-rw-r--r--usr/src/uts/common/inet/ipf/ipf.h (renamed from usr/src/common/ipf/ipf.h)87
-rw-r--r--usr/src/uts/common/inet/ipf/ipmon.h (renamed from usr/src/common/ipf/ipmon.h)50
-rw-r--r--usr/src/uts/common/inet/ipf/ipt.h (renamed from usr/src/common/ipf/ipt.h)0
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/Makefile (renamed from usr/src/common/ipf/Makefile)6
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_auth.h (renamed from usr/src/common/ipf/ip_auth.h)12
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_compat.h (renamed from usr/src/common/ipf/ip_compat.h)977
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_fil.h (renamed from usr/src/common/ipf/ip_fil.h)269
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_frag.h (renamed from usr/src/common/ipf/ip_frag.h)16
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_ftp_pxy.c (renamed from usr/src/common/ipf/ip_ftp_pxy.c)603
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_h323_pxy.c (renamed from usr/src/common/ipf/ip_h323_pxy.c)21
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_htable.h (renamed from usr/src/common/ipf/ip_htable.h)6
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_ipsec_pxy.c (renamed from usr/src/common/ipf/ip_ipsec_pxy.c)109
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_irc_pxy.c (renamed from usr/src/common/ipf/ip_irc_pxy.c)45
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_lookup.h (renamed from usr/src/common/ipf/ip_lookup.h)30
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_nat.h (renamed from usr/src/common/ipf/ip_nat.h)52
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_netbios_pxy.c (renamed from usr/src/common/ipf/ip_netbios_pxy.c)20
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_pool.h (renamed from usr/src/common/ipf/ip_pool.h)30
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_pptp_pxy.c528
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_proxy.h (renamed from usr/src/common/ipf/ip_proxy.h)64
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_raudio_pxy.c (renamed from usr/src/common/ipf/ip_raudio_pxy.c)39
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_rcmd_pxy.c (renamed from usr/src/common/ipf/ip_rcmd_pxy.c)31
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_rpcb_pxy.c (renamed from usr/src/common/ipf/ip_rpcb_pxy.c)50
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_state.h (renamed from usr/src/common/ipf/ip_state.h)23
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ipl.h23
-rw-r--r--usr/src/uts/common/inet/ipf/opts.h (renamed from usr/src/common/ipf/opts.h)7
-rw-r--r--usr/src/uts/common/inet/ipf/pfil.conf2
-rw-r--r--usr/src/uts/common/inet/ipf/radix.c (renamed from usr/src/common/ipf/radix.c)227
-rw-r--r--usr/src/uts/common/inet/ipf/radix.h (renamed from usr/src/common/ipf/radix.h)0
-rw-r--r--usr/src/uts/common/inet/ipf/radix_ipf.h212
-rw-r--r--usr/src/uts/common/inet/ipf/solaris.c696
-rw-r--r--usr/src/uts/common/inet/pfil/compat.h (renamed from usr/src/uts/common/inet/ipf/compat.h)36
-rw-r--r--usr/src/uts/common/inet/pfil/misc.c (renamed from usr/src/uts/common/inet/ipf/misc.c)6
-rw-r--r--usr/src/uts/common/inet/pfil/ndd.c (renamed from usr/src/uts/common/inet/ipf/ndd.c)72
-rw-r--r--usr/src/uts/common/inet/pfil/os.h (renamed from usr/src/uts/common/inet/ipf/os.h)10
-rw-r--r--usr/src/uts/common/inet/pfil/pfil.c (renamed from usr/src/uts/common/inet/ipf/pfil.c)25
-rw-r--r--usr/src/uts/common/inet/pfil/pfil.conf28
-rw-r--r--usr/src/uts/common/inet/pfil/pfil.h (renamed from usr/src/uts/common/inet/ipf/pfil.h)27
-rw-r--r--usr/src/uts/common/inet/pfil/pfild.h (renamed from usr/src/common/ipf/pfild.h)0
-rw-r--r--usr/src/uts/common/inet/pfil/pfildrv.c (renamed from usr/src/uts/common/inet/ipf/pfildrv.c)500
-rw-r--r--usr/src/uts/common/inet/pfil/pfilstream.c (renamed from usr/src/uts/common/inet/ipf/pfilstream.c)92
-rw-r--r--usr/src/uts/common/inet/pfil/pkt.c (renamed from usr/src/uts/common/inet/ipf/pkt.c)7
-rw-r--r--usr/src/uts/common/inet/pfil/qif.c (renamed from usr/src/uts/common/inet/ipf/qif.c)75
-rw-r--r--usr/src/uts/common/inet/pfil/qif.h (renamed from usr/src/uts/common/inet/ipf/qif.h)26
-rw-r--r--usr/src/uts/intel/ipf/Makefile4
-rw-r--r--usr/src/uts/intel/pfil/Makefile9
-rw-r--r--usr/src/uts/req.flg1
-rw-r--r--usr/src/uts/sparc/ipf/Makefile4
-rw-r--r--usr/src/uts/sparc/pfil/Makefile9
131 files changed, 11184 insertions, 7159 deletions
diff --git a/usr/src/Makefile b/usr/src/Makefile
index f04c2c9388..1707c95d75 100644
--- a/usr/src/Makefile
+++ b/usr/src/Makefile
@@ -180,7 +180,7 @@ cmdheaders: FRC
@cd cmd/mdb; pwd; $(MAKE) install_h
commonheaders: FRC
- @cd common/ipf; pwd; $(MAKE) install_h
+ @cd uts/common/inet/ipf/netinet; pwd; $(MAKE) install_h
# each xmod target depends on a corresponding MACH-specific pseudotarget
# before doing common xmod work
diff --git a/usr/src/cmd/ipf/Makefile.ipf b/usr/src/cmd/ipf/Makefile.ipf
index b4bb4d8620..7a6d8c4c16 100644
--- a/usr/src/cmd/ipf/Makefile.ipf
+++ b/usr/src/cmd/ipf/Makefile.ipf
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -11,8 +11,8 @@
LIBIPF= ../../lib/$(MACH)/libipf.a
LIBIPF64= ../../lib/$(MACH64)/libipf.a
-COMMONIPF= $(SRC)/common/ipf
-KERNELIPF= $(SRC)/uts/common/inet/ipf
+COMMONIPF= $(SRC)/uts/common/inet/ipf
+KERNELIPF= $(SRC)/uts/common/inet/pfil
MINOR= echo $(RELEASE) | cut -d. -f2
CPPFLAGS += -I$(COMMONIPF) -I$(KERNELIPF) -DSUNDDI -DUSE_INET6 \
diff --git a/usr/src/cmd/ipf/lib/Makefile.com b/usr/src/cmd/ipf/lib/Makefile.com
index c2f50235b5..70f7d0a179 100644
--- a/usr/src/cmd/ipf/lib/Makefile.com
+++ b/usr/src/cmd/ipf/lib/Makefile.com
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -17,19 +17,21 @@ OBJECTS= addicmp.o addipopt.o bcopywrap.o \
getline.o getnattype.o getport.o getportproto.o \
getproto.o getsumd.o hostmask.o hostname.o \
hostnum.o icmpcode.o inet_addr.o initparse.o \
- ionames.o ipoptsec.o ipft_ef.o ipft_hx.o \
- ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o kmem.o \
- kmemcpywrap.o kvatoname.o load_hash.o load_pool.o \
- load_hashnode.o load_poolnode.o loglevel.o \
- mutex_emul.o nametokva.o natparse.o ntomask.o \
- optname.o optprint.o optprintv6.o optvalue.o \
+ ionames.o v6ionames.o ipoptsec.o ipf_dotuning.o \
+ ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o \
+ ipft_tx.o kmem.o kmemcpywrap.o kvatoname.o \
+ load_hash.o load_pool.o load_hashnode.o \
+ load_poolnode.o loglevel.o mutex_emul.o nametokva.o \
+ natparse.o ntomask.o optname.o optprint.o \
+ optprintv6.o optvalue.o \
portname.o portnum.o ports.o print_toif.o \
- printaps.o printbuf.o printhash.o printhashnode.o \
- printip.o printpool.o printpoolnode.o printfr.o \
+ printactivenat.o printaps.o printbuf.o printhash.o \
+ printhashnode.o printip.o printpool.o \
+ printpoolnode.o printfr.o printfraginfo.o \
printhostmap.o printifname.o printhostmask.o \
- printlog.o printmask.o printnat.o printportcmp.o \
- printpacket.o printpacket6.o printsbuf.o \
- printstate.o ratoi.o \
+ printlog.o printmask.o printnat.o printpacket.o \
+ printpacket6.o printportcmp.o printproto.o \
+ printsbuf.o printstate.o printtunable.o ratoi.o \
remove_pool.o remove_poolnode.o remove_hash.o \
remove_hashnode.o resetlexer.o rwlock_emul.o \
tcpflags.o to_interface.o var.o verbose.o \
diff --git a/usr/src/cmd/ipf/lib/common/addicmp.c b/usr/src/cmd/ipf/lib/common/addicmp.c
index 4892ba09ed..e18a787a0a 100644
--- a/usr/src/cmd/ipf/lib/common/addicmp.c
+++ b/usr/src/cmd/ipf/lib/common/addicmp.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: addicmp.c,v 1.8 2002/01/28 06:50:45 darrenr Exp $
+ * $Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp $
*/
#include <ctype.h>
@@ -34,7 +34,7 @@ int linenum;
return -1;
if (!fp->fr_proto) /* to catch lusers */
fp->fr_proto = IPPROTO_ICMP;
- if (isdigit(***cp)) {
+ if (ISDIGIT(***cp)) {
if (!ratoi(**cp, &i, 0, 255)) {
fprintf(stderr,
"%d: Invalid icmp-type (%s) specified\n",
@@ -68,9 +68,9 @@ int linenum;
if (**cp && strcasecmp("code", **cp))
return 0;
(*cp)++;
- if (isdigit(***cp)) {
+ if (ISDIGIT(***cp)) {
if (!ratoi(**cp, &i, 0, 255)) {
- fprintf(stderr,
+ fprintf(stderr,
"%d: Invalid icmp code (%s) specified\n",
linenum, **cp);
return -1;
@@ -78,7 +78,7 @@ int linenum;
} else {
i = icmpcode(**cp);
if (i == -1) {
- fprintf(stderr,
+ fprintf(stderr,
"%d: Unknown icmp code (%s) specified\n",
linenum, **cp);
return -1;
diff --git a/usr/src/cmd/ipf/lib/common/checkrev.c b/usr/src/cmd/ipf/lib/common/checkrev.c
index c57295385f..f95cc7977a 100644
--- a/usr/src/cmd/ipf/lib/common/checkrev.c
+++ b/usr/src/cmd/ipf/lib/common/checkrev.c
@@ -3,21 +3,21 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: checkrev.c,v 1.9 2003/04/27 17:09:46 darrenr Exp $
+ * $Id: checkrev.c,v 1.12.2.1 2004/03/09 14:44:39 darrenr Exp $
*/
#include <sys/ioctl.h>
#include <fcntl.h>
#include "ipf.h"
-#include "ipl.h"
+#include "netinet/ipl.h"
int checkrev(ipfname)
char *ipfname;
{
+ static int vfd = -1;
struct friostat fio, *fiop = &fio;
ipfobj_t ipfo;
- int vfd;
bzero((caddr_t)&ipfo, sizeof(ipfo));
ipfo.ipfo_rev = IPFILTER_VERSION;
@@ -25,7 +25,7 @@ char *ipfname;
ipfo.ipfo_ptr = (void *)fiop;
ipfo.ipfo_type = IPFOBJ_IPFSTAT;
- if ((vfd = open(ipfname, O_RDONLY)) == -1) {
+ if ((vfd == -1) && ((vfd = open(ipfname, O_RDONLY)) == -1)) {
perror("open device");
return -1;
}
@@ -33,9 +33,9 @@ char *ipfname;
if (ioctl(vfd, SIOCGETFS, &ipfo)) {
perror("ioctl(SIOCGETFS)");
close(vfd);
+ vfd = -1;
return -1;
}
- close(vfd);
if (strncmp(IPL_VERSION, fio.f_version, sizeof(fio.f_version))) {
return -1;
diff --git a/usr/src/cmd/ipf/lib/common/facpri.c b/usr/src/cmd/ipf/lib/common/facpri.c
index eb76ee0f95..9d6faa9055 100644
--- a/usr/src/cmd/ipf/lib/common/facpri.c
+++ b/usr/src/cmd/ipf/lib/common/facpri.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: facpri.c,v 1.5 2001/06/09 17:09:24 darrenr Exp $
+ * $Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp $
*/
#include <stdio.h>
@@ -20,7 +20,7 @@
#include "facpri.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: facpri.c,v 1.5 2001/06/09 17:09:24 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp $";
#endif
@@ -35,7 +35,7 @@ table_t facs[] = {
{ "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG },
{ "lpr", LOG_LPR }, { "news", LOG_NEWS },
{ "uucp", LOG_UUCP },
-#if LOG_CRON == LOG_CRON2
+#if LOG_CRON == LOG_CRON2
{ "cron2", LOG_CRON1 },
#else
{ "cron", LOG_CRON1 },
diff --git a/usr/src/cmd/ipf/lib/common/genmask.c b/usr/src/cmd/ipf/lib/common/genmask.c
index e57a65499b..238e5b62af 100644
--- a/usr/src/cmd/ipf/lib/common/genmask.c
+++ b/usr/src/cmd/ipf/lib/common/genmask.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: genmask.c,v 1.6 2002/01/28 06:50:46 darrenr Exp $
+ * $Id: genmask.c,v 1.7 2003/11/11 13:40:15 darrenr Exp $
*/
#include "ipf.h"
diff --git a/usr/src/cmd/ipf/lib/common/gethost.c b/usr/src/cmd/ipf/lib/common/gethost.c
index bc5d8975ee..5ecea3adaf 100644
--- a/usr/src/cmd/ipf/lib/common/gethost.c
+++ b/usr/src/cmd/ipf/lib/common/gethost.c
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#include "ipf.h"
int gethost(name, hostp)
@@ -5,8 +10,14 @@ char *name;
u_32_t *hostp;
{
struct hostent *h;
+ struct netent *n;
u_32_t addr;
+ if (!strcmp(name, "test.host.dots")) {
+ *hostp = htonl(0xfedcba98);
+ return 0;
+ }
+
if (!strcmp(name, "<thishost>"))
name = thishost;
@@ -18,5 +29,11 @@ u_32_t *hostp;
return 0;
}
}
+
+ n = getnetbyname(name);
+ if (n != NULL) {
+ *hostp = (u_32_t)htonl(n->n_net & 0xffffffff);
+ return 0;
+ }
return -1;
}
diff --git a/usr/src/cmd/ipf/lib/common/getifname.c b/usr/src/cmd/ipf/lib/common/getifname.c
index 39d193dcc6..a42a4e089b 100644
--- a/usr/src/cmd/ipf/lib/common/getifname.c
+++ b/usr/src/cmd/ipf/lib/common/getifname.c
@@ -1,6 +1,16 @@
+/*
+ * Copyright (C) 2003 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
#include "ipf.h"
#include "qif.h"
-
#include "kmem.h"
/*
@@ -10,24 +20,34 @@
char *getifname(ptr)
struct ifnet *ptr;
{
-#if SOLARIS
+#if SOLARIS || defined(__hpux)
+# if SOLARIS
+# include <sys/mutex.h>
+# include <sys/condvar.h>
+# endif
+# ifdef __hpux
+# include "compat.h"
+# endif
char *ifname;
- s_ill_t ill;
+ qif_t qif;
if ((void *)ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
- if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
+ if (kmemcpy((char *)&qif, (u_long)ptr, sizeof(qif)) == -1)
return "X";
- ifname = malloc(sizeof(ill.ill_name) + 1);
- strncpy(ifname, ill.ill_name, sizeof(ill.ill_name));
- ifname[sizeof(ill.ill_name)] = '\0';
+ ifname = strdup(qif.qf_name);
+ if ((ifname != NULL) && (*ifname == '\0')) {
+ free(ifname);
+ return "!";
+ }
return ifname;
#else
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
+ defined(__OpenBSD__) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
#else
char buf[32];
int len;
@@ -42,7 +62,8 @@ struct ifnet *ptr;
if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
return "X";
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
+ defined(__OpenBSD__) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
return strdup(netif.if_xname);
# else
if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
diff --git a/usr/src/cmd/ipf/lib/common/getnattype.c b/usr/src/cmd/ipf/lib/common/getnattype.c
index d3b32d2d77..312a862c3e 100644
--- a/usr/src/cmd/ipf/lib/common/getnattype.c
+++ b/usr/src/cmd/ipf/lib/common/getnattype.c
@@ -9,7 +9,7 @@
#include "kmem.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: getnattype.c,v 1.2 2002/01/28 06:50:46 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: getnattype.c,v 1.3 2004/01/17 17:26:07 darrenr Exp $";
#endif
@@ -23,9 +23,10 @@ ipnat_t *ipnat;
ipnat_t ipnatbuff;
char *which;
- if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat,
- sizeof(ipnatbuff))))
+ if (!ipnat)
return "???";
+ if (kmemcpy((char *)&ipnatbuff, (long)ipnat, sizeof(ipnatbuff)))
+ return "!!!";
switch (ipnatbuff.in_redir)
{
diff --git a/usr/src/cmd/ipf/lib/common/getport.c b/usr/src/cmd/ipf/lib/common/getport.c
index 9e77c665d3..415522ffc0 100644
--- a/usr/src/cmd/ipf/lib/common/getport.c
+++ b/usr/src/cmd/ipf/lib/common/getport.c
@@ -1,8 +1,14 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#include "ipf.h"
-int getport(fr, name)
+int getport(fr, name, port)
frentry_t *fr;
char *name;
+u_short *port;
{
struct protoent *p;
struct servent *s;
@@ -10,8 +16,10 @@ char *name;
if (fr == NULL || fr->fr_type != FR_T_IPF) {
s = getservbyname(name, NULL);
- if (s != NULL)
- return s->s_port;
+ if (s != NULL) {
+ *port = s->s_port;
+ return 0;
+ }
return -1;
}
@@ -27,13 +35,15 @@ char *name;
s = getservbyname(name, "udp");
if (s == NULL || s->s_port != p1)
return -1;
- return p1;
+ *port = p1;
+ return 0;
}
p = getprotobynumber(fr->fr_proto);
s = getservbyname(name, p ? p->p_name : NULL);
- if (s != NULL)
- return s->s_port;
-
+ if (s != NULL) {
+ *port = s->s_port;
+ return 0;
+ }
return -1;
}
diff --git a/usr/src/cmd/ipf/lib/common/getportproto.c b/usr/src/cmd/ipf/lib/common/getportproto.c
index 6237e39ab9..ae04229c67 100644
--- a/usr/src/cmd/ipf/lib/common/getportproto.c
+++ b/usr/src/cmd/ipf/lib/common/getportproto.c
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#include <ctype.h>
#include "ipf.h"
@@ -8,14 +13,23 @@ int proto;
struct servent *s;
struct protoent *p;
- if (isdigit(*name) && atoi(name) > 0)
- return htons(atoi(name) & 65535);
+ if (ISDIGIT(*name)) {
+ int number;
+ char *s;
- p = getprotobynumber(proto);
- if (p != NULL) {
- s = getservbyname(name, p->p_name);
- if (s != NULL)
- return s->s_port;
+ for (s = name; *s != '\0'; s++)
+ if (!ISDIGIT(*s))
+ return -1;
+
+ number = atoi(name);
+ if (number < 0 || number > 65535)
+ return -1;
+ return htons(number);
}
- return 0;
+
+ p = getprotobynumber(proto);
+ s = getservbyname(name, p ? p->p_name : NULL);
+ if (s != NULL)
+ return s->s_port;
+ return -1;
}
diff --git a/usr/src/cmd/ipf/lib/common/getproto.c b/usr/src/cmd/ipf/lib/common/getproto.c
index 43a3029f47..472fe148ab 100644
--- a/usr/src/cmd/ipf/lib/common/getproto.c
+++ b/usr/src/cmd/ipf/lib/common/getproto.c
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#include "ipf.h"
int getproto(name)
@@ -7,11 +12,19 @@ char *name;
char *s;
for (s = name; *s != '\0'; s++)
- if (!isdigit(*s))
+ if (!ISDIGIT(*s))
break;
if (*s == '\0')
return atoi(name);
+#ifdef _AIX51
+ /*
+ * For some bogus reason, "ip" is 252 in /etc/protocols on AIX 5
+ */
+ if (!strcasecmp(name, "ip"))
+ return 0;
+#endif
+
p = getprotobyname(name);
if (p != NULL)
return p->p_proto;
diff --git a/usr/src/cmd/ipf/lib/common/hostname.c b/usr/src/cmd/ipf/lib/common/hostname.c
index d0c8b490fe..4bca028c16 100644
--- a/usr/src/cmd/ipf/lib/common/hostname.c
+++ b/usr/src/cmd/ipf/lib/common/hostname.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -15,17 +15,43 @@ char *hostname(v, ip)
int v;
void *ip;
{
-#ifdef USE_INET6
- static char hostbuf[INET6_ADDRSTRLEN];
-#endif
+ static char hostbuf[MAXHOSTNAMELEN+1];
+ struct hostent *hp;
struct in_addr ipa;
+ struct netent *np;
if (v == 4) {
ipa.s_addr = *(u_32_t *)ip;
+ if (ipa.s_addr == htonl(0xfedcba98))
+ return "test.host.dots";
+ }
+
+ if ((opts & OPT_NORESOLVE) == 0) {
+ if (v == 4) {
+ hp = gethostbyaddr(ip, 4, AF_INET);
+ if (hp != NULL && hp->h_name != NULL &&
+ *hp->h_name != '\0') {
+ strncpy(hostbuf, hp->h_name, sizeof(hostbuf));
+ hostbuf[sizeof(hostbuf) - 1] = '\0';
+ return hostbuf;
+ }
+
+ np = getnetbyaddr(ipa.s_addr, AF_INET);
+ if (np != NULL && np->n_name != NULL &&
+ *np->n_name != '\0') {
+ strncpy(hostbuf, np->n_name, sizeof(hostbuf));
+ hostbuf[sizeof(hostbuf) - 1] = '\0';
+ return hostbuf;
+ }
+ }
+ }
+
+ if (v == 4) {
return inet_ntoa(ipa);
}
#ifdef USE_INET6
- (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf));
+ (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
+ hostbuf[MAXHOSTNAMELEN] = '\0';
return hostbuf;
#else
return "IPv6";
diff --git a/usr/src/cmd/ipf/lib/common/hostnum.c b/usr/src/cmd/ipf/lib/common/hostnum.c
index edef2997dd..2ec0529a29 100644
--- a/usr/src/cmd/ipf/lib/common/hostnum.c
+++ b/usr/src/cmd/ipf/lib/common/hostnum.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: hostnum.c,v 1.8 2002/01/28 06:50:46 darrenr Exp $
+ * $Id: hostnum.c,v 1.10.2.1 2004/12/09 19:41:20 darrenr Exp $
*/
#include <ctype.h>
@@ -21,13 +21,12 @@ char *host;
int linenum;
char *ifname;
{
- struct hostent *hp;
- struct netent *np;
struct in_addr ip;
if (!strcasecmp("any", host) ||
(ifname && *ifname && !strcasecmp(ifname, host)))
return 0;
+
#ifdef USE_INET6
if (use_inet6) {
if (inet_pton(AF_INET6, host, ipa) == 1)
@@ -36,7 +35,7 @@ char *ifname;
return -1;
}
#endif
- if (isdigit(*host) && inet_aton(host, &ip)) {
+ if (ISDIGIT(*host) && inet_aton(host, &ip)) {
*ipa = ip.s_addr;
return 0;
}
@@ -44,15 +43,5 @@ char *ifname;
if (!strcasecmp("<thishost>", host))
host = thishost;
- if (!(hp = gethostbyname(host))) {
- if (!(np = getnetbyname(host))) {
- fprintf(stderr, "%d: can't resolve hostname: %s\n",
- linenum, host);
- return -1;
- }
- *ipa = htonl(np->n_net);
- return 0;
- }
- *ipa = *(u_32_t *)hp->h_addr;
- return 0;
+ return gethost(host, ipa);
}
diff --git a/usr/src/cmd/ipf/lib/common/icmpcode.c b/usr/src/cmd/ipf/lib/common/icmpcode.c
index 1dac556cec..fd1e647687 100644
--- a/usr/src/cmd/ipf/lib/common/icmpcode.c
+++ b/usr/src/cmd/ipf/lib/common/icmpcode.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: icmpcode.c,v 1.6 2001/06/09 17:09:24 darrenr Exp $
+ * $Id: icmpcode.c,v 1.7.2.1 2004/12/09 19:41:20 darrenr Exp $
*/
#include <ctype.h>
@@ -18,7 +18,7 @@
char *icmpcodes[MAX_ICMPCODE + 1] = {
"net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail",
"net-unk", "host-unk", "isolate", "net-prohib", "host-prohib",
- "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff",
+ "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff",
NULL };
/*
@@ -32,7 +32,7 @@ char *str;
if ((s = strrchr(str, ')')))
*s = '\0';
- if (isdigit(*str)) {
+ if (ISDIGIT(*str)) {
if (!ratoi(str, &i, 0, 255))
return -1;
else
diff --git a/usr/src/cmd/ipf/lib/common/inet_addr.c b/usr/src/cmd/ipf/lib/common/inet_addr.c
index 5c91169141..820b7b58a4 100644
--- a/usr/src/cmd/ipf/lib/common/inet_addr.c
+++ b/usr/src/cmd/ipf/lib/common/inet_addr.c
@@ -3,7 +3,7 @@
* -
* Copyright (c) 1983, 1990, 1993
* The Regents of the University of California. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +33,14 @@
* SUCH DAMAGE.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ *
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -55,7 +55,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-static const char rcsid[] = "@(#)$Id: inet_addr.c,v 1.4 2002/02/21 09:25:42 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: inet_addr.c,v 1.8.2.3 2004/12/09 19:41:20 darrenr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -70,9 +70,24 @@ static const char rcsid[] = "@(#)$Id: inet_addr.c,v 1.4 2002/02/21 09:25:42 darr
# define __P(x) ()
# endif
#endif
+#ifndef linux
int inet_aton __P((const char *, struct in_addr *));
-/*
+/*
+ * Because the ctype(3) posix definition, if used "safely" in code everywhere,
+ * would mean all normal code that walks through strings needed casts. Yuck.
+ */
+#define ISALNUM(x) isalnum((u_char)(x))
+#define ISALPHA(x) isalpha((u_char)(x))
+#define ISASCII(x) isascii((u_char)(x))
+#define ISDIGIT(x) isdigit((u_char)(x))
+#define ISPRINT(x) isprint((u_char)(x))
+#define ISSPACE(x) isspace((u_char)(x))
+#define ISUPPER(x) isupper((u_char)(x))
+#define ISXDIGIT(x) isxdigit((u_char)(x))
+#define ISLOWER(x) islower((u_char)(x))
+
+/*
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
@@ -97,7 +112,7 @@ inet_aton(cp, addr)
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
- if (!isdigit(c))
+ if (!ISDIGIT(c))
return (0);
val = 0; base = 10;
if (c == '0') {
@@ -108,12 +123,12 @@ inet_aton(cp, addr)
base = 8;
}
for (;;) {
- if (isascii(c) && isdigit(c)) {
+ if (ISASCII(c) && ISDIGIT(c)) {
val = (val * base) + (c - '0');
c = *++cp;
- } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ } else if (base == 16 && ISASCII(c) && ISXDIGIT(c)) {
val = (val << 4) |
- (c + 10 - (islower(c) ? 'a' : 'A'));
+ (c + 10 - (ISLOWER(c) ? 'a' : 'A'));
c = *++cp;
} else
break;
@@ -135,7 +150,7 @@ inet_aton(cp, addr)
/*
* Check for trailing characters.
*/
- if (c != '\0' && (!isascii(c) || !isspace(c)))
+ if (c != '\0' && (!ISASCII(c) || !ISSPACE(c)))
return (0);
/*
* Concoct the address according to
@@ -172,6 +187,7 @@ inet_aton(cp, addr)
addr->s_addr = htonl(val);
return (1);
}
+#endif
/* these are compatibility routines, not needed on recent BSD releases */
@@ -179,16 +195,9 @@ inet_aton(cp, addr)
* Ascii internet address interpretation routine.
* The value returned is in network order.
*/
-#if (defined(SOLARIS2) && (SOLARIS2 > 5)) || defined(__hpux) || \
- defined(__osf__) || (defined(IRIX) && (IRIX >= 605)) || \
- (defined(__FreeBSD__) && (__FreeBSD__ >= 4)) || \
- defined(__OpenBSD__)
-in_addr_t
-#else
-u_long
-#endif
+#if 0
inet_addr(cp)
- register const char *cp;
+ const char *cp;
{
struct in_addr val;
@@ -196,3 +205,4 @@ inet_addr(cp)
return (val.s_addr);
return (0xffffffff);
}
+#endif
diff --git a/usr/src/cmd/ipf/lib/common/ipf_dotuning.c b/usr/src/cmd/ipf/lib/common/ipf_dotuning.c
new file mode 100644
index 0000000000..0746bd1e67
--- /dev/null
+++ b/usr/src/cmd/ipf/lib/common/ipf_dotuning.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+#include "netinet/ipl.h"
+#include <sys/ioctl.h>
+
+void ipf_dotuning(fd, tuneargs, iocfn)
+int fd;
+char *tuneargs;
+ioctlfunc_t iocfn;
+{
+ ipfobj_t obj;
+ ipftune_t tu;
+ char *s, *t;
+
+ bzero((char *)&tu, sizeof(tu));
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = sizeof(tu);;
+ obj.ipfo_ptr = (void *)&tu;
+ obj.ipfo_type = IPFOBJ_TUNEABLE;
+
+ for (s = strtok(tuneargs, ","); s != NULL; s = strtok(NULL, ",")) {
+ if (!strcmp(s, "list")) {
+ while (1) {
+ if ((*iocfn)(fd, SIOCIPFGETNEXT, &obj) == -1) {
+ perror("ioctl(SIOCIPFGETNEXT)");
+ break;
+ }
+ if (tu.ipft_cookie == NULL)
+ break;
+
+ tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0';
+ printtunable(&tu);
+ }
+ } else if ((t = strchr(s, '=')) != NULL) {
+ tu.ipft_cookie = NULL;
+ *t++ = '\0';
+ strncpy(tu.ipft_name, s, sizeof(tu.ipft_name));
+ if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) {
+ if ((*iocfn)(fd, SIOCIPFSET, &obj) == -1) {
+ perror("ioctl(SIOCIPFSET)");
+ return;
+ }
+ } else {
+ fprintf(stderr, "invalid value '%s'\n", s);
+ return;
+ }
+ } else {
+ tu.ipft_cookie = NULL;
+ strncpy(tu.ipft_name, s, sizeof(tu.ipft_name));
+ if ((*iocfn)(fd, SIOCIPFGET, &obj) == -1) {
+ perror("ioctl(SIOCIPFGET)");
+ return;
+ }
+ if (tu.ipft_cookie == NULL) {
+ fprintf(stderr, "Null cookie for %s\n", s);
+ return;
+ }
+
+ tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0';
+ printtunable(&tu);
+ }
+ }
+}
diff --git a/usr/src/cmd/ipf/lib/common/ipft_ef.c b/usr/src/cmd/ipf/lib/common/ipft_ef.c
index 411dc51a91..237febcb4b 100644
--- a/usr/src/cmd/ipf/lib/common/ipft_ef.c
+++ b/usr/src/cmd/ipf/lib/common/ipft_ef.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ipft_ef.c,v 1.11 2003/06/02 12:22:49 darrenr Exp $
+ * $Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp $
*/
/*
@@ -23,16 +23,15 @@ etherfind -n -t
#include "ipf.h"
#include "ipt.h"
-#undef ICMP_MAXTYPE
-#include <netinet/ip_icmp.h>
+#ifndef linux
#include <netinet/ip_var.h>
-#include <netinet/udp.h>
+#endif
#include <netinet/tcpip.h>
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 1.11 2003/06/02 12:22:49 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp $";
#endif
static int etherf_open __P((char *));
diff --git a/usr/src/cmd/ipf/lib/common/ipft_hx.c b/usr/src/cmd/ipf/lib/common/ipft_hx.c
index 3a02700206..fa5923b756 100644
--- a/usr/src/cmd/ipf/lib/common/ipft_hx.c
+++ b/usr/src/cmd/ipf/lib/common/ipft_hx.c
@@ -5,7 +5,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 1.11 2003/02/16 02:32:35 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 1.11.4.1 2004/12/09 19:41:20 darrenr Exp $";
#endif
#include <ctype.h>
@@ -111,7 +111,7 @@ int cnt, *dir;
if (t < (char *)ip)
putchar('\t');
while (t < (char *)ip) {
- if (isprint(*t) && isascii(*t))
+ if (ISPRINT(*t) && ISASCII(*t))
putchar(*t);
else
putchar('.');
@@ -133,7 +133,7 @@ register char *src, *dst;
char c;
while ((c = *src++)) {
- if (isspace(c)) {
+ if (ISSPACE(c)) {
if (state) {
dst++;
state = 0;
@@ -141,7 +141,7 @@ register char *src, *dst;
continue;
} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F')) {
- c = isdigit(c) ? (c - '0') : (toupper(c) - 55);
+ c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55);
if (state == 0) {
*dst = (c << 4);
state++;
diff --git a/usr/src/cmd/ipf/lib/common/ipft_pc.c b/usr/src/cmd/ipf/lib/common/ipft_pc.c
index 92b482bfaa..3042a3976c 100644
--- a/usr/src/cmd/ipf/lib/common/ipft_pc.c
+++ b/usr/src/cmd/ipf/lib/common/ipft_pc.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ipft_pc.c,v 1.9 2003/02/16 02:32:36 darrenr Exp $
+ * $Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp $
*/
#include "ipf.h"
#include "pcap-ipf.h"
@@ -11,7 +11,7 @@
#include "ipt.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 1.9 2003/02/16 02:32:36 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp $";
#endif
struct llc {
@@ -75,7 +75,7 @@ static int pcap_readip __P((char *, int, char **, int *));
static void swap_hdr __P((pcaphdr_t *));
static int pcap_read_rec __P((struct pcap_pkthdr *));
-static int pfd = -1, s_type = -1, swapped = 0;
+static int pfd = -1, swapped = 0;
static struct llc *llcp = NULL;
struct ipread pcap = { pcap_open, pcap_close, pcap_readip, 0 };
@@ -139,7 +139,6 @@ char *fname;
}
pfd = fd;
- s_type = ph.pc_type;
printf("opened pcap file %s:\n", fname);
printf("\tid: %08x version: %d.%d type: %d snap %d\n",
ph.pc_id, ph.pc_v_maj, ph.pc_v_min, ph.pc_type, ph.pc_slen);
diff --git a/usr/src/cmd/ipf/lib/common/ipft_td.c b/usr/src/cmd/ipf/lib/common/ipft_td.c
index acc3631e46..1aa616670a 100644
--- a/usr/src/cmd/ipf/lib/common/ipft_td.c
+++ b/usr/src/cmd/ipf/lib/common/ipft_td.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ipft_td.c,v 1.11 2003/06/03 16:01:01 darrenr Exp $
+ * $Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp $
*/
/*
@@ -32,16 +32,15 @@ tcpdump -nqte
#include "ipf.h"
#include "ipt.h"
-#undef ICMP_MAXTYPE
-#include <netinet/ip_icmp.h>
+#ifndef linux
#include <netinet/ip_var.h>
-#include <netinet/udp.h>
+#endif
#include <netinet/tcpip.h>
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.11 2003/06/03 16:01:01 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp $";
#endif
static int tcpd_open __P((char *));
@@ -97,7 +96,6 @@ int cnt, *dir;
{
struct tcpiphdr pkt;
ip_t *ip = (ip_t *)&pkt;
- struct protoent *p;
char src[32], dst[32], misc[256], time[32], link1[32], link2[32];
char lbuf[160], *s;
int n, slen, extra = 0;
diff --git a/usr/src/cmd/ipf/lib/common/ipft_tx.c b/usr/src/cmd/ipf/lib/common/ipft_tx.c
index 3d0f5800ce..82eca169d8 100644
--- a/usr/src/cmd/ipf/lib/common/ipft_tx.c
+++ b/usr/src/cmd/ipf/lib/common/ipft_tx.c
@@ -3,11 +3,11 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ipft_tx.c,v 1.11 2003/02/16 02:32:01 darrenr Exp $
+ * $Id: ipft_tx.c,v 1.15.2.3 2005/06/18 02:41:34 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.11 2003/02/16 02:32:01 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.3 2005/06/18 02:41:34 darrenr Exp $";
#endif
#include <ctype.h>
@@ -15,10 +15,9 @@ static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.11 2003/02/16 02:32:01 darre
#include "ipf.h"
#include "ipt.h"
-#undef ICMP_MAXTYPE
-#include <netinet/ip_icmp.h>
+#ifndef linux
#include <netinet/ip_var.h>
-#include <netinet/udp.h>
+#endif
#include <netinet/tcpip.h>
@@ -30,8 +29,8 @@ static int text_open __P((char *)), text_close __P((void));
static int text_readip __P((char *, int, char **, int *));
static int parseline __P((char *, ip_t *, char **, int *));
-static char _tcp_flagset[] = "FSRPAUEC";
-static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
+static char myflagset[] = "FSRPAUEC";
+static u_char myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
TH_ACK, TH_URG, TH_ECN, TH_CWR };
struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM };
@@ -50,24 +49,20 @@ static u_32_t tx_hostnum(host, resolved)
char *host;
int *resolved;
{
- struct hostent *hp;
- struct netent *np;
+ u_32_t ipa;
*resolved = 0;
- if (!strcasecmp("any",host))
+ if (!strcasecmp("any", host))
return 0L;
- if (isdigit(*host))
+ if (ISDIGIT(*host))
return inet_addr(host);
- if (!(hp = gethostbyname(host))) {
- if (!(np = getnetbyname(host))) {
- *resolved = -1;
- fprintf(stderr, "can't resolve hostname: %s\n", host);
- return 0;
- }
- return htonl(np->n_net);
+ if (gethost(host, &ipa) == -1) {
+ *resolved = -1;
+ fprintf(stderr, "can't resolve hostname: %s\n", host);
+ return 0;
}
- return *(u_32_t *)hp->h_addr;
+ return ipa;
}
@@ -81,7 +76,7 @@ char *name;
struct servent *sp, *sp2;
u_short p1 = 0;
- if (isdigit(*name))
+ if (ISDIGIT(*name))
return (u_short)atoi(name);
if (!tx_proto)
tx_proto = "tcp/udp";
@@ -205,11 +200,11 @@ int *out;
return 1;
c = **cpp;
- if (!isalpha(c) || (tolower(c) != 'o' && tolower(c) != 'i')) {
+ if (!ISALPHA(c) || (TOLOWER(c) != 'o' && TOLOWER(c) != 'i')) {
fprintf(stderr, "bad direction \"%s\"\n", *cpp);
return 1;
}
- *out = (tolower(c) == 'o') ? 1 : 0;
+ *out = (TOLOWER(c) == 'o') ? 1 : 0;
cpp++;
if (!*cpp)
return 1;
@@ -241,7 +236,7 @@ int *out;
tx_proto = "icmp";
}
cpp++;
- } else if (isdigit(**cpp) && !index(*cpp, '.')) {
+ } else if (ISDIGIT(**cpp) && !index(*cpp, '.')) {
ip->ip_p = atoi(*cpp);
cpp++;
} else
@@ -259,6 +254,10 @@ int *out;
}
*last++ = '\0';
tcp->th_sport = htons(tx_portnum(last));
+ if (ip->ip_p == IPPROTO_TCP) {
+ tcp->th_win = htons(4096);
+ TCP_OFF_A(tcp, sizeof(*tcp) >> 2);
+ }
}
ip->ip_src.s_addr = tx_hostnum(*cpp, &r);
cpp++;
@@ -279,19 +278,18 @@ int *out;
ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);
cpp++;
if (*cpp && ip->ip_p == IPPROTO_TCP) {
- extern char _tcp_flagset[];
- extern u_char _tcp_flags[];
char *s, *t;
+ tcp->th_flags = 0;
for (s = *cpp; *s; s++)
- if ((t = strchr(_tcp_flagset, *s)))
- tcp->th_flags |= _tcp_flags[t - _tcp_flagset];
+ if ((t = strchr(myflagset, *s)))
+ tcp->th_flags |= myflags[t - myflagset];
if (tcp->th_flags)
cpp++;
if (tcp->th_flags == 0)
abort();
- tcp->th_win = htons(4096);
- TCP_OFF_A(tcp, sizeof(*tcp) >> 2);
+ if (tcp->th_flags & TH_URG)
+ tcp->th_urp = htons(1);
} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {
extern char *tx_icmptypes[];
char **s, *t;
diff --git a/usr/src/cmd/ipf/lib/common/kmem.c b/usr/src/cmd/ipf/lib/common/kmem.c
index a90b897cf7..3142d68011 100644
--- a/usr/src/cmd/ipf/lib/common/kmem.c
+++ b/usr/src/cmd/ipf/lib/common/kmem.c
@@ -9,7 +9,7 @@
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -23,7 +23,7 @@
#include <string.h>
#include <fcntl.h>
#include <sys/file.h>
-#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__)
+#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51)
#include <kvm.h>
#endif
#include <fcntl.h>
@@ -37,6 +37,9 @@
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
+#if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux)
+# include <stdlib.h>
+#endif
#include "kmem.h"
@@ -46,12 +49,13 @@
#if !defined(lint)
static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
-static const char rcsid[] = "@(#)$Id: kmem.c,v 1.11 2003/06/02 12:22:29 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp $";
#endif
-#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__)
+#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \
+ !defined(linux) && !defined(_AIX51)
/*
* For all platforms where there is a libkvm and a kvm_t, we use that...
*/
@@ -62,17 +66,21 @@ static kvm_t *kvm_f = NULL;
*...and for the others (HP-UX, IRIX, Tru64), we have to provide our own.
*/
-typedef int kvm_t;
+typedef int * kvm_t;
-static kvm_t kvm_f = -1;
+static kvm_t kvm_f = NULL;
static char *kvm_errstr = NULL;
+kvm_t kvm_open __P((char *, char *, char *, int, char *));
+int kvm_read __P((kvm_t, u_long, char *, size_t));
+
kvm_t kvm_open(kernel, core, swap, mode, errstr)
char *kernel, *core, *swap;
int mode;
char *errstr;
{
- kvm_t fd;
+ kvm_t k;
+ int fd;
kvm_errstr = errstr;
@@ -80,7 +88,15 @@ char *errstr;
core = "/dev/kmem";
fd = open(core, mode);
- return fd;
+ if (fd == -1)
+ return NULL;
+ k = malloc(sizeof(*k));
+ if (k == NULL) {
+ close(fd);
+ return NULL;
+ }
+ *k = fd;
+ return k;
}
int kvm_read(kvm, pos, buffer, size)
@@ -89,10 +105,10 @@ u_long pos;
char *buffer;
size_t size;
{
- int r, left;
+ int r = 0, left;
char *bufp;
- if (lseek(kvm, pos, 0) == -1) {
+ if (lseek(*kvm, pos, 0) == -1) {
if (kvm_errstr != NULL) {
fprintf(stderr, "%s", kvm_errstr);
perror("lseek");
@@ -101,19 +117,19 @@ size_t size;
}
for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
- r = read(kvm, bufp, 1);
+ r = read(*kvm, bufp, left);
#ifdef __osf__
/*
* Tru64 returns "0" for successful operation, not the number
* of bytes read.
*/
- return r;
-#else
+ if (r == 0)
+ r = left;
+#endif
if (r <= 0)
return -1;
-#endif
}
- return 0;
+ return r;
}
#endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */
@@ -126,7 +142,7 @@ char *kern, *core;
perror("openkmem:open");
return -1;
}
- return 0;
+ return kvm_f != NULL;
}
int kmemcpy(buf, pos, n)
@@ -179,7 +195,7 @@ register int n;
if (r <= 0)
{
fprintf(stderr, "pos=0x%lx ", (u_long)pos);
- perror("kstrncpy:read");
+ perror("kmemcpy:read");
return -1;
}
else
diff --git a/usr/src/cmd/ipf/lib/common/load_hash.c b/usr/src/cmd/ipf/lib/common/load_hash.c
index a86052478e..e43ddf54a3 100644
--- a/usr/src/cmd/ipf/lib/common/load_hash.c
+++ b/usr/src/cmd/ipf/lib/common/load_hash.c
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: load_hash.c,v 1.10 2003/04/26 04:55:11 darrenr Exp $
+ * $Id: load_hash.c,v 1.11.2.2 2005/02/01 02:44:05 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -14,13 +14,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
static int hashfd = -1;
@@ -40,8 +35,6 @@ ioctlfunc_t iocfunc;
hashfd = open(IPLOOKUP_NAME, O_RDWR);
if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0))
return -1;
- if (list == NULL)
- return 0;
for (n = 0, a = list; a != NULL; a = a->ipe_next)
n++;
@@ -58,20 +51,29 @@ ioctlfunc_t iocfunc;
iph.iph_type = iphp->iph_type;
strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name));
iph.iph_flags = iphp->iph_flags;
+ if (n <= 0)
+ n = 1;
if (iphp->iph_size == 0)
size = n * 2 - 1;
else
size = iphp->iph_size;
+ if ((list == NULL) && (size == 1)) {
+ fprintf(stderr,
+ "WARNING: empty hash table %s, recommend setting %s\n",
+ iphp->iph_name, "size to match expected use");
+ }
iph.iph_size = size;
iph.iph_seed = iphp->iph_seed;
iph.iph_table = NULL;
iph.iph_ref = 0;
- if ((*iocfunc)(hashfd, SIOCLOOKUPADDTABLE, &op))
- if ((opts & OPT_DONOTHING) == 0) {
- perror("load_hash:SIOCLOOKUPADDTABLE");
- return -1;
- }
+ if ((opts & OPT_REMOVE) == 0) {
+ if ((*iocfunc)(hashfd, SIOCLOOKUPADDTABLE, &op))
+ if ((opts & OPT_DONOTHING) == 0) {
+ perror("load_hash:SIOCLOOKUPADDTABLE");
+ return -1;
+ }
+ }
strncpy(op.iplo_name, iph.iph_name, sizeof(op.iplo_name));
strncpy(iphp->iph_name, iph.iph_name, sizeof(op.iplo_name));
@@ -89,7 +91,7 @@ ioctlfunc_t iocfunc;
return -1;
}
iph.iph_table[0] = list;
- printhash(&iph, bcopywrap, opts);
+ printhash(&iph, bcopywrap, iph.iph_name, opts);
free(iph.iph_table);
for (a = list; a != NULL; a = a->ipe_next) {
@@ -106,5 +108,12 @@ ioctlfunc_t iocfunc;
for (a = list; a != NULL; a = a->ipe_next)
load_hashnode(iphp->iph_unit, iph.iph_name, a, iocfunc);
+ if ((opts & OPT_REMOVE) != 0) {
+ if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op))
+ if ((opts & OPT_DONOTHING) == 0) {
+ perror("load_hash:SIOCLOOKUPDELTABLE");
+ return -1;
+ }
+ }
return 0;
}
diff --git a/usr/src/cmd/ipf/lib/common/load_hashnode.c b/usr/src/cmd/ipf/lib/common/load_hashnode.c
index c072031abc..8cf1bb2c67 100644
--- a/usr/src/cmd/ipf/lib/common/load_hashnode.c
+++ b/usr/src/cmd/ipf/lib/common/load_hashnode.c
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: load_hashnode.c,v 1.2 2003/04/26 04:55:11 darrenr Exp $
+ * $Id: load_hashnode.c,v 1.2.4.1 2004/03/06 14:33:28 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -14,14 +14,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
static int hashfd = -1;
@@ -34,6 +28,7 @@ ioctlfunc_t iocfunc;
{
iplookupop_t op;
iphtent_t ipe;
+ int err;
if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0))
hashfd = open(IPLOOKUP_NAME, O_RDWR);
@@ -56,9 +51,14 @@ ioctlfunc_t iocfunc;
bcopy((char *)&node->ipe_group, (char *)&ipe.ipe_group,
sizeof(ipe.ipe_group));
- if ((*iocfunc)(hashfd, SIOCLOOKUPADDNODE, &op))
+ if ((opts & OPT_REMOVE) == 0)
+ err = (*iocfunc)(hashfd, SIOCLOOKUPADDNODE, &op);
+ else
+ err = (*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op);
+
+ if (err != 0)
if (!(opts & OPT_DONOTHING)) {
- perror("load_hash:SIOCLOOKUPADDNODE");
+ perror("load_hash:SIOCLOOKUP*NODE");
return -1;
}
return 0;
diff --git a/usr/src/cmd/ipf/lib/common/load_pool.c b/usr/src/cmd/ipf/lib/common/load_pool.c
index e87db99119..d27b6c381b 100644
--- a/usr/src/cmd/ipf/lib/common/load_pool.c
+++ b/usr/src/cmd/ipf/lib/common/load_pool.c
@@ -3,19 +3,14 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: load_pool.c,v 1.12 2003/04/26 04:55:11 darrenr Exp $
+ * $Id: load_pool.c,v 1.14.2.2 2005/02/01 02:44:06 darrenr Exp $
*/
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_pool.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
-#endif
static int poolfd = -1;
@@ -44,20 +39,29 @@ ioctlfunc_t iocfunc;
if (*plp->ipo_name == '\0')
op.iplo_arg |= IPOOL_ANON;
- if ((*iocfunc)(poolfd, SIOCLOOKUPADDTABLE, &op))
- if ((opts & OPT_DONOTHING) == 0) {
- perror("load_pool:SIOCLOOKUPADDTABLE");
- return -1;
- }
+ if ((opts & OPT_REMOVE) == 0) {
+ if ((*iocfunc)(poolfd, SIOCLOOKUPADDTABLE, &op))
+ if ((opts & OPT_DONOTHING) == 0) {
+ perror("load_pool:SIOCLOOKUPADDTABLE");
+ return -1;
+ }
+ }
if ((opts & OPT_VERBOSE) != 0) {
pool.ipo_list = plp->ipo_list;
- printpool(&pool, bcopywrap, opts);
+ printpool(&pool, bcopywrap, pool.ipo_name, opts);
pool.ipo_list = NULL;
}
for (a = plp->ipo_list; a != NULL; a = a->ipn_next)
load_poolnode(plp->ipo_unit, plp->ipo_name, a, iocfunc);
+ if ((opts & OPT_REMOVE) != 0) {
+ if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op))
+ if ((opts & OPT_DONOTHING) == 0) {
+ perror("load_pool:SIOCLOOKUPDELTABLE");
+ return -1;
+ }
+ }
return 0;
}
diff --git a/usr/src/cmd/ipf/lib/common/load_poolnode.c b/usr/src/cmd/ipf/lib/common/load_poolnode.c
index 50c06b538d..e992a80281 100644
--- a/usr/src/cmd/ipf/lib/common/load_poolnode.c
+++ b/usr/src/cmd/ipf/lib/common/load_poolnode.c
@@ -3,20 +3,14 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: load_poolnode.c,v 1.2 2003/04/26 04:55:11 darrenr Exp $
+ * $Id: load_poolnode.c,v 1.3.2.1 2004/03/06 14:33:29 darrenr Exp $
*/
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_pool.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
-#endif
static int poolfd = -1;
@@ -29,6 +23,7 @@ ioctlfunc_t iocfunc;
{
ip_pool_node_t pn;
iplookupop_t op;
+ int err;
if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0))
poolfd = open(IPLOOKUP_NAME, O_RDWR);
@@ -50,9 +45,14 @@ ioctlfunc_t iocfunc;
pn.ipn_info = node->ipn_info;
strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name));
- if ((*iocfunc)(poolfd, SIOCLOOKUPADDNODE, &op)) {
+ if ((opts & OPT_REMOVE) == 0)
+ err = (*iocfunc)(poolfd, SIOCLOOKUPADDNODE, &op);
+ else
+ err = (*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op);
+
+ if (err != 0) {
if ((opts & OPT_DONOTHING) == 0) {
- perror("load_pool:SIOCLOOKUPADDNODE");
+ perror("load_pool:SIOCLOOKUP*NODE");
return -1;
}
}
diff --git a/usr/src/cmd/ipf/lib/common/natparse.c b/usr/src/cmd/ipf/lib/common/natparse.c
index b6dd7318a5..9937380f35 100644
--- a/usr/src/cmd/ipf/lib/common/natparse.c
+++ b/usr/src/cmd/ipf/lib/common/natparse.c
@@ -5,7 +5,7 @@
*/
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$Id: natparse.c,v 1.6 2002/11/09 14:08:04 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: natparse.c,v 1.8.2.1 2004/12/09 19:41:21 darrenr Exp $";
#endif
#include <sys/ioctl.h>
@@ -55,7 +55,7 @@ int linenum;
*s = '\0';
if ((s = strchr(line, '#')))
*s = '\0';
- while (*line && isspace(*line))
+ while (*line && ISSPACE(*line))
line++;
if (!*line)
return NULL;
@@ -223,7 +223,7 @@ int linenum;
return NULL;
}
- if (isdigit(**cpp) && (s = strchr(*cpp, '-')))
+ if (ISDIGIT(**cpp) && (s = strchr(*cpp, '-')))
*s++ = '\0';
else
s = NULL;
@@ -357,7 +357,7 @@ int linenum;
return NULL;
ipn.in_pnext = htons(ipn.in_pnext);
cpp++;
- }
+ }
if (dnetm && *dnetm == '/')
*dnetm++ = '\0';
@@ -559,7 +559,7 @@ int linenum;
}
*t++ = '\0';
- if (!icmpidnum(*cpp, &ipn.in_pmin, linenum) ||
+ if (!icmpidnum(*cpp, &ipn.in_pmin, linenum) ||
!icmpidnum(t, &ipn.in_pmax, linenum))
return NULL;
} else if (!strcasecmp(*cpp, "portmap")) {
diff --git a/usr/src/cmd/ipf/lib/common/portname.c b/usr/src/cmd/ipf/lib/common/portname.c
index 7e9586ee47..7136d8c017 100644
--- a/usr/src/cmd/ipf/lib/common/portname.c
+++ b/usr/src/cmd/ipf/lib/common/portname.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: portname.c,v 1.6 2002/01/28 06:50:47 darrenr Exp $
+ * $Id: portname.c,v 1.7 2003/08/14 14:27:43 darrenr Exp $
*/
#include "ipf.h"
@@ -15,21 +15,23 @@ int pr, port;
struct protoent *p = NULL;
struct servent *sv = NULL, *sv1 = NULL;
- if (pr == -1) {
- if ((sv = getservbyport(htons(port), "tcp"))) {
- strncpy(buf, sv->s_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- sv1 = getservbyport(htons(port), "udp");
- sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
- NULL : sv1;
- }
- if (sv)
- return buf;
- } else if ((pr != -2) && (p = getprotobynumber(pr))) {
- if ((sv = getservbyport(htons(port), p->p_name))) {
- strncpy(buf, sv->s_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- return buf;
+ if ((opts & OPT_NORESOLVE) == 0) {
+ if (pr == -1) {
+ if ((sv = getservbyport(htons(port), "tcp"))) {
+ strncpy(buf, sv->s_name, sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+ sv1 = getservbyport(htons(port), "udp");
+ sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
+ NULL : sv1;
+ }
+ if (sv)
+ return buf;
+ } else if ((pr != -2) && (p = getprotobynumber(pr))) {
+ if ((sv = getservbyport(htons(port), p->p_name))) {
+ strncpy(buf, sv->s_name, sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+ return buf;
+ }
}
}
diff --git a/usr/src/cmd/ipf/lib/common/portnum.c b/usr/src/cmd/ipf/lib/common/portnum.c
index 07556337c8..4079f464c2 100644
--- a/usr/src/cmd/ipf/lib/common/portnum.c
+++ b/usr/src/cmd/ipf/lib/common/portnum.c
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
*
- * $Id: portnum.c,v 1.6 2001/06/09 17:09:24 darrenr Exp $
+ * $Id: portnum.c,v 1.6.4.1 2004/12/09 19:41:22 darrenr Exp $
*/
#include <ctype.h>
@@ -25,7 +25,7 @@ int linenum;
u_short p1 = 0;
int i;
- if (isdigit(*name)) {
+ if (ISDIGIT(*name)) {
if (ratoi(name, &i, 0, USHRT_MAX)) {
*port = (u_short)i;
return 1;
diff --git a/usr/src/cmd/ipf/lib/common/ports.c b/usr/src/cmd/ipf/lib/common/ports.c
index 1c56f6e9ca..9a44e2c06a 100644
--- a/usr/src/cmd/ipf/lib/common/ports.c
+++ b/usr/src/cmd/ipf/lib/common/ports.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ports.c,v 1.9 2002/01/28 06:50:47 darrenr Exp $
+ * $Id: ports.c,v 1.9.4.1 2004/12/09 19:41:22 darrenr Exp $
*/
#include <ctype.h>
@@ -28,7 +28,7 @@ int linenum;
return 0;
if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
(*seg)++;
- if (isalnum(***seg) && *(*seg + 2)) {
+ if (ISALNUM(***seg) && *(*seg + 2)) {
if (portnum(**seg, proto, pp, linenum) == 0)
return -1;
(*seg)++;
diff --git a/usr/src/cmd/ipf/lib/common/print_toif.c b/usr/src/cmd/ipf/lib/common/print_toif.c
index 81524396d2..fc57a302e8 100644
--- a/usr/src/cmd/ipf/lib/common/print_toif.c
+++ b/usr/src/cmd/ipf/lib/common/print_toif.c
@@ -5,7 +5,7 @@
*
* $Id: print_toif.c,v 1.8 2002/01/28 06:50:47 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,7 +28,7 @@ frdest_t *fdp;
char ipv6addr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr,
- sizeof(ipv6addr));
+ sizeof(fdp->fd_ip6));
printf(":%s", ipv6addr);
} else
#endif
diff --git a/usr/src/cmd/ipf/lib/common/printactivenat.c b/usr/src/cmd/ipf/lib/common/printactivenat.c
new file mode 100644
index 0000000000..389818b67b
--- /dev/null
+++ b/usr/src/cmd/ipf/lib/common/printactivenat.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 1993-2001 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
+ */
+
+#include "ipf.h"
+
+
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: printactivenat.c,v 1.3.2.4 2004/05/11 16:07:32 darrenr Exp $";
+#endif
+
+
+void printactivenat(nat, opts)
+nat_t *nat;
+int opts;
+{
+
+ printf("%s", getnattype(nat->nat_ptr));
+
+ if (nat->nat_flags & SI_CLONE)
+ printf(" CLONE");
+
+ printf(" %-15s", inet_ntoa(nat->nat_inip));
+
+ if ((nat->nat_flags & IPN_TCPUDP) != 0)
+ printf(" %-5hu", ntohs(nat->nat_inport));
+
+ printf(" <- -> %-15s",inet_ntoa(nat->nat_outip));
+
+ if ((nat->nat_flags & IPN_TCPUDP) != 0)
+ printf(" %-5hu", ntohs(nat->nat_outport));
+
+ printf(" [%s", inet_ntoa(nat->nat_oip));
+ if ((nat->nat_flags & IPN_TCPUDP) != 0)
+ printf(" %hu", ntohs(nat->nat_oport));
+ printf("]");
+
+ if (opts & OPT_VERBOSE) {
+ printf("\n\tage %lu use %hu sumd %s/",
+ nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0]));
+ printf("%s pr %u bkt %d/%d flags %x\n",
+ getsumd(nat->nat_sumd[1]), nat->nat_p,
+ nat->nat_hv[0], nat->nat_hv[1], nat->nat_flags);
+ printf("\tifp %s", getifname(nat->nat_ifps[0]));
+ printf(",%s ", getifname(nat->nat_ifps[1]));
+#ifdef USE_QUAD_T
+ printf("bytes %qu/%qu pkts %qu/%qu",
+ (unsigned long long)nat->nat_bytes[0],
+ (unsigned long long)nat->nat_bytes[1],
+ (unsigned long long)nat->nat_pkts[0],
+ (unsigned long long)nat->nat_pkts[1]);
+#else
+ printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0],
+ nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]);
+#endif
+ printf(" ipsumd %x", nat->nat_ipsumd);
+ }
+
+ if (opts & OPT_DEBUG) {
+ printf("\n\tnat_next %p _pnext %p _hm %p\n",
+ nat->nat_next, nat->nat_pnext, nat->nat_hm);
+ printf("\t_hnext %p/%p _phnext %p/%p\n",
+ nat->nat_hnext[0], nat->nat_hnext[1],
+ nat->nat_phnext[0], nat->nat_phnext[1]);
+ printf("\t_data %p _me %p _state %p _aps %p\n",
+ nat->nat_data, nat->nat_me, nat->nat_state, nat->nat_aps);
+ printf("\tfr %p ptr %p ifps %p/%p sync %p\n",
+ nat->nat_fr, nat->nat_ptr, nat->nat_ifps[0],
+ nat->nat_ifps[1], nat->nat_sync);
+ printf("\ttqe:pnext %p next %p ifq %p parent %p/%p\n",
+ nat->nat_tqe.tqe_pnext, nat->nat_tqe.tqe_next,
+ nat->nat_tqe.tqe_ifq, nat->nat_tqe.tqe_parent, nat);
+ printf("\ttqe:die %ld touched %ld flags %x state %d/%d\n",
+ nat->nat_tqe.tqe_die, nat->nat_tqe.tqe_touched,
+ nat->nat_tqe.tqe_flags, nat->nat_tqe.tqe_state[0],
+ nat->nat_tqe.tqe_state[1]);
+ }
+ putchar('\n');
+}
diff --git a/usr/src/cmd/ipf/lib/common/printaps.c b/usr/src/cmd/ipf/lib/common/printaps.c
index 437fc03ae9..45b4b2f6ad 100644
--- a/usr/src/cmd/ipf/lib/common/printaps.c
+++ b/usr/src/cmd/ipf/lib/common/printaps.c
@@ -11,7 +11,7 @@
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id";
+static const char rcsid[] = "@(#)$Id: printaps.c,v 1.4 2004/01/08 13:34:32 darrenr Exp $";
#endif
diff --git a/usr/src/cmd/ipf/lib/common/printbuf.c b/usr/src/cmd/ipf/lib/common/printbuf.c
index dae0e541a0..613293ae19 100644
--- a/usr/src/cmd/ipf/lib/common/printbuf.c
+++ b/usr/src/cmd/ipf/lib/common/printbuf.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: printbuf.c,v 1.5 2001/06/09 17:09:24 darrenr Exp $
+ * $Id: printbuf.c,v 1.5.4.1 2004/12/09 19:41:22 darrenr Exp $
*/
#include <ctype.h>
@@ -20,7 +20,7 @@ int len, zend;
for (s = buf, i = len; i; i--) {
c = *s++;
- if (isprint(c))
+ if (ISPRINT(c))
putchar(c);
else
printf("\\%03o", c);
diff --git a/usr/src/cmd/ipf/lib/common/printfr.c b/usr/src/cmd/ipf/lib/common/printfr.c
index fc7a3a1a8e..d7bd3f2bbf 100644
--- a/usr/src/cmd/ipf/lib/common/printfr.c
+++ b/usr/src/cmd/ipf/lib/common/printfr.c
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: printfr.c,v 1.37 2003/06/03 16:01:12 darrenr Exp $
+ * $Id: printfr.c,v 1.43.2.12 2005/06/12 07:18:42 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -13,6 +13,60 @@
#include "ipf.h"
+static void printaddr(int, int, char *, u_32_t *, u_32_t *);
+
+static void printaddr(v, type, ifname, addr, mask)
+int v, type;
+char *ifname;
+u_32_t *addr, *mask;
+{
+ char *suffix;
+
+ switch (type)
+ {
+ case FRI_BROADCAST :
+ suffix = "/bcast";
+ break;
+
+ case FRI_DYNAMIC :
+ printf("%s", ifname);
+ printmask(v, mask);
+ suffix = NULL;
+ break;
+
+ case FRI_NETWORK :
+ suffix = "/net";
+ break;
+
+ case FRI_NETMASKED :
+ suffix = "/netmasked";
+ break;
+
+ case FRI_PEERADDR :
+ suffix = "/peer";
+ break;
+
+ case FRI_LOOKUP :
+ suffix = NULL;
+ printlookup((i6addr_t *)addr, (i6addr_t *)mask);
+ break;
+
+ case FRI_NORMAL :
+ printhostmask(v, addr, mask);
+ suffix = NULL;
+ break;
+ default :
+ printf("<%d>", type);
+ printmask(v, mask);
+ suffix = NULL;
+ break;
+ }
+
+ if (suffix != NULL) {
+ printf("%s/%s", ifname, suffix);
+ }
+}
+
void printlookup(addr, mask)
i6addr_t *addr, *mask;
@@ -59,6 +113,9 @@ ioctlfunc_t iocfunc;
if ((fp->fr_type & FR_T_BUILTIN) != 0)
printf("# Builtin: ");
+ if (fp->fr_collect != 0)
+ printf("%u ", fp->fr_collect);
+
if (fp->fr_type == FR_T_CALLFUNC) {
;
} else if (fp->fr_func != NULL) {
@@ -120,30 +177,32 @@ ioctlfunc_t iocfunc;
if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
putchar(' ');
+ }
- if (*fp->fr_dif.fd_ifname)
- print_toif("dup-to", &fp->fr_dif);
- if (*fp->fr_tif.fd_ifname)
- print_toif("to", &fp->fr_tif);
- if (fp->fr_flags & FR_FASTROUTE)
- printf("fastroute ");
-
- if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
- (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
- if (fp->fr_flags & FR_OUTQUE)
- printf("in-via ");
- else
- printf("out-via ");
+ if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP))
+ print_toif("dup-to", &fp->fr_dif);
+ if (*fp->fr_tif.fd_ifname)
+ print_toif("to", &fp->fr_tif);
+ if (*fp->fr_rif.fd_ifname)
+ print_toif("reply-to", &fp->fr_rif);
+ if (fp->fr_flags & FR_FASTROUTE)
+ printf("fastroute ");
- if (*fp->fr_ifnames[2]) {
- printifname("", fp->fr_ifnames[2],
- fp->fr_ifas[2]);
- putchar(' ');
+ if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
+ (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
+ if (fp->fr_flags & FR_OUTQUE)
+ printf("in-via ");
+ else
+ printf("out-via ");
+
+ if (*fp->fr_ifnames[2]) {
+ printifname("", fp->fr_ifnames[2],
+ fp->fr_ifas[2]);
+ putchar(' ');
- if (*fp->fr_ifnames[3]) {
- printifname(",", fp->fr_ifnames[3],
- fp->fr_ifas[3]);
- }
+ if (*fp->fr_ifnames[3]) {
+ printifname(",", fp->fr_ifnames[3],
+ fp->fr_ifas[3]);
}
}
}
@@ -158,10 +217,10 @@ ioctlfunc_t iocfunc;
pr = -1;
} else if (fp->fr_mip.fi_p) {
pr = fp->fr_ip.fi_p;
- if ((p = getprotobynumber(fp->fr_proto)))
- printf("proto %s ", p->p_name);
- else
- printf("proto %d ", fp->fr_proto);
+ p = getprotobynumber(pr);
+ printf("proto ");
+ printproto(p, pr, NULL);
+ putchar(' ');
}
}
@@ -169,133 +228,17 @@ ioctlfunc_t iocfunc;
printf("all");
} else if (type == FR_T_IPF) {
printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
- if (fp->fr_satype != FRI_NORMAL) {
- printf("%s", fp->fr_ifname);
- if (fp->fr_satype == FRI_BROADCAST)
- printf("/bcast");
- else if (fp->fr_satype == FRI_NETWORK)
- printf("/net");
- else if (fp->fr_satype == FRI_NETMASKED)
- printf("/netmasked");
- else if (fp->fr_satype == FRI_PEERADDR)
- printf("/peer");
- else if (fp->fr_satype == FRI_LOOKUP)
- printlookup(&fp->fr_ip.fi_src,
- &fp->fr_mip.fi_src);
- else
- printmask(fp->fr_v,
- (u_32_t *)&fp->fr_smsk.s_addr);
- } else
- printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
- (u_32_t *)&fp->fr_smsk.s_addr);
+ printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname,
+ &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
if (fp->fr_scmp)
printportcmp(pr, &fp->fr_tuc.ftu_src);
printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
- if (fp->fr_datype != FRI_NORMAL) {
- printf("%s", fp->fr_ifname);
- if (fp->fr_datype == FRI_BROADCAST)
- printf("/bcast");
- else if (fp->fr_datype == FRI_NETWORK)
- printf("/net");
- else if (fp->fr_datype == FRI_NETMASKED)
- printf("/netmasked");
- else if (fp->fr_datype == FRI_PEERADDR)
- printf("/peer");
- else if (fp->fr_datype == FRI_LOOKUP)
- printlookup(&fp->fr_ip.fi_dst,
- &fp->fr_mip.fi_dst);
- else
- printmask(fp->fr_v,
- (u_32_t *)&fp->fr_dmsk.s_addr);
- } else
- printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
- (u_32_t *)&fp->fr_dmsk.s_addr);
+ printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname,
+ &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
if (fp->fr_dcmp)
printportcmp(pr, &fp->fr_tuc.ftu_dst);
- if ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
- fp->fr_optbits || fp->fr_optmask ||
- fp->fr_secbits || fp->fr_secmask) {
- printf(" with");
- if (fp->fr_optbits || fp->fr_optmask ||
- fp->fr_secbits || fp->fr_secmask) {
- sec[0] = fp->fr_secmask;
- sec[1] = fp->fr_secbits;
- if (fp->fr_v == 4)
- optprint(sec, fp->fr_optmask,
- fp->fr_optbits);
-#ifdef USE_INET6
- else
- optprintv6(sec, fp->fr_optmask,
- fp->fr_optbits);
-#endif
- } else if (fp->fr_mflx & FI_OPTIONS) {
- if (!(fp->fr_flx & FI_OPTIONS))
- printf(" not");
- printf(" ipopts");
- }
- if (fp->fr_mflx & FI_SHORT) {
- if (!(fp->fr_flx & FI_SHORT))
- printf(" not");
- printf(" short");
- }
- if (fp->fr_mflx & FI_FRAG) {
- if (!(fp->fr_flx & FI_FRAG))
- printf(" not");
- printf(" frag");
- }
- if (fp->fr_mflx & FI_NATED) {
- if (!(fp->fr_flx & FI_NATED))
- printf(" not");
- printf(" nat");
- }
- if (fp->fr_mflx & FI_MULTICAST) {
- if (!(fp->fr_flx & FI_MULTICAST))
- printf(" not");
- printf(" multicast");
- }
- if (fp->fr_mflx & FI_BROADCAST) {
- if (!(fp->fr_flx & FI_BROADCAST))
- printf(" not");
- printf(" bcast");
- }
- if (fp->fr_mflx & FI_MBCAST) {
- if (!(fp->fr_flx & FI_MBCAST))
- printf(" not");
- printf(" mbcast");
- }
- if (fp->fr_mflx & FI_STATE) {
- if (!(fp->fr_flx & FI_STATE))
- printf(" not");
- printf(" state");
- }
- if (fp->fr_mflx & FI_BADNAT) {
- if (!(fp->fr_flx & FI_BADNAT))
- printf(" not");
- printf(" bad-nat");
- }
- if (fp->fr_mflx & FI_BAD) {
- if (!(fp->fr_flx & FI_BAD))
- printf(" not");
- printf(" bad");
- }
- if (fp->fr_mflx & FI_OOW) {
- if (!(fp->fr_flx & FI_OOW))
- printf(" not");
- printf(" oow");
- }
- if (fp->fr_mflx & FI_LOWTTL) {
- if (!(fp->fr_flx & FI_LOWTTL))
- printf(" not");
- printf(" lowttl");
- }
- if (fp->fr_mflx & FI_BADSRC) {
- if (!(fp->fr_flx & FI_BADSRC))
- printf(" not");
- printf(" bad-src");
- }
- }
if ((fp->fr_proto == IPPROTO_ICMP
#ifdef USE_INET6
|| fp->fr_proto == IPPROTO_ICMPV6
@@ -334,19 +277,18 @@ ioctlfunc_t iocfunc;
(void)putchar(*s);
}
}
-#ifdef IPFILTER_BPF
} else if (type == FR_T_BPFOPC) {
- u_32_t *bp;
+ fakebpf_t *fb;
int i;
- printf("{");
- i = fp->fr_dsize / sizeof(*bp);
+ printf("bpf-v%d { \"", fp->fr_v);
+ i = fp->fr_dsize / sizeof(*fb);
- for (bp = fp->fr_data; i; i--, bp++)
- printf(" 0x%08x", *bp);
+ for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
+ printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
+ fb->fb_f, fb->fb_k);
- printf(" }");
-#endif
+ printf("\" }");
} else if (type == FR_T_COMPIPF) {
;
} else if (type == FR_T_CALLFUNC) {
@@ -355,21 +297,153 @@ ioctlfunc_t iocfunc;
printf("[unknown filter type %#x]", fp->fr_type);
}
+ if ((type == FR_T_IPF) &&
+ ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
+ fp->fr_optbits || fp->fr_optmask ||
+ fp->fr_secbits || fp->fr_secmask)) {
+ char *comma = " ";
+
+ printf(" with");
+ if (fp->fr_optbits || fp->fr_optmask ||
+ fp->fr_secbits || fp->fr_secmask) {
+ sec[0] = fp->fr_secmask;
+ sec[1] = fp->fr_secbits;
+ if (fp->fr_v == 4)
+ optprint(sec, fp->fr_optmask, fp->fr_optbits);
+#ifdef USE_INET6
+ else
+ optprintv6(sec, fp->fr_optmask,
+ fp->fr_optbits);
+#endif
+ } else if (fp->fr_mflx & FI_OPTIONS) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_OPTIONS))
+ printf("not ");
+ printf("ipopts");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_SHORT) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_SHORT))
+ printf("not ");
+ printf("short");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_FRAG) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_FRAG))
+ printf("not ");
+ printf("frag");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_FRAGBODY) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_FRAGBODY))
+ printf("not ");
+ printf("frag-body");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_NATED) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_NATED))
+ printf("not ");
+ printf("nat");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_LOWTTL) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_LOWTTL))
+ printf("not ");
+ printf("lowttl");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_BAD) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_BAD))
+ printf("not ");
+ printf("bad");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_BADSRC) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_BADSRC))
+ printf("not ");
+ printf("bad-src");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_BADNAT) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_BADNAT))
+ printf("not ");
+ printf("bad-nat");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_OOW) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_OOW))
+ printf("not ");
+ printf("oow");
+ }
+ if (fp->fr_mflx & FI_MULTICAST) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_MULTICAST))
+ printf("not ");
+ printf("multicast");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_BROADCAST) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_BROADCAST))
+ printf("not ");
+ printf("bcast");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_MBCAST) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_MBCAST))
+ printf("not ");
+ printf("mbcast");
+ comma = ",";
+ }
+ if (fp->fr_mflx & FI_STATE) {
+ fputs(comma, stdout);
+ if (!(fp->fr_flx & FI_STATE))
+ printf("not ");
+ printf("state");
+ comma = ",";
+ }
+ }
+
if (fp->fr_flags & FR_KEEPSTATE) {
printf(" keep state");
- if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN)) ||
+ if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) ||
(fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
+ char *comma = "";
printf(" (");
- if (fp->fr_statemax != 0)
- printf(" limit %u", fp->fr_statemax);
- if (fp->fr_flags & FR_FRSTRICT)
- printf(" strict");
- if (fp->fr_flags & FR_NEWISN)
- printf(" newisn");
+ if (fp->fr_statemax != 0) {
+ printf("limit %u", fp->fr_statemax);
+ comma = ",";
+ }
+ if (fp->fr_flags & FR_STSTRICT) {
+ printf("%sstrict", comma);
+ comma = ",";
+ }
+ if (fp->fr_flags & FR_NEWISN) {
+ printf("%snewisn", comma);
+ comma = ",";
+ }
+ if (fp->fr_flags & FR_NOICMPERR) {
+ printf("%sno-icmp-err", comma);
+ comma = ",";
+ }
+ if (fp->fr_flags & FR_STATESYNC) {
+ printf("%ssync", comma);
+ comma = ",";
+ }
if (fp->fr_age[0] || fp->fr_age[1])
- printf(" age %d/%d", fp->fr_age[0],
+ printf("%sage %d/%d", comma, fp->fr_age[0],
fp->fr_age[1]);
- printf(" )");
+ printf(")");
}
}
if (fp->fr_flags & FR_KEEPFRAG) {
@@ -392,8 +466,20 @@ ioctlfunc_t iocfunc;
printf(" head %s", fp->fr_grhead);
if (*fp->fr_group != '\0')
printf(" group %s", fp->fr_group);
- if (fp->fr_logtag != FR_NOLOGTAG)
- printf(" log-tag %u", fp->fr_logtag);
+ if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) {
+ char *s = "";
+
+ printf(" set-tag(");
+ if (fp->fr_logtag != FR_NOLOGTAG) {
+ printf("log=%u", fp->fr_logtag);
+ s = ", ";
+ }
+ if (*fp->fr_nattag.ipt_tag) {
+ printf("%snat=%-.*s", s, IPFTAG_LEN,
+ fp->fr_nattag.ipt_tag);
+ }
+ printf(")");
+ }
if (fp->fr_pps)
printf(" pps %d", fp->fr_pps);
(void)putchar('\n');
diff --git a/usr/src/cmd/ipf/lib/common/printfraginfo.c b/usr/src/cmd/ipf/lib/common/printfraginfo.c
new file mode 100644
index 0000000000..557b031a6b
--- /dev/null
+++ b/usr/src/cmd/ipf/lib/common/printfraginfo.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: printfraginfo.c,v 1.1.2.2 2004/03/23 15:15:45 darrenr Exp $
+ */
+#include "ipf.h"
+#include "kmem.h"
+
+void printfraginfo(prefix, ifr)
+char *prefix;
+struct ipfr *ifr;
+{
+ frentry_t fr;
+
+ fr.fr_flags = 0xffffffff;
+
+ printf("%s%s -> ", prefix, hostname(4, &ifr->ipfr_src));
+ if (kmemcpy((char *)&fr, (u_long)ifr->ipfr_rule,
+ sizeof(fr)) == -1)
+ return;
+ printf("%s id %d ttl %d pr %d seen0 %d ifp %p tos %#02x = %#x\n",
+ hostname(4, &ifr->ipfr_dst), ifr->ipfr_id, ifr->ipfr_seen0,
+ ifr->ipfr_ttl, ifr->ipfr_p, ifr->ipfr_ifp, ifr->ipfr_tos,
+ fr.fr_flags);
+}
diff --git a/usr/src/cmd/ipf/lib/common/printhash.c b/usr/src/cmd/ipf/lib/common/printhash.c
index f683226026..034c952d6f 100644
--- a/usr/src/cmd/ipf/lib/common/printhash.c
+++ b/usr/src/cmd/ipf/lib/common/printhash.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -14,19 +14,24 @@
#define PRINTF (void)printf
#define FPRINTF (void)fprintf
-iphtable_t *printhash(hp, copyfunc, opts)
+
+iphtable_t *printhash(hp, copyfunc, name, opts)
iphtable_t *hp;
copyfunc_t copyfunc;
+char *name;
int opts;
{
iphtent_t *ipep, **table;
iphtable_t iph;
+ int i, printed;
size_t sz;
- int i;
if ((*copyfunc)((char *)hp, (char *)&iph, sizeof(iph)))
return NULL;
+ if ((name != NULL) && strncmp(name, iph.iph_name, FR_GROUPLEN))
+ return iph.iph_next;
+
if ((opts & OPT_DEBUG) == 0) {
if ((iph.iph_type & IPHASH_ANON) == IPHASH_ANON)
PRINTF("# 'anonymous' table\n");
@@ -124,11 +129,14 @@ int opts;
if ((*copyfunc)((char *)iph.iph_table, (char *)table, sz))
return NULL;
- for (i = 0; i < iph.iph_size; i++) {
+ for (i = 0, printed = 0; i < iph.iph_size; i++) {
for (ipep = table[i]; ipep != NULL; ) {
ipep = printhashnode(&iph, ipep, copyfunc, opts);
+ printed++;
}
}
+ if (printed == 0)
+ putchar(';');
free(table);
diff --git a/usr/src/cmd/ipf/lib/common/printhashnode.c b/usr/src/cmd/ipf/lib/common/printhashnode.c
index 83cd57eab1..10f2223f28 100644
--- a/usr/src/cmd/ipf/lib/common/printhashnode.c
+++ b/usr/src/cmd/ipf/lib/common/printhashnode.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,8 +47,8 @@ int opts;
#endif
printmask(4, (u_32_t *)&ipe.ipe_mask.in4_addr);
- PRINTF("\tRef. Count: %d\tValue: %d\n", ipe.ipe_ref,
- ipe.ipe_value);
+ PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref,
+ ipe.ipe_group);
} else {
putchar(' ');
#ifdef USE_INET6
@@ -65,8 +65,10 @@ int opts;
switch (iph->iph_type & ~IPHASH_ANON)
{
case IPHASH_GROUPMAP :
- PRINTF(", group = %s", ipe.ipe_group);
- break;
+ if (strncmp(ipe.ipe_group, iph->iph_name,
+ FR_GROUPLEN))
+ PRINTF(", group = %s", ipe.ipe_group);
+ break;
}
}
putchar(';');
diff --git a/usr/src/cmd/ipf/lib/common/printnat.c b/usr/src/cmd/ipf/lib/common/printnat.c
index 2f6c058bc4..0e228652fa 100644
--- a/usr/src/cmd/ipf/lib/common/printnat.c
+++ b/usr/src/cmd/ipf/lib/common/printnat.c
@@ -5,7 +5,7 @@
*
* Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -16,84 +16,9 @@
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: printnat.c,v 1.14 2003/04/13 06:39:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.9 2005/06/12 07:18:43 darrenr Exp $";
#endif
-
-void printactivenat(nat, opts)
-nat_t *nat;
-int opts;
-{
- u_int hv1, hv2;
-
- printf("%s", getnattype(nat->nat_ptr));
-
- if (nat->nat_flags & SI_CLONE)
- printf(" CLONE");
-
- printf(" %-15s", inet_ntoa(nat->nat_inip));
-
- if ((nat->nat_flags & IPN_TCPUDP) != 0)
- printf(" %-5hu", ntohs(nat->nat_inport));
-
- printf(" <- -> %-15s",inet_ntoa(nat->nat_outip));
-
- if ((nat->nat_flags & IPN_TCPUDP) != 0)
- printf(" %-5hu", ntohs(nat->nat_outport));
-
- printf(" [%s", inet_ntoa(nat->nat_oip));
- if ((nat->nat_flags & IPN_TCPUDP) != 0)
- printf(" %hu", ntohs(nat->nat_oport));
- printf("]");
-
- if (opts & OPT_VERBOSE) {
- printf("\n\tage %lu use %hu sumd %s/",
- nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0]));
- if ((nat->nat_flags & SI_WILDP) == 0) {
- hv1 = NAT_HASH_FN(nat->nat_inip.s_addr,
- nat->nat_inport, 0xffffffff);
- hv1 = NAT_HASH_FN(nat->nat_oip.s_addr,
- hv1 + nat->nat_oport, NAT_TABLE_SZ);
- hv2 = NAT_HASH_FN(nat->nat_outip.s_addr,
- nat->nat_outport, 0xffffffff);
- hv2 = NAT_HASH_FN(nat->nat_oip.s_addr,
- hv2 + nat->nat_oport, NAT_TABLE_SZ);
- } else {
- hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0,
- 0xffffffff);
- hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1,
- NAT_TABLE_SZ);
- hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0,
- 0xffffffff);
- hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2,
- NAT_TABLE_SZ);
- }
- printf("%s pr %u bkt %d/%d flags %x\n",
- getsumd(nat->nat_sumd[1]), nat->nat_p,
- hv1, hv2, nat->nat_flags);
- printf("\tifp %s", getifname(nat->nat_ifps[0]));
- printf(",%s ", getifname(nat->nat_ifps[1]));
-#ifdef USE_QUAD_T
- printf("bytes %qu/%qu pkts %qu/%qu",
- (unsigned long long)nat->nat_bytes[0],
- (unsigned long long)nat->nat_bytes[1],
- (unsigned long long)nat->nat_pkts[0],
- (unsigned long long)nat->nat_pkts[1]);
-#else
- printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0],
- nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]);
-#endif
-#if SOLARIS
- printf(" %lx", nat->nat_ipsumd);
-#endif
- }
-
- putchar('\n');
- if (nat->nat_aps)
- printaps(nat->nat_aps, opts);
-}
-
-
/*
* Print out a NAT rule
*/
@@ -102,7 +27,6 @@ ipnat_t *np;
int opts;
{
struct protoent *pr;
- struct servent *sv;
int bits;
pr = getprotobynumber(np->in_p);
@@ -167,33 +91,26 @@ int opts;
printf("%s", inet_ntoa(np->in_out[0].in4));
bits = count4bits(np->in_outmsk);
if (bits != -1)
- printf("/%d ", bits);
+ printf("/%d", bits);
else
- printf("/%s ", inet_ntoa(np->in_out[1].in4));
- printf("port %d", ntohs(np->in_pmin));
- if (np->in_pmax != np->in_pmin)
- printf("-%d", ntohs(np->in_pmax));
+ printf("/%s", inet_ntoa(np->in_out[1].in4));
+ if (np->in_flags & IPN_TCPUDP) {
+ printf(" port %d", ntohs(np->in_pmin));
+ if (np->in_pmax != np->in_pmin)
+ printf("-%d", ntohs(np->in_pmax));
+ }
}
printf(" -> %s", inet_ntoa(np->in_in[0].in4));
if (np->in_flags & IPN_SPLIT)
printf(",%s", inet_ntoa(np->in_in[1].in4));
- if (np->in_inip == 0) {
- bits = count4bits(np->in_inmsk);
- printf("/%d", bits);
+ if (np->in_flags & IPN_TCPUDP) {
+ if ((np->in_flags & IPN_FIXEDDPORT) != 0)
+ printf(" port = %d", ntohs(np->in_pnext));
+ else
+ printf(" port %d", ntohs(np->in_pnext));
}
- printf(" port %d", ntohs(np->in_pnext));
- if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
- printf(" tcp/udp");
- else if ((np->in_flags & IPN_TCP) == IPN_TCP)
- printf(" tcp");
- else if ((np->in_flags & IPN_UDP) == IPN_UDP)
- printf(" udp");
- else if (np->in_p == 0)
- printf(" ip");
- else if (pr != NULL)
- printf(" %s", pr->p_name);
- else
- printf(" %d", np->in_p);
+ putchar(' ');
+ printproto(pr, np->in_p, np);
if (np->in_flags & IPN_ROUNDR)
printf(" round-robin");
if (np->in_flags & IPN_FRAG)
@@ -205,19 +122,14 @@ int opts;
printf(" sticky");
if (np->in_mssclamp != 0)
printf(" mssclamp %d", np->in_mssclamp);
- if (*np->in_plabel != '\0') {
- printf(" proxy %.*s/", (int)sizeof(np->in_plabel),
+ if (*np->in_plabel != '\0')
+ printf(" proxy %.*s", (int)sizeof(np->in_plabel),
np->in_plabel);
- if (pr != NULL)
- fputs(pr->p_name, stdout);
- else
- printf("%d", np->in_p);
- }
+ if (np->in_tag.ipt_tag[0] != '\0')
+ printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag);
printf("\n");
if (opts & OPT_DEBUG)
- printf("\tspc %lu flg %#x max %u use %d\n",
- np->in_space, np->in_flags,
- np->in_pmax, np->in_use);
+ printf("\tpmax %u\n", np->in_pmax);
} else {
if (!(np->in_flags & IPN_FILTER)) {
printf("%s/", inet_ntoa(np->in_in[0].in4));
@@ -240,26 +152,21 @@ int opts;
printf("%s", inet_ntoa(np->in_out[1].in4));
}
if (*np->in_plabel != '\0') {
- printf(" proxy port");
+ printf(" proxy port ");
if (np->in_dcmp != 0)
np->in_dport = htons(np->in_dport);
if (np->in_dport != 0) {
- if (pr != NULL)
- sv = getservbyport(np->in_dport,
- pr->p_name);
- else
- sv = getservbyport(np->in_dport, NULL);
- if (sv != NULL)
- printf(" %s", sv->s_name);
+ char *s;
+
+ s = portname(np->in_p, ntohs(np->in_dport));
+ if (s != NULL)
+ fputs(s, stdout);
else
- printf(" %hu", ntohs(np->in_dport));
+ fputs("???", stdout);
}
printf(" %.*s/", (int)sizeof(np->in_plabel),
np->in_plabel);
- if (pr != NULL)
- fputs(pr->p_name, stdout);
- else
- printf("%d", np->in_p);
+ printproto(pr, np->in_p, NULL);
} else if (np->in_redir == NAT_MAPBLK) {
if ((np->in_pmin == 0) &&
(np->in_flags & IPN_AUTOPORTMAP))
@@ -269,13 +176,12 @@ int opts;
if (opts & OPT_DEBUG)
printf("\n\tip modulous %d", np->in_pmax);
} else if (np->in_pmin || np->in_pmax) {
- printf(" portmap");
- if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
- printf(" tcp/udp");
- else if (np->in_flags & IPN_TCP)
- printf(" tcp");
- else if (np->in_flags & IPN_UDP)
- printf(" udp");
+ if (np->in_flags & IPN_ICMPQUERY) {
+ printf(" icmpidmap ");
+ } else {
+ printf(" portmap ");
+ }
+ printproto(pr, np->in_p, np);
if (np->in_flags & IPN_AUTOPORTMAP) {
printf(" auto");
if (opts & OPT_DEBUG)
@@ -287,7 +193,11 @@ 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)
printf(" frag");
if (np->in_age[0] != 0 || np->in_age[1] != 0) {
@@ -295,16 +205,26 @@ int opts;
}
if (np->in_mssclamp != 0)
printf(" mssclamp %d", np->in_mssclamp);
+ if (np->in_tag.ipt_tag[0] != '\0')
+ printf(" tag %s", np->in_tag.ipt_tag);
printf("\n");
if (opts & OPT_DEBUG) {
struct in_addr nip;
nip.s_addr = htonl(np->in_nextip.s_addr);
- printf("\tspace %lu nextip %s pnext %d", np->in_space,
+ printf("\tnextip %s pnext %d\n",
inet_ntoa(nip), np->in_pnext);
- printf(" flags %x use %u\n",
- np->in_flags, np->in_use);
}
}
+
+ if (opts & OPT_DEBUG) {
+ printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n",
+ np->in_space, np->in_use, np->in_hits,
+ np->in_flags, np->in_p, np->in_hv);
+ printf("\tifp[0] %p ifp[1] %p apr %p\n",
+ np->in_ifps[0], np->in_ifps[1], np->in_apr);
+ printf("\ttqehead %p/%p comment %p\n",
+ np->in_tqehead[0], np->in_tqehead[1], np->in_comment);
+ }
}
diff --git a/usr/src/cmd/ipf/lib/common/printpacket.c b/usr/src/cmd/ipf/lib/common/printpacket.c
index 6f2194af70..4121e3acd5 100644
--- a/usr/src/cmd/ipf/lib/common/printpacket.c
+++ b/usr/src/cmd/ipf/lib/common/printpacket.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: printpacket.c,v 1.12 2002/11/02 13:27:29 darrenr Exp $
+ * $Id: printpacket.c,v 1.12.4.1 2005/02/21 05:09:24 darrenr Exp $
*/
#include "ipf.h"
@@ -18,11 +18,15 @@ struct ip *ip;
{
struct tcphdr *tcp;
u_short len;
+ u_short off;
- if (IP_V(ip) == 6)
+ if (IP_V(ip) == 6) {
+ off = 0;
len = ntohs(((u_short *)ip)[2]) + 40;
- else
+ } else {
+ off = ntohs(ip->ip_off);
len = ntohs(ip->ip_len);
+ }
if ((opts & OPT_HEX) == OPT_HEX) {
u_char *s;
@@ -47,15 +51,15 @@ struct ip *ip;
tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2));
printf("ip %d(%d) %d", ntohs(ip->ip_len), IP_HL(ip) << 2, ip->ip_p);
- if (ip->ip_off & IP_OFFMASK)
- printf(" @%d", ip->ip_off << 3);
+ if (off & IP_OFFMASK)
+ printf(" @%d", off << 3);
printf(" %s", inet_ntoa(ip->ip_src));
- if (!(ip->ip_off & IP_OFFMASK))
+ if (!(off & IP_OFFMASK))
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
printf(",%d", ntohs(tcp->th_sport));
printf(" > ");
printf("%s", inet_ntoa(ip->ip_dst));
- if (!(ip->ip_off & IP_OFFMASK)) {
+ if (!(off & IP_OFFMASK)) {
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
printf(",%d", ntohs(tcp->th_dport));
if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) {
diff --git a/usr/src/cmd/ipf/lib/common/printpool.c b/usr/src/cmd/ipf/lib/common/printpool.c
index 59f5d727e7..842086274b 100644
--- a/usr/src/cmd/ipf/lib/common/printpool.c
+++ b/usr/src/cmd/ipf/lib/common/printpool.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -14,17 +14,21 @@
#define PRINTF (void)printf
#define FPRINTF (void)fprintf
-ip_pool_t *printpool(pp, copyfunc, opts)
+ip_pool_t *printpool(pp, copyfunc, name, opts)
ip_pool_t *pp;
copyfunc_t copyfunc;
+char *name;
int opts;
{
- ip_pool_node_t *ipnp, *ipnpn;
+ ip_pool_node_t *ipnp, *ipnpn, ipn;
ip_pool_t ipp;
if ((*copyfunc)(pp, &ipp, sizeof(ipp)))
return NULL;
+ if ((name != NULL) && strncmp(name, ipp.ipo_name, FR_GROUPLEN))
+ return ipp.ipo_next;
+
if ((opts & OPT_DEBUG) == 0) {
if ((ipp.ipo_flags & IPOOL_ANON) != 0)
PRINTF("# 'anonymous' tree %s\n", ipp.ipo_name);
@@ -82,17 +86,22 @@ int opts;
ipp.ipo_list = NULL;
while (ipnpn != NULL) {
ipnp = (ip_pool_node_t *)malloc(sizeof(*ipnp));
- (*copyfunc)(ipnpn, ipnp, sizeof(*ipnp));
+ (*copyfunc)(ipnpn, ipnp, sizeof(ipn));
ipnpn = ipnp->ipn_next;
ipnp->ipn_next = ipp.ipo_list;
ipp.ipo_list = ipnp;
}
- for (ipnp = ipp.ipo_list; ipnp != NULL; ) {
- ipnp = printpoolnode(ipnp, opts);
+ if (ipp.ipo_list == NULL) {
+ putchar(';');
+ } else {
+ for (ipnp = ipp.ipo_list; ipnp != NULL; ) {
+ ipnp = printpoolnode(ipnp, opts);
- if ((opts & OPT_DEBUG) == 0)
- putchar(';');
+ if ((opts & OPT_DEBUG) == 0) {
+ putchar(';');
+ }
+ }
}
if ((opts & OPT_DEBUG) == 0)
diff --git a/usr/src/cmd/ipf/lib/common/printproto.c b/usr/src/cmd/ipf/lib/common/printproto.c
new file mode 100644
index 0000000000..dd0ce39ca5
--- /dev/null
+++ b/usr/src/cmd/ipf/lib/common/printproto.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: printproto.c,v 1.1.2.1 2005/06/12 07:21:53 darrenr Exp $";
+#endif
+
+
+void printproto(pr, p, np)
+struct protoent *pr;
+int p;
+ipnat_t *np;
+{
+ if (np != NULL) {
+ if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
+ printf("tcp/udp");
+ else if (np->in_flags & IPN_TCP)
+ printf("tcp");
+ else if (np->in_flags & IPN_UDP)
+ printf("udp");
+ else if (np->in_flags & IPN_ICMPQUERY)
+ printf("icmp");
+#ifdef _AIX51
+ /*
+ * To make up for "ip = 252" and "hopopt = 0" in /etc/protocols
+ */
+ else if (np->in_p == 0)
+ printf("ip");
+#endif
+ else if (pr != NULL)
+ printf("%s", pr->p_name);
+ else
+ printf("%d", np->in_p);
+ } else {
+#ifdef _AIX51
+ if (p == 0)
+ printf("ip");
+ else
+#endif
+ if (pr != NULL)
+ printf("%s", pr->p_name);
+ else
+ printf("%d", p);
+ }
+}
diff --git a/usr/src/cmd/ipf/lib/common/printsbuf.c b/usr/src/cmd/ipf/lib/common/printsbuf.c
index 98139cebc9..cc13e19b6b 100644
--- a/usr/src/cmd/ipf/lib/common/printsbuf.c
+++ b/usr/src/cmd/ipf/lib/common/printsbuf.c
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#ifdef IPFILTER_SCAN
#include <ctype.h>
@@ -12,7 +17,7 @@ char *buf;
int i;
for (s = (u_char *)buf, i = ISC_TLEN; i; i--, s++) {
- if (isprint(*s))
+ if (ISPRINT(*s))
putchar(*s);
else
printf("\\%o", *s);
diff --git a/usr/src/cmd/ipf/lib/common/printstate.c b/usr/src/cmd/ipf/lib/common/printstate.c
index 369c1665bf..b0a58abfd7 100644
--- a/usr/src/cmd/ipf/lib/common/printstate.c
+++ b/usr/src/cmd/ipf/lib/common/printstate.c
@@ -10,11 +10,15 @@
#define PRINTF (void)printf
#define FPRINTF (void)fprintf
-ipstate_t *printstate(sp, opts)
+ipstate_t *printstate(sp, opts, now)
ipstate_t *sp;
int opts;
+u_long now;
{
ipstate_t ips;
+#ifdef IPFILTER_SYNC
+ synclist_t ipsync;
+#endif
if (kmemcpy((char *)&ips, (u_long)sp, sizeof(ips)))
return NULL;
@@ -23,7 +27,7 @@ int opts;
PRINTF("%s pass %#x pr %d state %d/%d bkt %d\n",
hostname(ips.is_v, &ips.is_dst.in4), ips.is_pass, ips.is_p,
ips.is_state[0], ips.is_state[1], ips.is_hv);
- PRINTF("\ttag %u age %lu/%lu", ips.is_tag, ips.is_die, ips.is_touched);
+ PRINTF("\ttag %u ttl %lu", ips.is_tag, ips.is_die - now);
if (ips.is_p == IPPROTO_TCP) {
PRINTF("\n\t%hu -> %hu %x:%x %hu<<%d:%hu<<%d\n",
@@ -45,10 +49,13 @@ int opts;
printsbuf(ips.is_sbuf[1]);
PRINTF("]\n");
#endif
- } else if (ips.is_p == IPPROTO_UDP)
+ } else if (ips.is_p == IPPROTO_UDP) {
PRINTF(" %hu -> %hu\n", ntohs(ips.is_sport),
ntohs(ips.is_dport));
- else if (ips.is_p == IPPROTO_ICMP
+ } else if (ips.is_p == IPPROTO_GRE) {
+ PRINTF(" call %hx/%hx\n", ntohs(ips.is_gre.gs_call[0]),
+ ntohs(ips.is_gre.gs_call[1]));
+ } else if (ips.is_p == IPPROTO_ICMP
#ifdef USE_INET6
|| ips.is_p == IPPROTO_ICMPV6
#endif
@@ -57,7 +64,7 @@ int opts;
ntohs(ips.is_icmp.ici_seq), ips.is_icmp.ici_type);
#ifdef USE_QUAD_T
- PRINTF("\tforward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n\tbackward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd",
+ PRINTF("\tforward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n\tbackward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n",
ips.is_pkts[0], ips.is_bytes[0],
ips.is_pkts[1], ips.is_bytes[1],
ips.is_pkts[2], ips.is_bytes[2],
@@ -126,16 +133,19 @@ int opts;
if (ips.is_pass & FR_KEEPFRAG)
PRINTF(" keep frags");
/* a given; no? */
- if (ips.is_pass & FR_KEEPSTATE)
+ if (ips.is_pass & FR_KEEPSTATE) {
PRINTF(" keep state");
+ if (ips.is_pass & FR_STATESYNC)
+ PRINTF(" ( sync )");
+ }
PRINTF("\tIPv%d", ips.is_v);
PRINTF("\n");
PRINTF("\tpkt_flags & %x(%x) = %x,\t",
ips.is_flags & 0xf, ips.is_flags,
ips.is_flags >> 4);
- PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk,
- ips.is_opt);
+ PRINTF("\tpkt_options & %x = %x, %x = %x \n", ips.is_optmsk[0],
+ ips.is_opt[0], ips.is_optmsk[1], ips.is_opt[1]);
PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n",
ips.is_secmsk, ips.is_sec, ips.is_authmsk,
ips.is_auth);
@@ -159,5 +169,23 @@ int opts;
PRINTF("/%p", ips.is_ifp[3]);
PRINTF("]\n");
+#ifdef IPFILTER_SYNC
+ if (ips.is_sync != NULL) {
+
+ if (kmemcpy((char *)&ipsync, (u_long)ips.is_sync, sizeof(ipsync))) {
+
+ PRINTF("\tSync status: status could not be retrieved\n");
+ return NULL;
+ }
+
+ PRINTF("\tSync status: idx %d num %d v %d pr %d rev %d\n",
+ ipsync.sl_idx, ipsync.sl_num, ipsync.sl_v,
+ ipsync.sl_p, ipsync.sl_rev);
+
+ } else {
+ PRINTF("\tSync status: not synchronized\n");
+ }
+#endif
+
return ips.is_next;
}
diff --git a/usr/src/cmd/ipf/lib/common/printtunable.c b/usr/src/cmd/ipf/lib/common/printtunable.c
new file mode 100644
index 0000000000..01ea7e8985
--- /dev/null
+++ b/usr/src/cmd/ipf/lib/common/printtunable.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
+#include "ipf.h"
+
+void printtunable(tup)
+ipftune_t *tup;
+{
+ printf("%s\tmin %#lx\tmax %#lx\tcurrent ",
+ tup->ipft_name, tup->ipft_min, tup->ipft_max);
+ if (tup->ipft_sz == sizeof(u_long))
+ printf("%lu\n", tup->ipft_vlong);
+ else if (tup->ipft_sz == sizeof(u_int))
+ printf("%u\n", tup->ipft_vint);
+ else if (tup->ipft_sz == sizeof(u_short))
+ printf("%hu\n", tup->ipft_vshort);
+ else if (tup->ipft_sz == sizeof(u_char))
+ printf("%u\n", (u_int)tup->ipft_vchar);
+ else {
+ printf("sz = %d\n", tup->ipft_sz);
+ }
+}
diff --git a/usr/src/cmd/ipf/lib/common/remove_hash.c b/usr/src/cmd/ipf/lib/common/remove_hash.c
index d939f97b71..d1830ac76a 100644
--- a/usr/src/cmd/ipf/lib/common/remove_hash.c
+++ b/usr/src/cmd/ipf/lib/common/remove_hash.c
@@ -9,14 +9,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
static int hashfd = -1;
diff --git a/usr/src/cmd/ipf/lib/common/remove_hashnode.c b/usr/src/cmd/ipf/lib/common/remove_hashnode.c
index b9c65d5914..afa0dbc554 100644
--- a/usr/src/cmd/ipf/lib/common/remove_hashnode.c
+++ b/usr/src/cmd/ipf/lib/common/remove_hashnode.c
@@ -9,14 +9,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
static int hashfd = -1;
diff --git a/usr/src/cmd/ipf/lib/common/remove_pool.c b/usr/src/cmd/ipf/lib/common/remove_pool.c
index 398ce376ed..d14529ab40 100644
--- a/usr/src/cmd/ipf/lib/common/remove_pool.c
+++ b/usr/src/cmd/ipf/lib/common/remove_pool.c
@@ -9,14 +9,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
static int poolfd = -1;
diff --git a/usr/src/cmd/ipf/lib/common/remove_poolnode.c b/usr/src/cmd/ipf/lib/common/remove_poolnode.c
index 1b5b537913..2c7f9d3028 100644
--- a/usr/src/cmd/ipf/lib/common/remove_poolnode.c
+++ b/usr/src/cmd/ipf/lib/common/remove_poolnode.c
@@ -3,20 +3,14 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: remove_poolnode.c,v 1.1 2003/04/13 06:40:14 darrenr Exp $
+ * $Id: remove_poolnode.c,v 1.3 2003/11/22 10:14:36 darrenr Exp $
*/
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ipf.h"
-
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
-#include "netinet/ip_htable.h"
-#endif
+#include "netinet/ip_pool.h"
static int poolfd = -1;
diff --git a/usr/src/cmd/ipf/lib/common/v6ionames.c b/usr/src/cmd/ipf/lib/common/v6ionames.c
index 9b47cfd9fd..27affe5e50 100644
--- a/usr/src/cmd/ipf/lib/common/v6ionames.c
+++ b/usr/src/cmd/ipf/lib/common/v6ionames.c
@@ -3,10 +3,8 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: v6ionames.c,v 1.1 2003/04/26 04:55:58 darrenr Exp $
+ * $Id: v6ionames.c,v 1.1.4.1 2005/01/02 13:08:49 darrenr Exp $
*/
-
-
#include "ipf.h"
diff --git a/usr/src/cmd/ipf/lib/common/var.c b/usr/src/cmd/ipf/lib/common/var.c
index 994d5bcdb3..706a55ba97 100644
--- a/usr/src/cmd/ipf/lib/common/var.c
+++ b/usr/src/cmd/ipf/lib/common/var.c
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
#include <ctype.h>
#include "ipf.h"
@@ -44,9 +49,9 @@ int line;
fprintf(stderr, "%d: { without }\n", line);
return NULL;
}
- } else if (isalpha(*s)) {
+ } else if (ISALPHA(*s)) {
for (t = s + 1; *t != '\0'; t++)
- if (!isalpha(*t) && !isdigit(*t))
+ if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_'))
break;
} else {
fprintf(stderr, "%d: variables cannot start with '%c'\n",
@@ -95,6 +100,9 @@ int line;
break;
default :
c = *s;
+ if (c == '\0')
+ return newstring;
+
value = get_variable(s, &p3, line);
if (value == NULL)
return NULL;
@@ -119,7 +127,7 @@ int line;
if (p3 != NULL)
strcat(p1, p3);
- s = p1 + len - strlen(p3);
+ s = p1 + len - strlen(p3) - 1;
if (newstring != oldstring)
free(newstring);
newstring = p1;
diff --git a/usr/src/cmd/ipf/tools/Makefile.tools b/usr/src/cmd/ipf/tools/Makefile.tools
index c4cd838a04..17ec18ab93 100644
--- a/usr/src/cmd/ipf/tools/Makefile.tools
+++ b/usr/src/cmd/ipf/tools/Makefile.tools
@@ -48,7 +48,7 @@ ipftest := LDLIBS += -lsocket -lnsl -lmd
ipfstat := LDLIBS += -lsocket -lnsl -lkvm -lelf
ipmon := LDLIBS += -lsocket -lnsl
ipnat := LDLIBS += -lsocket -lnsl -lkvm -lelf
-ippool := LDLIBS += -lnsl -lkvm
+ippool := LDLIBS += -lsocket -lnsl -lkvm
CLEANFILES += $(OBJS)
@@ -90,7 +90,7 @@ ipf: $(IPF_OBJS) $(LIBIPF)
$(LINK.c) -o ipf $(IPF_OBJS) $(LDLIBS)
$(POST_PROCESS)
-ipf_y.o: ../ipf_y.c $(COMMONIPF)/ip_fil.h $(COMMONIPF)/ipf.h \
+ipf_y.o: ../ipf_y.c $(COMMONIPF)/netinet/ip_fil.h $(COMMONIPF)/ipf.h \
../ipf_y.c ../ipf_l.h
../ipf_y.c ../ipf_y.h: ../ipf_y.y
@@ -100,11 +100,11 @@ ipf_y.o: ../ipf_y.c $(COMMONIPF)/ip_fil.h $(COMMONIPF)/ipf.h \
sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.h/' \
ipf.tab.h > ../ipf_y.h
-ipf_l.o: ../ipf_l.c $(COMMONIPF)/ip_fil.h $(COMMONIPF)/ipf.h \
+ipf_l.o: ../ipf_l.c $(COMMONIPF)/netinet/ip_fil.h $(COMMONIPF)/ipf.h \
../ipf_y.h ../ipf_l.h
$(COMPILE.c) ../ipf_l.c -o $@
-../ipf_l.c: ../lexer.c $(COMMONIPF)/ipf.h $(COMMONIPF)/ip_fil.h
+../ipf_l.c: ../lexer.c $(COMMONIPF)/ipf.h $(COMMONIPF)/netinet/ip_fil.h
sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.h/' \
-e 's/lexer.h/ipf_l.h/' ../lexer.c > $@
@@ -149,7 +149,7 @@ ipnat: $(IPNAT_OBJS) $(LIBIPF)
$(LINK.c) -o ipnat $(IPNAT_OBJS) $(LDLIBS)
$(POST_PROCESS)
-ipnat_y.o: ../ipnat_y.c $(COMMONIPF)/ip_nat.h \
+ipnat_y.o: ../ipnat_y.c $(COMMONIPF)/netinet/ip_nat.h \
../ipnat_y.h ../ipnat_l.h
../ipnat_y.c ../ipnat_y.h: ../ipnat_y.y
@@ -161,10 +161,10 @@ ipnat_y.o: ../ipnat_y.c $(COMMONIPF)/ip_nat.h \
sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.h/ipnat_y.h/' \
ipnat.tab.h > ../ipnat_y.h
-ipnat_l.o: ../ipnat_l.c $(COMMONIPF)/ip_nat.h ../ipnat_l.h
+ipnat_l.o: ../ipnat_l.c $(COMMONIPF)/netinet/ip_nat.h ../ipnat_l.h
$(COMPILE.c) ../ipnat_l.c -o $@
-../ipnat_l.c: ../lexer.c $(COMMONIPF)/ip_nat.h
+../ipnat_l.c: ../lexer.c $(COMMONIPF)/netinet/ip_nat.h
sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.h/ipnat_y.h/' \
-e 's/lexer.h/ipnat_l.h/' ../lexer.c > $@
@@ -175,7 +175,7 @@ ippool: $(IPPOOL_OBJS) $(LIBIPF)
$(LINK.c) -o ippool $(IPPOOL_OBJS) $(LDLIBS)
$(POST_PROCESS)
-ippool_y.o: ../ippool_y.c $(COMMONIPF)/ip_pool.h \
+ippool_y.o: ../ippool_y.c $(COMMONIPF)/netinet/ip_pool.h \
../ippool_y.h ../ippool_l.h
../ippool_y.c ../ippool_y.h: ../ippool_y.y
@@ -187,10 +187,10 @@ ippool_y.o: ../ippool_y.c $(COMMONIPF)/ip_pool.h \
sed -e 's/yy/ippool_yy/g' -e 's/y.tab.h/ippool_y.h/' \
ippool.tab.h > ../ippool_y.h
-ippool_l.o: ../ippool_l.c $(COMMONIPF)/ip_pool.h ../ippool_l.h
+ippool_l.o: ../ippool_l.c $(COMMONIPF)/netinet/ip_pool.h ../ippool_l.h
$(COMPILE.c) ../ippool_l.c -o $@
-../ippool_l.c: ../lexer.c $(COMMONIPF)/ip_pool.h
+../ippool_l.c: ../lexer.c $(COMMONIPF)/netinet/ip_pool.h
sed -e 's/yy/ippool_yy/g' -e 's/y.tab.h/ippool_y.h/' \
-e 's/lexer.h/ippool_l.h/' ../lexer.c > $@
@@ -206,7 +206,7 @@ clean:
lint: lint_SRCS
-%.o: $(SRC)/common/ipf/%.c
+%.o: $(SRC)/uts/common/inet/ipf/%.c
$(COMPILE.c) $<
%.o: ../%.c
diff --git a/usr/src/cmd/ipf/tools/ip_fil.c b/usr/src/cmd/ipf/tools/ip_fil.c
index ae11de166e..0011968b9a 100644
--- a/usr/src/cmd/ipf/tools/ip_fil.c
+++ b/usr/src/cmd/ipf/tools/ip_fil.c
@@ -3,26 +3,21 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.121 2003/06/28 17:01:55 darrenr Exp $";
+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.9 2005/01/08 14:22:18 darrenr Exp $";
#endif
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#if defined(KERNEL) || defined(_KERNEL)
-# undef KERNEL
-# undef _KERNEL
-# define KERNEL 1
-# define _KERNEL 1
-#endif
#include <sys/param.h>
#if defined(__FreeBSD__) && !defined(__FreeBSD_version)
# if defined(IPFILTER_LKM)
@@ -36,30 +31,20 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.121 2003/06/28 17:01:55 darre
# endif
#endif
#include <sys/errno.h>
+#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL)
+# include <sys/kern_svcs.h>
+#endif
#include <sys/types.h>
-
-#ifdef _KERNEL
-# include <sys/systm.h>
-# include <sys/fcntl.h>
-#else
-# define _KERNEL
-# ifdef __OpenBSD__
+#define _KERNEL
+#define KERNEL
+#ifdef __OpenBSD__
struct file;
-# endif
-
-# include <sys/uio.h>
-# undef _KERNEL
#endif
-
+#include <sys/uio.h>
+#undef _KERNEL
+#undef KERNEL
#include <sys/file.h>
#include <sys/ioctl.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <fcntl.h>
-
#ifdef __sgi
# include <sys/ptimers.h>
#endif
@@ -73,7 +58,9 @@ struct file;
#else
# include <sys/filio.h>
#endif
-#include <sys/protosw.h>
+#ifndef linux
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#include <stdio.h>
@@ -81,6 +68,7 @@ struct file;
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
+#include <arpa/inet.h>
#ifdef __hpux
# define _NET_ROUTE_INCLUDED
@@ -98,19 +86,28 @@ struct file;
#include <sys/hashing.h>
# endif
#endif
+#if defined(__FreeBSD__)
+# include "radix_ipf.h"
+#endif
#include <net/route.h>
#include <netinet/in.h>
#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \
- !defined(__hpux)
+ !defined(__hpux) && !defined(linux)
# include <netinet/in_var.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#if defined(__osf__)
# include <netinet/tcp_timer.h>
#endif
+#if defined(__osf__) || defined(__hpux) || defined(__sgi)
+# include "radix_ipf_local.h"
+# define _RADIX_H_
+#endif
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
@@ -119,15 +116,6 @@ struct file;
#ifdef __hpux
# undef _NET_ROUTE_INCLUDED
#endif
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#include "ip_auth.h"
-#else
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
@@ -135,18 +123,13 @@ struct file;
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
-#endif
#ifdef IPFILTER_SYNC
#include "netinet/ip_sync.h"
#endif
#ifdef IPFILTER_SCAN
#include "netinet/ip_scan.h"
#endif
-#if SOLARIS2 >= 10
-#include "ip_pool.h"
-#else
#include "netinet/ip_pool.h"
-#endif
#ifdef IPFILTER_COMPILED
# include "netinet/ip_rules.h"
#endif
@@ -156,8 +139,8 @@ struct file;
#ifdef __hpux
struct rtentry;
#endif
+#include "md5.h"
-#include <sys/md5.h>
#if !defined(__osf__)
extern struct protosw inetsw[];
@@ -168,8 +151,9 @@ static struct ifnet **ifneta = NULL;
static int nifs = 0;
static int frzerostats __P((caddr_t));
+static void fr_setifpaddr __P((struct ifnet *, char *));
void init_ifp __P((void));
-#if defined(__sgi) && (IRIX < 605)
+#if defined(__sgi) && (IRIX < 60500)
static int no_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *));
static int write_output __P((struct ifnet *, struct mbuf *,
@@ -220,18 +204,12 @@ caddr_t data;
}
-
/*
* Filter ioctl interface.
*/
int iplioctl(dev, cmd, data, mode)
int dev;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
caddr_t data;
int mode;
{
@@ -260,7 +238,8 @@ int mode;
}
if (unit == IPL_LOGAUTH) {
if (fr_running > 0) {
- if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) {
+ if ((cmd == (ioctlcmd_t)SIOCADAFR) ||
+ (cmd == (ioctlcmd_t)SIOCRMAFR)) {
if (!(mode & FWRITE)) {
error = EPERM;
} else {
@@ -325,6 +304,15 @@ int mode;
error = ipldetach();
}
break;
+ case SIOCIPFSET :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
+ case SIOCIPFGETNEXT :
+ case SIOCIPFGET :
+ error = fr_ipftune(cmd, (void *)data);
+ break;
case SIOCSETFF :
if (!(mode & FWRITE))
error = EPERM;
@@ -422,7 +410,7 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else {
- frsync();
+ frsync(NULL);
}
break;
default :
@@ -471,7 +459,7 @@ void *ifp;
}
-void fr_resolvdest(fdp, v)
+void fr_resolvedest(fdp, v)
frdest_t *fdp;
int v;
{
@@ -485,7 +473,7 @@ int v;
}
-#if defined(__sgi) && (IRIX < 605)
+#if defined(__sgi) && (IRIX < 60500)
static int no_output(ifp, m, s)
#else
# if TRU64 >= 1885
@@ -504,7 +492,7 @@ struct sockaddr *s;
}
-#if defined(__sgi) && (IRIX < 605)
+#if defined(__sgi) && (IRIX < 60500)
static int write_output(ifp, m, s)
#else
# if TRU64 >= 1885
@@ -528,7 +516,8 @@ struct sockaddr *s;
ip = MTOD(mb, ip_t *);
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
sprintf(fname, "/tmp/%s", ifp->if_xname);
#else
sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
@@ -544,20 +533,75 @@ struct sockaddr *s;
}
+static void fr_setifpaddr(ifp, addr)
+struct ifnet *ifp;
+char *addr;
+{
+#ifdef __sgi
+ struct in_ifaddr *ifa;
+#else
+ struct ifaddr *ifa;
+#endif
+
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ if (ifp->if_addrlist.tqh_first != NULL)
+#else
+# ifdef __sgi
+ if (ifp->in_ifaddr != NULL)
+# else
+ if (ifp->if_addrlist != NULL)
+# endif
+#endif
+ return;
+
+ ifa = (struct ifaddr *)malloc(sizeof(*ifa));
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ ifp->if_addrlist.tqh_first = ifa;
+#else
+# ifdef __sgi
+ ifp->in_ifaddr = ifa;
+# else
+ ifp->if_addrlist = ifa;
+# endif
+#endif
+
+ if (ifa != NULL) {
+ struct sockaddr_in *sin;
+
+#ifdef __sgi
+ sin = (struct sockaddr_in *)&ifa->ia_addr;
+#else
+ sin = (struct sockaddr_in *)&ifa->ifa_addr;
+#endif
+ sin->sin_addr.s_addr = inet_addr(addr);
+ if (sin->sin_addr.s_addr == 0)
+ abort();
+ }
+}
+
struct ifnet *get_unit(name, v)
char *name;
int v;
{
- struct ifnet *ifp, **ifa, **old_ifneta;
+ struct ifnet *ifp, **ifpp, **old_ifneta;
+ char *addr;
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
if (name == NULL)
name = "anon0";
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- if (!strcmp(name, ifp->if_xname))
+ addr = strchr(name, '=');
+ if (addr != NULL)
+ *addr++ = '\0';
+
+ for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
+ if (!strcmp(name, ifp->if_xname)) {
+ if (addr != NULL)
+ fr_setifpaddr(ifp, addr);
return ifp;
+ }
}
#else
char *s, ifname[LIFNAMSIZ+1];
@@ -565,10 +609,17 @@ int v;
if (name == NULL)
name = "anon0";
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
+ addr = strchr(name, '=');
+ if (addr != NULL)
+ *addr++ = '\0';
+
+ for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
COPYIFNAME(ifp, ifname);
- if (!strcmp(name, ifname))
+ if (!strcmp(name, ifname)) {
+ if (addr != NULL)
+ fr_setifpaddr(ifp, addr);
return ifp;
+ }
}
#endif
@@ -587,7 +638,7 @@ int v;
old_ifneta = ifneta;
nifs++;
ifneta = (struct ifnet **)realloc(ifneta,
- (nifs + 1) * sizeof(*ifa));
+ (nifs + 1) * sizeof(ifp));
if (!ifneta) {
free(old_ifneta);
nifs = 0;
@@ -603,12 +654,13 @@ int v;
ifp = ifneta[nifs - 1];
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
+ (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
#else
- for (s = name; *s && !isdigit(*s); s++)
+ for (s = name; *s && !ISDIGIT(*s); s++)
;
- if (*s && isdigit(*s)) {
+ if (*s && ISDIGIT(*s)) {
ifp->if_unit = atoi(s);
ifp->if_name = (char *)malloc(s - name + 1);
if (ifp->if_name == NULL) {
@@ -619,7 +671,7 @@ int v;
perror("malloc");
exit(1);
}
- strncpy(ifp->if_name, name, s - name);
+ (void) strncpy(ifp->if_name, name, s - name);
ifp->if_name[s - name] = '\0';
} else {
ifp->if_name = strdup(name);
@@ -627,6 +679,11 @@ int v;
}
#endif
ifp->if_output = no_output;
+
+ if (addr != NULL) {
+ fr_setifpaddr(ifp, addr);
+ }
+
return ifp;
}
@@ -636,7 +693,8 @@ struct ifnet *ifp;
{
static char ifname[LIFNAMSIZ];
-#if defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
sprintf(ifname, "%s", ifp->if_xname);
#else
sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
@@ -648,13 +706,14 @@ struct ifnet *ifp;
void init_ifp()
{
- struct ifnet *ifp, **ifa;
+ struct ifnet *ifp, **ifpp;
char fname[32];
int fd;
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
+ for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
ifp->if_output = write_output;
sprintf(fname, "/tmp/%s", ifp->if_xname);
fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
@@ -665,7 +724,7 @@ void init_ifp()
}
#else
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
+ for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
ifp->if_output = write_output;
sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
@@ -692,7 +751,7 @@ frdest_t *fdp;
ip->ip_len = htons((u_short)ip->ip_len);
ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
ip->ip_sum = 0;
-#if defined(__sgi) && (IRIX < 605)
+#if defined(__sgi) && (IRIX < 60500)
(*ifp->if_output)(ifp, (void *)ip, NULL);
# if TRU64 >= 1885
(*ifp->if_output)(ifp, (void *)m, NULL, 0, 0);
@@ -717,12 +776,13 @@ int type;
fr_info_t *fin;
int dst;
{
- verbose("- TCP RST sent\n");
+ verbose("- ICMP unreachable sent\n");
return 0;
}
-void frsync()
+void frsync(ifp)
+void *ifp;
{
return;
}
@@ -860,3 +920,74 @@ fr_info_t *fin;
fin->fin_flx |= FI_BAD;
}
#endif
+
+
+/*
+ * See above for description, except that all addressing is in user space.
+ */
+int copyoutptr(src, dst, size)
+void *src, *dst;
+size_t size;
+{
+ caddr_t ca;
+
+ bcopy(dst, (char *)&ca, sizeof(ca));
+ bcopy(src, ca, size);
+ return 0;
+}
+
+
+/*
+ * See above for description, except that all addressing is in user space.
+ */
+int copyinptr(src, dst, size)
+void *src, *dst;
+size_t size;
+{
+ caddr_t ca;
+
+ bcopy(src, (char *)&ca, sizeof(ca));
+ bcopy(ca, dst, size);
+ return 0;
+}
+
+
+/*
+ * return the first IP Address associated with an interface
+ */
+int fr_ifpaddr(v, atype, ifptr, inp, inpmask)
+int v, atype;
+void *ifptr;
+struct in_addr *inp, *inpmask;
+{
+ struct ifnet *ifp = ifptr;
+#ifdef __sgi
+ struct in_ifaddr *ifa;
+#else
+ struct ifaddr *ifa;
+#endif
+
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ ifa = ifp->if_addrlist.tqh_first;
+#else
+# ifdef __sgi
+ ifa = (struct in_ifaddr *)ifp->in_ifaddr;
+# else
+ ifa = ifp->if_addrlist;
+# endif
+#endif
+ if (ifa != NULL) {
+ struct sockaddr_in *sin, mask;
+
+ mask.sin_addr.s_addr = 0xffffffff;
+
+#ifdef __sgi
+ sin = (struct sockaddr_in *)&ifa->ia_addr;
+#else
+ sin = (struct sockaddr_in *)&ifa->ifa_addr;
+#endif
+
+ return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask);
+ }
+ return 0;
+}
diff --git a/usr/src/cmd/ipf/tools/ipf.c b/usr/src/cmd/ipf/tools/ipf.c
index 1a06567959..a9621ef7df 100644
--- a/usr/src/cmd/ipf/tools/ipf.c
+++ b/usr/src/cmd/ipf/tools/ipf.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -21,20 +21,13 @@
#include "ipf.h"
#include <fcntl.h>
#include <sys/ioctl.h>
-#if SOLARIS2 >= 10
-#include "ipl.h"
-#else
#include "netinet/ipl.h"
-#endif
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipf.c,v 1.24 2003/07/01 16:30:47 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipf.c,v 1.35.2.3 2004/12/15 18:27:17 darrenr Exp $";
#endif
-#if SOLARIS
-static void blockunknown __P((void));
-#endif
#if !defined(__SVR4) && defined(__GNUC__)
extern char *index __P((const char *, int));
#endif
@@ -44,7 +37,7 @@ extern int optind;
extern frentry_t *frtop;
-void frsync __P((void));
+void ipf_frsync __P((void));
void zerostats __P((void));
int main __P((int, char *[]));
@@ -62,8 +55,6 @@ static void usage __P((void));
static int showversion __P((void));
static int get_flags __P((void));
static void ipf_interceptadd __P((int, ioctlfunc_t, void *));
-static void dotuning __P((char *));
-static void printtunable __P((ipftune_t *));
static int fd = -1;
static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
@@ -73,13 +64,9 @@ static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
static void usage()
{
- fprintf(stderr, "usage: ipf [-"
-#ifdef USE_INET6
- "6"
-#endif
- "AdDEInoPrsUvVyzZ] %s %s %s %s\n",
- "[-l block|pass|nomatch|state|nat]", "[-T optionlist]",
- "[-F i|o|a|s|S|u]", "[-f filename]");
+ fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n",
+ "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]",
+ "[-f filename] [-T <tuneopts>]");
exit(1);
}
@@ -93,7 +80,7 @@ char *argv[];
if (argc < 2)
usage();
- while ((c = getopt(argc, argv, "6ACdDEf:F:Il:noPrsT:UvVyzZ")) != -1) {
+ while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) {
switch (c)
{
case '?' :
@@ -107,11 +94,10 @@ char *argv[];
case 'A' :
opts &= ~OPT_INACTIVE;
break;
-#ifdef USE_OPTIONC
- case 'C' :
- outputc = 1;
+ case 'c' :
+ if (strcmp(optarg, "c") == 0)
+ outputc = 1;
break;
-#endif
case 'E' :
set_state((u_int)1);
break;
@@ -141,6 +127,9 @@ char *argv[];
case 'P' :
ipfname = IPAUTH_NAME;
break;
+ case 'R' :
+ opts ^= OPT_NORESOLVE;
+ break;
case 'r' :
opts ^= OPT_REMOVE;
break;
@@ -148,13 +137,9 @@ char *argv[];
swapactive();
break;
case 'T' :
- dotuning(optarg);
- break;
-#if SOLARIS
- case 'U' :
- blockunknown();
+ if (opendevice(ipfname, 1) >= 0)
+ ipf_dotuning(fd, optarg, ioctl);
break;
-#endif
case 'v' :
opts += OPT_VERBOSE;
break;
@@ -163,7 +148,7 @@ char *argv[];
exit(1);
break;
case 'y' :
- frsync();
+ ipf_frsync();
break;
case 'z' :
opts ^= OPT_ZERORULEST;
@@ -275,7 +260,7 @@ void *ptr;
static void packetlogon(opt)
char *opt;
{
- int flag, xfd, logopt;
+ int flag, xfd, logopt, change = 0;
flag = get_flags();
if (flag != 0) {
@@ -289,24 +274,35 @@ char *opt;
flag |= FF_LOGPASS;
if (opts & OPT_VERBOSE)
printf("set log flag: pass\n");
+ change = 1;
}
if (strstr(opt, "nomatch")) {
flag |= FF_LOGNOMATCH;
if (opts & OPT_VERBOSE)
printf("set log flag: nomatch\n");
+ change = 1;
}
if (strstr(opt, "block") || index(opt, 'd')) {
flag |= FF_LOGBLOCK;
if (opts & OPT_VERBOSE)
printf("set log flag: block\n");
+ change = 1;
+ }
+ if (strstr(opt, "none")) {
+ if (opts & OPT_VERBOSE)
+ printf("disable all log flags\n");
+ change = 1;
}
- if (opendevice(ipfname, 1) != -2 && (ioctl(fd, SIOCSETFF, &flag) != 0))
- perror("ioctl(SIOCSETFF)");
+ if (change == 1) {
+ if (opendevice(ipfname, 1) != -2 &&
+ (ioctl(fd, SIOCSETFF, &flag) != 0))
+ perror("ioctl(SIOCSETFF)");
+ }
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
flag = get_flags();
- printf("log flag is now %#x\n", flag);
+ printf("log flags are now %#x\n", flag);
}
if (strstr(opt, "state")) {
@@ -360,19 +356,22 @@ char *arg;
rem = fl;
closedevice();
+ if (opendevice(IPSTATE_NAME, 1) == -2)
+ exit(1);
- if (opendevice(IPSTATE_NAME, 1) != -2) {
+ if (!(opts & OPT_DONOTHING)) {
if (use_inet6) {
-#ifdef USE_INET6
- if (ioctl(fd, SIOCIPFL6, &fl) == -1)
- perror("SIOCIPFL6");
-#endif
+ if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
+ perror("ioctl(SIOCIPFL6)");
+ exit(1);
+ }
} else {
- if (ioctl(fd, SIOCIPFFL, &fl) == -1)
- perror("SIOCIPFFL");
+ if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
+ perror("ioctl(SIOCIPFFL)");
+ exit(1);
+ }
}
}
-
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
printf("remove flags %s (%d)\n", arg, rem);
printf("removed %d filter rules\n", fl);
@@ -408,15 +407,20 @@ char *arg;
fl |= FR_INACTIVE;
rem = fl;
- if (opendevice(ipfname, 1) != -2) {
+ if (opendevice(ipfname, 1) == -2)
+ exit(1);
+
+ if (!(opts & OPT_DONOTHING)) {
if (use_inet6) {
-#ifdef USE_INET6
- if (ioctl(fd, SIOCIPFL6, &fl) == -1)
- perror("SIOCIPFL6");
-#endif
+ if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
+ perror("ioctl(SIOCIPFL6)");
+ exit(1);
+ }
} else {
- if (ioctl(fd, SIOCIPFFL, &fl) == -1)
- perror("SIOCIPFFL");
+ if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
+ perror("ioctl(SIOCIPFFL)");
+ exit(1);
+ }
}
}
@@ -440,7 +444,7 @@ static void swapactive()
}
-void frsync()
+void ipf_frsync()
{
int frsyn = 0;
@@ -493,33 +497,6 @@ friostat_t *fp;
}
-#if SOLARIS
-static void blockunknown()
-{
- u_32_t flag;
-
- if (opendevice(ipfname, 1) == -1)
- return;
-
- flag = get_flags();
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
- printf("log flag is currently %#x\n", flag);
-
- flag ^= FF_BLOCKNONIP;
-
- if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSETFF, &flag))
- perror("ioctl(SIOCSETFF)");
-
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
- if (ioctl(fd, SIOCGETFF, &flag))
- perror("ioctl(SIOCGETFF)");
-
- printf("log flag is now %#x\n", flag);
- }
-}
-#endif
-
-
static int showversion()
{
struct friostat fio;
@@ -583,82 +560,7 @@ static int showversion()
s = "nomatch -> block";
printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un");
printf("Active list: %d\n", fio.f_active);
+ printf("Feature mask: %#x\n", fio.f_features);
return 0;
}
-
-
-static void dotuning(tuneargs)
-char *tuneargs;
-{
- ipfobj_t obj;
- ipftune_t tu;
- char *s, *t;
-
- if (opendevice(ipfname, 1) < 0)
- return;
-
- bzero((char *)&tu, sizeof(tu));
- obj.ipfo_rev = IPFILTER_VERSION;
- obj.ipfo_size = sizeof(tu);;
- obj.ipfo_ptr = (void *)&tu;
- obj.ipfo_type = IPFOBJ_TUNEABLE;
-
- for (s = strtok(tuneargs, ","); s != NULL; s = strtok(NULL, ",")) {
- if (!strcmp(s, "list")) {
- while (1) {
- if (ioctl(fd, SIOCIPFGETNEXT, &obj) == -1) {
- perror("ioctl(SIOCIPFGETNEXT)");
- break;
- }
- if (tu.ipft_cookie == NULL)
- break;
-
- tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0';
- printtunable(&tu);
- }
- } else if ((t = strchr(s, '=')) != NULL) {
- *t++ = '\0';
- strncpy(tu.ipft_name, s, sizeof(tu.ipft_name));
- if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) {
- if (ioctl(fd, SIOCIPFSET, &obj) == -1) {
- perror("ioctl(SIOCIPFSET)");
- return;
- }
- } else {
- fprintf(stderr, "invalid value '%s'\n", s);
- return;
- }
- } else {
- strncpy(tu.ipft_name, s, sizeof(tu.ipft_name));
- if (ioctl(fd, SIOCIPFGET, &obj) == -1) {
- perror("ioctl(SIOCIPFGET)");
- return;
- }
- if (tu.ipft_cookie == NULL)
- return;
-
- tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0';
- printtunable(&tu);
- }
- }
-}
-
-
-static void printtunable(tup)
-ipftune_t *tup;
-{
- printf("%s\tmin %#lx\tmax %#lx\tcurrent ",
- tup->ipft_name, tup->ipft_min, tup->ipft_max);
- if (tup->ipft_sz == sizeof(u_long))
- printf("%lu\n", tup->ipft_vlong);
- else if (tup->ipft_sz == sizeof(u_int))
- printf("%u\n", tup->ipft_vint);
- else if (tup->ipft_sz == sizeof(u_short))
- printf("%hu\n", tup->ipft_vshort);
- else if (tup->ipft_sz == sizeof(u_char))
- printf("%u\n", (u_int)tup->ipft_vchar);
- else {
- printf("sz = %d\n", tup->ipft_sz);
- }
-}
diff --git a/usr/src/cmd/ipf/tools/ipf_y.y b/usr/src/cmd/ipf/tools/ipf_y.y
index f1fc0096f0..31af5ef875 100644
--- a/usr/src/cmd/ipf/tools/ipf_y.y
+++ b/usr/src/cmd/ipf/tools/ipf_y.y
@@ -4,47 +4,36 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "ipf.h"
-#include <netinet/ip_icmp.h>
#include <sys/ioctl.h>
#include <syslog.h>
#ifdef IPFILTER_BPF
-# include <net/bpf.h>
-# include <pcap-int.h>
+# include "pcap-bpf.h"
+# define _NET_BPF_H_
# include <pcap.h>
#endif
-#if SOLARIS2 >= 10
-#include "ip_pool.h"
-#include "ip_htable.h"
-#include "ipl.h"
-#else
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
#include "netinet/ipl.h"
-#endif
#include "ipf_l.h"
#define YYDEBUG 1
#define DOALL(x) for (fr = frc; fr != NULL; fr = fr->fr_next) { x }
#define DOREM(x) for (; fr != NULL; fr = fr->fr_next) { x }
-#if SOLARIS2 >= 10
-#define VNI "vni"
-#define VNISTRLEN 3
-#endif
-#define OPTION_LOG 0x1
-#define OPTION_QUICK 0x2
-#define OPTION_DUP 0x4
-#define OPTION_PROUTE 0x8
-#define OPTION_ON 0x10
-#define OPTION_REPLYTO 0x20
-#define OPTION_FROUTE 0x40
+#define OPTION_LOG 0x1
+#define OPTION_QUICK 0x2
+#define OPTION_DUP 0x4
+#define OPTION_PROUTE 0x8
+#define OPTION_ON 0x10
+#define OPTION_REPLYTO 0x20
+#define OPTION_FROUTE 0x40
extern void yyerror __P((char *));
extern int yyparse __P((void));
@@ -56,7 +45,7 @@ extern int yylineNum;
static void newrule __P((void));
static void setipftype __P((void));
static u_32_t lookuphost __P((char *));
-static void dobpf __P((char *));
+static void dobpf __P((int, char *));
static void resetaddr __P((void));
static struct alist_s *newalist __P((struct alist_s *));
static u_int makehash __P((struct alist_s *));
@@ -77,14 +66,20 @@ static int nrules = 0;
static int newlist = 0;
static int added = 0;
static int ipffd = -1;
+static int ruleopts = 0;
static int *yycont = 0;
-static int ruleopts = 0;
static ioctlfunc_t ipfioctl[IPL_LOGSIZE];
static addfunc_t ipfaddfunc = NULL;
-static wordtab_t addrwords[4];
-static wordtab_t maskwords[5];
-static wordtab_t *savewords;
-static int set_ipv6_addr = 0;
+static struct wordtab ipfwords[95];
+static struct wordtab addrwords[4];
+static struct wordtab maskwords[5];
+static struct wordtab icmpcodewords[17];
+static struct wordtab icmptypewords[16];
+static struct wordtab ipv4optwords[25];
+static struct wordtab ipv4secwords[9];
+static struct wordtab ipv6optwords[8];
+static struct wordtab logwords[33];
+static int set_ipv6_addr = 0;
%}
%union {
@@ -94,6 +89,7 @@ static int set_ipv6_addr = 0;
frentry_t fr;
frtuc_t *frt;
struct alist_s *alist;
+ u_short port;
struct {
u_short p1;
u_short p2;
@@ -106,10 +102,11 @@ static int set_ipv6_addr = 0;
union i6addr ip6;
};
-%type <num> portnum facility priority icmpcode seclevel secname icmptype
+%type <port> portnum
+%type <num> facility priority icmpcode seclevel secname icmptype
%type <num> opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
-%type <num> portc porteq
-%type <ipa> hostname ipv4 ipv4mask
+%type <num> portc porteq
+%type <ipa> hostname ipv4 ipv4mask ipv4_16 ipv4_24
%type <ip6> ipv6mask
%type <ipp> addr ipaddr
%type <str> servicename name interfacename
@@ -127,13 +124,13 @@ static int set_ipv6_addr = 0;
%token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
%token IPFY_IN IPFY_OUT
%token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
-%token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO
+%token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
%token IPFY_TOS IPFY_TTL IPFY_PROTO
%token IPFY_HEAD IPFY_GROUP
-%token IPFY_AUTH IPFY_PREAUTH IPFY_DIVERT
+%token IPFY_AUTH IPFY_PREAUTH
%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK
-%token IPFY_LOGTAG IPFY_TAG IPFY_SKIP
-%token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPF IPFY_POOL IPFY_HASH
+%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP
+%token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
%token IPFY_PPS
%token IPFY_ESP IPFY_AH
%token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
@@ -146,6 +143,7 @@ static int set_ipv6_addr = 0;
%token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
%token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
%token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
+%token IPFY_SYNC IPFY_FRAGBODY
%token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
%token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
%token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
@@ -212,16 +210,19 @@ assigning:
'=' { yyvarnext = 1; }
;
-rule: inrule
- | outrule
+rule: inrule eol
+ | outrule eol
+ ;
+
+eol: | ';'
;
inrule:
- rulehead markin { ruleopts = 0; } inopts rulemain ruletail
+ rulehead markin { ruleopts = 0; } inopts rulemain ruletail intag ruletail2
;
outrule:
- rulehead markout { ruleopts = 0; } outopts rulemain ruletail
+ rulehead markout { ruleopts = 0; } outopts rulemain ruletail outtag ruletail2
;
rulehead:
@@ -246,15 +247,26 @@ ipfrule:
;
bpfrule:
- IPFY_BPF '{' YY_STR '}' { dobpf($3); free($3); }
+ IPFY_BPFV4 '{' YY_STR '}' { dobpf(4, $3); free($3); }
+ | IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); }
;
ruletail:
- keep head group tag pps age new
+ with keep head group
+ ;
+
+ruletail2:
+ pps age new
+ ;
+
+intag: settagin matchtagin
+ ;
+
+outtag: settagout matchtagout
;
insert:
- '@' YY_NUMBER { fr->fr_hits = (U_QUAD_T)$2; }
+ '@' YY_NUMBER { fr->fr_hits = (U_QUAD_T)$2 + 1; }
;
collection:
@@ -263,8 +275,6 @@ collection:
action: block
| IPFY_PASS { fr->fr_flags |= FR_PASS; }
- | IPFY_DIVERT YY_NUMBER { fr->fr_flags |= FR_DIVERT;
- fr->fr_arg = $2; }
| log
| IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; }
| auth
@@ -429,7 +439,7 @@ lmore: lanother { if (newlist == 1) {
}
fr = addrule();
if (yycont != NULL)
- *yycont = 1;
+ *yycont = 1;
}
;
@@ -454,7 +464,7 @@ protox: IPFY_PROTO { setipftype();
yysetdict(NULL); }
;
-ip: srcdst flags with icmp
+ip: srcdst flags icmp
;
group: | IPFY_GROUP YY_STR { DOALL(strncpy(fr->fr_group, $2, \
@@ -473,21 +483,50 @@ head: | IPFY_HEAD YY_STR { DOALL(strncpy(fr->fr_grhead, $2, \
$2);) }
;
-tag: | IPFY_TAG YY_NUMBER { DOALL(fr->fr_logtag = $2;) }
- | IPFY_TAG '(' taglist ')'
+settagin:
+ | IPFY_SETTAG '(' taginlist ')'
+ ;
-taglist:
- tagspec
- | taglist ',' tagspec
+taginlist:
+ taginspec
+ | taginlist ',' taginspec
;
-tagspec:
- IPFY_NAT '=' YY_STR { DOALL(strncpy(fr->fr_nattag.ipt_tag,\
- $3, 16););
+taginspec:
+ logtag
+ |nattag
+ ;
+
+nattag: IPFY_NAT '=' YY_STR { DOALL(strncpy(fr->fr_nattag.ipt_tag,\
+ $3, IPFTAG_LEN););
free($3); }
| IPFY_NAT '=' YY_NUMBER { DOALL(sprintf(fr->fr_nattag.ipt_tag,\
- "%15d", $3);) }
- | IPFY_LOG '=' YY_NUMBER { DOALL(fr->fr_logtag = $3;) }
+ "%d", $3 & 0xffffffff);) }
+ ;
+
+logtag: IPFY_LOG '=' YY_NUMBER { DOALL(fr->fr_logtag = $3;) }
+ ;
+
+settagout:
+ | IPFY_SETTAG '(' tagoutlist ')'
+ ;
+
+tagoutlist:
+ tagoutspec
+ | tagoutlist ',' tagoutspec
+ ;
+
+tagoutspec:
+ logtag
+ | nattag
+ ;
+
+matchtagin:
+ | IPFY_MATCHTAG '(' tagoutlist ')'
+ ;
+
+matchtagout:
+ | IPFY_MATCHTAG '(' taginlist ')'
;
pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) }
@@ -517,114 +556,26 @@ on: IPFY_ON onname
;
onname: interfacename
- {
-#if SOLARIS2 >=10
- char *cp;
-#endif
- strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $1, VNISTRLEN) == 0) {
- cp = $1 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $1);
- }
- }
-#endif
+ { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
free($1);
}
- | interfacename ',' name
- {
-#if SOLARIS2 >= 10
- char *cp;
-#endif
- strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $1, VNISTRLEN) == 0) {
- cp = $1 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $1);
- }
- }
-#endif
+ | interfacename ',' interfacename
+ { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
free($1);
strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $3, VNISTRLEN) == 0) {
- cp = $3 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $3);
- }
- }
-#endif
free($3);
}
;
vianame:
- interfacename
- {
-#if SOLARIS2 >= 10
- char *cp;
-#endif
- strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $1, VNISTRLEN) == 0) {
- cp = $1 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $1);
- }
- }
-#endif
+ name
+ { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
free($1);
}
- | interfacename ',' name
- {
-#if SOLARIS2 >= 10
- char *cp;
-#endif
- strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $1, VNISTRLEN) == 0) {
- cp = $1 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $1);
- }
- }
-#endif
+ | name ',' name
+ { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
free($1);
strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3]));
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $3, VNISTRLEN) == 0) {
- cp = $3 + VNISTRLEN;
- cp += strspn(cp, "0123456789");
- if (*cp == '\0' || *cp == ':') {
- fprintf(stderr, "%d: Warning- %s specified. vni"
- " is a virtual interface, use a physical"
- " interface instead. See vni(7D)\n",
- yylineNum, $3);
- }
- }
-#endif
free($3);
}
;
@@ -633,33 +584,56 @@ dup: IPFY_DUPTO name
{ strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
free($2);
}
- | IPFY_DUPTO name ':' hostname
+ | IPFY_DUPTO name duptoseparator hostname
{ strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
fr->fr_dif.fd_ip = $4;
+ yyexpectaddr = 0;
+ free($2);
+ }
+ | IPFY_DUPTO name duptoseparator YY_IPV6
+ { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
+ bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6));
+ yyexpectaddr = 0;
free($2);
}
;
+duptoseparator:
+ ':' { yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); }
+ ;
+
froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; }
;
-proute: IPFY_TO name
+proute: routeto name
{ strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
free($2);
}
- | IPFY_TO name ':' hostname
+ | routeto name duptoseparator hostname
{ strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
fr->fr_tif.fd_ip = $4;
+ yyexpectaddr = 0;
+ free($2);
+ }
+ | routeto name duptoseparator YY_IPV6
+ { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
+ bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6));
+ yyexpectaddr = 0;
free($2);
}
;
+routeto:
+ IPFY_TO
+ | IPFY_ROUTETO
+ ;
+
replyto:
IPFY_REPLY_TO name
{ strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
free($2);
}
- | IPFY_REPLY_TO name ':' hostname
+ | IPFY_REPLY_TO name duptoseparator hostname
{ strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
fr->fr_rif.fd_ip = $4;
free($2);
@@ -686,7 +660,7 @@ starticmpcode:
'(' { yysetdict(icmpcodewords); }
;
-srcdst: IPFY_ALL
+srcdst: | IPFY_ALL
| fromto
;
@@ -699,7 +673,7 @@ protocol:
} else {
int p = getproto($1);
if (p == -1)
- fprintf(stderr, "protocol unknown: %s, line %d\n", $1, yylineNum);
+ yyerror("protocol unknown");
DOREM(fr->fr_proto = p; \
fr->fr_mproto = 0xff;)
}
@@ -730,6 +704,8 @@ from: IPFY_FROM { setipftype();
if (fr == NULL)
fr = frc;
yyexpectaddr = 1;
+ if (yydebug)
+ printf("set yyexpectaddr\n");
yycont = &yyexpectaddr;
yysetdict(addrwords);
resetaddr(); }
@@ -738,6 +714,8 @@ from: IPFY_FROM { setipftype();
to: IPFY_TO { if (fr == NULL)
fr = frc;
yyexpectaddr = 1;
+ if (yydebug)
+ printf("set yyexpectaddr\n");
yycont = &yyexpectaddr;
yysetdict(addrwords);
resetaddr(); }
@@ -751,34 +729,42 @@ andwith:
| IPFY_AND { nowith = 0; setipftype(); }
;
-flags: | IPFY_FLAGS flagset
+flags: | startflags flagset
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
- | IPFY_FLAGS flagset '/' flagset
+ | startflags flagset '/' flagset
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
- | IPFY_FLAGS '/' flagset
+ | startflags '/' flagset
{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
- | IPFY_FLAGS YY_NUMBER
+ | startflags YY_NUMBER
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
- | IPFY_FLAGS '/' YY_NUMBER
+ | startflags '/' YY_NUMBER
{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
- | IPFY_FLAGS YY_NUMBER '/' YY_NUMBER
+ | startflags YY_NUMBER '/' YY_NUMBER
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
- | IPFY_FLAGS flagset '/' YY_NUMBER
+ | startflags flagset '/' YY_NUMBER
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
- | IPFY_FLAGS YY_NUMBER '/' flagset
+ | startflags YY_NUMBER '/' flagset
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
;
+startflags:
+ IPFY_FLAGS { if (frc->fr_type != FR_T_IPF)
+ yyerror("flags with non-ipf type rule");
+ if (frc->fr_proto != IPPROTO_TCP)
+ yyerror("flags with non-TCP rule");
+ }
+ ;
+
flagset:
YY_STR { $$ = tcpflags($1); free($1); }
| YY_HEX { $$ = $1; }
;
srcobject:
- srcaddr srcport
+ { yyresetdict(); } fromport
+ | srcaddr srcport
| '!' srcaddr srcport
{ DOALL(fr->fr_flags |= FR_NOTSRCIP;) }
- | fromport
;
srcaddr:
@@ -840,7 +826,7 @@ srcportlist:
;
dstobject:
- toport
+ { yyresetdict(); } toport
| dstaddr dstport
| '!' dstaddr dstport
{ DOALL(fr->fr_flags |= FR_NOTDSTIP;) }
@@ -960,7 +946,11 @@ maskspace:
ipv4mask:
ipv4 { $$ = $1; }
| YY_HEX { $$.s_addr = htonl($1); }
- | YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$); }
+ | YY_NUMBER { if (($1 >= 0) && ($1 <= 32)) {
+ ntomask(4, $1, (u_32_t *)&$$);
+ } else
+ yyerror("invalid mask");
+ }
| IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
$$.s_addr = 0;
ifpflag = FRI_BROADCAST;
@@ -988,7 +978,11 @@ ipv4mask:
;
ipv6mask:
- YY_NUMBER { ntomask(6, $1, $$.i6); }
+ YY_NUMBER { if (($1 >= 0) && ($1 <= 128)) {
+ ntomask(6, $1, $$.i6);
+ } else
+ yyerror("invalid mask");
+ }
| IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
bzero(&$$, sizeof($$));
ifpflag = FRI_BROADCAST;
@@ -1174,6 +1168,7 @@ age: | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \
keep: | IPFY_KEEP keepstate
| IPFY_KEEP keepfrag
| IPFY_KEEP keepstate IPFY_KEEP keepfrag
+ | IPFY_KEEP keepfrag IPFY_KEEP keepstate
;
keepstate:
@@ -1182,6 +1177,7 @@ keepstate:
keepfrag:
IPFY_FRAGS fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
+ | IPFY_FRAG fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
;
fragoptlist:
@@ -1219,34 +1215,46 @@ stateopt:
fr->fr_flags |= FR_NEWISN;)
}
| IPFY_NOICMPERR { DOALL(fr->fr_flags |= FR_NOICMPERR;) }
+
+ | IPFY_SYNC { DOALL(fr->fr_flags |= FR_STATESYNC;) }
;
portnum:
- servicename { $$ = ntohs(getport(frc, $1));
- if ($$ == -1)
- fprintf(stderr, "service unknown: %s, line %d\n", $1, yylineNum);
+ servicename { if (getport(frc, $1, &($$)) == -1)
+ yyerror("service unknown");
+ else
+ $$ = ntohs($$);
free($1);
}
- | YY_NUMBER { $$ = $1; }
+ | YY_NUMBER { if ($1 > 65535) /* Unsigned */
+ yyerror("invalid port number");
+ else
+ $$ = $1;
+ }
;
withlist:
withopt
| withlist withopt
+ | withlist ',' withopt
;
withopt:
opttype { DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) }
| notwith opttype
- { DOALL(fr->fr_mflx |= $2;) }
- | IPFY_OPT ipopts
- | notwith IPFY_OPT ipopts
- | startv6hdrs ipv6hdrs
+ { DOALL(fr->fr_mflx |= $2;) }
+ | ipopt ipopts { yyresetdict(); }
+ | notwith ipopt ipopts { yyresetdict(); }
+ | startv6hdrs ipv6hdrs { yyresetdict(); }
+ ;
+
+ipopt: IPFY_OPT { yysetdict(ipv4optwords); }
;
startv6hdrs:
IPF6_V6HDRS { if (use_inet6 == 0)
yyerror("only available with IPv6");
+ yysetdict(ipv6optwords);
}
;
@@ -1264,6 +1272,8 @@ opttype:
| IPFY_BADSRC { $$ = FI_BADSRC; }
| IPFY_LOWTTL { $$ = FI_LOWTTL; }
| IPFY_FRAG { $$ = FI_FRAG; }
+ | IPFY_FRAGBODY { $$ = FI_FRAGBODY; }
+ | IPFY_FRAGS { $$ = FI_FRAG; }
| IPFY_MBCAST { $$ = FI_MBCAST; }
| IPFY_MULTICAST { $$ = FI_MULTICAST; }
| IPFY_BROADCAST { $$ = FI_BROADCAST; }
@@ -1374,14 +1384,19 @@ opt:
| IPFY_IPOPT_NSAPA { $$ = getoptbyvalue(IPOPT_NSAPA); }
| IPFY_IPOPT_RTRALRT { $$ = getoptbyvalue(IPOPT_RTRALRT); }
| IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); }
- | IPFY_SECCLASS secname
+ | setsecclass secname
{ DOALL(fr->fr_mip.fi_secmsk |= $2;
if (!nowith)
fr->fr_ip.fi_secmsk |= $2;)
$$ = 0;
+ yyresetdict();
}
;
+setsecclass:
+ IPFY_SECCLASS { yysetdict(ipv4secwords); }
+ ;
+
ipv6hdr:
IPFY_AH { $$ = getv6optbyvalue(IPPROTO_AH); }
| IPFY_IPV6OPT_DSTOPTS { $$ = getv6optbyvalue(IPPROTO_DSTOPTS); }
@@ -1439,8 +1454,7 @@ priority:
;
compare:
- '=' { $$ = FR_EQUAL; }
- | YY_CMP_EQ { $$ = FR_EQUAL; }
+ YY_CMP_EQ { $$ = FR_EQUAL; }
| YY_CMP_NE { $$ = FR_NEQUAL; }
| YY_CMP_LT { $$ = FR_LESST; }
| YY_CMP_LE { $$ = FR_LESSTE; }
@@ -1460,32 +1474,51 @@ servicename:
interfacename: YY_STR { $$ = $1; }
| YY_STR ':' YY_NUMBER
{ $$ = $1;
-#if SOLARIS2 >= 10
- if (strncmp(VNI, $1, VNISTRLEN) != 0)
-#endif
fprintf(stderr, "%d: Logical interface %s:%d unsupported, "
- "use the physical interface %s instead.\n",
- yylineNum, $1, $3, $1);
+ "use the physical interface %s instead.\n",
+ yylineNum, $1, $3, $1);
}
;
name: YY_STR { $$ = $1; }
;
-ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
- { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
+ipv4_16:
+ YY_NUMBER '.' YY_NUMBER
+ { if ($1 > 255 || $3 > 255) {
yyerror("Invalid octet string for IP address");
return 0;
}
- $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
+ $$.s_addr = ($1 << 24) | ($3 << 16);
$$.s_addr = htonl($$.s_addr);
}
;
+
+ipv4_24:
+ ipv4_16 '.' YY_NUMBER
+ { if ($3 > 255) {
+ yyerror("Invalid octet string for IP address");
+ return 0;
+ }
+ $$.s_addr |= htonl($3 << 8);
+ }
+ ;
+
+ipv4: ipv4_24 '.' YY_NUMBER
+ { if ($3 > 255) {
+ yyerror("Invalid octet string for IP address");
+ return 0;
+ }
+ $$.s_addr |= htonl($3);
+ }
+ | ipv4_24
+ | ipv4_16
+ ;
+
%%
-static struct wordtab ipfwords[] = {
- { "addext", IPFY_IPOPT_ADDEXT },
+static struct wordtab ipfwords[95] = {
{ "age", IPFY_AGE },
{ "ah", IPFY_AH },
{ "all", IPFY_ALL },
@@ -1497,58 +1530,43 @@ static struct wordtab ipfwords[] = {
{ "bcast", IPFY_BROADCAST },
{ "block", IPFY_BLOCK },
{ "body", IPFY_BODY },
- { "bpf", IPFY_BPF },
+ { "bpf-v4", IPFY_BPFV4 },
+#ifdef USE_INET6
+ { "bpf-v6", IPFY_BPFV6 },
+#endif
{ "call", IPFY_CALL },
- { "cipso", IPFY_IPOPT_CIPSO },
{ "code", IPFY_ICMPCODE },
- { "confid", IPFY_SEC_CONF },
{ "count", IPFY_COUNT },
- { "divert", IPFY_DIVERT },
- { "dps", IPFY_IPOPT_DPS },
- { "dstopts", IPFY_IPV6OPT_DSTOPTS },
{ "dup-to", IPFY_DUPTO },
- { "e-sec", IPFY_IPOPT_ESEC },
- { "eip", IPFY_IPOPT_EIP },
- { "encode", IPFY_IPOPT_ENCODE },
{ "eq", YY_CMP_EQ },
{ "esp", IPFY_ESP },
{ "fastroute", IPFY_FROUTE },
{ "first", IPFY_FIRST },
- { "finn", IPFY_IPOPT_FINN },
- { "frag", IPFY_FRAG },
{ "flags", IPFY_FLAGS },
+ { "frag", IPFY_FRAG },
+ { "frag-body", IPFY_FRAGBODY },
{ "frags", IPFY_FRAGS },
{ "from", IPFY_FROM },
{ "ge", YY_CMP_GE },
{ "group", IPFY_GROUP },
{ "gt", YY_CMP_GT },
{ "head", IPFY_HEAD },
- { "hopopts", IPFY_IPV6OPT_HOPOPTS },
- { "host-preced", IPFY_ICMPC_HSTPRE },
- { "host-prohib", IPFY_ICMPC_HSTPRO },
- { "host-tos", IPFY_ICMPC_HSTTOS },
- { "host-unk", IPFY_ICMPC_HSTUNK },
- { "host-unr", IPFY_ICMPC_HSTUNR },
{ "icmp", IPFY_ICMP },
{ "icmp-type", IPFY_ICMPTYPE },
- { "imitd", IPFY_IPOPT_IMITD },
{ "in", IPFY_IN },
{ "in-via", IPFY_INVIA },
{ "ipopt", IPFY_IPOPTS },
{ "ipopts", IPFY_IPOPTS },
- { "ipv6", IPFY_IPV6OPT_IPV6 },
{ "keep", IPFY_KEEP },
{ "le", YY_CMP_LE },
{ "level", IPFY_LEVEL },
{ "limit", IPFY_LIMIT },
{ "log", IPFY_LOG },
{ "lowttl", IPFY_LOWTTL },
- { "lsrr", IPFY_IPOPT_LSRR },
{ "lt", YY_CMP_LT },
{ "mask", IPFY_MASK },
+ { "match-tag", IPFY_MATCHTAG },
{ "mbcast", IPFY_MBCAST },
- { "mtup", IPFY_IPOPT_MTUP },
- { "mtur", IPFY_IPOPT_MTUR },
{ "multicast", IPFY_MULTICAST },
{ "nat", IPFY_NAT },
{ "ne", YY_CMP_NE },
@@ -1556,11 +1574,8 @@ static struct wordtab ipfwords[] = {
{ "newisn", IPFY_NEWISN },
{ "no", IPFY_NO },
{ "no-icmp-err", IPFY_NOICMPERR },
- { "none", IPFY_IPV6OPT_NONE },
- { "nop", IPFY_IPOPT_NOP },
{ "now", IPFY_NOW },
{ "not", IPFY_NOT },
- { "nsapa", IPFY_IPOPT_NSAPA },
{ "oow", IPFY_OOW },
{ "on", IPFY_ON },
{ "opt", IPFY_OPT },
@@ -1574,42 +1589,26 @@ static struct wordtab ipfwords[] = {
{ "proto", IPFY_PROTO },
{ "quick", IPFY_QUICK },
{ "reply-to", IPFY_REPLY_TO },
- { "reserv-1", IPFY_SEC_RSV1 },
- { "reserv-2", IPFY_SEC_RSV2 },
- { "reserv-3", IPFY_SEC_RSV3 },
- { "reserv-4", IPFY_SEC_RSV4 },
{ "return-icmp", IPFY_RETICMP },
{ "return-icmp-as-dest", IPFY_RETICMPASDST },
{ "return-rst", IPFY_RETRST },
- { "routing", IPFY_IPV6OPT_ROUTING },
- { "rr", IPFY_IPOPT_RR },
- { "rtralrt", IPFY_IPOPT_RTRALRT },
- { "satid", IPFY_IPOPT_SATID },
- { "sdb", IPFY_IPOPT_SDB },
- { "sec", IPFY_IPOPT_SEC },
+ { "route-to", IPFY_ROUTETO },
{ "sec-class", IPFY_SECCLASS },
- { "secret", IPFY_SEC_SEC },
+ { "set-tag", IPFY_SETTAG },
{ "skip", IPFY_SKIP },
{ "short", IPFY_SHORT },
- { "ssrr", IPFY_IPOPT_SSRR },
{ "state", IPFY_STATE },
+ { "state-age", IPFY_AGE },
{ "strict", IPFY_STRICT },
- { "tag", IPFY_TAG },
+ { "sync", IPFY_SYNC },
{ "tcp", IPFY_TCP },
{ "tcp-udp", IPFY_TCPUDP },
{ "tos", IPFY_TOS },
- { "topsecret", IPFY_SEC_TS },
{ "to", IPFY_TO },
- { "tr", IPFY_IPOPT_TR },
- { "ts", IPFY_IPOPT_TS },
{ "ttl", IPFY_TTL },
{ "udp", IPFY_UDP },
- { "ump", IPFY_IPOPT_UMP },
- { "unclass", IPFY_SEC_UNC },
{ "v6hdrs", IPF6_V6HDRS },
- { "visa", IPFY_IPOPT_VISA },
{ "with", IPFY_WITH },
- { "zsu", IPFY_IPOPT_ZSU },
{ NULL, 0 }
};
@@ -1667,7 +1666,58 @@ static struct wordtab icmpcodewords[17] = {
{ NULL, 0 },
};
-static struct wordtab logwords[] = {
+static struct wordtab ipv4optwords[25] = {
+ { "addext", IPFY_IPOPT_ADDEXT },
+ { "cipso", IPFY_IPOPT_CIPSO },
+ { "dps", IPFY_IPOPT_DPS },
+ { "e-sec", IPFY_IPOPT_ESEC },
+ { "eip", IPFY_IPOPT_EIP },
+ { "encode", IPFY_IPOPT_ENCODE },
+ { "finn", IPFY_IPOPT_FINN },
+ { "imitd", IPFY_IPOPT_IMITD },
+ { "lsrr", IPFY_IPOPT_LSRR },
+ { "mtup", IPFY_IPOPT_MTUP },
+ { "mtur", IPFY_IPOPT_MTUR },
+ { "nop", IPFY_IPOPT_NOP },
+ { "nsapa", IPFY_IPOPT_NSAPA },
+ { "rr", IPFY_IPOPT_RR },
+ { "rtralrt", IPFY_IPOPT_RTRALRT },
+ { "satid", IPFY_IPOPT_SATID },
+ { "sdb", IPFY_IPOPT_SDB },
+ { "sec", IPFY_IPOPT_SEC },
+ { "ssrr", IPFY_IPOPT_SSRR },
+ { "tr", IPFY_IPOPT_TR },
+ { "ts", IPFY_IPOPT_TS },
+ { "ump", IPFY_IPOPT_UMP },
+ { "visa", IPFY_IPOPT_VISA },
+ { "zsu", IPFY_IPOPT_ZSU },
+ { NULL, 0 },
+};
+
+static struct wordtab ipv4secwords[9] = {
+ { "confid", IPFY_SEC_CONF },
+ { "reserv-1", IPFY_SEC_RSV1 },
+ { "reserv-2", IPFY_SEC_RSV2 },
+ { "reserv-3", IPFY_SEC_RSV3 },
+ { "reserv-4", IPFY_SEC_RSV4 },
+ { "secret", IPFY_SEC_SEC },
+ { "topsecret", IPFY_SEC_TS },
+ { "unclass", IPFY_SEC_UNC },
+ { NULL, 0 },
+};
+
+static struct wordtab ipv6optwords[8] = {
+ { "dstopts", IPFY_IPV6OPT_DSTOPTS },
+ { "esp", IPFY_ESP },
+ { "frag", IPFY_FRAG },
+ { "hopopts", IPFY_IPV6OPT_HOPOPTS },
+ { "ipv6", IPFY_IPV6OPT_IPV6 },
+ { "none", IPFY_IPV6OPT_NONE },
+ { "routing", IPFY_IPV6OPT_ROUTING },
+ { NULL, 0 },
+};
+
+static struct wordtab logwords[33] = {
{ "kern", IPFY_FAC_KERN },
{ "user", IPFY_FAC_USER },
{ "mail", IPFY_FAC_MAIL },
@@ -1892,46 +1942,74 @@ char *name;
}
if (gethost(name, &addr) == -1) {
+ fprintf(stderr, "unknown name \"%s\"\n", name);
return 0;
}
return addr;
}
-static void dobpf(phrase)
+static void dobpf(v, phrase)
+int v;
char *phrase;
{
#ifdef IPFILTER_BPF
struct bpf_program bpf;
struct pcap *p;
+#endif
+ fakebpf_t *fb;
u_32_t l;
char *s;
int i;
for (fr = frc; fr != NULL; fr = fr->fr_next) {
if (fr->fr_type != FR_T_NONE) {
- fprintf(stderr, "cannoy mix IPF and BPF matching\n");
+ fprintf(stderr, "cannot mix IPF and BPF matching\n");
return;
}
- fr->fr_type = FR_T_IPF;
+ fr->fr_v = v;
+ fr->fr_type = FR_T_BPFOPC;
if (!strncmp(phrase, "\"0x", 2)) {
phrase++;
- fr->fr_data = malloc(4);
- if (fr->fr_data == NULL)
+ fb = malloc(sizeof(fakebpf_t));
+ if (fb == NULL)
yyerror("sorry, out of memory");
- for (i = 0, s = strtok(phrase, " \r\n\t"; s != NULL;
+ for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL;
s = strtok(NULL, " \r\n\t"), i++) {
- fr->fr_data = realloc(fr->fr_data, (i + 1) * 4);
- if (fr->fr_data == NULL)
+ fb = realloc(fb, (i / 4 + 1) * sizeof(*fb));
+ if (fb == NULL)
yyerror("sorry, out of memory");
l = (u_32_t)strtol(s, NULL, 0);
- ((u_32_t *)fr->fr_data)[i] = l;
+ switch (i & 3)
+ {
+ case 0 :
+ fb[i / 4].fb_c = l & 0xffff;
+ break;
+ case 1 :
+ fb[i / 4].fb_t = l & 0xff;
+ break;
+ case 2 :
+ fb[i / 4].fb_f = l & 0xff;
+ break;
+ case 3 :
+ fb[i / 4].fb_k = l;
+ break;
+ }
}
+ if ((i & 3) != 0) {
+ fprintf(stderr,
+ "Odd number of bytes in BPF code\n");
+ exit(1);
+ }
+ i--;
+ fr->fr_dsize = (i / 4 + 1) * sizeof(*fb);
+ fr->fr_data = fb;
return;
}
+#ifdef IPFILTER_BPF
bzero((char *)&bpf, sizeof(bpf));
p = pcap_open_dead(DLT_RAW, 1);
if (!p) {
@@ -1939,29 +2017,32 @@ char *phrase;
return;
}
- if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff) {
+ if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) {
pcap_perror(p, "ipf");
pcap_close(p);
- fprintf(stderr, "pcap parsing failed\n");
+ fprintf(stderr, "pcap parsing failed (%s)\n", phrase);
return;
}
pcap_close(p);
fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn);
- fr->fr_data = malloc(bpf.bf_len);
+ fr->fr_data = malloc(fr->fr_dsize);
if (fr->fr_data == NULL)
yyerror("sorry, out of memory");
- bcopy((char *)bpf.bf_insns, fr->fr_data, bpf.bf_len);
+ bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize);
if (!bpf_validate(fr->fr_data, bpf.bf_len)) {
fprintf(stderr, "BPF validation failed\n");
return;
}
+#endif
}
+#ifdef IPFILTER_BPF
if (opts & OPT_DEBUG)
bpf_dump(&bpf, 0);
#else
- fprintf(stderr, "BPF expressions for matching not supported\n");
+ fprintf(stderr, "BPF filter expressions not supported\n");
+ exit(1);
#endif
}
@@ -2087,7 +2168,7 @@ int fd;
ioctlfunc_t ioctlfunc;
void *ptr;
{
- u_int add, del;
+ ioctlcmd_t add, del;
frentry_t *fr;
ipfobj_t obj;
@@ -2148,7 +2229,7 @@ void *ptr;
}
} else if ((opts & OPT_REMOVE) != 0) {
if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
- if ((opts & OPT_DONOTHING) == 0) {
+ if ((opts & OPT_DONOTHING) != 0) {
fprintf(stderr, "%d:", yylineNum);
perror("ioctl(delete rule)");
}
@@ -2157,23 +2238,22 @@ void *ptr;
if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
if (!(opts & OPT_DONOTHING)) {
fprintf(stderr, "%d:", yylineNum);
- fprintf(stderr,"ioctl(add/insert rule) failed: rule exists\n");
+ perror("ioctl(add/insert rule)");
}
}
}
}
-
static void setsyslog()
{
- savewords = yysettab(logwords);
+ yysetdict(logwords);
yybreakondot = 1;
}
static void unsetsyslog()
{
- yysettab(savewords);
+ yyresetdict();
yybreakondot = 0;
}
@@ -2182,7 +2262,6 @@ static void fillgroup(fr)
frentry_t *fr;
{
frentry_t *f;
- int i;
for (f = frold; f != NULL; f = f->fr_next)
if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0)
@@ -2192,7 +2271,9 @@ frentry_t *fr;
/*
* Only copy down matching fields if the rules are of the same type
- * and are of ipf type.
+ * and are of ipf type. The only fields that are copied are those
+ * that impact the rule parsing itself, eg. need for knowing what the
+ * protocol should be for rules with port comparisons in them.
*/
if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF)
return;
@@ -2205,36 +2286,7 @@ frentry_t *fr;
if (fr->fr_proto == 0 && f->fr_proto != 0)
fr->fr_proto = f->fr_proto;
- if (fr->fr_proto == IPPROTO_TCP) {
- if (fr->fr_tcpfm == 0 && f->fr_tcpfm != 0)
- fr->fr_tcpfm = f->fr_tcpfm;
- if (fr->fr_tcpf == 0 && f->fr_tcpf != 0)
- fr->fr_tcpf = f->fr_tcpf;
- }
-
- if (fr->fr_proto == IPPROTO_ICMP) {
- if (fr->fr_icmpm == 0 && f->fr_icmpm != 0)
- fr->fr_icmpm = f->fr_icmpm;
- if (fr->fr_icmp == 0 && f->fr_icmp != 0)
- fr->fr_icmp = f->fr_icmp;
- }
-
- if (fr->fr_optbits == 0 && f->fr_optbits != 0)
- fr->fr_optbits = f->fr_optbits;
- if (fr->fr_optmask == 0 && f->fr_optmask != 0)
- fr->fr_optmask = f->fr_optmask;
- if (fr->fr_secbits == 0 && f->fr_secbits != 0)
- fr->fr_secbits = f->fr_secbits;
- if (fr->fr_secmask == 0 && f->fr_secmask != 0)
- fr->fr_secmask = f->fr_secmask;
- if (fr->fr_authbits == 0 && f->fr_authbits != 0)
- fr->fr_authbits = f->fr_authbits;
- if (fr->fr_authmask == 0 && f->fr_authmask != 0)
- fr->fr_authmask = f->fr_authmask;
-
- for (i = 0; i < 3; i++) {
- if (*f->fr_ifnames[i] != '\0' && *fr->fr_ifnames[i] == '\0')
- strncpy(fr->fr_ifnames[i], f->fr_ifnames[i],
- sizeof(f->fr_ifnames[i]));
- }
+ if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) &&
+ ((f->fr_flx & FI_TCPUDP) != 0))
+ fr->fr_flx |= FI_TCPUDP;
}
diff --git a/usr/src/cmd/ipf/tools/ipfcomp.c b/usr/src/cmd/ipf/tools/ipfcomp.c
index 05e0202d73..f09bfd314f 100644
--- a/usr/src/cmd/ipf/tools/ipfcomp.c
+++ b/usr/src/cmd/ipf/tools/ipfcomp.c
@@ -5,7 +5,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: ipfcomp.c,v 1.19 2003/04/09 19:04:33 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.2 2004/04/28 10:34:44 darrenr Exp $";
#endif
#include "ipf.h"
@@ -95,7 +95,9 @@ frentry_t *fr;
fprintf(fp, "#include <sys/types.h>\n");
fprintf(fp, "#include <sys/time.h>\n");
fprintf(fp, "#include <sys/socket.h>\n");
- fprintf(fp, "#include <sys/systm.h>\n");
+ fprintf(fp, "#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n");
+ fprintf(fp, "# include <sys/systm.h>\n");
+ fprintf(fp, "#endif\n");
fprintf(fp, "#include <sys/errno.h>\n");
fprintf(fp, "#include <sys/param.h>\n");
fprintf(fp,
@@ -113,9 +115,14 @@ frentry_t *fr;
fprintf(fp, "#include <netinet/in_systm.h>\n");
fprintf(fp, "#include <netinet/ip.h>\n");
fprintf(fp, "#include <netinet/tcp.h>\n");
- fprintf(fp, "#include \"ip_compat.h\"\n");
- fprintf(fp, "#include \"ip_fil.h\"\n\n");
- fprintf(fp, "#include \"ip_rules.h\"\n\n");
+ fprintf(fp, "#include \"netinet/ip_compat.h\"\n");
+ fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n");
+ fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n");
+ fprintf(fp, "#ifndef _KERNEL\n");
+ fprintf(fp, "# include <string.h>\n");
+ fprintf(fp, "#endif /* _KERNEL */\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#ifdef IPFILTER_COMPILED\n");
}
addrule(fp, fr);
@@ -152,18 +159,9 @@ frentry_t *fr;
int i;
f = (frentry_t *)malloc(sizeof(*f));
- if (f == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
bcopy((char *)fr, (char *)f, sizeof(*fr));
if (fr->fr_ipf) {
f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf));
- if (f->fr_ipf == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf,
sizeof(*fr->fr_ipf));
}
@@ -176,10 +174,6 @@ frentry_t *fr;
if (g == NULL) {
g = (frgroup_t *)calloc(1, sizeof(*g));
- if (g == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
g->fg_next = groups;
groups = g;
g->fg_head = f;
@@ -220,10 +214,6 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n",
break;
if (g == NULL) {
g = (frgroup_t *)calloc(1, sizeof(*g));
- if (g == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
g->fg_next = groups;
groups = g;
g->fg_head = f;
@@ -332,7 +322,9 @@ frentry_t *fr;
}
}
emittail();
+ fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n");
}
+
}
@@ -723,7 +715,7 @@ u_int incount, outcount;
/*
* print out C code that implements a filter rule.
- */
+ */
for (; i < FRC_MAX; i++) {
switch(m[i].c)
{
@@ -941,10 +933,6 @@ u_int incount, outcount;
}
if (n == NULL)
n = (mc_t *)malloc(sizeof(*n) * FRC_MAX);
- if (n == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX);
sin = in;
}
@@ -958,10 +946,6 @@ int dir;
if (m == NULL)
m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX);
- if (m == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
for (g = groups; g != NULL; g = g->fg_next) {
if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0))
@@ -1309,6 +1293,9 @@ int ipfrule_add_%s_%s()\n", instr, group);
fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
(in != 0) ? "IN" : "OUT", instr, group);
+ fprintf(fp, "\
+ fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n",
+ instr, group);
fprintf(fp, "\
fp->fr_v = 4;\n\
diff --git a/usr/src/cmd/ipf/tools/ipfs.c b/usr/src/cmd/ipf/tools/ipfs.c
index 91ee4498ef..e8a5148143 100644
--- a/usr/src/cmd/ipf/tools/ipfs.c
+++ b/usr/src/cmd/ipf/tools/ipfs.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,9 +45,10 @@
#include <arpa/nameser.h>
#include <resolv.h>
#include "ipf.h"
+#include "netinet/ipl.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipfs.c,v 1.9 2003/05/17 09:47:35 darrenr Exp $";
+static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp";
#endif
#ifndef IPF_SAVEDIR
@@ -254,7 +255,7 @@ char *argv[];
set = 1;
break;
case 'r' :
- if ((ns >= 0) || dirname || (rw != -1))
+ if (dirname || (rw != -1) || (ns == -1))
usage();
rw = 0;
set = 1;
@@ -389,6 +390,7 @@ int fd;
char *file;
{
ipstate_save_t ips, *ipsp;
+ ipfobj_t obj;
int wfd = -1;
if (!file)
@@ -402,12 +404,19 @@ char *file;
}
ipsp = &ips;
+ bzero((char *)&obj, sizeof(obj));
bzero((char *)ipsp, sizeof(ips));
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = sizeof(*ipsp);
+ obj.ipfo_type = IPFOBJ_STATESAVE;
+ obj.ipfo_ptr = ipsp;
+
do {
+
if (opts & OPT_VERBOSE)
printf("Getting state from addr %p\n", ips.ips_next);
- if (ioctl(fd, SIOCSTGET, &ipsp)) {
+ if (ioctl(fd, SIOCSTGET, &obj)) {
if (errno == ENOENT)
break;
perror("state:SIOCSTGET");
@@ -434,6 +443,7 @@ char *file;
{
ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL;
int sfd = -1, i;
+ ipfobj_t obj;
if (!file)
file = IPF_STATEFILE;
@@ -460,8 +470,8 @@ char *file;
if (i == 0)
break;
if (i != sizeof(ips)) {
- fprintf(stderr, "incomplete read: %d != %d\n", i,
- (int)sizeof(ips));
+ fprintf(stderr, "state:incomplete read: %d != %d\n",
+ i, (int)sizeof(ips));
close(sfd);
return 1;
}
@@ -502,6 +512,10 @@ char *file;
close(sfd);
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = sizeof(*is);
+ obj.ipfo_type = IPFOBJ_STATESAVE;
+
for (is = ipshead; is; is = is->ips_next) {
if (opts & OPT_VERBOSE)
printf("Loading new state table entry\n");
@@ -509,8 +523,10 @@ char *file;
if (opts & OPT_VERBOSE)
printf("Loading new filter rule\n");
}
+
+ obj.ipfo_ptr = is;
if (!(opts & OPT_DONOTHING))
- if (ioctl(fd, SIOCSTPUT, &is)) {
+ if (ioctl(fd, SIOCSTPUT, &obj)) {
perror("SIOCSTPUT");
return 1;
}
@@ -532,9 +548,12 @@ int readnat(fd, file)
int fd;
char *file;
{
- nat_save_t ipn, *in, *ipnhead, *in1, *ipntail, *ipnp;
+ nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL;
+ ipfobj_t obj;
int nfd, i;
nat_t *nat;
+ char *s;
+ int n;
nfd = -1;
in = NULL;
@@ -552,7 +571,6 @@ char *file;
}
bzero((char *)&ipn, sizeof(ipn));
- ipnp = &ipn;
/*
* 1. Read all state information in.
@@ -567,42 +585,36 @@ char *file;
if (i == 0)
break;
if (i != sizeof(ipn)) {
- fprintf(stderr, "incomplete read: %d != %d\n", i,
- (int)sizeof(ipn));
+ fprintf(stderr, "nat:incomplete read: %d != %d\n",
+ i, (int)sizeof(ipn));
close(nfd);
return 1;
}
- if (ipn.ipn_dsize > 0) {
- char *s = ipnp->ipn_data;
- int n = ipnp->ipn_dsize;
-
- n -= sizeof(ipnp->ipn_data);
- in = malloc(sizeof(*in) + n);
- if (!in)
- break;
+ in = (nat_save_t *)malloc(ipn.ipn_dsize);
+ if (!in)
+ break;
- s += sizeof(ipnp->ipn_data);
- i = read(nfd, s, n);
- if (i == 0)
- break;
- if (i != n) {
- fprintf(stderr, "incomplete read: %d != %d\n",
- i, n);
- close(nfd);
- free(in);
- return 1;
+ if (ipn.ipn_dsize > sizeof(ipn)) {
+ n = ipn.ipn_dsize - sizeof(ipn);
+ if (n > 0) {
+ s = in->ipn_data + sizeof(in->ipn_data);
+ i = read(nfd, s, n);
+ if (i == 0)
+ break;
+ if (i != n) {
+ fprintf(stderr,
+ "nat:incomplete read: %d != %d\n",
+ i, n);
+ close(nfd);
+ return 1;
+ }
}
- } else {
- ipn.ipn_dsize = 0;
- in = (nat_save_t *)malloc(sizeof(*in));
- if (in == NULL)
- break;
}
- bcopy((char *)ipnp, (char *)in, sizeof(ipn));
+ bcopy((char *)&ipn, (char *)in, sizeof(ipn));
/*
- * Check to see if this is the first state entry that will
+ * Check to see if this is the first NAT entry that will
* reference a particular rule and if so, flag it as such
* else just adjust the rule pointer to become a pointer to
* the other. We do this so we have a means later for tracking
@@ -632,6 +644,10 @@ char *file;
} while (1);
close(nfd);
+ nfd = -1;
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_NATSAVE;
for (in = ipnhead; in; in = in->ipn_next) {
if (opts & OPT_VERBOSE)
@@ -641,8 +657,12 @@ char *file;
if (opts & OPT_VERBOSE)
printf("Loading new filter rule\n");
}
+
+ obj.ipfo_ptr = in;
+ obj.ipfo_size = in->ipn_dsize;
if (!(opts & OPT_DONOTHING))
- if (ioctl(fd, SIOCSTPUT, &in)) {
+ if (ioctl(fd, SIOCSTPUT, &obj)) {
+ fprintf(stderr, "in=%p:", in);
perror("SIOCSTPUT");
return 1;
}
@@ -665,6 +685,7 @@ int fd;
char *file;
{
nat_save_t *ipnp = NULL, *next = NULL;
+ ipfobj_t obj;
int nfd = -1;
natget_t ng;
@@ -678,6 +699,8 @@ char *file;
return 1;
}
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_NATSAVE;
do {
if (opts & OPT_VERBOSE)
@@ -709,8 +732,11 @@ char *file;
}
bzero((char *)ipnp, ng.ng_sz);
+ obj.ipfo_size = ng.ng_sz;
+ obj.ipfo_ptr = ipnp;
+ ipnp->ipn_dsize = ng.ng_sz;
ipnp->ipn_next = next;
- if (ioctl(fd, SIOCSTGET, &ipnp)) {
+ if (ioctl(fd, SIOCSTGET, &obj)) {
if (errno == ENOENT)
break;
perror("nat:SIOCSTGET");
@@ -720,8 +746,9 @@ char *file;
}
if (opts & OPT_VERBOSE)
- printf("Got nat next %p\n", ipnp->ipn_next);
- if (write(nfd, ipnp, ng.ng_sz) != ng.ng_sz) {
+ printf("Got nat next %p ipn_dsize %d ng_sz %d\n",
+ ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz);
+ if (write(nfd, ipnp, ipnp->ipn_dsize) != ipnp->ipn_dsize) {
perror("nat:write");
close(nfd);
free(ipnp);
@@ -746,6 +773,7 @@ char *dirname;
dirname = IPF_SAVEDIR;
if (chdir(dirname)) {
+ fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname);
perror("chdir(IPF_SAVEDIR)");
return 1;
}
diff --git a/usr/src/cmd/ipf/tools/ipfstat.c b/usr/src/cmd/ipf/tools/ipfstat.c
index e3de41316c..b2f3195a99 100644
--- a/usr/src/cmd/ipf/tools/ipfstat.c
+++ b/usr/src/cmd/ipf/tools/ipfstat.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -20,14 +20,20 @@
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
-#include <nlist.h>
+#ifdef linux
+# include <linux/a.out.h>
+#else
+# include <nlist.h>
+#endif
#include <ctype.h>
-#include <stddef.h>
+#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
+# include <stddef.h>
+#endif
#include "ipf.h"
-#include "ipl.h"
+#include "netinet/ipl.h"
#if defined(STATETOP)
# if defined(_BSDI_VERSION)
-# undef STATETOP)
+# undef STATETOP
# endif
# if defined(__FreeBSD__) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 430000))
@@ -49,16 +55,15 @@
# include <netinet/tcp_fsm.h>
#endif
#ifdef STATETOP
-#if SOLARIS2 >= 10
-# include "ipl.h"
-#else
-# include "netinet/ipl.h"
-#endif
+# include <ctype.h>
+# include <signal.h>
# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \
defined(__sgi)
# ifdef ERR
# undef ERR
# endif
+# undef ISASCII
+# undef ISPRINT
# include <curses.h>
# else /* SOLARIS */
# include <ncurses.h>
@@ -71,7 +76,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.28 2003/07/01 01:03:04 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.12 2005/06/12 07:18:46 darrenr Exp $";
#endif
#ifdef __hpux
@@ -80,6 +85,7 @@ static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.28 2003/07/01 01:03:04 darre
extern char *optarg;
extern int optind;
+extern int opterr;
#define PRINTF (void)printf
#define FPRINTF (void)fprintf
@@ -107,8 +113,10 @@ int ipf_fd = -1;
#define STSORT_BYTES 2
#define STSORT_TTL 3
#define STSORT_SRCIP 4
-#define STSORT_DSTIP 5
-#define STSORT_MAX STSORT_DSTIP
+#define STSORT_SRCPT 5
+#define STSORT_DSTIP 6
+#define STSORT_DSTPT 7
+#define STSORT_MAX STSORT_DSTPT
#define STSORT_DEFAULT STSORT_BYTES
@@ -118,6 +126,7 @@ typedef struct statetop {
u_short st_sport;
u_short st_dport;
u_char st_p;
+ u_char st_v;
u_char st_state[2];
U_QUAD_T st_pkts;
U_QUAD_T st_bytes;
@@ -125,42 +134,54 @@ typedef struct statetop {
} statetop_t;
#endif
-extern int main __P((int, char *[]));
+int main __P((int, char *[]));
+
static void showstats __P((friostat_t *, u_32_t));
static void showfrstates __P((ipfrstat_t *));
static void showlist __P((friostat_t *));
static void showipstates __P((ips_stat_t *));
static void showauthstates __P((fr_authstat_t *));
static void showgroups __P((friostat_t *));
-static void Usage __P((char *));
+static void usage __P((char *));
static void printlist __P((frentry_t *, char *));
-static void parse_ipportstr __P((const char *, struct in_addr *, int *));
+static void parse_ipportstr __P((const char *, i6addr_t *, int *));
static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **,
ipfrstat_t **, fr_authstat_t **, u_32_t *));
static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **,
ipfrstat_t **, fr_authstat_t **, u_32_t *));
#ifdef STATETOP
-static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int));
+static void topipstates __P((i6addr_t, i6addr_t, int, int, int,
+ int, int, int));
+static void sig_break __P((int));
+static void sig_resize __P((int));
+static char *getip __P((int, i6addr_t *));
static char *ttl_to_string __P((long));
static int sort_p __P((const void *, const void *));
static int sort_pkts __P((const void *, const void *));
static int sort_bytes __P((const void *, const void *));
static int sort_ttl __P((const void *, const void *));
static int sort_srcip __P((const void *, const void *));
+static int sort_srcpt __P((const void *, const void *));
static int sort_dstip __P((const void *, const void *));
+static int sort_dstpt __P((const void *, const void *));
#endif
-static void Usage(name)
+static void usage(name)
char *name;
{
#ifdef USE_INET6
- fprintf(stderr, "Usage: %s [-6aAfhIinosv] [-d <device>]\n", name);
+ fprintf(stderr, "Usage: %s [-6aAdfghIilnoRsv]\n", name);
#else
- fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
+ fprintf(stderr, "Usage: %s [-aAdfghIilnoRsv]\n", name);
#endif
- fprintf(stderr, "\t\t[-M corefile] [-N symbol-list]\n");
- fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
+ fprintf(stderr, " %s [-M corefile] [-N symbol-list]\n", name);
+#ifdef USE_INET6
+ fprintf(stderr, " %s -t [-6C] ", name);
+#else
+ fprintf(stderr, " %s -t [-C] ", name);
+#endif
+ fprintf(stderr, "[-D destination address] [-P protocol] [-S source address] [-T refresh time]\n");
exit(1);
}
@@ -178,27 +199,39 @@ char *argv[];
ipfrstat_t ifrst;
ipfrstat_t *ifrstp = &ifrst;
char *device = IPL_NAME, *memf = NULL;
- char *kern = NULL;
+ char *options, *kern = NULL;
int c, myoptind;
- struct protoent *proto;
int protocol = -1; /* -1 = wild card for any protocol */
int refreshtime = 1; /* default update time */
int sport = -1; /* -1 = wild card for any source port */
int dport = -1; /* -1 = wild card for any dest port */
int topclosed = 0; /* do not show closed tcp sessions */
- struct in_addr saddr, daddr;
+ i6addr_t saddr, daddr;
u_32_t frf;
- saddr.s_addr = INADDR_ANY; /* default any source addr */
- daddr.s_addr = INADDR_ANY; /* default any dest addr */
+#ifdef USE_INET6
+ options = "6aACdfghIilnostvD:M:N:P:RS:T:";
+#else
+ options = "aACdfghIilnostvD:M:N:P:RS:T:";
+#endif
+
+ saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */
+ daddr.in4.s_addr = INADDR_ANY; /* default any v4 dest addr */
+#ifdef USE_INET6
+ saddr.in6 = in6addr_any; /* default any v6 source addr */
+ daddr.in6 = in6addr_any; /* default any v6 dest addr */
+#endif
+
+ /* Don't warn about invalid flags when we run getopt for the 1st time */
+ opterr = 0;
/*
* Parse these two arguments now lest there be any buffer overflows
* in the parsing of the rest.
*/
myoptind = optind;
- while ((c = getopt(argc, argv, "6aACdfghIilnostvD:M:N:P:S:T:")) != -1)
+ while ((c = getopt(argc, argv, options)) != -1) {
switch (c)
{
case 'M' :
@@ -210,32 +243,37 @@ char *argv[];
live_kernel = 0;
break;
}
+ }
optind = myoptind;
if (live_kernel == 1) {
if ((state_fd = open(IPSTATE_NAME, O_RDONLY)) == -1) {
- perror("open");
+ perror("open(IPSTATE_NAME)");
exit(-1);
}
if ((ipf_fd = open(device, O_RDONLY)) == -1) {
- perror("open");
+ fprintf(stderr, "open(%s)", device);
+ perror("");
exit(-1);
}
}
- if (kern != NULL || memf != NULL)
- {
+ if (kern != NULL || memf != NULL) {
(void)setgid(getgid());
(void)setreuid(getuid(), getuid());
}
+ if (live_kernel == 1)
+ (void) checkrev(device);
if (openkmem(kern, memf) == -1)
exit(-1);
(void)setgid(getgid());
(void)setreuid(getuid(), getuid());
- while ((c = getopt(argc, argv, "6aACdfghIilnostvD:M:N:P:S:T:")) != -1)
+ opterr = 1;
+
+ while ((c = getopt(argc, argv, options)) != -1)
{
switch (c)
{
@@ -288,15 +326,16 @@ char *argv[];
opts |= OPT_OUTQUE|OPT_SHOWLIST;
break;
case 'P' :
- if ((proto = getprotobyname(optarg)) != NULL) {
- protocol = proto->p_proto;
- } else if (!sscanf(optarg, "%d", &protocol) ||
- (protocol < 0)) {
- fprintf(stderr, "%s : Invalid protocol: %s\n",
+ protocol = getproto(optarg);
+ if (protocol == -1) {
+ fprintf(stderr, "%s: Invalid protocol: %s\n",
argv[0], optarg);
exit(-2);
}
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 's' :
opts |= OPT_IPSTATES;
break;
@@ -309,7 +348,7 @@ char *argv[];
break;
#else
fprintf(stderr,
- "%s : state top facility not compiled in\n",
+ "%s: state top facility not compiled in\n",
argv[0]);
exit(-2);
#endif
@@ -317,7 +356,7 @@ char *argv[];
if (!sscanf(optarg, "%d", &refreshtime) ||
(refreshtime <= 0)) {
fprintf(stderr,
- "%s : Invalid refreshtime < 1 : %s\n",
+ "%s: Invalid refreshtime < 1 : %s\n",
argv[0], optarg);
exit(-2);
}
@@ -327,7 +366,7 @@ char *argv[];
opts |= OPT_UNDEF;
break;
default :
- Usage(argv[0]);
+ usage(argv[0]);
break;
}
}
@@ -350,21 +389,20 @@ char *argv[];
opts &= ~OPT_OUTQUE;
showlist(fiop);
}
- } else {
- if (opts & OPT_FRSTATES)
- showfrstates(ifrstp);
+ } else if (opts & OPT_FRSTATES)
+ showfrstates(ifrstp);
#ifdef STATETOP
- else if (opts & OPT_STATETOP)
- topipstates(saddr, daddr, sport, dport,
- protocol, refreshtime, topclosed);
+ else if (opts & OPT_STATETOP)
+ topipstates(saddr, daddr, sport, dport, protocol,
+ use_inet6 ? 6 : 4, refreshtime, topclosed);
#endif
- else if (opts & OPT_AUTHSTATS)
- showauthstates(frauthstp);
- else if (opts & OPT_GROUPS)
- showgroups(fiop);
- else
- showstats(fiop, frf);
- }
+ else if (opts & OPT_AUTHSTATS)
+ showauthstates(frauthstp);
+ else if (opts & OPT_GROUPS)
+ showgroups(fiop);
+ else
+ showstats(fiop, frf);
+
return 0;
}
@@ -685,12 +723,12 @@ u_32_t frf;
PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
fp->f_st[0].fr_nom);
- PRINTF(" counted %lu short %lu\n",
+ PRINTF(" counted %lu short %lu\n",
fp->f_st[0].fr_acct, fp->f_st[0].fr_short);
PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
fp->f_st[1].fr_nom);
- PRINTF(" counted %lu short %lu\n",
+ PRINTF(" counted %lu short %lu\n",
fp->f_st[1].fr_acct, fp->f_st[1].fr_short);
PRINTF(" input packets logged:\tblocked %lu passed %lu\n",
fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
@@ -700,10 +738,12 @@ u_32_t frf;
fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl);
PRINTF(" log failures:\t\tinput %lu output %lu\n",
fp->f_st[0].fr_skip, fp->f_st[1].fr_skip);
- PRINTF("fragment state(in):\tkept %lu\tlost %lu\n",
- fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr);
- PRINTF("fragment state(out):\tkept %lu\tlost %lu\n",
- fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr);
+ PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
+ fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr,
+ fp->f_st[0].fr_cfr);
+ PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
+ fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr,
+ fp->f_st[0].fr_cfr);
PRINTF("packet state(in):\tkept %lu\tlost %lu\n",
fp->f_st[0].fr_ads, fp->f_st[0].fr_bads);
PRINTF("packet state(out):\tkept %lu\tlost %lu\n",
@@ -787,7 +827,7 @@ char *comment;
}
printfr(fp, ioctl);
- if (opts & OPT_VERBOSE) {
+ if (opts & OPT_DEBUG) {
binprint(fp, sizeof(*fp));
if (fp->fr_data != NULL && fp->fr_dsize > 0)
binprint(fp->fr_data, fp->fr_dsize);
@@ -902,6 +942,8 @@ ips_stat_t *ipsp;
ipsp->iss_miss);
PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu max bucket\n",
ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_bucketfull);
+ PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n",
+ ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse);
PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n",
ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
@@ -936,13 +978,13 @@ ips_stat_t *ipsp;
if (opts & OPT_VERBOSE) {
PRINTF("\nCurrent bucket sizes :\n");
for (i = 0; i < ipsp->iss_statesize; i++) {
- if ((i % ENTRIES_PER_LINE) == 0)
+ if ((i % ENTRIES_PER_LINE) == 0)
PRINTF("\t");
PRINTF("%4d -> %4lu", i, buckets[i]);
if ((i % ENTRIES_PER_LINE) ==
- (ENTRIES_PER_LINE - 1))
+ (ENTRIES_PER_LINE - 1))
PRINTF("\n");
- else
+ else
PRINTF(" ");
}
PRINTF("\n");
@@ -957,7 +999,8 @@ ips_stat_t *ipsp;
* Print out all the state information currently held in the kernel.
*/
while (ipsp->iss_list != NULL) {
- ipsp->iss_list = printstate(ipsp->iss_list, opts);
+ ipsp->iss_list = printstate(ipsp->iss_list, opts,
+ ipsp->iss_ticks);
}
free(buckets);
@@ -965,39 +1008,52 @@ ips_stat_t *ipsp;
#ifdef STATETOP
-static void topipstates(saddr, daddr, sport, dport, protocol,
+static int handle_resize = 0, handle_break = 0;
+
+static void topipstates(saddr, daddr, sport, dport, protocol, ver,
refreshtime, topclosed)
-struct in_addr saddr;
-struct in_addr daddr;
+i6addr_t saddr;
+i6addr_t daddr;
int sport;
int dport;
int protocol;
+int ver;
int refreshtime;
int topclosed;
{
char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE];
int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT;
- int i, j, winx, tsentry, maxx, maxy, redraw = 0;
+ int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0;
+ int len, srclen, dstlen, forward = 1, c = 0;
ips_stat_t ipsst, *ipsstp = &ipsst;
statetop_t *tstable = NULL, *tp;
+ const char *errstr = "";
ipstate_t ips;
ipfobj_t ipfo;
- struct timeval selecttimeout;
+ struct timeval selecttimeout;
char hostnm[HOSTNMLEN];
struct protoent *proto;
fd_set readfd;
- int c = 0;
time_t t;
+ /* install signal handlers */
+ signal(SIGINT, sig_break);
+ signal(SIGQUIT, sig_break);
+ signal(SIGTERM, sig_break);
+ signal(SIGWINCH, sig_resize);
+
/* init ncurses stuff */
initscr();
cbreak();
noecho();
+ curs_set(0);
+ timeout(0);
+ getmaxyx(stdscr, maxy, maxx);
/* init hostname */
gethostname(hostnm, sizeof(hostnm) - 1);
hostnm[sizeof(hostnm) - 1] = '\0';
-
+
/* init ipfobj_t stuff */
bzero((caddr_t)&ipfo, sizeof(ipfo));
ipfo.ipfo_rev = IPFILTER_VERSION;
@@ -1011,73 +1067,111 @@ int topclosed;
/* get state table */
bzero((char *)&ipsst, sizeof(ipsst));
if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) {
- perror("ioctl(SIOCGETFS)");
- break;
+ errstr = "ioctl(SIOCGETFS)";
+ ret = -1;
+ goto out;
}
/* clear the history */
tsentry = -1;
+ /* reset max str len */
+ srclen = dstlen = 0;
+
/* read the state table and store in tstable */
- while (ipsstp->iss_list) {
+ for (; ipsstp->iss_list; ipsstp->iss_list = ips.is_next) {
+
if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list,
sizeof(ips)))
break;
- ipsstp->iss_list = ips.is_next;
-
- if (((saddr.s_addr == INADDR_ANY) ||
- (saddr.s_addr == ips.is_saddr)) &&
- ((daddr.s_addr == INADDR_ANY) ||
- (daddr.s_addr == ips.is_daddr)) &&
- ((protocol < 0) || (protocol == ips.is_p)) &&
- (((ips.is_p != IPPROTO_TCP) &&
- (ips.is_p != IPPROTO_UDP)) ||
- (((sport < 0) ||
- (htons(sport) == ips.is_sport)) &&
- ((dport < 0) ||
- (htons(dport) == ips.is_dport)))) &&
- (topclosed || (ips.is_p != IPPROTO_TCP) ||
- (ips.is_state[0] < TCPS_LAST_ACK) ||
- (ips.is_state[1] < TCPS_LAST_ACK))) {
- /*
- * if necessary make room for this state
- * entry
- */
- tsentry++;
- if (!maxtsentries ||
- (tsentry == maxtsentries)) {
-
- maxtsentries += STGROWSIZE;
- tstable = realloc(tstable, maxtsentries * sizeof(statetop_t));
- if (!tstable) {
- perror("malloc");
- goto breakout;
- }
- }
- /* fill structure */
- tp = tstable + tsentry;
- tp->st_src = ips.is_src;
- tp->st_dst = ips.is_dst;
- tp->st_p = ips.is_p;
- tp->st_state[0] = ips.is_state[0];
- tp->st_state[1] = ips.is_state[1];
- tp->st_pkts = ips.is_pkts[0] + ips.is_pkts[1];
- tp->st_bytes = ips.is_bytes[0] +
- ips.is_bytes[1];
- tp->st_age = ips.is_die - ipsstp->iss_ticks;
- if ((ips.is_p == IPPROTO_TCP) ||
- (ips.is_p == IPPROTO_UDP)) {
- tp->st_sport = ips.is_sport;
- tp->st_dport = ips.is_dport;
+ if (ips.is_v != ver)
+ continue;
+
+ /* check v4 src/dest addresses */
+ if (ips.is_v == 4) {
+ if ((saddr.in4.s_addr != INADDR_ANY &&
+ saddr.in4.s_addr != ips.is_saddr) ||
+ (daddr.in4.s_addr != INADDR_ANY &&
+ daddr.in4.s_addr != ips.is_daddr))
+ continue;
+ }
+#ifdef USE_INET6
+ /* check v6 src/dest addresses */
+ if (ips.is_v == 6) {
+ if ((IP6_NEQ(&saddr, &in6addr_any) &&
+ IP6_NEQ(&saddr, &ips.is_src)) ||
+ (IP6_NEQ(&daddr, &in6addr_any) &&
+ IP6_NEQ(&daddr, &ips.is_dst)))
+ continue;
+ }
+#endif
+ /* check protocol */
+ if (protocol > 0 && protocol != ips.is_p)
+ continue;
+
+ /* check ports if protocol is TCP or UDP */
+ if (((ips.is_p == IPPROTO_TCP) ||
+ (ips.is_p == IPPROTO_UDP)) &&
+ (((sport > 0) && (htons(sport) != ips.is_sport)) ||
+ ((dport > 0) && (htons(dport) != ips.is_dport))))
+ continue;
+
+ /* show closed TCP sessions ? */
+ if ((topclosed == 0) && (ips.is_p == IPPROTO_TCP) &&
+ (ips.is_state[0] >= IPF_TCPS_LAST_ACK) &&
+ (ips.is_state[1] >= IPF_TCPS_LAST_ACK))
+ continue;
+
+ /*
+ * if necessary make room for this state
+ * entry
+ */
+ tsentry++;
+ if (!maxtsentries || tsentry == maxtsentries) {
+ maxtsentries += STGROWSIZE;
+ tstable = realloc(tstable,
+ maxtsentries * sizeof(statetop_t));
+ if (tstable == NULL) {
+ perror("realloc");
+ exit(-1);
}
+ }
+ /* get max src/dest address string length */
+ len = strlen(getip(ips.is_v, &ips.is_src));
+ if (srclen < len)
+ srclen = len;
+ len = strlen(getip(ips.is_v, &ips.is_dst));
+ if (dstlen < len)
+ dstlen = len;
+
+ /* fill structure */
+ tp = tstable + tsentry;
+ tp->st_src = ips.is_src;
+ tp->st_dst = ips.is_dst;
+ tp->st_p = ips.is_p;
+ tp->st_v = ips.is_v;
+ tp->st_state[0] = ips.is_state[0];
+ tp->st_state[1] = ips.is_state[1];
+ if (forward) {
+ tp->st_pkts = ips.is_pkts[0]+ips.is_pkts[1];
+ tp->st_bytes = ips.is_bytes[0]+ips.is_bytes[1];
+ } else {
+ tp->st_pkts = ips.is_pkts[2]+ips.is_pkts[3];
+ tp->st_bytes = ips.is_bytes[2]+ips.is_bytes[3];
+ }
+ tp->st_age = ips.is_die - ipsstp->iss_ticks;
+ if ((ips.is_p == IPPROTO_TCP) ||
+ (ips.is_p == IPPROTO_UDP)) {
+ tp->st_sport = ips.is_sport;
+ tp->st_dport = ips.is_dport;
}
}
/* sort the array */
- if (tsentry != -1)
+ if (tsentry != -1) {
switch (sorting)
{
case STSORT_PR:
@@ -1100,20 +1194,45 @@ int topclosed;
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_srcip);
break;
+ case STSORT_SRCPT:
+ qsort(tstable, tsentry +1,
+ sizeof(statetop_t), sort_srcpt);
+ break;
case STSORT_DSTIP:
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_dstip);
break;
+ case STSORT_DSTPT:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_dstpt);
+ break;
default:
break;
}
+ }
+
+ /* handle window resizes */
+ if (handle_resize) {
+ endwin();
+ initscr();
+ cbreak();
+ noecho();
+ curs_set(0);
+ timeout(0);
+ getmaxyx(stdscr, maxy, maxx);
+ redraw = 1;
+ handle_resize = 0;
+ }
+
+ /* stop program? */
+ if (handle_break)
+ break;
/* print title */
erase();
- getmaxyx(stdscr, maxy, maxx);
attron(A_BOLD);
- winx = 0;
- move(winx,0);
+ winy = 0;
+ move(winy,0);
sprintf(str1, "%s - %s - state top", hostnm, IPL_VERSION);
for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++)
printw(" ");
@@ -1121,30 +1240,30 @@ int topclosed;
attroff(A_BOLD);
/* just for fun add a clock */
- move(winx, maxx - 8);
+ move(winy, maxx - 8);
t = time(NULL);
strftime(str1, 80, "%T", localtime(&t));
printw("%s\n", str1);
/*
- * print the display filters, this is placed in the loop,
+ * print the display filters, this is placed in the loop,
* because someday I might add code for changing these
* while the programming is running :-)
*/
if (sport >= 0)
- sprintf(str1, "%s,%d", inet_ntoa(saddr), sport);
+ sprintf(str1, "%s,%d", getip(ver, &saddr), sport);
else
- sprintf(str1, "%s", inet_ntoa(saddr));
+ sprintf(str1, "%s", getip(ver, &saddr));
if (dport >= 0)
- sprintf(str2, "%s,%d", inet_ntoa(daddr), dport);
+ sprintf(str2, "%s,%d", getip(ver, &daddr), dport);
else
- sprintf(str2, "%s", inet_ntoa(daddr));
+ sprintf(str2, "%s", getip(ver, &daddr));
if (protocol < 0)
strcpy(str3, "any");
else if ((proto = getprotobynumber(protocol)) != NULL)
- sprintf(str3, "%s", proto->p_name);
+ sprintf(str3, "%s", proto->p_name);
else
sprintf(str3, "%d", protocol);
@@ -1163,10 +1282,16 @@ int topclosed;
sprintf(str4, "ttl");
break;
case STSORT_SRCIP:
- sprintf(str4, "srcip");
+ sprintf(str4, "src ip");
+ break;
+ case STSORT_SRCPT:
+ sprintf(str4, "src port");
break;
case STSORT_DSTIP:
- sprintf(str4, "dstip");
+ sprintf(str4, "dest ip");
+ break;
+ case STSORT_DSTPT:
+ sprintf(str4, "dest port");
break;
default:
sprintf(str4, "unknown");
@@ -1176,17 +1301,33 @@ int topclosed;
if (reverse)
strcat(str4, " (reverse)");
- winx += 2;
- move(winx,0);
- printw("Src = %s Dest = %s Proto = %s Sorted by = %s\n\n",
+ winy += 2;
+ move(winy,0);
+ printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n",
str1, str2, str3, str4);
+ /*
+ * For an IPv4 IP address we need at most 15 characters,
+ * 4 tuples of 3 digits, separated by 3 dots. Enforce this
+ * length, so the colums do not change positions based
+ * on the size of the IP address. This length makes the
+ * output fit in a 80 column terminal.
+ * We are lacking a good solution for IPv6 addresses (that
+ * can be longer that 15 characters), so we do not enforce
+ * a maximum on the IP field size.
+ */
+ if (srclen < 15)
+ srclen = 15;
+ if (dstlen < 15)
+ dstlen = 15;
+
/* print column description */
- winx += 2;
- move(winx,0);
+ winy += 2;
+ move(winy,0);
attron(A_BOLD);
- printw("%-21s %-21s %3s %4s %7s %9s %9s\n", "Source IP",
- "Destination IP", "ST", "PR", "#pkts", "#bytes", "ttl");
+ printw("%-*s %-*s %3s %4s %7s %9s %9s\n",
+ srclen + 6, "Source IP", dstlen + 6, "Destination IP",
+ "ST", "PR", "#pkts", "#bytes", "ttl");
attroff(A_BOLD);
/* print all the entries */
@@ -1201,25 +1342,27 @@ int topclosed;
if ((tp->st_p == IPPROTO_TCP) ||
(tp->st_p == IPPROTO_UDP)) {
sprintf(str1, "%s,%hu",
- inet_ntoa(tp->st_src.in4),
+ getip(tp->st_v, &tp->st_src),
ntohs(tp->st_sport));
sprintf(str2, "%s,%hu",
- inet_ntoa(tp->st_dst.in4),
+ getip(tp->st_v, &tp->st_dst),
ntohs(tp->st_dport));
} else {
- sprintf(str1, "%s", inet_ntoa(tp->st_src.in4));
- sprintf(str2, "%s", inet_ntoa(tp->st_dst.in4));
+ sprintf(str1, "%s", getip(tp->st_v,
+ &tp->st_src));
+ sprintf(str2, "%s", getip(tp->st_v,
+ &tp->st_dst));
}
- winx++;
- move(winx, 0);
- printw("%-21s %-21s", str1, str2);
+ winy++;
+ move(winy, 0);
+ printw("%-*s %-*s", srclen + 6, str1, dstlen + 6, str2);
/* print state */
sprintf(str1, "%X/%X", tp->st_state[0],
tp->st_state[1]);
printw(" %3s", str1);
- /* print proto */
+ /* print protocol */
proto = getprotobynumber(tp->st_p);
if (proto) {
strncpy(str1, proto->p_name, 4);
@@ -1227,8 +1370,12 @@ int topclosed;
} else {
sprintf(str1, "%d", tp->st_p);
}
+ /* just print icmp for IPv6-ICMP */
+ if (tp->st_p == IPPROTO_ICMPV6)
+ strcpy(str1, "icmp");
printw(" %4s", str1);
- /* print #pkt/#bytes */
+
+ /* print #pkt/#bytes */
#ifdef USE_QUAD_T
printw(" %7qu %9qu", (unsigned long long) tp->st_pkts,
(unsigned long long) tp->st_bytes);
@@ -1247,7 +1394,8 @@ int topclosed;
if (redraw)
clearok(stdscr,1);
- refresh();
+ if (refresh() == ERR)
+ break;
if (redraw) {
clearok(stdscr,0);
redraw = 0;
@@ -1266,27 +1414,34 @@ int topclosed;
if (c == ERR)
continue;
- if (tolower(c) == 'l') {
+ if (ISALPHA(c) && ISUPPER(c))
+ c = TOLOWER(c);
+ if (c == 'l') {
redraw = 1;
- } else if (tolower(c) == 'q') {
+ } else if (c == 'q') {
break;
- } else if (tolower(c) == 'r') {
+ } else if (c == 'r') {
reverse = !reverse;
- } else if (tolower(c) == 's') {
- sorting++;
- if (sorting > STSORT_MAX)
+ } else if (c == 'b') {
+ forward = 0;
+ } else if (c == 'f') {
+ forward = 1;
+ } else if (c == 's') {
+ if (++sorting > STSORT_MAX)
sorting = 0;
}
}
} /* while */
-breakout:
+out:
printw("\n");
+ curs_set(1);
nocbreak();
endwin();
- if (tstable != NULL)
- free(tstable);
+ free(tstable);
+ if (ret != 0)
+ perror(errstr);
}
#endif
@@ -1298,7 +1453,6 @@ static void showfrstates(ifsp)
ipfrstat_t *ifsp;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
- frentry_t fr;
int i;
/*
@@ -1306,7 +1460,8 @@ ipfrstat_t *ifsp;
*/
PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits);
- PRINTF("\t%lu retrans\n\t%lu too short\n", ifsp->ifs_retrans0, ifsp->ifs_short);
+ PRINTF("\t%lu retrans\n\t%lu too short\n",
+ ifsp->ifs_retrans0, ifsp->ifs_short);
PRINTF("\t%lu no memory\n\t%lu already exist\n",
ifsp->ifs_nomem, ifsp->ifs_exists);
PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
@@ -1316,36 +1471,26 @@ ipfrstat_t *ifsp;
/*
* Print out the contents (if any) of the fragment cache table.
*/
+ PRINTF("\n");
for (i = 0; i < IPFT_SIZE; i++)
- while (ipfrtab[i]) {
+ while (ipfrtab[i] != NULL) {
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
sizeof(ifr)) == -1)
break;
- PRINTF("%s -> ", hostname(4, &ifr.ipfr_src));
- if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
- sizeof(fr)) == -1)
- break;
- PRINTF("%s %d %d %d %#02x = %#x\n",
- hostname(4, &ifr.ipfr_dst), ifr.ipfr_id,
- ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
- fr.fr_flags);
+ printfraginfo("", &ifr);
ipfrtab[i] = ifr.ipfr_next;
}
+ /*
+ * Print out the contents (if any) of the NAT fragment cache table.
+ */
if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab)))
return;
for (i = 0; i < IPFT_SIZE; i++)
- while (ipfrtab[i]) {
+ while (ipfrtab[i] != NULL) {
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
sizeof(ifr)) == -1)
break;
- PRINTF("NAT: %s -> ", hostname(4, &ifr.ipfr_src));
- if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
- sizeof(fr)) == -1)
- break;
- PRINTF("%s %d %d %d %#02x = %#x\n",
- hostname(4, &ifr.ipfr_dst), ifr.ipfr_id,
- ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
- fr.fr_flags);
+ printfraginfo("NAT: ", &ifr);
ipfrtab[i] = ifr.ipfr_next;
}
}
@@ -1393,6 +1538,7 @@ static void showgroups(fiop)
struct friostat *fiop;
{
static char *gnames[3] = { "Filter", "Accounting", "Authentication" };
+ static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH };
frgroup_t *fp, grp;
int on, off, i;
@@ -1401,13 +1547,15 @@ struct friostat *fiop;
for (i = 0; i < 3; i++) {
printf("%s groups (active):\n", gnames[i]);
- for (fp = fiop->f_groups[i][on]; fp; fp = grp.fg_next)
+ for (fp = fiop->f_groups[gnums[i]][on]; fp != NULL;
+ fp = grp.fg_next)
if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp)))
break;
else
printf("%s\n", grp.fg_name);
printf("%s groups (inactive):\n", gnames[i]);
- for (fp = fiop->f_groups[i][off]; fp; fp = grp.fg_next)
+ for (fp = fiop->f_groups[gnums[i]][off]; fp != NULL;
+ fp = grp.fg_next)
if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp)))
break;
else
@@ -1417,11 +1565,11 @@ struct friostat *fiop;
static void parse_ipportstr(argument, ip, port)
const char *argument;
-struct in_addr *ip;
+i6addr_t *ip;
int *port;
{
-
char *s, *comma;
+ int ok = 0;
/* make working copy of argument, Theoretically you must be able
* to write to optarg, but that seems very ugly to me....
@@ -1447,8 +1595,16 @@ int *port;
/* get ip address */
if (!strcasecmp(s, "any")) {
- ip->s_addr = INADDR_ANY;
- } else if (!inet_aton(s, ip)) {
+ ip->in4.s_addr = INADDR_ANY;
+#ifdef USE_INET6
+ ip->in6 = in6addr_any;
+ } else if (use_inet6 && inet_pton(AF_INET6, s, &ip->in6)) {
+ ok = 1;
+#endif
+ } else if (inet_aton(s, &ip->in4))
+ ok = 1;
+
+ if (ok == 0) {
fprintf(stderr, "Invalid IP address: %s\n", s);
free(s);
exit(-2);
@@ -1460,12 +1616,43 @@ int *port;
#ifdef STATETOP
-static char ttlbuf[STSTRSIZE];
+static void sig_resize(s)
+int s;
+{
+ handle_resize = 1;
+}
+
+static void sig_break(s)
+int s;
+{
+ handle_break = 1;
+}
+
+static char *getip(v, addr)
+int v;
+i6addr_t *addr;
+{
+#ifdef USE_INET6
+ static char hostbuf[MAXHOSTNAMELEN+1];
+#endif
+
+ if (v == 4)
+ return inet_ntoa(addr->in4);
+
+#ifdef USE_INET6
+ (void) inet_ntop(AF_INET6, &addr->in6, hostbuf, sizeof(hostbuf) - 1);
+ hostbuf[MAXHOSTNAMELEN] = '\0';
+ return hostbuf;
+#else
+ return "IPv6";
+#endif
+}
+
static char *ttl_to_string(ttl)
long int ttl;
{
-
+ static char ttlbuf[STSTRSIZE];
int hours, minutes, seconds;
/* ttl is in half seconds */
@@ -1476,7 +1663,7 @@ long int ttl;
minutes = ttl / 60;
seconds = ttl % 60;
- if (hours > 0 )
+ if (hours > 0)
sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds);
else
sprintf(ttlbuf, "%2d:%02d", minutes, seconds);
@@ -1551,9 +1738,35 @@ const void *b;
register const statetop_t *ap = a;
register const statetop_t *bp = b;
- if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr))
+#ifdef USE_INET6
+ if (use_inet6) {
+ if (IP6_EQ(&ap->st_src, &bp->st_src))
+ return 0;
+ else if (IP6_GT(&ap->st_src, &bp->st_src))
+ return 1;
+ } else
+#endif
+ {
+ if (ntohl(ap->st_src.in4.s_addr) ==
+ ntohl(bp->st_src.in4.s_addr))
+ return 0;
+ else if (ntohl(ap->st_src.in4.s_addr) >
+ ntohl(bp->st_src.in4.s_addr))
+ return 1;
+ }
+ return -1;
+}
+
+static int sort_srcpt(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (htons(ap->st_sport) == htons(bp->st_sport))
return 0;
- else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr))
+ else if (htons(ap->st_sport) > htons(bp->st_sport))
return 1;
return -1;
}
@@ -1565,10 +1778,37 @@ const void *b;
register const statetop_t *ap = a;
register const statetop_t *bp = b;
- if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr))
+#ifdef USE_INET6
+ if (use_inet6) {
+ if (IP6_EQ(&ap->st_dst, &bp->st_dst))
+ return 0;
+ else if (IP6_GT(&ap->st_dst, &bp->st_dst))
+ return 1;
+ } else
+#endif
+ {
+ if (ntohl(ap->st_dst.in4.s_addr) ==
+ ntohl(bp->st_dst.in4.s_addr))
+ return 0;
+ else if (ntohl(ap->st_dst.in4.s_addr) >
+ ntohl(bp->st_dst.in4.s_addr))
+ return 1;
+ }
+ return -1;
+}
+
+static int sort_dstpt(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (htons(ap->st_dport) == htons(bp->st_dport))
return 0;
- else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr))
+ else if (htons(ap->st_dport) > htons(bp->st_dport))
return 1;
return -1;
}
+
#endif
diff --git a/usr/src/cmd/ipf/tools/ipftest.c b/usr/src/cmd/ipf/tools/ipftest.c
index 3ea511e326..9704597bd9 100644
--- a/usr/src/cmd/ipf/tools/ipftest.c
+++ b/usr/src/cmd/ipf/tools/ipftest.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -16,7 +16,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipftest.c,v 1.35 2003/07/01 01:03:04 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipftest.c,v 1.44.2.4 2005/07/16 06:05:28 darrenr Exp $";
#endif
extern char *optarg;
@@ -29,7 +29,7 @@ extern int fr_running;
ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert;
ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock;
-ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw;
+ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw, ipf_frcache;
ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
int opts = OPT_DONOTHING;
int use_inet6 = 0;
@@ -47,7 +47,7 @@ void fixv4sums __P((mb_t *, ip_t *));
#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \
- defined(__osf__)
+ defined(__osf__) || defined(linux)
int ipftestioctl __P((int, ioctlcmd_t, ...));
int ipnattestioctl __P((int, ioctlcmd_t, ...));
int ipstatetestioctl __P((int, ioctlcmd_t, ...));
@@ -101,19 +101,15 @@ char *argv[];
MUTEX_INIT(&ipf_timeoutlock, "ipf timeout lock");
RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
+ RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock");
initparse();
- fr_loginit();
- fr_authinit();
- fr_fraginit();
- fr_stateinit();
- fr_natinit();
- appr_init();
- ip_lookup_init();
+ if (fr_initialise() == -1)
+ abort();
fr_running = 1;
- while ((c = getopt(argc, argv, "6bdDF:i:I:l:N:P:or:vxX")) != -1)
+ while ((c = getopt(argc, argv, "6bdDF:i:I:l:N:P:or:RT:vxX")) != -1)
switch (c)
{
case '6' :
@@ -165,6 +161,9 @@ char *argv[];
return -1;
loaded = 1;
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
@@ -180,6 +179,9 @@ char *argv[];
return -1;
loaded = 1;
break;
+ case 'T' :
+ ipf_dotuning(-1, optarg, ipftestioctl);
+ break;
case 'x' :
opts |= OPT_HEX;
break;
@@ -272,7 +274,7 @@ char *argv[];
} else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF))
printpacket(ip);
if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL))
-#if defined(__sgi) && (IRIX < 605)
+#if defined(__sgi) && (IRIX < 60500)
(*ifp->if_output)(ifp, (void *)m, NULL);
#else
# if TRU64 >= 1885
@@ -303,19 +305,7 @@ char *argv[];
dumpgroups();
}
- for (i = IPL_LOGMAX; i >= 0; i--)
- (void) ipflog_clear(i);
-
- fr_fragunload();
- fr_authunload();
- fr_stateunload();
- fr_natunload();
- appr_unload();
-
- i = frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
- i += frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE);
-
- ip_lookup_unload();
+ fr_deinitialise();
return 0;
}
@@ -323,7 +313,7 @@ char *argv[];
#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \
- defined(__osf__)
+ defined(__osf__) || defined(linux)
int ipftestioctl(int dev, ioctlcmd_t cmd, ...)
{
caddr_t data;
@@ -338,7 +328,11 @@ int ipftestioctl(int dev, ioctlcmd_t cmd, ...)
if (opts & OPT_DEBUG)
fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -356,7 +350,11 @@ int ipnattestioctl(int dev, ioctlcmd_t cmd, ...)
if (opts & OPT_DEBUG)
fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -374,7 +372,11 @@ int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...)
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -392,7 +394,11 @@ int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...)
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -410,7 +416,11 @@ int ipscantestioctl(int dev, ioctlcmd_t cmd, ...)
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -428,7 +438,11 @@ int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...)
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -446,7 +460,11 @@ int ipooltestioctl(int dev, ioctlcmd_t cmd, ...)
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n",
(u_int)cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
#else
int ipftestioctl(dev, cmd, data)
@@ -459,7 +477,11 @@ void *data;
i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -473,7 +495,11 @@ void *data;
i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -487,7 +513,11 @@ void *data;
i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -501,7 +531,11 @@ void *data;
i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -515,7 +549,11 @@ void *data;
i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -529,7 +567,11 @@ void *data;
i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
@@ -543,7 +585,11 @@ void *data;
i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", cmd, data, i);
- return i;
+ if (i != 0) {
+ errno = i;
+ return -1;
+ }
+ return 0;
}
#endif
@@ -585,8 +631,11 @@ void dumpnat()
for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next)
printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
printf("\nList of active sessions:\n");
- for (nat = nat_instances; nat; nat = nat->nat_next)
+ for (nat = nat_instances; nat; nat = nat->nat_next) {
printactivenat(nat, opts);
+ if (nat->nat_aps)
+ printaps(nat->nat_aps, opts);
+ }
}
@@ -599,7 +648,8 @@ void dumpstate()
printf("List of active state sessions:\n");
for (ips = ips_list; ips != NULL; )
- ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE));
+ ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE),
+ fr_ticks);
}
@@ -612,12 +662,12 @@ void dumplookups()
printf("List of configured pools\n");
for (i = 0; i < IPL_LOGSIZE; i++)
for (ipl = ip_pool_list[i]; ipl != NULL; ipl = ipl->ipo_next)
- printpool(ipl, bcopywrap, opts);
+ printpool(ipl, bcopywrap, NULL, opts);
printf("List of configured hash tables\n");
for (i = 0; i < IPL_LOGSIZE; i++)
for (iph = ipf_htables[i]; iph != NULL; iph = iph->iph_next)
- printhash(iph, bcopywrap, opts);
+ printhash(iph, bcopywrap, NULL, opts);
}
@@ -666,7 +716,7 @@ char *filename;
struct iovec iov;
struct uio uio;
size_t resid;
- int fd;
+ int fd, i;
fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
if (fd == -1) {
@@ -674,26 +724,27 @@ char *filename;
return;
}
- while (1) {
- bzero((char *)&iov, sizeof(iov));
- iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
-
- bzero((char *)&uio, sizeof(uio));
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = iov.iov_len;
- resid = uio.uio_resid;
-
- if (ipflog_read(0, &uio) == 0) {
- /*
- * If nothing was read then break out.
- */
- if (uio.uio_resid == resid)
+ for (i = 0; i <= IPL_LOGMAX; i++)
+ while (1) {
+ bzero((char *)&iov, sizeof(iov));
+ iov.iov_base = buffer;
+ iov.iov_len = sizeof(buffer);
+
+ bzero((char *)&uio, sizeof(uio));
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_resid = iov.iov_len;
+ resid = uio.uio_resid;
+
+ if (ipflog_read(i, &uio) == 0) {
+ /*
+ * If nothing was read then break out.
+ */
+ if (uio.uio_resid == resid)
+ break;
+ write(fd, buffer, resid - uio.uio_resid);
+ } else
break;
- write(fd, buffer, resid - uio.uio_resid);
- } else
- break;
}
close(fd);
diff --git a/usr/src/cmd/ipf/tools/ipmon.c b/usr/src/cmd/ipf/tools/ipmon.c
index 80fbcbe753..0cacc6ce54 100644
--- a/usr/src/cmd/ipf/tools/ipmon.c
+++ b/usr/src/cmd/ipf/tools/ipmon.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <fcntl.h>
#include <errno.h>
+#include <time.h>
#if !defined(__SVR4) && !defined(__svr4__)
# if (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@@ -49,7 +50,7 @@
#include <netinet/in_systm.h>
#include <net/if.h>
#include <netinet/ip.h>
-#if !defined(__hpux)
+#if !defined(__hpux) && !defined(linux)
# include <netinet/tcp_fsm.h>
#endif
#include <netdb.h>
@@ -60,8 +61,10 @@
#endif
#include <resolv.h>
-#include <sys/protosw.h>
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
@@ -69,26 +72,17 @@
#include <ctype.h>
#include <syslog.h>
-#include <netinet/tcpip.h>
-
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#else
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
-#endif
#include "ipmon.h"
#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.22 2003/06/14 02:56:57 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.10 2005/06/18 02:41:35 darrenr Exp $";
#endif
@@ -146,10 +140,8 @@ static char *pidfile = "/etc/ipmon.pid";
static char line[2048];
static int opts = 0;
-static FILE *newlog = NULL;
static char *logfile = NULL;
static FILE *binarylog = NULL;
-static FILE *newbinarylog = NULL;
static char *binarylogfile = NULL;
static int donehup = 0;
static void usage __P((char *));
@@ -401,17 +393,7 @@ size_t tablesz;
static void handlehup(sig)
int sig;
{
- FILE *fp;
-
signal(SIGHUP, handlehup);
- if (logfile && (fp = fopen(logfile, "a")))
- newlog = fp;
- if (binarylogfile && (fp = fopen(binarylogfile, "a")))
- newbinarylog = fp;
- init_tabs();
- if (conf_file)
- if (load_config(conf_file) == -1)
- exit(1);
donehup = 1;
}
@@ -442,6 +424,14 @@ static void init_tabs()
p->p_name != NULL && protocols[p->p_proto] == NULL)
protocols[p->p_proto] = strdup(p->p_name);
endprotoent();
+#if defined(_AIX51)
+ if (protocols[0])
+ free(protocols[0]);
+ if (protocols[252])
+ free(protocols[252]);
+ protocols[0] = "ip";
+ protocols[252] = NULL;
+#endif
}
if (udp_ports != NULL) {
@@ -678,7 +668,7 @@ int len;
sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
- *t++ = (isprint(*s) ? *s : '.');
+ *t++ = (ISPRINT(*s) ? *s : '.');
s--;
}
@@ -696,7 +686,7 @@ int len;
t += 7;
s -= j & 0xf;
for (k = j & 0xf; k; k--, s++)
- *t++ = (isprint(*s) ? *s : '.');
+ *t++ = (ISPRINT(*s) ? *s : '.');
*t++ = '\n';
*t = '\0';
}
@@ -787,7 +777,7 @@ int blen;
(long long)nl->nl_bytes[0],
(long long)nl->nl_bytes[1]);
#else
- (void) sprintf(t, " Pkts %ld Bytes %ld",
+ (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld",
nl->nl_pkts[0], nl->nl_pkts[1],
nl->nl_bytes[0], nl->nl_bytes[1]);
#endif
@@ -876,6 +866,13 @@ int blen;
(void) sprintf(t, "%s PR icmpv6 %d",
hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
+ } else {
+ (void) sprintf(t, "%s -> ",
+ hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src));
+ t += strlen(t);
+ (void) sprintf(t, "%s PR %s",
+ hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
+ proto);
}
t += strlen(t);
if (sl->isl_tag != FR_NOLOGTAG) {
@@ -885,7 +882,14 @@ int blen;
if (sl->isl_type != ISL_NEW) {
sprintf(t,
#ifdef USE_QUAD_T
+#ifdef PRId64
+ " Forward: Pkts in %" PRId64 " Bytes in %" PRId64
+ " Pkts out %" PRId64 " Bytes out %" PRId64
+ " Backward: Pkts in %" PRId64 " Bytes in %" PRId64
+ " Pkts out %" PRId64 " Bytes out %" PRId64,
+#else
" Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd",
+#endif /* PRId64 */
#else
" Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld",
#endif
@@ -944,25 +948,16 @@ int logtype, blen;
}
if (logtype == IPL_LOGIPF) {
- if (ipl->ipl_magic != IPL_MAGIC) {
- /* invalid data or out of sync */
- break;
- }
- print_ipflog(log, buf, psize);
+ if (ipl->ipl_magic == IPL_MAGIC)
+ print_ipflog(log, buf, psize);
} else if (logtype == IPL_LOGNAT) {
- if (ipl->ipl_magic != IPL_MAGIC) {
- /* invalid data or out of sync */
- break;
- }
- print_natlog(log, buf, psize);
+ if (ipl->ipl_magic == IPL_MAGIC_NAT)
+ print_natlog(log, buf, psize);
} else if (logtype == IPL_LOGSTATE) {
- if (ipl->ipl_magic != IPL_MAGIC) {
- /* invalid data or out of sync */
- break;
- }
- print_statelog(log, buf, psize);
+ if (ipl->ipl_magic == IPL_MAGIC_STATE)
+ print_statelog(log, buf, psize);
}
blen -= psize;
@@ -984,9 +979,9 @@ int blen;
struct icmp *icmp;
struct tm *tm;
char *t, *proto;
- int i, v, lvl, res, len, off, plen, ipoff;
- u_32_t *s, *d, cmdflags;
+ int i, v, lvl, res, len, off, plen, ipoff, defaction;
ip_t *ipc, *ip;
+ u_32_t *s, *d;
u_short hl, p;
ipflog_t *ipf;
iplog_t *ipl;
@@ -1020,6 +1015,7 @@ int blen;
}
#if (defined(MENTAT) || \
(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
{
char ifname[sizeof(ipf->fl_ifname) + 1];
@@ -1028,8 +1024,8 @@ int blen;
ifname[sizeof(ipf->fl_ifname)] = '\0';
(void) sprintf(t, "%s", ifname);
t += strlen(t);
-# if defined(MENTAT)
- if (isalpha(*(t - 1))) {
+# if defined(MENTAT) || defined(linux)
+ if (ISALPHA(*(t - 1))) {
sprintf(t, "%d", ipf->fl_unit);
t += strlen(t);
}
@@ -1044,7 +1040,12 @@ int blen;
(void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
t += strlen(t);
#endif
+#if defined(__sgi) || defined(_AIX51) || defined(__powerpc__) || \
+ defined(__arm__)
+ if ((ipf->fl_group[0] == 255) && (ipf->fl_group[1] == '\0'))
+#else
if ((ipf->fl_group[0] == -1) && (ipf->fl_group[1] == '\0'))
+#endif
strcat(t, " @-1:");
else if (ipf->fl_group[0] == '\0')
(void) strcpy(t, " @0:");
@@ -1064,7 +1065,6 @@ int blen;
lvl = LOG_ERR;
}
- cmdflags = ipf->fl_flags & FR_CMDMASK;
if (FR_ISPASS(ipf->fl_flags)) {
if (ipf->fl_flags & FR_LOGP)
*t++ = 'p';
@@ -1099,7 +1099,7 @@ int blen;
p = (u_short)ip6->ip6_nxt;
s = (u_32_t *)&ip6->ip6_src;
d = (u_32_t *)&ip6->ip6_dst;
- plen = ntohs(ip6->ip6_plen);
+ plen = hl + ntohs(ip6->ip6_plen);
#else
sprintf(t, "ipv6");
goto printipflog;
@@ -1218,11 +1218,13 @@ int blen;
IP_HL(ipc) << 2, i);
t += strlen(t);
if (ipoff & IP_OFFMASK) {
- (void) sprintf(t, " frag %s%s%hu@%hu",
- ipoff & IP_MF ? "+" : "",
- ipoff & IP_DF ? "-" : "",
+ (void) sprintf(t,
+ "(frag %d:%hu@%hu%s%s)",
+ ntohs(ipc->ip_id),
i - (IP_HL(ipc) << 2),
- (ipoff & IP_OFFMASK) << 3);
+ (ipoff & IP_OFFMASK) << 3,
+ ipoff & IP_MF ? "+" : "",
+ ipoff & IP_DF ? "-" : "");
}
}
@@ -1234,13 +1236,15 @@ int blen;
hostname(res, v, d), proto, hl, plen);
t += strlen(t);
if (off & IP_OFFMASK)
- (void) sprintf(t, " frag %s%s%hu@%hu",
+ (void) sprintf(t, " (frag %d:%hu@%hu%s%s)",
+ ntohs(ip->ip_id),
+ plen - hl, (off & IP_OFFMASK) << 3,
ipoff & IP_MF ? "+" : "",
- ipoff & IP_DF ? "-" : "",
- plen - hl, (off & IP_OFFMASK) << 3);
+ ipoff & IP_DF ? "-" : "");
}
t += strlen(t);
+printipflog:
if (ipf->fl_flags & FR_KEEPSTATE) {
(void) strcpy(t, " K-S");
t += strlen(t);
@@ -1256,25 +1260,73 @@ int blen;
else if (ipf->fl_dir == 1)
strcpy(t, " OUT");
t += strlen(t);
- if (ipf->fl_tag) {
- sprintf(t, " tag %d", ipf->fl_tag);
+ if (ipf->fl_logtag != 0) {
+ sprintf(t, " log-tag %d", ipf->fl_logtag);
t += strlen(t);
}
-printipflog:
+ if (ipf->fl_nattag.ipt_num[0] != 0) {
+ strcpy(t, " nat-tag ");
+ t += strlen(t);
+ strncpy(t, ipf->fl_nattag.ipt_tag, sizeof(ipf->fl_nattag));
+ t += strlen(t);
+ }
+ if ((ipf->fl_lflags & FI_LOWTTL) != 0) {
+ strcpy(t, " low-ttl");
+ t += 8;
+ }
+ if ((ipf->fl_lflags & FI_OOW) != 0) {
+ strcpy(t, " OOW");
+ t += 4;
+ }
+ if ((ipf->fl_lflags & FI_BAD) != 0) {
+ strcpy(t, " bad");
+ t += 4;
+ }
+ if ((ipf->fl_lflags & FI_NATED) != 0) {
+ strcpy(t, " NAT");
+ t += 4;
+ }
+ if ((ipf->fl_lflags & FI_BADNAT) != 0) {
+ strcpy(t, " bad-NAT");
+ t += 8;
+ }
+ if ((ipf->fl_lflags & FI_BADSRC) != 0) {
+ strcpy(t, " bad-src");
+ t += 8;
+ }
+ if ((ipf->fl_lflags & FI_MULTICAST) != 0) {
+ strcpy(t, " multicast");
+ t += 10;
+ }
+ if ((ipf->fl_lflags & FI_BROADCAST) != 0) {
+ strcpy(t, " broadcast");
+ t += 10;
+ }
+ if ((ipf->fl_lflags & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST)) ==
+ FI_MBCAST) {
+ strcpy(t, " mbcast");
+ t += 7;
+ }
*t++ = '\n';
*t++ = '\0';
- if (opts & OPT_SYSLOG)
- syslog(lvl, "%s", line);
- else
- (void) fprintf(log, "%s", line);
- if (opts & OPT_HEXHDR)
- dumphex(log, opts, buf, sizeof(iplog_t) + sizeof(*ipf));
- if (opts & OPT_HEXBODY)
- dumphex(log, opts, (char *)ip, ipf->fl_plen + ipf->fl_hlen);
- else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY))
- dumphex(log, opts, (char *)ip + ipf->fl_hlen, ipf->fl_plen);
- if (conf_file)
- check_action(buf, opts, line);
+ defaction = 0;
+ if (conf_file != NULL)
+ defaction = check_action(buf, line, opts, lvl);
+ if (defaction == 0) {
+ if (opts & OPT_SYSLOG)
+ syslog(lvl, "%s", line);
+ else
+ (void) fprintf(log, "%s", line);
+ if (opts & OPT_HEXHDR)
+ dumphex(log, opts, buf,
+ sizeof(iplog_t) + sizeof(*ipf));
+ if (opts & OPT_HEXBODY)
+ dumphex(log, opts, (char *)ip,
+ ipf->fl_plen + ipf->fl_hlen);
+ else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY))
+ dumphex(log, opts, (char *)ip + ipf->fl_hlen,
+ ipf->fl_plen);
+ }
}
@@ -1378,6 +1430,7 @@ char *argv[];
{
struct stat sb;
FILE *log = stdout;
+ FILE *fp;
int fd[3], doread, n, i;
int tr, nr, regular[3], c;
int fdt[3], devices = 0, make_daemon = 0;
@@ -1581,17 +1634,18 @@ char *argv[];
tr = read_log(fd[i], &n, buf, sizeof(buf));
if (donehup) {
- donehup = 0;
- if (newlog) {
+ if (logfile && (fp = fopen(logfile, "a"))) {
fclose(log);
- log = newlog;
- newlog = NULL;
+ log = fp;
}
- if (newbinarylog) {
+ if (binarylogfile && (fp = fopen(binarylogfile, "a"))) {
fclose(binarylog);
- binarylog = newbinarylog;
- newbinarylog = NULL;
+ binarylog = fp;
}
+ init_tabs();
+ if (conf_file != NULL)
+ load_config(conf_file);
+ donehup = 0;
}
switch (tr)
diff --git a/usr/src/cmd/ipf/tools/ipmon_y.y b/usr/src/cmd/ipf/tools/ipmon_y.y
index b8ddb45de2..e6dda81c35 100644
--- a/usr/src/cmd/ipf/tools/ipmon_y.y
+++ b/usr/src/cmd/ipf/tools/ipmon_y.y
@@ -1,5 +1,11 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+
%{
#include "ipf.h"
+#include <syslog.h>
#undef OPT_NAT
#undef OPT_VERBOSE
#include "ipmon_l.h"
@@ -25,8 +31,9 @@ typedef struct opt {
static void build_action __P((struct opt *));
static opt_t *new_opt __P((int));
+static void free_action __P((ipmon_action_t *));
-static action_t *alist = NULL;
+static ipmon_action_t *alist = NULL;
%}
%union {
@@ -37,20 +44,24 @@ static action_t *alist = NULL;
union i6addr ip6;
}
-%token <num> YY_NUMBER YY_HEX
-%token <str> YY_STR
-%token YY_COMMENT
-%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
-%token YY_RANGE_OUT YY_RANGE_IN
-%token <ip6> YY_IPV6
+%token <num> YY_NUMBER YY_HEX
+%token <str> YY_STR
+%token <ip6> YY_IPV6
+%token YY_COMMENT
+%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
+%token YY_RANGE_OUT YY_RANGE_IN
-%token IPM_ACTION IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
+%token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT
%token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
-%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_TAG IPM_YES
+%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
+%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT
+%token IPM_STATE IPM_NATTAG IPM_IPF
%type <addr> ipv4
-%type <opt> direction dstip dstport every execute group interface option
-%type <opt> options protocol result rule srcip srcport tag
+%type <opt> direction dstip dstport every execute group interface
+%type <opt> protocol result rule srcip srcport logtag matching
+%type <opt> matchopt nattag type doopt doing save syslog nothing
+%type <num> saveopts saveopt typeopt
%%
file: line
@@ -59,8 +70,10 @@ file: line
| file assign
;
-line: IPM_ACTION '{' options '}' ';' { build_action($3); resetlexer(); }
+line: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';'
+ { build_action($3); resetlexer(); }
| IPM_COMMENT
+ | YY_COMMENT
;
assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
@@ -74,16 +87,16 @@ assigning:
'=' { yyvarnext = 1; }
;
-options:
- option { $$ = $1; }
- | option ',' options { $1->o_next = $3; $$ = $1; }
+matching:
+ matchopt { $$ = $1; }
+ | matchopt ',' matching { $1->o_next = $3; $$ = $1; }
;
-option: direction { $$ = $1; }
+matchopt:
+ direction { $$ = $1; }
| dstip { $$ = $1; }
| dstport { $$ = $1; }
| every { $$ = $1; }
- | execute { $$ = $1; }
| group { $$ = $1; }
| interface { $$ = $1; }
| protocol { $$ = $1; }
@@ -91,7 +104,21 @@ option: direction { $$ = $1; }
| rule { $$ = $1; }
| srcip { $$ = $1; }
| srcport { $$ = $1; }
- | tag { $$ = $1; }
+ | logtag { $$ = $1; }
+ | nattag { $$ = $1; }
+ | type { $$ = $1; }
+ ;
+
+doing:
+ doopt { $$ = $1; }
+ | doopt ',' doing { $1->o_next = $3; $$ = $1; }
+ ;
+
+doopt:
+ execute { $$ = $1; }
+ | save { $$ = $1; }
+ | syslog { $$ = $1; }
+ | nothing { $$ = $1; }
;
direction:
@@ -123,11 +150,6 @@ every: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND);
$$->o_num = $2; }
;
-execute:
- IPM_EXECUTE '=' YY_STR { $$ = new_opt(IPM_EXECUTE);
- $$->o_str = $3; }
- ;
-
group: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP);
$$->o_num = $3; }
| IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP);
@@ -139,6 +161,14 @@ interface:
$$->o_str = $3; }
;
+logtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG);
+ $$->o_num = $3; }
+ ;
+
+nattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG);
+ $$->o_str = $3; }
+ ;
+
protocol:
IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL);
$$->o_num = $3; }
@@ -168,10 +198,42 @@ srcport:
$$->o_str = $3; }
;
-tag: IPM_TAG '=' YY_NUMBER { $$ = new_opt(IPM_TAG);
+type: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE);
$$->o_num = $3; }
;
+typeopt:
+ IPM_IPF { $$ = IPL_MAGIC; }
+ | IPM_NAT { $$ = IPL_MAGIC_NAT; }
+ | IPM_STATE { $$ = IPL_MAGIC_STATE; }
+ ;
+
+execute:
+ IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE);
+ $$->o_str = $2; }
+ ;
+
+save: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE);
+ $$->o_num = $2;
+ $$->o_str = $3; }
+ ;
+
+saveopts: { $$ = 0; }
+ | saveopt { $$ = $1; }
+ | saveopt ',' saveopts { $$ = $1 | $3; }
+ ;
+
+saveopt:
+ IPM_RAW { $$ = IPMDO_SAVERAW; }
+ ;
+
+syslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); }
+ ;
+
+nothing:
+ IPM_NOTHING { $$ = 0; }
+ ;
+
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
yyerror("Invalid octet string for IP address");
@@ -182,9 +244,9 @@ ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
}
%%
static struct wordtab yywords[] = {
- { "action", IPM_ACTION },
{ "body", IPM_BODY },
{ "direction", IPM_DIRECTION },
+ { "do", IPM_DO },
{ "dstip", IPM_DSTIP },
{ "dstport", IPM_DSTPORT },
{ "every", IPM_EVERY },
@@ -192,29 +254,39 @@ static struct wordtab yywords[] = {
{ "group", IPM_GROUP },
{ "in", IPM_IN },
{ "interface", IPM_INTERFACE },
+ { "ipf", IPM_IPF },
+ { "logtag", IPM_LOGTAG },
+ { "match", IPM_MATCH },
+ { "nat", IPM_NAT },
+ { "nattag", IPM_NATTAG },
{ "no", IPM_NO },
+ { "nothing", IPM_NOTHING },
{ "out", IPM_OUT },
{ "packet", IPM_PACKET },
{ "packets", IPM_PACKETS },
{ "protocol", IPM_PROTOCOL },
{ "result", IPM_RESULT },
{ "rule", IPM_RULE },
+ { "save", IPM_SAVE },
+ { "raw", IPM_RAW },
{ "second", IPM_SECOND },
{ "seconds", IPM_SECONDS },
{ "srcip", IPM_SRCIP },
{ "srcport", IPM_SRCPORT },
- { "tag", IPM_TAG },
- { "yes", IPM_YES },
+ { "state", IPM_STATE },
+ { "syslog", IPM_SYSLOG },
+ { "with", IPM_WITH },
{ NULL, 0 }
};
-static int macflags[15][2] = {
+static int macflags[17][2] = {
{ IPM_DIRECTION, IPMAC_DIRECTION },
{ IPM_DSTIP, IPMAC_DSTIP },
{ IPM_DSTPORT, IPMAC_DSTPORT },
- { IPM_EXECUTE, IPMAC_EXECUTE },
{ IPM_GROUP, IPMAC_GROUP },
{ IPM_INTERFACE, IPMAC_INTERFACE },
+ { IPM_LOGTAG, IPMAC_LOGTAG },
+ { IPM_NATTAG, IPMAC_NATTAG },
{ IPM_PACKET, IPMAC_EVERY },
{ IPM_PROTOCOL, IPMAC_PROTOCOL },
{ IPM_RESULT, IPMAC_RESULT },
@@ -222,7 +294,8 @@ static int macflags[15][2] = {
{ IPM_SECOND, IPMAC_EVERY },
{ IPM_SRCIP, IPMAC_SRCIP },
{ IPM_SRCPORT, IPMAC_SRCPORT },
- { IPM_TAG, IPMAC_TAG },
+ { IPM_TYPE, IPMAC_TYPE },
+ { IPM_WITH, IPMAC_WITH },
{ 0, 0 }
};
@@ -238,22 +311,26 @@ int type;
o->o_line = yylineNum;
o->o_num = 0;
o->o_str = (char *)0;
+ o->o_next = NULL;
return o;
}
static void build_action(olist)
opt_t *olist;
{
- action_t *a;
+ ipmon_action_t *a;
opt_t *o;
- u_32_t m;
char c;
int i;
- a = (action_t *)calloc(1, sizeof(*a));
- if (!a)
+ a = (ipmon_action_t *)calloc(1, sizeof(*a));
+ if (a == NULL)
return;
- while ((o = olist)) {
+ while ((o = olist) != NULL) {
+ /*
+ * Check to see if the same comparator is being used more than
+ * once per matching statement.
+ */
for (i = 0; macflags[i][0]; i++)
if (macflags[i][0] == o->o_type)
break;
@@ -276,11 +353,7 @@ opt_t *olist;
break;
case IPM_DSTIP :
a->ac_dip = o->o_ip.s_addr;
- for (i = o->o_num, m = 0; i; i--) {
- m >>= 1;
- m |= 0x80000000;
- }
- a->ac_dmsk = htonl(m);
+ a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num));
break;
case IPM_DSTPORT :
a->ac_dport = htons(o->o_num);
@@ -308,6 +381,12 @@ opt_t *olist;
else
sprintf(a->ac_group, "%d", o->o_num);
break;
+ case IPM_LOGTAG :
+ a->ac_logtag = o->o_num;
+ break;
+ case IPM_NATTAG :
+ strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag));
+ break;
case IPM_PACKET :
a->ac_packet = o->o_num;
break;
@@ -322,8 +401,6 @@ opt_t *olist;
a->ac_result = IPMR_PASS;
else if (!strcasecmp(o->o_str, "block"))
a->ac_result = IPMR_BLOCK;
- else if (!strcasecmp(o->o_str, "short"))
- a->ac_result = IPMR_SHORT;
else if (!strcasecmp(o->o_str, "nomatch"))
a->ac_result = IPMR_NOMATCH;
else if (!strcasecmp(o->o_str, "log"))
@@ -334,17 +411,33 @@ opt_t *olist;
break;
case IPM_SRCIP :
a->ac_sip = o->o_ip.s_addr;
- for (i = o->o_num, m = 0; i; i--) {
- m >>= 1;
- m |= 0x80000000;
- }
- a->ac_smsk = htonl(m);
+ a->ac_smsk = htonl(0xffffffff << (32 - o->o_num));
break;
case IPM_SRCPORT :
a->ac_sport = htons(o->o_num);
break;
- case IPM_TAG :
- a->ac_tag = o->o_num;
+ case IPM_SAVE :
+ if (a->ac_savefile != NULL) {
+ fprintf(stderr, "%s redfined on line %d\n",
+ yykeytostr(o->o_type), yylineNum);
+ break;
+ }
+ a->ac_savefile = strdup(o->o_str);
+ a->ac_savefp = fopen(o->o_str, "a");
+ a->ac_dflag |= o->o_num & IPMDO_SAVERAW;
+ break;
+ case IPM_SYSLOG :
+ if (a->ac_syslog != 0) {
+ fprintf(stderr, "%s redfined on line %d\n",
+ yykeytostr(o->o_type), yylineNum);
+ break;
+ }
+ a->ac_syslog = 1;
+ break;
+ case IPM_TYPE :
+ a->ac_type = o->o_num;
+ break;
+ case IPM_WITH :
break;
default :
break;
@@ -355,54 +448,58 @@ opt_t *olist;
free(o->o_str);
free(o);
}
- a->a_next = alist;
+ a->ac_next = alist;
alist = a;
}
-void check_action(buf, opts, log)
-char *buf;
-int opts;
-char *log;
+int check_action(buf, log, opts, lvl)
+char *buf, *log;
+int opts, lvl;
{
+ ipmon_action_t *a;
struct timeval tv;
ipflog_t *ipf;
tcphdr_t *tcp;
iplog_t *ipl;
- action_t *a;
+ int matched;
u_long t1;
ip_t *ip;
+ matched = 0;
ipl = (iplog_t *)buf;
ipf = (ipflog_t *)(ipl +1);
ip = (ip_t *)(ipf + 1);
tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
- for (a = alist; a; a = a->a_next) {
- if (a->ac_mflag & IPMAC_DIRECTION) {
+ for (a = alist; a != NULL; a = a->ac_next) {
+ if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
if (a->ac_direction == IPM_IN) {
- if (!(ipf->fl_flags & FR_INQUE))
+ if ((ipf->fl_flags & FR_INQUE) == 0)
continue;
} else if (a->ac_direction == IPM_OUT) {
- if (!(ipf->fl_flags & FR_OUTQUE))
+ if ((ipf->fl_flags & FR_OUTQUE) == 0)
continue;
}
}
- if (a->ac_mflag & IPMAC_EVERY) {
+ if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic))
+ continue;
+
+ if ((a->ac_mflag & IPMAC_EVERY) != 0) {
gettimeofday(&tv, NULL);
t1 = tv.tv_sec - a->ac_lastsec;
if (tv.tv_usec <= a->ac_lastusec)
t1--;
- if (a->ac_second) {
+ if (a->ac_second != 0) {
if (t1 < a->ac_second)
continue;
a->ac_lastsec = tv.tv_sec;
a->ac_lastusec = tv.tv_usec;
}
- if (a->ac_packet) {
- if (!a->ac_pktcnt)
+ if (a->ac_packet != 0) {
+ if (a->ac_pktcnt == 0)
a->ac_pktcnt++;
else if (a->ac_pktcnt == a->ac_packet) {
a->ac_pktcnt = 0;
@@ -414,37 +511,37 @@ char *log;
}
}
- if (a->ac_mflag & IPMAC_DSTIP) {
+ if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip)
continue;
}
- if (a->ac_mflag & IPMAC_DSTPORT) {
+ if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
continue;
if (tcp->th_dport != a->ac_dport)
continue;
}
- if (a->ac_mflag & IPMAC_GROUP) {
+ if ((a->ac_mflag & IPMAC_GROUP) != 0) {
if (strncmp(a->ac_group, ipf->fl_group,
FR_GROUPLEN) != 0)
continue;
}
- if (a->ac_mflag & IPMAC_INTERFACE) {
+ if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
if (strcmp(a->ac_iface, ipf->fl_ifname))
continue;
}
- if (a->ac_mflag & IPMAC_PROTOCOL) {
+ if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
if (a->ac_proto != ip->ip_p)
continue;
}
- if (a->ac_mflag & IPMAC_RESULT) {
- if (ipf->fl_lflags & FI_SHORT) {
- if (a->ac_result != IPMR_SHORT)
+ if ((a->ac_mflag & IPMAC_RESULT) != 0) {
+ if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
+ if (a->ac_result != IPMR_NOMATCH)
continue;
} else if (FR_ISPASS(ipf->fl_flags)) {
if (a->ac_result != IPMR_PASS)
@@ -452,41 +549,57 @@ char *log;
} else if (FR_ISBLOCK(ipf->fl_flags)) {
if (a->ac_result != IPMR_BLOCK)
continue;
- } else if (ipf->fl_flags & FF_LOGNOMATCH) {
- if (a->ac_result != IPMR_NOMATCH)
- continue;
} else { /* Log only */
if (a->ac_result != IPMR_LOG)
continue;
}
}
- if (a->ac_mflag & IPMAC_RULE) {
+ if ((a->ac_mflag & IPMAC_RULE) != 0) {
if (a->ac_rule != ipf->fl_rule)
continue;
}
- if (a->ac_mflag & IPMAC_SRCIP) {
+ if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip)
continue;
}
- if (a->ac_mflag & IPMAC_SRCPORT) {
+ if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
continue;
if (tcp->th_sport != a->ac_sport)
continue;
}
- if (a->ac_mflag & IPMAC_TAG) {
- if (a->ac_tag != ipf->fl_tag)
+ if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
+ if (a->ac_logtag != ipf->fl_logtag)
continue;
}
+ if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
+ if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
+ IPFTAG_LEN) != 0)
+ continue;
+ }
+
+ matched = 1;
+
/*
* It matched so now execute the command
*/
- if (a->ac_exec) {
+ if (a->ac_syslog != 0) {
+ syslog(lvl, "%s", log);
+ }
+
+ if (a->ac_savefp != NULL) {
+ if (a->ac_dflag & IPMDO_SAVERAW)
+ fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp);
+ else
+ fputs(log, a->ac_savefp);
+ }
+
+ if (a->ac_exec != NULL) {
switch (fork())
{
case 0 :
@@ -494,14 +607,14 @@ char *log;
FILE *pi;
pi = popen(a->ac_run, "w");
- if (pi) {
+ if (pi != NULL) {
fprintf(pi, "%s\n", log);
- if (opts & OPT_HEXHDR) {
+ if ((opts & OPT_HEXHDR) != 0) {
dumphex(pi, 0, buf,
sizeof(*ipl) +
sizeof(*ipf));
}
- if (opts & OPT_HEXBODY) {
+ if ((opts & OPT_HEXBODY) != 0) {
dumphex(pi, 0, (char *)ip,
ipf->fl_hlen +
ipf->fl_plen);
@@ -517,15 +630,60 @@ char *log;
}
}
}
+
+ return matched;
+}
+
+
+static void free_action(a)
+ipmon_action_t *a;
+{
+ if (a->ac_savefile != NULL) {
+ free(a->ac_savefile);
+ a->ac_savefile = NULL;
+ }
+ if (a->ac_savefp != NULL) {
+ fclose(a->ac_savefp);
+ a->ac_savefp = NULL;
+ }
+ if (a->ac_exec != NULL) {
+ free(a->ac_exec);
+ if (a->ac_run == a->ac_exec)
+ a->ac_run = NULL;
+ a->ac_exec = NULL;
+ }
+ if (a->ac_run != NULL) {
+ free(a->ac_run);
+ a->ac_run = NULL;
+ }
+ if (a->ac_iface != NULL) {
+ free(a->ac_iface);
+ a->ac_iface = NULL;
+ }
+ a->ac_next = NULL;
+ free(a);
}
int load_config(file)
char *file;
{
+ ipmon_action_t *a;
FILE *fp;
+ char *s;
+
+ s = getenv("YYDEBUG");
+ if (s != NULL)
+ yydebug = atoi(s);
+ else
+ yydebug = 0;
+
+ while ((a = alist) != NULL) {
+ alist = a->ac_next;
+ free_action(a);
+ }
- yylineNum = 0;
+ yylineNum = 1;
(void) yysettab(yywords);
diff --git a/usr/src/cmd/ipf/tools/ipnat.c b/usr/src/cmd/ipf/tools/ipnat.c
index e1d93224c6..6989a511f1 100644
--- a/usr/src/cmd/ipf/tools/ipnat.c
+++ b/usr/src/cmd/ipf/tools/ipnat.c
@@ -5,7 +5,7 @@
*
* Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,9 +49,13 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
-#include <nlist.h>
+#if defined(linux)
+# include <linux/a.out.h>
+#else
+# include <nlist.h>
+#endif
#include "ipf.h"
-#include "ipl.h"
+#include "netinet/ipl.h"
#include "kmem.h"
#ifdef __hpux
@@ -67,7 +71,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.20 2003/07/01 16:30:27 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.2 2005/05/10 21:19:30 darrenr Exp $";
#endif
@@ -90,7 +94,7 @@ int opts;
void usage(name)
char *name;
{
- fprintf(stderr, "Usage: %s [-CdFhlnrsv] [-f filename]\n", name);
+ fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name);
exit(1);
}
@@ -112,7 +116,7 @@ char *argv[];
kernel = NULL;
mode = O_RDWR;
- while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1)
+ while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1)
switch (c)
{
case 'C' :
@@ -144,6 +148,9 @@ char *argv[];
opts |= OPT_DONOTHING;
mode = O_RDONLY;
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 'r' :
opts |= OPT_REMOVE;
break;
@@ -313,7 +320,7 @@ int opts;
break;
}
if (opts & OPT_HITS)
- printf("%d ", ipn.in_hits);
+ printf("%lu ", ipn.in_hits);
printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
nsp->ns_list = ipn.in_next;
}
@@ -324,6 +331,8 @@ int opts;
if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
break;
printactivenat(&nat, opts);
+ if (nat.nat_aps)
+ printaps(nat.nat_aps, opts);
}
if (opts & OPT_VERBOSE)
diff --git a/usr/src/cmd/ipf/tools/ipnat_y.y b/usr/src/cmd/ipf/tools/ipnat_y.y
index 064a6abe35..e382d78afd 100644
--- a/usr/src/cmd/ipf/tools/ipnat_y.y
+++ b/usr/src/cmd/ipf/tools/ipnat_y.y
@@ -4,7 +4,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -33,11 +33,6 @@
#include <stddef.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
-#ifdef IPFILTER_BPF
-# include <net/bpf.h>
-# include <pcap-int.h>
-# include <pcap.h>
-#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <sys/time.h>
@@ -46,17 +41,11 @@
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ipf.h"
-#if SOLARIS2 >= 10
-#include "ipl.h"
-#else
#include "netinet/ipl.h"
-#endif
#include "ipnat_l.h"
#define YYDEBUG 1
@@ -84,6 +73,7 @@ static void setnatproto __P((int));
struct in_addr ipa;
frentry_t fr;
frtuc_t *frt;
+ u_short port;
struct {
u_short p1;
u_short p2;
@@ -108,7 +98,8 @@ static void setnatproto __P((int));
%token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY
%token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG
%token IPNY_TLATE
-%type <num> hexnumber numports compare range proto
+%type <port> portspec
+%type <num> hexnumber compare range proto
%type <ipa> hostname ipv4
%type <ipp> addr nummask rhaddr
%type <pc> portstuff
@@ -143,13 +134,17 @@ assigning:
xx: { newnatrule(); }
;
-rule: map
- | mapblock
- | redir
+rule: map eol
+ | mapblock eol
+ | redir eol
+ ;
+
+eol: | ';'
;
map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
- { nat->in_inip = $3.a.s_addr;
+ { nat->in_v = 4;
+ nat->in_inip = $3.a.s_addr;
nat->in_inmsk = $3.m.s_addr;
nat->in_outip = $5.a.s_addr;
nat->in_outmsk = $5.m.s_addr;
@@ -164,7 +159,8 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
nat_setgroupmap(nat);
}
| mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions
- { nat->in_inip = $3.a.s_addr;
+ { nat->in_v = 4;
+ nat->in_inip = $3.a.s_addr;
nat->in_inmsk = $3.m.s_addr;
nat->in_outip = $5.a.s_addr;
nat->in_outmsk = $5.m.s_addr;
@@ -172,14 +168,15 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
strncpy(nat->in_ifnames[1],
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
- if ((nat->in_flags & IPN_TCPUDP) == 0)
+ if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
setnatproto(nat->in_p);
if (((nat->in_redir & NAT_MAPBLK) != 0) ||
((nat->in_flags & IPN_AUTOPORTMAP) != 0))
nat_setgroupmap(nat);
}
| mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions
- { nat->in_outip = $5.a.s_addr;
+ { nat->in_v = 4;
+ nat->in_outip = $5.a.s_addr;
nat->in_outmsk = $5.m.s_addr;
if (nat->in_ifnames[1][0] == '\0')
strncpy(nat->in_ifnames[1],
@@ -192,13 +189,14 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
nat_setgroupmap(nat);
}
| mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions
- { nat->in_outip = $5.a.s_addr;
+ { nat->in_v = 4;
+ nat->in_outip = $5.a.s_addr;
nat->in_outmsk = $5.m.s_addr;
if (nat->in_ifnames[1][0] == '\0')
strncpy(nat->in_ifnames[1],
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
- if ((nat->in_flags & IPN_TCPUDP) == 0)
+ if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0)
setnatproto(nat->in_p);
if (((nat->in_redir & NAT_MAPBLK) != 0) ||
((nat->in_flags & IPN_AUTOPORTMAP) != 0))
@@ -208,7 +206,8 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
mapblock:
mapblockit ifnames addr IPNY_TLATE addr ports mapoptions
- { nat->in_inip = $3.a.s_addr;
+ { nat->in_v = 4;
+ nat->in_inip = $3.a.s_addr;
nat->in_inmsk = $3.m.s_addr;
nat->in_outip = $5.a.s_addr;
nat->in_outmsk = $5.m.s_addr;
@@ -224,8 +223,9 @@ mapblock:
}
;
-redir: rdrit ifnames addr dport IPNY_TLATE dip nport rdrproto rdroptions
- { nat->in_outip = $3.a.s_addr;
+redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions
+ { nat->in_v = 4;
+ nat->in_outip = $3.a.s_addr;
nat->in_outmsk = $3.m.s_addr;
if (nat->in_ifnames[1][0] == '\0')
strncpy(nat->in_ifnames[1],
@@ -238,8 +238,9 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport rdrproto rdroptions
nat->in_pnext != 0))
setnatproto(IPPROTO_TCP);
}
- | rdrit ifnames rdrfrom IPNY_TLATE dip nport rdrproto rdroptions
- { if ((nat->in_p == 0) &&
+ | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
+ { nat->in_v = 4;
+ if ((nat->in_p == 0) &&
((nat->in_flags & IPN_TCPUDP) == 0) &&
(nat->in_pmin != 0 ||
nat->in_pmax != 0 ||
@@ -250,8 +251,9 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport rdrproto rdroptions
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
- | rdrit ifnames addr IPNY_TLATE dip rdrproto rdroptions
- { nat->in_outip = $3.a.s_addr;
+ | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions
+ { nat->in_v = 4;
+ nat->in_outip = $3.a.s_addr;
nat->in_outmsk = $3.m.s_addr;
if (nat->in_ifnames[1][0] == '\0')
strncpy(nat->in_ifnames[1],
@@ -260,7 +262,7 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport rdrproto rdroptions
}
;
-proxy: | IPNY_PROXY IPNY_PORT YY_NUMBER YY_STR '/' proto
+proxy: | IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto
{ strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
if (nat->in_dcmp == 0) {
nat->in_dport = htons($3);
@@ -271,24 +273,35 @@ proxy: | IPNY_PROXY IPNY_PORT YY_NUMBER YY_STR '/' proto
free($4);
}
| IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto
- { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
- nat->in_dport = getportproto($3, $6);
+ { int pnum;
+ strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
+ pnum = getportproto($3, $6);
+ if (pnum == -1)
+ yyerror("invalid port number");
+ nat->in_dport = pnum;
setnatproto($6);
free($3);
free($4);
}
;
-rdrproto:
- | IPNY_TCP { setnatproto(IPPROTO_TCP); }
- | IPNY_UDP { setnatproto(IPPROTO_UDP); }
- | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0; }
- | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0; }
- | YY_NUMBER { setnatproto($1); }
- | YY_STR { setnatproto(getproto($1));
- free($1);
+setproto:
+ | proto { if (nat->in_p != 0 ||
+ nat->in_flags & IPN_TCPUDP)
+ yyerror("protocol set twice");
+ setnatproto($1);
+ }
+ | IPNY_TCPUDP { if (nat->in_p != 0 ||
+ nat->in_flags & IPN_TCPUDP)
+ yyerror("protocol set twice");
+ nat->in_flags |= IPN_TCPUDP;
+ nat->in_p = 0;
+ }
+ | IPNY_TCP '/' IPNY_UDP { if (nat->in_p != 0 ||
+ nat->in_flags & IPN_TCPUDP)
+ yyerror("protocol set twice");
+ nat->in_flags |= IPN_TCPUDP;
+ nat->in_p = 0;
}
;
@@ -296,29 +309,43 @@ rhaddr: addr { $$.a = $1.a; $$.m = $1.m; }
| IPNY_RANGE ipv4 '-' ipv4
{ $$.a = $2; $$.m = $4;
nat->in_flags |= IPN_IPRANGE; }
+ ;
+
dip:
- ipv4 { nat->in_inip = $1.s_addr;
+ hostname { nat->in_inip = $1.s_addr;
nat->in_inmsk = 0xffffffff; }
- | ipv4 '/' YY_NUMBER { nat->in_inip = $1.s_addr;
- if (nat->in_inip != 0 ||
- ($3 != 0 && $3 != 32))
- yyerror("Invalid mask for dip");
- ntomask(4, $3, &nat->in_inmsk); }
- | ipv4 ',' ipv4 { nat->in_flags |= IPN_SPLIT;
+ | hostname ',' hostname { nat->in_flags |= IPN_SPLIT;
nat->in_inip = $1.s_addr;
nat->in_inmsk = $3.s_addr; }
;
-dport: | IPNY_PORT YY_NUMBER { nat->in_pmin = htons($2);
+portspec:
+ YY_NUMBER { if ($1 > 65535) /* Unsigned */
+ yyerror("invalid port number");
+ else
+ $$ = $1;
+ }
+ | YY_STR { if (getport(NULL, $1, &($$)) == -1)
+ yyerror("invalid port number");
+ $$ = ntohs($$);
+ }
+ ;
+
+dport: | IPNY_PORT portspec { nat->in_pmin = htons($2);
nat->in_pmax = htons($2); }
- | IPNY_PORT YY_NUMBER '-' YY_NUMBER { nat->in_pmin = htons($2);
+ | IPNY_PORT portspec '-' portspec { nat->in_pmin = htons($2);
+ nat->in_pmax = htons($4); }
+ | IPNY_PORT portspec ':' portspec { nat->in_pmin = htons($2);
nat->in_pmax = htons($4); }
;
-nport: IPNY_PORT YY_NUMBER { nat->in_pnext = htons($2); }
+nport: IPNY_PORT portspec { nat->in_pnext = htons($2); }
+ | IPNY_PORT '=' portspec { nat->in_pnext = htons($3);
+ nat->in_flags |= IPN_FIXEDDPORT;
+ }
;
-ports: | IPNY_PORTS numports { nat->in_pmin = $2; }
+ports: | IPNY_PORTS YY_NUMBER { nat->in_pmin = $2; }
| IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; }
;
@@ -353,26 +380,44 @@ ifnames:
| ifname ',' otherifname
;
-ifname: YY_STR { strncpy(nat->in_ifnames[0], $1,
- sizeof(nat->in_ifnames[0]));
- free($1);
- }
+ifname: YY_STR { strncpy(nat->in_ifnames[0], $1,
+ sizeof(nat->in_ifnames[0]));
+ nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
+ free($1);
+ }
;
otherifname:
- YY_STR { strncpy(nat->in_ifnames[1], $1,
- sizeof(nat->in_ifnames[1]));
- free($1);
- }
+ YY_STR { strncpy(nat->in_ifnames[1], $1,
+ sizeof(nat->in_ifnames[1]));
+ nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
+ free($1);
+ }
;
mapport:
- IPNY_PORTMAP tcpudp YY_NUMBER ':' YY_NUMBER
- { nat->in_pmin = htons($3);
- nat->in_pmax = htons($5); }
- | IPNY_PORTMAP tcpudp IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP;
- nat->in_pmin = htons(1024);
- nat->in_pmax = htons(65535); }
+ IPNY_PORTMAP tcpudp portspec ':' portspec
+ { nat->in_pmin = htons($3);
+ nat->in_pmax = htons($5);
+ }
+ | IPNY_PORTMAP tcpudp IPNY_AUTO
+ { nat->in_flags |= IPN_AUTOPORTMAP;
+ nat->in_pmin = htons(1024);
+ nat->in_pmax = htons(65535);
+ }
+ | IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER
+ { if (strcmp($2, "icmp") != 0) {
+ yyerror("icmpidmap not followed by icmp");
+ }
+ free($2);
+ if ($3 < 0 || $3 > 65535)
+ yyerror("invalid ICMP Id number");
+ if ($5 < 0 || $5 > 65535)
+ yyerror("invalid ICMP Id number");
+ nat->in_flags = IPN_ICMPQUERY;
+ nat->in_pmin = htons($3);
+ nat->in_pmax = htons($5);
+ }
;
sobject:
@@ -433,12 +478,12 @@ nummask:
;
portstuff:
- compare YY_NUMBER { $$.pc = $1; $$.p1 = $2; }
- | YY_NUMBER range YY_NUMBER { $$.pc = $2; $$.p1 = $1; $$.p2 = $3; }
+ compare portspec { $$.pc = $1; $$.p1 = $2; }
+ | portspec range portspec { $$.pc = $2; $$.p1 = $1; $$.p1 = $3; }
;
mapoptions:
- rr frag age mssclamp nattag
+ rr frag age mssclamp nattag setproto
;
rdroptions:
@@ -484,10 +529,11 @@ tcpudp: | IPNY_TCP { setnatproto(IPPROTO_TCP); }
;
rdrproxy:
- | IPNY_PROXY YY_STR
+ IPNY_PROXY YY_STR
{ strncpy(nat->in_plabel, $2,
sizeof(nat->in_plabel));
nat->in_dport = nat->in_pnext;
+ nat->in_dport = htons(nat->in_dport);
free($2);
}
| proxy { if (nat->in_plabel[0] != '\0') {
@@ -498,10 +544,6 @@ rdrproxy:
}
;
-numports:
- YY_NUMBER { $$ = $1; }
- ;
-
proto: YY_NUMBER { $$ = $1; }
| IPNY_TCP { $$ = IPPROTO_TCP; }
| IPNY_UDP { $$ = IPPROTO_UDP; }
@@ -562,6 +604,7 @@ static wordtab_t yywords[] = {
{ "map", IPNY_MAP },
{ "map-block", IPNY_MAPBLOCK },
{ "mssclamp", IPNY_MSSCLAMP },
+ { "netmask", IPNY_MASK },
{ "port", IPNY_PORT },
{ "portmap", IPNY_PORTMAP },
{ "ports", IPNY_PORTS },
@@ -572,6 +615,7 @@ static wordtab_t yywords[] = {
{ "sticky", IPNY_STICKY },
{ "tag", IPNY_TAG },
{ "tcp", IPNY_TCP },
+ { "tcpudp", IPNY_TCPUDP },
{ "to", IPNY_TO },
{ "udp", IPNY_UDP },
{ "-", '-' },
@@ -689,8 +733,23 @@ int p;
nat->in_flags |= IPN_UDP;
nat->in_flags &= ~IPN_TCP;
break;
+ case IPPROTO_ICMP :
+ nat->in_flags &= ~IPN_TCPUDP;
+ if (!(nat->in_flags & IPN_ICMPQUERY)) {
+ nat->in_dcmp = 0;
+ nat->in_scmp = 0;
+ nat->in_pmin = 0;
+ nat->in_pmax = 0;
+ nat->in_pnext = 0;
+ }
+ break;
default :
if ((nat->in_redir & NAT_MAPBLK) == 0) {
+ /* Only reset dcmp/scmp in case dport/sport not set */
+ if (0 == nat->in_tuc.ftu_dport)
+ nat->in_dcmp = 0;
+ if (0 == nat->in_tuc.ftu_sport)
+ nat->in_scmp = 0;
nat->in_pmin = 0;
nat->in_pmax = 0;
nat->in_pnext = 0;
@@ -698,6 +757,9 @@ int p;
}
break;
}
+
+ if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT)
+ nat->in_flags &= ~IPN_FIXEDDPORT;
}
@@ -706,8 +768,8 @@ int fd;
ioctlfunc_t ioctlfunc;
void *ptr;
{
+ ioctlcmd_t add, del;
ipfobj_t obj;
- int add, del;
ipnat_t *ipn;
ipn = ptr;
diff --git a/usr/src/cmd/ipf/tools/ippool.c b/usr/src/cmd/ipf/tools/ippool.c
index da6cc9273e..9e7919c757 100644
--- a/usr/src/cmd/ipf/tools/ippool.c
+++ b/usr/src/cmd/ipf/tools/ippool.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,15 +35,9 @@
#include <unistd.h>
#include "ipf.h"
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_pool.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
-#endif
#include "kmem.h"
@@ -142,7 +136,7 @@ char *argv[];
role = IPL_LOGIPF;
bzero((char *)&node, sizeof(node));
- while ((c = getopt(argc, argv, "di:m:no:v")) != -1)
+ while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
switch (c)
{
case 'd' :
@@ -162,7 +156,9 @@ char *argv[];
if (s != NULL)
*s = '\0';
ipset = 1;
+ node.ipn_addr.adf_len = sizeof(node.ipn_addr);
node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg);
+ node.ipn_mask.adf_len = sizeof(node.ipn_mask);
node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
break;
case 'm' :
@@ -176,11 +172,17 @@ char *argv[];
if (role == IPL_LOGNONE)
return -1;
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
}
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
+
if (ipset == 0)
return -1;
if (poolname == NULL) {
@@ -213,7 +215,7 @@ char *argv[];
bzero((char *)&iph, sizeof(iph));
bzero((char *)&pool, sizeof(pool));
- while ((c = getopt(argc, argv, "dm:no:S:t:v")) != -1)
+ while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1)
switch (c)
{
case 'd' :
@@ -233,6 +235,9 @@ char *argv[];
return -1;
}
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 'S' :
iph.iph_seed = atoi(optarg);
break;
@@ -248,6 +253,9 @@ char *argv[];
break;
}
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "poolcommand: opts = %#x\n", opts);
+
if (poolname == NULL) {
fprintf(stderr, "poolname not given with add/remove pool\n");
return -1;
@@ -296,7 +304,7 @@ char *argv[], *infile;
infile = optarg;
- while ((c = getopt(argc, argv, "dnrv")) != -1)
+ while ((c = getopt(argc, argv, "dnRuv")) != -1)
switch (c)
{
case 'd' :
@@ -306,7 +314,10 @@ char *argv[], *infile;
case 'n' :
opts |= OPT_DONOTHING;
break;
- case 'r' :
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
+ case 'u' :
opts |= OPT_REMOVE;
break;
case 'v' :
@@ -314,6 +325,9 @@ char *argv[], *infile;
break;
}
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
+
if (!(opts & OPT_DONOTHING) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
@@ -347,7 +361,7 @@ char *argv[];
poolname = NULL;
role = IPL_LOGALL;
- while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
+ while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
switch (c)
{
case 'd' :
@@ -371,6 +385,9 @@ char *argv[];
return -1;
}
break;
+ case 'R' :
+ opts |= OPT_NORESOLVE;
+ break;
case 't' :
type = gettype(optarg, NULL);
if (type == IPLT_NONE) {
@@ -418,14 +435,15 @@ char *argv[];
if (role != IPL_LOGALL) {
ptr = plstp->ipls_list[role];
while (ptr != NULL) {
- ptr = printpool(ptr, kmemcpywrap, opts);
+ ptr = printpool(ptr, kmemcpywrap, poolname,
+ opts);
}
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
ptr = plstp->ipls_list[role];
while (ptr != NULL) {
ptr = printpool(ptr, kmemcpywrap,
- opts);
+ poolname, opts);
}
}
role = IPL_LOGALL;
@@ -445,14 +463,15 @@ char *argv[];
if (role != IPL_LOGALL) {
hptr = htstp->iphs_tables;
while (hptr != NULL) {
- hptr = printhash(hptr, kmemcpywrap, opts);
+ hptr = printhash(hptr, kmemcpywrap,
+ poolname, opts);
}
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
hptr = htstp->iphs_tables;
while (hptr != NULL) {
hptr = printhash(hptr, kmemcpywrap,
- opts);
+ poolname, opts);
}
op.iplo_unit = role;
@@ -601,6 +620,9 @@ char *argv[];
break;
}
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "poolflush: opts = %#x\n", opts);
+
if (!(opts & OPT_DONOTHING) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
@@ -665,7 +687,7 @@ u_int *minor;
{
int type;
- if (!strcasecmp(optarg, "pool")) {
+ if (!strcasecmp(optarg, "tree")) {
type = IPLT_POOL;
} else if (!strcasecmp(optarg, "hash")) {
type = IPLT_HASH;
diff --git a/usr/src/cmd/ipf/tools/ippool_y.y b/usr/src/cmd/ipf/tools/ippool_y.y
index a952538c39..a074dff823 100644
--- a/usr/src/cmd/ipf/tools/ippool_y.y
+++ b/usr/src/cmd/ipf/tools/ippool_y.y
@@ -4,7 +4,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,15 +36,9 @@
#include <unistd.h>
#include "ipf.h"
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#include "ip_pool.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
-#endif
#include "ippool_l.h"
#include "kmem.h"
@@ -164,25 +158,23 @@ role:
;
ipftree:
- IPT_TYPE '=' IPT_TREE number '{' { yyexpectaddr = 1; }
- addrlist '}'
+ IPT_TYPE '=' IPT_TREE number start addrlist end
{ strncpy(iplo.ipo_name, $4,
sizeof(iplo.ipo_name));
- $$ = $7;
+ $$ = $6;
}
;
ipfhash:
- IPT_TYPE '=' IPT_HASH number hashopts '{' { yyexpectaddr = 1; }
- hashlist '}'
+ IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
{ strncpy(ipht.iph_name, $4,
sizeof(ipht.iph_name));
- $$ = $8;
+ $$ = $7;
}
;
ipfgroup:
- setgroup hashopts '{' grouplist '}'
+ setgroup hashopts start grouplist end
{ iphtent_t *e;
for (e = $4; e != NULL;
e = e->ipe_next)
@@ -192,10 +184,10 @@ ipfgroup:
FR_GROUPLEN);
$$ = $4;
}
- | hashopts '{' setgrouplist '}' { $$ = $3; }
+ | hashopts start setgrouplist end { $$ = $3; }
;
-number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3);
+number: IPT_NUM '=' YY_NUMBER { snprintf(poolname, FR_GROUPLEN, "%u", $3);
$$ = poolname;
}
| IPT_NAME '=' YY_STR { $$ = $3; }
@@ -208,7 +200,7 @@ setgroup:
$$ = strdup(tmp);
}
| IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1];
- sprintf(tmp, "%u", $3);
+ snprintf(tmp, FR_GROUPLEN, "%u", $3);
$$ = strdup(tmp);
}
;
@@ -220,14 +212,15 @@ hashopts:
;
addrlist:
- next { $$ = NULL; }
+ ';' { $$ = NULL; }
| range next addrlist { $1->ipn_next = $3; $$ = $1; }
| range next { $$ = $1; }
- | range { $$ = $1; }
+ | range
;
grouplist:
- groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
+ ';' { $$ = NULL; }
+ | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
| addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t));
if ($$ == NULL)
yyerror("sorry, out of memory");
@@ -242,7 +235,8 @@ grouplist:
(char *)&($$->ipe_mask),
sizeof($$->ipe_mask));
set_ipv6_addr = 0;
- $$->ipe_next = $3; }
+ $$->ipe_next = $3;
+ }
| groupentry next { $$ = $1; }
| addrmask next { $$ = calloc(1, sizeof(iphtent_t));
if ($$ == NULL)
@@ -262,34 +256,38 @@ grouplist:
;
setgrouplist:
- groupentry next { $$ = $1; }
+ ';' { $$ = NULL; }
+ | groupentry next { $$ = $1; }
| groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; }
;
groupentry:
- addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
- if ($$ == NULL)
- yyerror("sorry, out of memory");
- if (set_ipv6_addr)
- $$->ipe_family = AF_INET6;
- else
- $$->ipe_family = AF_INET;
- bcopy((char *)&($1[0]),
- (char *)&($$->ipe_addr),
- sizeof($$->ipe_addr));
- bcopy((char *)&($1[1]),
- (char *)&($$->ipe_mask),
- sizeof($$->ipe_mask));
- set_ipv6_addr = 0;
- strncpy($$->ipe_group, $3, FR_GROUPLEN);
- free($3); }
-
+ addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
+ if ($$ == NULL)
+ yyerror("sorry, out of memory");
+ if (set_ipv6_addr)
+ $$->ipe_family = AF_INET6;
+ else
+ $$->ipe_family = AF_INET;
+ bcopy((char *)&($1[0]),
+ (char *)&($$->ipe_addr),
+ sizeof($$->ipe_addr));
+ bcopy((char *)&($1[1]),
+ (char *)&($$->ipe_mask),
+ sizeof($$->ipe_mask));
+ set_ipv6_addr = 0;
+ strncpy($$->ipe_group, $3,
+ FR_GROUPLEN);
+ free($3);
+ }
;
range: addrmask { $$ = calloc(1, sizeof(*$$));
if ($$ == NULL)
yyerror("sorry, out of memory");
$$->ipn_info = 0;
+ $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
+ $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
if (set_ipv6_addr) {
$$->ipn_addr.adf_family = AF_INET6;
$$->ipn_addr.adf_addr = $1[0];
@@ -306,6 +304,8 @@ range: addrmask { $$ = calloc(1, sizeof(*$$));
if ($$ == NULL)
yyerror("sorry, out of memory");
$$->ipn_info = 1;
+ $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
+ $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
if (set_ipv6_addr) {
$$->ipn_addr.adf_family = AF_INET6;
$$->ipn_addr.adf_addr = $2[0];
@@ -319,12 +319,13 @@ range: addrmask { $$ = calloc(1, sizeof(*$$));
}
hashlist:
- hashentry next { $$ = $1; }
+ ';' { $$ = NULL; }
+ | hashentry next { $$ = $1; }
| hashentry next hashlist { $1->ipe_next = $3; $$ = $1; }
;
hashentry:
- addrmask { $$ = calloc(1, sizeof(iphtent_t));
+ addrmask { $$ = calloc(1, sizeof(iphtent_t));
if ($$ == NULL)
yyerror("sorry, out of memory");
if (set_ipv6_addr)
@@ -337,34 +338,49 @@ hashentry:
bcopy((char *)&($1[1]),
(char *)&($$->ipe_mask),
sizeof($$->ipe_mask));
- set_ipv6_addr = 0;
}
;
addrmask:
- ipaddr '/' mask { $$[0] = $1; $$[1] = $3; }
- | ipaddr { $$[0] = $1;
+ ipaddr '/' mask { $$[0] = $1; $$[1] = $3;
+ yyexpectaddr = 0;
+ }
+ | ipaddr { $$[0] = $1;
+ yyexpectaddr = 0;
if (set_ipv6_addr)
fill6bits(128, (u_32_t *)$$[1].in6.s6_addr);
else
- $$[1].in4.s_addr = 0xffffffff; }
+ $$[1].in4.s_addr = 0xffffffff;
+ }
;
ipaddr: ipv4 { $$ = $1; }
| YY_NUMBER { $$.in4.s_addr = htonl($1); }
- | YY_IPV6 { set_ipv6_addr = 1;
+ | YY_IPV6 { set_ipv6_addr = 1;
bcopy(&$1, &$$, sizeof($$));
yyexpectaddr = 0; }
+ | YY_STR { if (gethost($1, &($$.in4.s_addr)) == -1)
+ yyerror("Unknown hostname");
+ }
;
mask: YY_NUMBER { if (set_ipv6_addr)
- ntomask(6, $1, (u_32_t *)$$.in6.s6_addr);
+ ntomask(6, $1, (u_32_t *)$$.in6.s6_addr);
else
- ntomask(4, $1, (u_32_t *)&$$.in4.s_addr);
- }
+ ntomask(4, $1, (u_32_t *)&$$.in4.s_addr); }
| ipv4 { $$ = $1; }
;
+start: '{' { yyexpectaddr = 1; }
+ ;
+
+end: '}' { yyexpectaddr = 0; }
+ ;
+
+next: ',' { yyexpectaddr = 1; }
+ | ';' { yyexpectaddr = 1; }
+ ;
+
size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
;
@@ -380,12 +396,6 @@ ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
$$.in4.s_addr = htonl($$.in4.s_addr);
}
;
-
-next: ';' { yyexpectaddr = 1; }
- | ',' { yyexpectaddr = 1; }
- ;
-
-
%%
static wordtab_t yywords[] = {
{ "auth", IPT_AUTH },
diff --git a/usr/src/cmd/ipf/tools/lexer.c b/usr/src/cmd/ipf/tools/lexer.c
index 72425e4589..39975a55ce 100644
--- a/usr/src/cmd/ipf/tools/lexer.c
+++ b/usr/src/cmd/ipf/tools/lexer.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,7 +30,7 @@ union {
FILE *yyin;
-#define ishex(c) (isdigit(c) || ((c) >= 'a' && (c) <= 'f') || \
+#define ishex(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || \
((c) >= 'A' && (c) <= 'F'))
#define TOOLONG -3
@@ -61,13 +61,14 @@ static int yyswallow __P((int));
static char *yytexttostr __P((int, int));
static void yystrtotext __P((char *));
-
static int yygetc()
{
int c;
if (yypos < yylast) {
c = yytext[yypos++];
+ if (c == '\n')
+ yylineNum++;
return c;
}
@@ -79,9 +80,9 @@ static int yygetc()
yypos++;
} else {
c = fgetc(yyin);
- if (c == '\n')
- yylineNum++;
}
+ if (c == '\n')
+ yylineNum++;
yytext[yypos++] = c;
yylast = yypos;
yytext[yypos] = '\0';
@@ -93,6 +94,8 @@ static int yygetc()
static void yyunputc(c)
int c;
{
+ if (c == '\n')
+ yylineNum--;
yytext[--yypos] = c;
}
@@ -186,6 +189,8 @@ nextchar:
}
yylast -= yypos;
yypos = 0;
+ lnext = 0;
+ nokey = 0;
goto nextchar;
case '\\' :
@@ -205,6 +210,9 @@ nextchar:
if (lnext == 1) {
lnext = 0;
+ if ((isbuilding == 0) && !ISALNUM(c)) {
+ return c;
+ }
goto nextchar;
}
@@ -232,13 +240,13 @@ nextchar:
}
(void) yygetc();
} else {
- if (!isalpha(n)) {
+ if (!ISALPHA(n)) {
yyunputc(n);
break;
}
do {
n = yygetc();
- } while (isalpha(n) || isdigit(n) || n == '_');
+ } while (ISALPHA(n) || ISDIGIT(n) || n == '_');
yyunputc(n);
}
@@ -290,7 +298,6 @@ nextchar:
yybreakondot = 0;
yyvarnext = 0;
yytokentype = 0;
- yysavedepth = 0;
return 0;
}
@@ -447,10 +454,10 @@ nextchar:
/*
* No negative numbers with leading - sign..
*/
- if (isbuilding == 0 && isdigit(c)) {
+ if (isbuilding == 0 && ISDIGIT(c)) {
do {
n = yygetc();
- } while (isdigit(n));
+ } while (ISDIGIT(n));
yyunputc(n);
rval = YY_NUMBER;
goto done;
@@ -488,12 +495,13 @@ done:
yytokentype = rval;
if (yydebug)
- printf("lexed(%s) => %d\n", yystr, rval);
+ printf("lexed(%s) [%d,%d,%d] => %d\n", yystr, string_start,
+ string_end, pos, rval);
switch (rval)
{
case YY_NUMBER :
- yylval.num = atoi(yystr);
+ sscanf(yystr, "%u", &yylval.num);
break;
case YY_HEX :
diff --git a/usr/src/common/ipf/ipl.h b/usr/src/common/ipf/ipl.h
deleted file mode 100644
index 5ae34d6599..0000000000
--- a/usr/src/common/ipf/ipl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 1999-2001, 2003 by Darren Reed.
- * See the IPFILTER.LICENCE file for details on licencing.
- *
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifndef __IPL_H__
-#define __IPL_H__
-
-#define IPL_VERSION "IP Filter: v4.0.3"
-
-#define IPFILTER_VERSION 4000300
-
-#endif /* __IPL_H__ */
diff --git a/usr/src/common/ipf/solaris.c b/usr/src/common/ipf/solaris.c
deleted file mode 100644
index f4ac8ff761..0000000000
--- a/usr/src/common/ipf/solaris.c
+++ /dev/null
@@ -1,1122 +0,0 @@
-/*
- * Copyright (C) 1993-2001, 2003 by Darren Reed.
- * See the IPFILTER.LICENCE file for details on licencing.
- *
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/systm.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/uio.h>
-#include <sys/buf.h>
-#include <sys/modctl.h>
-#include <sys/open.h>
-#include <sys/kmem.h>
-#include <sys/conf.h>
-#include <sys/cmn_err.h>
-#include <sys/stat.h>
-#include <sys/cred.h>
-#include <sys/dditypes.h>
-#include <sys/stream.h>
-#include <sys/poll.h>
-#include <sys/autoconf.h>
-#include <sys/byteorder.h>
-#include <sys/socket.h>
-#include <sys/dlpi.h>
-#include <sys/stropts.h>
-#include <sys/kstat.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#if SOLARIS2 >= 6
-# include <net/if_types.h>
-#endif
-#include <net/af.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/tcpip.h>
-#include <netinet/ip_icmp.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include "ip_compat.h"
-#include "ipl.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_auth.h"
-#include "ip_state.h"
-#if SOLARIS2 >= 10
-#include "pfild.h"
-#endif
-
-
-extern struct filterstats frstats[];
-extern ipfrwlock_t ipf_mutex, ipf_nat, ipf_global;
-extern ipfmutex_t ipf_rw, ipf_timeoutlock;
-extern int fr_running;
-extern int fr_flags;
-#ifdef IPFILTER_SYNC
-extern int iplwrite __P((dev_t, struct uio *, cred_t *));
-#endif
-
-extern ipnat_t *nat_list;
-
-static int ipf_getinfo __P((dev_info_t *, ddi_info_cmd_t,
- void *, void **));
-#if SOLARIS2 < 10
-static int ipf_identify __P((dev_info_t *));
-#endif
-static int ipf_attach __P((dev_info_t *, ddi_attach_cmd_t));
-static int ipf_detach __P((dev_info_t *, ddi_detach_cmd_t));
-static int fr_qifsync __P((ip_t *, int, void *, int, qif_t *, mblk_t **));
-static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
- IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
- IPLOOKUP_NAME, NULL };
-
-
-#if SOLARIS2 >= 7
-void fr_slowtimer __P((void *));
-timeout_id_t fr_timer_id;
-static timeout_id_t synctimeoutid = 0;
-#else
-void fr_slowtimer __P((void));
-int fr_timer_id;
-static int synctimeoutid = 0;
-#endif
-
-#ifndef IRE_ILL_CN
-#ifdef IPFDEBUG
-void printire __P((ire_t *));
-#endif
-#endif
-
-static struct cb_ops ipf_cb_ops = {
- iplopen,
- iplclose,
- nodev, /* strategy */
- nodev, /* print */
- nodev, /* dump */
- iplread,
-#ifdef IPFILTER_SYNC
- iplwrite, /* write */
-#else
- nodev, /* write */
-#endif
- iplioctl, /* ioctl */
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op,
- NULL,
- D_MTSAFE,
-#if SOLARIS2 > 4
- CB_REV,
- nodev, /* aread */
- nodev, /* awrite */
-#endif
-};
-
-static struct dev_ops ipf_ops = {
- DEVO_REV,
- 0,
- ipf_getinfo,
-#if SOLARIS2 >= 10
- nulldev,
-#else
- ipf_identify,
-#endif
- nulldev,
- ipf_attach,
- ipf_detach,
- nodev, /* reset */
- &ipf_cb_ops,
- (struct bus_ops *)0
-};
-
-extern struct mod_ops mod_driverops;
-static struct modldrv iplmod = {
- &mod_driverops, IPL_VERSION, &ipf_ops };
-static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL };
-
-#if SOLARIS2 >= 6
-static size_t hdrsizes[57][2] = {
- { 0, 0 },
- { IFT_OTHER, 0 },
- { IFT_1822, 0 },
- { IFT_HDH1822, 0 },
- { IFT_X25DDN, 0 },
- { IFT_X25, 0 },
- { IFT_ETHER, 14 },
- { IFT_ISO88023, 0 },
- { IFT_ISO88024, 0 },
- { IFT_ISO88025, 0 },
- { IFT_ISO88026, 0 },
- { IFT_STARLAN, 0 },
- { IFT_P10, 0 },
- { IFT_P80, 0 },
- { IFT_HY, 0 },
- { IFT_FDDI, 24 },
- { IFT_LAPB, 0 },
- { IFT_SDLC, 0 },
- { IFT_T1, 0 },
- { IFT_CEPT, 0 },
- { IFT_ISDNBASIC, 0 },
- { IFT_ISDNPRIMARY, 0 },
- { IFT_PTPSERIAL, 0 },
- { IFT_PPP, 0 },
- { IFT_LOOP, 0 },
- { IFT_EON, 0 },
- { IFT_XETHER, 0 },
- { IFT_NSIP, 0 },
- { IFT_SLIP, 0 },
- { IFT_ULTRA, 0 },
- { IFT_DS3, 0 },
- { IFT_SIP, 0 },
- { IFT_FRELAY, 0 },
- { IFT_RS232, 0 },
- { IFT_PARA, 0 },
- { IFT_ARCNET, 0 },
- { IFT_ARCNETPLUS, 0 },
- { IFT_ATM, 0 },
- { IFT_MIOX25, 0 },
- { IFT_SONET, 0 },
- { IFT_X25PLE, 0 },
- { IFT_ISO88022LLC, 0 },
- { IFT_LOCALTALK, 0 },
- { IFT_SMDSDXI, 0 },
- { IFT_FRELAYDCE, 0 },
- { IFT_V35, 0 },
- { IFT_HSSI, 0 },
- { IFT_HIPPI, 0 },
- { IFT_MODEM, 0 },
- { IFT_AAL5, 0 },
- { IFT_SONETPATH, 0 },
- { IFT_SONETVT, 0 },
- { IFT_SMDSICIP, 0 },
- { IFT_PROPVIRTUAL, 0 },
- { IFT_PROPMUX, 0 },
-};
-#endif /* SOLARIS2 >= 6 */
-
-static dev_info_t *ipf_dev_info = NULL;
-
-static const filter_kstats_t ipf_kstat_tmp = {
- { "pass", KSTAT_DATA_ULONG },
- { "block", KSTAT_DATA_ULONG },
- { "nomatch", KSTAT_DATA_ULONG },
- { "short", KSTAT_DATA_ULONG },
- { "pass, logged", KSTAT_DATA_ULONG },
- { "block, logged", KSTAT_DATA_ULONG },
- { "nomatch, logged", KSTAT_DATA_ULONG },
- { "logged", KSTAT_DATA_ULONG },
- { "skip", KSTAT_DATA_ULONG },
- { "return sent", KSTAT_DATA_ULONG },
- { "acct", KSTAT_DATA_ULONG },
- { "bad frag state alloc", KSTAT_DATA_ULONG },
- { "new frag state kept", KSTAT_DATA_ULONG },
- { "new frag state compl. pkt", KSTAT_DATA_ULONG },
- { "bad pkt state alloc", KSTAT_DATA_ULONG },
- { "new pkt kept state", KSTAT_DATA_ULONG },
- { "cachehit", KSTAT_DATA_ULONG },
- { "tcp cksum bad", KSTAT_DATA_ULONG },
- {{ "pullup ok", KSTAT_DATA_ULONG },
- { "pullup nok", KSTAT_DATA_ULONG }},
- { "src != route", KSTAT_DATA_ULONG },
- { "ttl invalid", KSTAT_DATA_ULONG },
- { "bad ip pkt", KSTAT_DATA_ULONG },
- { "ipv6 pkt", KSTAT_DATA_ULONG },
- { "dropped:pps ceiling", KSTAT_DATA_ULONG },
- { "ip upd. fail", KSTAT_DATA_ULONG }
-};
-
-kstat_t *ipf_kstatp[2] = {NULL, NULL};
-static int ipf_kstat_update(kstat_t *ksp, int rwflag);
-
-static void
-ipf_kstat_init(void)
-{
- int i;
-
- for (i = 0; i < 2; i++) {
- ipf_kstatp[i] = kstat_create("ipf", 0,
- (i==0)?"inbound":"outbound",
- "net",
- KSTAT_TYPE_NAMED,
- sizeof (filter_kstats_t) / sizeof (kstat_named_t),
- 0);
- if (ipf_kstatp[i] != NULL) {
- bcopy(&ipf_kstat_tmp, ipf_kstatp[i]->ks_data,
- sizeof (filter_kstats_t));
- ipf_kstatp[i]->ks_update = ipf_kstat_update;
- ipf_kstatp[i]->ks_private = &frstats[i];
- kstat_install(ipf_kstatp[i]);
- }
- }
-
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_kstat_init() installed 0x%x, 0x%x",
- ipf_kstatp[0], ipf_kstatp[1]);
-#endif
-}
-
-static void
-ipf_kstat_fini(void)
-{
- int i;
- for (i = 0; i < 2; i++) {
- if (ipf_kstatp[i] != NULL) {
- kstat_delete(ipf_kstatp[i]);
- ipf_kstatp[i] = NULL;
- }
- }
-}
-
-static int
-ipf_kstat_update(kstat_t *ksp, int rwflag)
-{
- filter_kstats_t *fkp;
- filterstats_t *fsp;
-
- if (rwflag == KSTAT_WRITE)
- return (EACCES);
-
- fkp = ksp->ks_data;
- fsp = ksp->ks_private;
-
- fkp->fks_pass.value.ul = fsp->fr_pass;
- fkp->fks_block.value.ul = fsp->fr_block;
- fkp->fks_nom.value.ul = fsp->fr_nom;
- fkp->fks_short.value.ul = fsp->fr_short;
- fkp->fks_ppkl.value.ul = fsp->fr_ppkl;
- fkp->fks_bpkl.value.ul = fsp->fr_bpkl;
- fkp->fks_npkl.value.ul = fsp->fr_npkl;
- fkp->fks_pkl.value.ul = fsp->fr_pkl;
- fkp->fks_skip.value.ul = fsp->fr_skip;
- fkp->fks_ret.value.ul = fsp->fr_ret;
- fkp->fks_acct.value.ul = fsp->fr_acct;
- fkp->fks_bnfr.value.ul = fsp->fr_bnfr;
- fkp->fks_nfr.value.ul = fsp->fr_nfr;
- fkp->fks_cfr.value.ul = fsp->fr_cfr;
- fkp->fks_bads.value.ul = fsp->fr_bads;
- fkp->fks_ads.value.ul = fsp->fr_ads;
- fkp->fks_chit.value.ul = fsp->fr_chit;
- fkp->fks_tcpbad.value.ul = fsp->fr_tcpbad;
- fkp->fks_pull[0].value.ul = fsp->fr_pull[0];
- fkp->fks_pull[1].value.ul = fsp->fr_pull[1];
- fkp->fks_badsrc.value.ul = fsp->fr_badsrc;
- fkp->fks_badttl.value.ul = fsp->fr_badttl;
- fkp->fks_bad.value.ul = fsp->fr_bad;
- fkp->fks_ipv6.value.ul = fsp->fr_ipv6;
- fkp->fks_ppshit.value.ul = fsp->fr_ppshit;
- fkp->fks_ipud.value.ul = fsp->fr_ipud;
-
- return (0);
-}
-
-int _init()
-{
- int status;
-
- /*
- * Initialize mutex's
- */
- RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
- RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
- ipf_kstat_init();
- status = mod_install(&modlink1);
- if (status != 0) {
- RW_DESTROY(&ipf_mutex);
- RW_DESTROY(&ipf_global);
- ipf_kstat_fini();
- }
-
- return status;
-}
-
-
-int _fini(void)
-{
- int status;
-
- status = mod_remove(&modlink1);
- if (status != 0)
- return status;
- ipf_kstat_fini();
- RW_DESTROY(&ipf_mutex);
- RW_DESTROY(&ipf_global);
- return status;
-}
-
-
-int _info(modinfop)
-struct modinfo *modinfop;
-{
- int status;
-
- status = mod_info(&modlink1, modinfop);
- return status;
-}
-
-
-#if SOLARIS2 < 10
-static int ipf_identify(dip)
-dev_info_t *dip;
-{
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
-#endif
- if (strcmp(ddi_get_name(dip), "ipf") == 0)
- return (DDI_IDENTIFIED);
- return (DDI_NOT_IDENTIFIED);
-}
-#endif
-
-
-static int ipf_attach(dip, cmd)
-dev_info_t *dip;
-ddi_attach_cmd_t cmd;
-{
- char *s;
- int i;
- int instance;
-
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
-#endif
-
-
- switch (cmd)
- {
- case DDI_ATTACH:
- instance = ddi_get_instance(dip);
- /* Only one instance of ipf (instance 0) can be attached.*/
- if (instance > 0)
- return DDI_FAILURE;
- if (fr_running != 0)
- return DDI_FAILURE;
-
- if (pfilinterface != PFIL_INTERFACE) {
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "pfilinterface(%d) != %d",
- pfilinterface, PFIL_INTERFACE);
-#endif
- return DDI_FAILURE;
- }
-
- if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, DDI_NO_AUTODETACH,
- 1) != DDI_PROP_SUCCESS) {
-#ifdef IPFDEBUG
- cmn_err(CE_WARN, "!updating %s failed",
- DDI_NO_AUTODETACH);
-#endif
- return DDI_FAILURE;
- }
-
- for (i = 0; ((s = ipf_devfiles[i]) != NULL); i++) {
- s = strrchr(s, '/');
- if (s == NULL)
- continue;
- s++;
- if (ddi_create_minor_node(dip, s, S_IFCHR, i,
- DDI_PSEUDO, 0) ==
- DDI_FAILURE) {
- ddi_remove_minor_node(dip, NULL);
- return DDI_FAILURE;
- }
- }
-
- ipf_dev_info = dip;
- /*
- * Lock people out while we set things up.
- */
- WRITE_ENTER(&ipf_global);
- if ((fr_running != 0) || (iplattach() == -1)) {
- RWLOCK_EXIT(&ipf_global);
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: iplattach() failed");
-#endif
- goto attach_failed;
- }
-
- if (pfil_add_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet4)) {
- RWLOCK_EXIT(&ipf_global);
- goto attach_failed;
- }
-
-#ifdef USE_INET6
- if (pfil_add_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet6)) {
- RWLOCK_EXIT(&ipf_global);
- goto attach_failed;
- }
-#endif
-
- if (pfil_add_hook(fr_qifsync, PFIL_IN|PFIL_OUT, &pfh_sync)) {
- RWLOCK_EXIT(&ipf_global);
- goto attach_failed;
- }
-
- fr_timer_id = timeout(fr_slowtimer, NULL,
- drv_usectohz(500000));
-
- fr_running = 1;
-
- RWLOCK_EXIT(&ipf_global);
-
- cmn_err(CE_CONT, "!%s, running.\n", ipfilter_version);
-
- return DDI_SUCCESS;
- /* NOTREACHED */
- default:
- return DDI_FAILURE;
- }
-
-attach_failed:
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: failed to attach");
-#endif
- /*
- * Use our own detach routine to toss
- * away any stuff we allocated above.
- */
- (void) ipf_detach(dip, DDI_DETACH);
- return DDI_FAILURE;
-}
-
-
-static int ipf_detach(dip, cmd)
-dev_info_t *dip;
-ddi_detach_cmd_t cmd;
-{
- int i;
-
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
-#endif
- switch (cmd) {
- case DDI_DETACH:
- if (fr_running == -2 || fr_running == 0) {
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: not yet attached "
- "or already detached");
-#endif
- break;
- }
- /*
- * Make sure we're the only one's modifying things. With
- * this lock others should just fall out of the loop.
- */
- WRITE_ENTER(&ipf_global);
- if (fr_running <= 0) {
- RWLOCK_EXIT(&ipf_global);
- return DDI_FAILURE;
- }
- fr_running = -2;
-
- (void) pfil_remove_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet4);
-#ifdef USE_INET6
- (void) pfil_remove_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet6);
-#endif
- (void) pfil_remove_hook(fr_qifsync, PFIL_IN|PFIL_OUT, &pfh_sync);
-
- RWLOCK_EXIT(&ipf_global);
-
- if (fr_timer_id != 0) {
- (void) untimeout(fr_timer_id);
- fr_timer_id = 0;
- }
-
- /*
- * Undo what we did in ipf_attach, freeing resources
- * and removing things we installed. The system
- * framework guarantees we are not active with this devinfo
- * node in any other entry points at this time.
- */
- ddi_prop_remove_all(dip);
- i = ddi_get_instance(dip);
- ddi_remove_minor_node(dip, NULL);
- if (i > 0) {
-#ifdef IPFDEBUG
- cmn_err(CE_CONT, "IP Filter: still attached (%d)\n", i);
-#endif
- return DDI_FAILURE;
- }
-
- WRITE_ENTER(&ipf_global);
- if (!ipldetach()) {
- RWLOCK_EXIT(&ipf_global);
-#ifdef IPFDEBUG
- cmn_err(CE_CONT, "!%s detached.\n", ipfilter_version);
-#endif
- return (DDI_SUCCESS);
- }
- RWLOCK_EXIT(&ipf_global);
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipldetach() failed");
-#endif
- break;
- default:
- return DDI_FAILURE;
- }
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: failed to detach");
-#endif
- return DDI_FAILURE;
-}
-
-
-/*ARGSUSED*/
-static int ipf_getinfo(dip, infocmd, arg, result)
-dev_info_t *dip;
-ddi_info_cmd_t infocmd;
-void *arg, **result;
-{
- int error;
-
- if (fr_running <= 0)
- return DDI_FAILURE;
- error = DDI_FAILURE;
-#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)", dip, infocmd, arg);
-#endif
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- *result = ipf_dev_info;
- error = DDI_SUCCESS;
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)0;
- error = DDI_SUCCESS;
- break;
- default:
- break;
- }
- return (error);
-}
-
-
-/*
- * look for bad consistancies between the list of interfaces the filter knows
- * about and those which are currently configured.
- */
-/*ARGSUSED*/
-static int fr_qifsync(ip, hlen, il, out, qif, mp)
-ip_t *ip;
-int hlen;
-void *il;
-int out;
-qif_t *qif;
-mblk_t **mp;
-{
-
- frsync();
- /*
- * Resync. any NAT `connections' using this interface and its IP #.
- */
- fr_natsync(il);
- fr_statesync(il);
- return 0;
-}
-
-
-/*
- * look for bad consistancies between the list of interfaces the filter knows
- * about and those which are currently configured.
- */
-int ipfsync()
-{
- qif_t *qf;
-
- frsync();
- /*
- * Resync. any NAT `connections' using this interface and its IP #.
- */
- qf = NULL;
- while (qif_walk(&qf))
- (void) fr_qifsync(NULL, 0, (void *)qf->qf_ill, -1, qf, NULL);
- return 0;
-}
-
-#ifndef IRE_ILL_CN
-#ifdef IPFDEBUG
-void printire(ire)
-ire_t *ire;
-{
- printf("ire: ll_hdr_mp %p rfq %p stq %p src_addr %x max_frag %d\n",
-# if SOLARIS2 >= 8
- NULL,
-# else
- ire->ire_ll_hdr_mp,
-# endif
- ire->ire_rfq, ire->ire_stq,
- ire->ire_src_addr, ire->ire_max_frag);
- printf("ire: mask %x addr %x gateway_addr %x type %d\n",
- ire->ire_mask, ire->ire_addr, ire->ire_gateway_addr,
- ire->ire_type);
- printf("ire: ll_hdr_length %d ll_hdr_saved_mp %p\n",
- ire->ire_ll_hdr_length,
-# if SOLARIS2 >= 8
- NULL
-# else
- ire->ire_ll_hdr_saved_mp
-# endif
- );
-
-}
-#endif
-#endif /* IRE_ILL_CN */
-
-/*
- * Function: fr_fastroute
- * Returns: 0: success;
- * -1: failed
- * Parameters:
- * mb: the message block where ip head starts
- * mpp: the pointer to the pointer of the orignal
- * packet message
- * fin: packet information
- * fdp: destination interface information
- * if it is NULL, no interface information provided.
- *
- * This function is for fastroute/to/dup-to rules. It calls
- * pfil_make_lay2_packet to search route, make lay-2 header
- * ,and identify output queue for the IP packet.
- * The destination address depends on the following conditions:
- * 1: for fastroute rule, fdp is passed in as NULL, so the
- * destination address is the IP Packet's destination address
- * 2: for to/dup-to rule, if an ip address is specified after
- * the interface name, this address is the as destination
- * address. Otherwise IP Packet's destination address is used
- */
-int fr_fastroute(mb, mpp, fin, fdp)
-mblk_t *mb, **mpp;
-fr_info_t *fin;
-frdest_t *fdp;
-{
-#ifndef IRE_ILL_CN
- ire_t *ir, *dir;
- struct in_addr dst;
- ill_t *ifp;
- u_char *s;
- size_t hlen = 0;
- frdest_t fd;
-#else
- void *target = NULL;
- char *ifname = NULL;
- s_ill_t *ifp;
-#endif
- queue_t *q = NULL;
- mblk_t *mp = NULL;
- frentry_t *fr = fin->fin_fr;
- qif_t *qf;
- ip_t *ip;
-#ifndef sparc
- u_short __iplen, __ipoff;
-#endif
-#ifndef IRE_ILL_CN
-#ifdef USE_INET6
- ip6_t *ip6 = (ip6_t *)fin->fin_ip;
-#endif
-#endif
- ip = fin->fin_ip;
- qf = fin->fin_qif;
-
- /*
- * If this is a duplicate mblk then we want ip to point at that
- * data, not the original, if and only if it is already pointing at
- * the current mblk data.
- *
- * Otherwise, if it's not a duplicate, and we're not already pointing
- * at the current mblk data, then we want to ensure that the data
- * points at ip.
- */
-
- if ((ip == (ip_t *)qf->qf_m->b_rptr) && (qf->qf_m != mb)) {
- ip = (ip_t *)mb->b_rptr;
- } else if ((qf->qf_m == mb) && (ip != (ip_t *)qf->qf_m->b_rptr)) {
- qf->qf_m->b_rptr = (uchar_t *)ip;
- qf->qf_off = 0;
- }
-
- /*
- * If there is another M_PROTO, we don't want it
- */
- if (*mpp != mb) {
- mp = unlinkb(*mpp);
- freeb(*mpp);
- *mpp = mp;
- }
-
-
- /*
- * In case we're here due to "to <if>" being used with
- * "keep state", check that we're going in the correct
- * direction.
- */
- if (fdp != NULL) {
- if ((fr != NULL) && (fdp->fd_ifp != NULL) &&
- (fin->fin_rev != 0) && (fdp == &fr->fr_tif))
- goto bad_fastroute;
- }
-
-#ifndef IRE_ILL_CN
- if (!fdp) {
- ipif_t *ipif;
-
- ifp = fin->fin_ifp;
- ipif = ifp->ill_ipif;
- if (!ipif)
- goto bad_fastroute;
-#if SOLARIS2 > 5
- ir = ire_ctable_lookup(ipif->ipif_local_addr, 0, IRE_LOCAL,
- NULL, NULL, MATCH_IRE_TYPE);
-#else
- ir = ire_lookup_myaddr(ipif->ipif_local_addr);
-#endif
- if (!ir)
- ir = (ire_t *)-1;
-
- fd.fd_ifp = (struct ifnet *)ir;
- fd.fd_ip = ip->ip_dst;
- fdp = &fd;
- }
-
- ir = (ire_t *)fdp->fd_ifp;
-
- if (fdp->fd_ip.s_addr)
- dst = fdp->fd_ip;
- else
- dst.s_addr = fin->fin_fi.fi_daddr;
-
-#if SOLARIS2 >= 6
- if (fin->fin_v == 4) {
- dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL,
- NULL, NULL, MATCH_IRE_DSTONLY|
- MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
- }
-#ifdef USE_INET6
- else if (fin->fin_v == 6) {
- dir = ire_route_lookup_v6(&ip6->ip6_dst, NULL, 0, 0,
- NULL, NULL, NULL, MATCH_IRE_DSTONLY|
- MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
- }
-#endif
-#else
- dir = ire_lookup(dst.s_addr);
-#endif
-#if SOLARIS2 < 8
- if (dir)
- if (!dir->ire_ll_hdr_mp || !dir->ire_ll_hdr_length)
- dir = NULL;
-#else
- if (dir)
- if (!dir->ire_fp_mp || !dir->ire_dlureq_mp)
- dir = NULL;
-#endif
-
- if (!ir)
- ir = dir;
-
- if (!ir || !dir)
- goto bad_fastroute;
-
-#if SOLARIS2 < 8
- mp = dir->ire_ll_hdr_mp;
- hlen = dir->ire_ll_hdr_length;
-#else
- mp = dir->ire_fp_mp;
- hlen = mp ? mp->b_wptr - mp->b_rptr : 0;
- if (mp == NULL)
- mp = dir->ire_dlureq_mp;
-#endif
- if (mp != NULL) {
- s = mb->b_rptr;
- if (
-#if SOLARIS2 >= 6
- (dohwcksum &&
- ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC) ||
-#endif
- (hlen && (s - mb->b_datap->db_base) >= hlen)) {
- s -= hlen;
- mb->b_rptr = (u_char *)s;
- bcopy((char *)mp->b_rptr, (char *)s, hlen);
- } else {
- mblk_t *mp2;
-
- mp2 = copyb(mp);
- if (!mp2)
- goto bad_fastroute;
- linkb(mp2, mb);
- mb = mp2;
- }
- }
-
- if (ir->ire_stq)
- q = ir->ire_stq;
- else if (ir->ire_rfq)
- q = WR(ir->ire_rfq);
- if (q)
- q = q->q_next;
- if (!q)
- goto bad_fastroute;
-
- ifp = ire_to_ill(ir);
- if (ifp == NULL)
- goto bad_fastroute;
-
- fin->fin_ifp = ifp;
-#else /* IRE_ILL_CN */
- if (fin->fin_v == 4) {
- if (fdp && (fdp->fd_ip.s_addr != 0))
- target = &fdp->fd_ip;
- }
-#ifdef USE_INET6
- else if (fin->fin_v == 6) {
- if (fdp && !IN6_IS_ADDR_UNSPECIFIED(&fdp->fd_ip6.in6))
- target = &fdp->fd_ip6.in6;
- }
-#endif
- else
- goto bad_fastroute;
-
- if (fdp && fdp->fd_ifname[0] != 0)
- ifname = fdp->fd_ifname;
-
- mp = pfil_make_dl_packet(mb, ip, target, ifname, &q);
- if (mp == NULL)
- {
- goto bad_fastroute;
- }
- mb = mp;
- /*
- * Determine the s_ill_t we're going out on
- */
- ifp = ((qif_t *)(q->q_ptr))->qf_ill;
-#endif /* IRE_ILL_CN */
-
- mb->b_queue = q;
- *mpp = mb;
-
- if (fin->fin_out == 0) {
- void *saveifp;
- u_32_t pass;
-
- saveifp = fin->fin_ifp;
- fin->fin_ifp = ifp;
- (void)fr_acctpkt(fin, &pass);
- fin->fin_fr = NULL;
- if (!fr || !(fr->fr_flags & FR_RETMASK))
- (void) fr_checkstate(fin, &pass);
- (void) fr_checknatout(fin, NULL);
- fin->fin_ifp = saveifp;
- }
-#ifndef sparc
- if (fin->fin_v == 4) {
- __iplen = (u_short)ip->ip_len,
- __ipoff = (u_short)ip->ip_off;
-
- ip->ip_len = htons(__iplen);
- ip->ip_off = htons(__ipoff);
- }
-#endif
-
-#ifndef IRE_ILL_CN
-#if SOLARIS2 >= 6
- if ((p == IPPROTO_TCP) && dohwcksum &&
- (ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
- tcphdr_t *tcp;
- u_32_t t;
-
- tcp = (tcphdr_t *)((char *)ip + fin->fin_hlen);
- t = ip->ip_src.s_addr;
- t += ip->ip_dst.s_addr;
- t += 30;
- t = (t & 0xffff) + (t >> 16);
- tcp->th_sum = t & 0xffff;
- }
-#endif
- RWLOCK_EXIT(&ipf_global);
- putnext(q, mb);
- READ_ENTER(&ipf_global);
-#else /* IRE_ILL_CN */
- pfil_send_dl_packet(q, mb);
-#endif /* IRE_ILL_CN */
- fr_frouteok[0]++;
- return 0;
-bad_fastroute:
- freemsg(mb);
- fr_frouteok[1]++;
- return -1;
-}
-
-#if SOLARIS2 >= 10
-/*
- * Function: addrset_match_v4
- * Returns: boolean_t
- * Parameters: addr - the IP address of interest
- * setp - pointer to an address set (generated by pfild)
- *
- * Support function for fr_verifysrc used on Solaris 10 and later.
- * Try to match an IPv4 address against an address set.
- * Returns true iff the specified address is a member of the set.
- * Note that addr is passed in network byte order; we convert it to host byte
- * order for searching the table.
- */
-static boolean_t addrset_match_v4(setp, addr)
-struct pfil_ifaddrset *setp;
-struct in_addr addr;
-{
- uint32_t haddr = ntohl(addr.s_addr);
- unsigned int low, high, mid;
- struct pfil_v4span *spans = (struct pfil_v4span *)(setp + 1);
-
- /* binary search */
- low = 0;
- high = setp->nspans;
- while (low < high) {
- mid = (high + low) / 2;
- if (haddr > spans[mid].last)
- low = mid + 1;
- else if (haddr < spans[mid].first)
- high = mid;
- else
- return B_TRUE;
- }
- return B_FALSE;
-}
-
-/*
- * Function: addrset_match_v6
- * Returns: boolean_t
- * Parameters: addr - the IP address of interest
- * setp - pointer to an address set (generated by pfild)
- *
- * Support function for fr_verifysrc used on Solaris 10 and later.
- * Try to match an IPv6 address against an address set.
- * Returns true iff the specified address is a member of the set.
- */
-static boolean_t addrset_match_v6(setp, addr)
-struct pfil_ifaddrset *setp;
-struct in6_addr addr;
-{
- unsigned int low, high, mid;
- struct pfil_v6span *spans = (struct pfil_v6span *)(setp + 1);
-
- /* binary search */
- low = 0;
- high = setp->nspans;
- while (low < high) {
- mid = (high + low) / 2;
- if (IP6_GT(&addr, &spans[mid].last))
- low = mid + 1;
- else if (IP6_LT(&addr, &spans[mid].first))
- high = mid;
- else
- return B_TRUE;
- }
- return B_FALSE;
-}
-#endif
-
-/*
- * Function: fr_verifysrc
- * Returns: int (really boolean)
- * Parameters: fin - packet information
- *
- * Check whether the packet has a valid source address for the interface on
- * which the packet arrived, implementing the "fr_chksrc" feature.
- * Returns true iff the packet's source address is valid.
- * Pre-Solaris 10, we call into the routing code to make the determination.
- * On Solaris 10 and later, we have a valid address set from pfild to check
- * against.
- */
-int fr_verifysrc(fin)
-fr_info_t *fin;
-{
-#if SOLARIS2 >= 10
- qif_t *qf = fin->fin_qif;
- struct pfil_ifaddrset *setp;
-
- if (qf->qf_addrset == NULL) {
- /* Warn here? pfild might not be running. */
- return 0;
- }
-
- setp = (struct pfil_ifaddrset *)qf->qf_addrset->b_rptr;
- if (!setp)
- return 0;
-
- if (fin->fin_v == IPVERSION && setp->af == AF_INET) {
- if (qf->qf_addrset->b_wptr - qf->qf_addrset->b_rptr <
- sizeof (*setp) + setp->nspans * sizeof (struct pfil_v4span))
- return 0; /* malformed set */
-
- return addrset_match_v4(setp, fin->fin_src);
- } else if (fin->fin_v == IPV6_VERSION && setp->af == AF_INET6) {
- if (qf->qf_addrset->b_wptr - qf->qf_addrset->b_rptr <
- sizeof (*setp) + setp->nspans * sizeof (struct pfil_v6span))
- return 0; /* malformed set */
-
- return addrset_match_v6(setp, fin->fin_src6);
- } else
- return 0;
-
-#else
- ire_t *ir, *dir;
-
-#if SOLARIS2 >= 6
- dir = ire_route_lookup(fin->fin_saddr, 0xffffffff, 0, 0, NULL,
- NULL, NULL, MATCH_IRE_DSTONLY|MATCH_IRE_DEFAULT|
- MATCH_IRE_RECURSIVE);
-#else
- dir = ire_lookup(fin->fin_saddr);
-#endif
-
- if (!dir)
- return 0;
- return (ire_to_ill(dir) == fin->fin_ifp);
-#endif /* SOLARIS2 >= 10 */
-}
-
-
-#if (SOLARIS2 < 7)
-void fr_slowtimer()
-#else
-/*ARGSUSED*/
-void fr_slowtimer __P((void *ptr))
-#endif
-{
-
- WRITE_ENTER(&ipf_global);
- if (fr_running <= 0) {
- if (fr_running == -1)
- fr_timer_id = timeout(fr_slowtimer, NULL,
- drv_usectohz(500000));
- else
- fr_timer_id = NULL;
- RWLOCK_EXIT(&ipf_global);
- return;
- }
- MUTEX_DOWNGRADE(&ipf_global);
-
- fr_fragexpire();
- fr_timeoutstate();
- fr_natexpire();
- fr_authexpire();
- fr_ticks++;
- if (fr_running == -1 || fr_running == 1)
- fr_timer_id = timeout(fr_slowtimer, NULL, drv_usectohz(500000));
- else
- fr_timer_id = NULL;
- RWLOCK_EXIT(&ipf_global);
-}
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index 82fdea4c43..7de4d5f59e 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -362,13 +362,13 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/tcp/%.c
$(CTFCONVERT_O)
-IPFFLAGS=-I $(UTSBASE)/common/inet/ipf
-$(OBJS_DIR)/%.o: $(SRC)/common/ipf/%.c
+IPFFLAGS=-I $(UTSBASE)/common/inet/pfil
+$(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/ipf/%.c
$(COMPILE.c) $(IPFFLAGS) -o $@ $<
$(CTFCONVERT_O)
-IPFFLAG2=-I $(SRC)/common/ipf
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/ipf/%.c
+IPFFLAG2=-I $(UTSBASE)/common/inet/ipf
+$(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/pfil/%.c
$(COMPILE.c) $(IPFFLAG2) -o $@ $<
$(CTFCONVERT_O)
@@ -1103,10 +1103,10 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/arp/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/ip/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(SRC)/common/ipf/%.c
+$(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/ipf/%.c
@($(LHEAD) $(LINT.c) $(IPFFLAGS) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/ipf/%.c
+$(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/pfil/%.c
@($(LHEAD) $(LINT.c) $(IPFFLAG2) $< $(LTAIL))
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/inet/kssl/%.c
diff --git a/usr/src/common/ipf/bpf-ipf.h b/usr/src/uts/common/inet/ipf/bpf-ipf.h
index 544455e5ff..544455e5ff 100644
--- a/usr/src/common/ipf/bpf-ipf.h
+++ b/usr/src/uts/common/inet/ipf/bpf-ipf.h
diff --git a/usr/src/common/ipf/fil.c b/usr/src/uts/common/inet/ipf/fil.c
index 0a53cfb32e..1dd95e9ba5 100644
--- a/usr/src/common/ipf/fil.c
+++ b/usr/src/uts/common/inet/ipf/fil.c
@@ -2,10 +2,8 @@
* Copyright (C) 1993-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,7 +38,9 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/fcntl.h>
+#if !defined(_AIX51)
+# include <sys/fcntl.h>
+#endif
#if defined(_KERNEL)
# include <sys/systm.h>
# include <sys/file.h>
@@ -48,6 +48,7 @@
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
+# include <stddef.h>
# include <sys/file.h>
# define _KERNEL
# ifdef __OpenBSD__
@@ -56,10 +57,13 @@ struct file;
# include <sys/uio.h>
# undef _KERNEL
#endif
-#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)
+#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \
+ !defined(linux)
# include <sys/mbuf.h>
#else
-# include <sys/byteorder.h>
+# if !defined(linux)
+# include <sys/byteorder.h>
+# endif
# if (SOLARIS2 < 5) && defined(sun)
# include <sys/dditypes.h>
# endif
@@ -67,65 +71,62 @@ struct file;
#ifdef __hpux
# define _NET_ROUTE_INCLUDED
#endif
-#include <sys/protosw.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#include <net/if.h>
#ifdef sun
# include <net/af.h>
#endif
+#if !defined(_KERNEL) && defined(__FreeBSD__)
+# include "radix_ipf.h"
+#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
# include <sys/hashing.h>
# include <netinet/in_var.h>
#endif
#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
+#if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL)
+# include <netinet/udp.h>
+# include <netinet/ip_icmp.h>
+#endif
#ifdef __hpux
# undef _NET_ROUTE_INCLUDED
#endif
-#if SOLARIS2 >= 10
-# include "ip_compat.h"
-#else
-# include "netinet/ip_compat.h"
-#endif
+#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
-# if !SOLARIS && defined(_KERNEL) && !defined(__osf__)
+# if !SOLARIS && defined(_KERNEL) && !defined(__osf__) && !defined(__hpux)
# include <netinet6/in6_var.h>
# endif
#endif
#include <netinet/tcpip.h>
-#if SOLARIS2 >= 10
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#include "ip_auth.h"
-#else
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
-#endif
#ifdef IPFILTER_SCAN
# include "netinet/ip_scan.h"
#endif
-#if SOLARIS2 >= 10
-#include "ip_pool.h"
-#include "ip_htable.h"
-#else
+#ifdef IPFILTER_SYNC
+# include "netinet/ip_sync.h"
+#endif
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
+#ifdef IPFILTER_COMPILED
+# include "netinet/ip_rules.h"
#endif
-#ifdef IPFILTER_BPF
+#if defined(IPFILTER_BPF) && defined(_KERNEL)
# include <net/bpf.h>
#endif
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
@@ -134,20 +135,18 @@ struct file;
# include "opt_ipfilter.h"
# endif
#endif
-#if SOLARIS2 >= 10
-#include "ipl.h"
-#else
#include "netinet/ipl.h"
-#endif
+/* END OF INCLUDES */
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fil.c,v 2.197 2003/07/01 18:30:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.64 2005/08/13 05:19:59 darrenr Exp $";
#endif
#ifndef _KERNEL
# include "ipf.h"
# include "ipt.h"
+# include "bpf-ipf.h"
extern int opts;
# define FR_VERBOSE(verb_pr) verbose verb_pr
@@ -158,6 +157,7 @@ extern int opts;
#endif /* _KERNEL */
+fr_info_t frcache[2][8];
struct filterstats frstats[2] = { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } };
struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
*ipfilter6[2][2] = { { NULL, NULL }, { NULL, NULL } },
@@ -165,6 +165,7 @@ struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
*ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } },
*ipnatrules[2][2] = { { NULL, NULL }, { NULL, NULL } };
struct frgroup *ipfgroups[IPL_LOGSIZE][2];
+char ipfilter_version[] = IPL_VERSION;
int fr_refcnt = 0;
/*
* For fr_running:
@@ -174,31 +175,49 @@ int fr_running = 0;
int fr_flags = IPF_LOGGING;
int fr_active = 0;
int fr_control_forwarding = 0;
-#ifdef _KERNEL
int fr_update_ipid = 0;
-#else
-int fr_update_ipid = 1;
-#endif
u_short fr_ip_id = 0;
-int fr_chksrc = 0;
+int fr_chksrc = 0; /* causes a system crash if enabled */
int fr_minttl = 4;
+int fr_icmpminfragmtu = 68;
+u_long fr_frouteok[2] = {0, 0};
+u_long fr_userifqs = 0;
+u_long fr_badcoalesces[2] = {0, 0};
+u_char ipf_iss_secret[32];
#if defined(IPFILTER_DEFAULT_BLOCK)
int fr_pass = FR_BLOCK|FR_NOMATCH;
#else
int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH;
#endif
-u_long fr_frouteok[2] = {0, 0};
-u_long fr_userifqs = 0;
-#ifdef ICMP_UNREACH_FILTER_PROHIB
-int fr_unreach = ICMP_UNREACH_FILTER_PROHIB;
-#else
-int fr_unreach = ICMP_UNREACH_FILTER;
+int fr_features = 0
+#ifdef IPFILTER_LKM
+ | IPF_FEAT_LKM
#endif
-u_char ipf_iss_secret[32];
-
-char ipfilter_version[] = IPL_VERSION;
-
-fr_info_t frcache[2][8];
+#ifdef IPFILTER_LOG
+ | IPF_FEAT_LOG
+#endif
+#ifdef IPFILTER_LOOKUP
+ | IPF_FEAT_LOOKUP
+#endif
+#ifdef IPFILTER_BPF
+ | IPF_FEAT_BPF
+#endif
+#ifdef IPFILTER_COMPILED
+ | IPF_FEAT_COMPILED
+#endif
+#ifdef IPFILTER_CKSUM
+ | IPF_FEAT_CKSUM
+#endif
+#ifdef IPFILTER_SYNC
+ | IPF_FEAT_SYNC
+#endif
+#ifdef IPFILTER_SCAN
+ | IPF_FEAT_SCAN
+#endif
+#ifdef USE_INET6
+ | IPF_FEAT_IPV6
+#endif
+ ;
static INLINE int fr_ipfcheck __P((fr_info_t *, frentry_t *, int));
static int fr_portcheck __P((frpcmp_t *, u_short *));
@@ -206,6 +225,7 @@ static int frflushlist __P((int, minor_t, int *, frentry_t **));
static ipfunc_t fr_findfunc __P((ipfunc_t));
static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *));
static int fr_funcinit __P((frentry_t *fr));
+static INLINE void frpr_ah __P((fr_info_t *));
static INLINE void frpr_esp __P((fr_info_t *));
static INLINE void frpr_gre __P((fr_info_t *));
static INLINE void frpr_udp __P((fr_info_t *));
@@ -221,13 +241,18 @@ static INLINE int fr_updateipid __P((fr_info_t *));
static int fr_grpmapinit __P((frentry_t *fr));
static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *));
#endif
-static void frsynclist __P((frentry_t *));
+static void frsynclist __P((frentry_t *, void *));
+static ipftuneable_t *fr_findtunebyname __P((const char *));
+static ipftuneable_t *fr_findtunebycookie __P((void *, void **));
/*
* bit values for identifying presence of individual IP options
+ * All of these tables should be ordered by increasing key value on the left
+ * hand side to allow for binary searching of the array and include a trailer
+ * with a 0 for the bitmask for linear searches to easily find the end with.
*/
-struct optlist ipopts[20] = {
+const struct optlist ipopts[20] = {
{ IPOPT_NOP, 0x000001 },
{ IPOPT_RR, 0x000002 },
{ IPOPT_ZSU, 0x000004 },
@@ -277,7 +302,7 @@ struct optlist tcpopts[] = {
/*
* bit values for identifying presence of individual IP security options
*/
-struct optlist secopt[8] = {
+const struct optlist secopt[8] = {
{ IPSO_CLASS_RES4, 0x01 },
{ IPSO_CLASS_TOPS, 0x02 },
{ IPSO_CLASS_SECR, 0x04 },
@@ -311,6 +336,9 @@ static ipfunc_resolve_t fr_availfuncs[] = {
* adding more code to a growing switch statement.
*/
#ifdef USE_INET6
+static INLINE int frpr_ah6 __P((fr_info_t *));
+static INLINE void frpr_esp6 __P((fr_info_t *));
+static INLINE void frpr_gre6 __P((fr_info_t *));
static INLINE void frpr_udp6 __P((fr_info_t *));
static INLINE void frpr_tcp6 __P((fr_info_t *));
static INLINE void frpr_icmp6 __P((fr_info_t *));
@@ -320,6 +348,7 @@ static INLINE int frpr_hopopts6 __P((fr_info_t *));
static INLINE int frpr_routing6 __P((fr_info_t *));
static INLINE int frpr_dstopts6 __P((fr_info_t *));
static INLINE int frpr_fragment6 __P((fr_info_t *));
+static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int));
/* ------------------------------------------------------------------------ */
@@ -329,32 +358,16 @@ static INLINE int frpr_fragment6 __P((fr_info_t *));
/* */
/* IPv6 Only */
/* This is function enforces the 'is a packet too short to be legit' rule */
-/* for IPv6 and marks the packet with FI_BAD/FI_SHORT if so. */
-/* See function comment for frpr_short() for more details. */
+/* for IPv6 and marks the packet with FI_SHORT if so. See function comment */
+/* for frpr_short() for more details. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_short6(fin, min)
+static INLINE void frpr_short6(fin, xmin)
fr_info_t *fin;
-int min;
+int xmin;
{
- fr_ip_t *fi = &fin->fin_fi;
- int off;
- off = fin->fin_off;
- if (off == 0) {
- if (fin->fin_dlen < min) {
- if (fin->fin_flx & FI_FRAG) {
- fin->fin_p = IPPROTO_FRAGMENT;
- fin->fin_flx |= FI_BAD;
- } else {
- fi->fi_flx |= FI_SHORT;
- }
- }
- } else if (off < min) {
- if (fin->fin_flx & FI_FRAG)
- fi->fi_flx |= FI_BAD;
- else
- fi->fi_flx |= FI_SHORT;
- }
+ if (fin->fin_dlen < xmin)
+ fin->fin_flx |= FI_SHORT;
}
@@ -370,8 +383,8 @@ int min;
static INLINE int frpr_ipv6hdr(fin)
fr_info_t *fin;
{
- int p, go = 1, i, hdrcount, coalesced;
ip6_t *ip6 = (ip6_t *)fin->fin_ip;
+ int p, go = 1, i, hdrcount;
fr_ip_t *fi = &fin->fin_fi;
fin->fin_off = 0;
@@ -381,7 +394,6 @@ fr_info_t *fin;
fi->fi_secmsk = 0;
fi->fi_auth = 0;
- coalesced = (fin->fin_flx & FI_COALESCE) ? 1 : 0;
p = ip6->ip6_nxt;
fi->fi_ttl = ip6->ip6_hlim;
fi->fi_src.in6 = ip6->ip6_src;
@@ -408,111 +420,102 @@ fr_info_t *fin;
break;
case IPPROTO_GRE :
- frpr_gre(fin);
+ frpr_gre6(fin);
go = 0;
break;
case IPPROTO_HOPOPTS :
/*
- * Actually, hop by hop header is only allowed right
- * after IPv6 header!
+ * hop by hop ext header is only allowed
+ * right after IPv6 header.
*/
- if (hdrcount != 0)
+ if (hdrcount != 0) {
fin->fin_flx |= FI_BAD;
-
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return 0;
+ p = IPPROTO_NONE;
+ } else {
+ p = frpr_hopopts6(fin);
}
- p = frpr_hopopts6(fin);
break;
case IPPROTO_DSTOPTS :
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return 0;
- }
p = frpr_dstopts6(fin);
break;
case IPPROTO_ROUTING :
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return 0;
- }
p = frpr_routing6(fin);
break;
+ case IPPROTO_AH :
+ p = frpr_ah6(fin);
+ break;
+
case IPPROTO_ESP :
- frpr_esp(fin);
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == p) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- break;
- }
+ frpr_esp6(fin);
go = 0;
break;
- case IPPROTO_AH :
- frpr_short6(fin, 16);
+ case IPPROTO_IPV6 :
for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
if (ip6exthdr[i].ol_val == p) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ fin->fin_flx |= ip6exthdr[i].ol_bit;
break;
}
go = 0;
break;
- case IPPROTO_IPV6 :
- frpr_short6(fin, sizeof(ip6_t));
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == p) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- break;
- }
+ case IPPROTO_NONE :
go = 0;
break;
case IPPROTO_FRAGMENT :
- p = frpr_fragment6(fin);
- if (fin->fin_off != 0) /* Not the first frag */
+ p = frpr_fragment6(fin);
+ if (fin->fin_off != 0) /* Not the first frag */
go = 0;
break;
- case IPPROTO_NONE :
- go = 0;
- break;
-
default :
go = 0;
break;
}
hdrcount++;
- }
+ /*
+ * It is important to note that at this point, for the
+ * extension headers (go != 0), the entire header may not have
+ * been pulled up when the code gets to this point. This is
+ * only done for "go != 0" because the other header handlers
+ * will all pullup their complete header. The other indicator
+ * of an incomplete packet is that this was just an extension
+ * header.
+ */
+ if ((go != 0) && (p != IPPROTO_NONE) &&
+ (frpr_pullup(fin, 0) == -1)) {
+ p = IPPROTO_NONE;
+ go = 0;
+ }
+ }
fi->fi_p = p;
- /* ext hdr error */
- if ((go && hdrcount && (fin->fin_flx & FI_FRAG)) ||
- (fin->fin_flx & FI_BAD))
- return -1;
+ if (fin->fin_flx & FI_BAD)
+ return -1;
+
return 0;
}
/* ------------------------------------------------------------------------ */
-/* Function: frpr_hopopts6 */
+/* Function: frpr_ipv6exthdr */
/* Returns: int - value of the next header or IPPROTO_NONE if error */
-/* Parameters: fin(I) - pointer to packet information */
+/* Parameters: fin(I) - pointer to packet information */
+/* multiple(I) - flag indicating yes/no if multiple occurances */
+/* of this extension header are allowed. */
+/* proto(I) - protocol number for this extension header */
/* */
/* IPv6 Only */
-/* This is function checks pending hop by hop options extension header */
/* ------------------------------------------------------------------------ */
-static INLINE int frpr_hopopts6(fin)
+static INLINE int frpr_ipv6exthdr(fin, multiple, proto)
fr_info_t *fin;
+int multiple, proto;
{
struct ip6_ext *hdr;
u_short shift;
@@ -520,10 +523,11 @@ fr_info_t *fin;
fin->fin_flx |= FI_V6EXTHDR;
- /* 8 is default length of extension hdr */
- frpr_short6(fin, 8);
- if (fin->fin_flx & (FI_BAD|FI_SHORT))
+ /* 8 is default length of extension hdr */
+ if ((fin->fin_dlen - 8) < 0) {
+ fin->fin_flx |= FI_SHORT;
return IPPROTO_NONE;
+ }
if (frpr_pullup(fin, 8) == -1)
return IPPROTO_NONE;
@@ -536,8 +540,15 @@ fr_info_t *fin;
}
for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_HOPOPTS) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ if (ip6exthdr[i].ol_val == proto) {
+ /*
+ * Most IPv6 extension headers are only allowed once.
+ */
+ if ((multiple == 0) &&
+ ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0))
+ fin->fin_flx |= FI_BAD;
+ else
+ fin->fin_optmsk |= ip6exthdr[i].ol_bit;
break;
}
@@ -549,6 +560,21 @@ fr_info_t *fin;
/* ------------------------------------------------------------------------ */
+/* Function: frpr_hopopts6 */
+/* Returns: int - value of the next header or IPPROTO_NONE if error */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* This is function checks pending hop by hop options extension header */
+/* ------------------------------------------------------------------------ */
+static INLINE int frpr_hopopts6(fin)
+fr_info_t *fin;
+{
+ return frpr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS);
+}
+
+
+/* ------------------------------------------------------------------------ */
/* Function: frpr_routing6 */
/* Returns: int - value of the next header or IPPROTO_NONE if error */
/* Parameters: fin(I) - pointer to packet information */
@@ -560,38 +586,26 @@ static INLINE int frpr_routing6(fin)
fr_info_t *fin;
{
struct ip6_ext *hdr;
- u_short shift;
- int i;
-
- fin->fin_flx |= FI_V6EXTHDR;
+ int shift;
- /* 8 is default length of extension hdr */
- frpr_short6(fin, 8);
- if (fin->fin_flx & (FI_BAD|FI_SHORT))
- return IPPROTO_NONE;
-
- if (frpr_pullup(fin, 8) == -1)
- return IPPROTO_NONE;
hdr = fin->fin_dp;
+ if (frpr_ipv6exthdr(fin, 0, IPPROTO_ROUTING) == IPPROTO_NONE)
+ return IPPROTO_NONE;
shift = 8 + (hdr->ip6e_len << 3);
/*
* Nasty extension header length?
*/
- if ((shift > fin->fin_dlen) || ((hdr->ip6e_len << 3) & 15)) {
+ if ((hdr->ip6e_len << 3) & 15) {
fin->fin_flx |= FI_BAD;
+ /*
+ * Compensate for the changes made in frpr_ipv6exthdr()
+ */
+ fin->fin_dlen += shift;
+ fin->fin_dp = (char *)fin->fin_dp - shift;
return IPPROTO_NONE;
}
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- break;
- }
-
- fin->fin_dp = (char *)fin->fin_dp + shift;
- fin->fin_dlen -= shift;
-
return hdr->ip6e_nxt;
}
@@ -603,64 +617,63 @@ fr_info_t *fin;
/* */
/* IPv6 Only */
/* Examine the IPv6 fragment header and extract fragment offset information.*/
+/* */
+/* We don't know where the transport layer header (or whatever is next is), */
+/* as it could be behind destination options (amongst others). Because */
+/* there is no fragment cache, there is no knowledge about whether or not an*/
+/* 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 int frpr_fragment6(fin)
fr_info_t *fin;
{
struct ip6_frag *frag;
- int i;
-
- fin->fin_flx |= (FI_FRAG|FI_V6EXTHDR);
+ int dlen;
- /*
- * Only one frgament header is allowed per IPv6 packet but it need
- * not be the first nor last (not possible in some cases.)
- */
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_FRAGMENT)
- break;
+ fin->fin_flx |= FI_FRAG;
- if (fin->fin_optmsk & ip6exthdr[i].ol_bit) {
- fin->fin_flx |= FI_BAD;
+ dlen = fin->fin_dlen;
+ if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE)
return IPPROTO_NONE;
- }
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
-
- /* 8 is default length of extension hdr */
- frpr_short6(fin, 8);
- if (fin->fin_flx & (FI_BAD|FI_SHORT))
+ if (frpr_pullup(fin, sizeof(*frag)) == -1)
return IPPROTO_NONE;
- if (frpr_pullup(fin, 8) == -1)
+ frpr_short6(fin, sizeof(*frag));
+
+ if ((fin->fin_flx & FI_SHORT) != 0)
return IPPROTO_NONE;
- if ((int)(fin->fin_dlen - sizeof(*frag)) < 0) {
- fin->fin_flx |= FI_SHORT;
+ frag = (struct ip6_frag *)((char *)fin->fin_dp - sizeof(*frag));
+ /*
+ * Fragment but no fragmentation info set? Bad packet...
+ */
+ if (frag->ip6f_offlg == 0) {
+ fin->fin_flx |= FI_BAD;
return IPPROTO_NONE;
}
- frag = fin->fin_dp;
fin->fin_id = frag->ip6f_ident;
fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
fin->fin_off = ntohs(fin->fin_off);
- if (!(frag->ip6f_offlg & IP6F_MORE_FRAG)) {
- fin->fin_flx |= FI_FRAGTAIL;
- } else if (fin->fin_dlen % 8) {
- /*
- * If the frag is not the last one and the payload length
- * is not multiple of 8, it must be dropped.
- */
- fin->fin_flx |= FI_BAD;
- return IPPROTO_NONE;
- }
+ if (fin->fin_off != 0)
+ fin->fin_flx |= FI_FRAGBODY;
- fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
- fin->fin_dlen -= sizeof(*frag);
+ fin->fin_dp = (char *)frag + sizeof(*frag);
+ fin->fin_dlen = dlen - sizeof(*frag);
/* length of hdrs(after frag hdr) + data */
fin->fin_flen = fin->fin_dlen;
+ /*
+ * If the frag is not the last one and the payload length
+ * is not multiple of 8, it must be dropped.
+ */
+ if ((frag->ip6f_offlg & IP6F_MORE_FRAG) && (dlen % 8)) {
+ fin->fin_flx |= FI_BAD;
+ return IPPROTO_NONE;
+ }
+
return frag->ip6f_nxt;
}
@@ -677,33 +690,7 @@ fr_info_t *fin;
static INLINE int frpr_dstopts6(fin)
fr_info_t *fin;
{
- struct ip6_ext *hdr;
- u_short shift;
- int i;
-
- /* 8 is default length of extension hdr */
- frpr_short6(fin, 8);
- if (fin->fin_flx & (FI_BAD|FI_SHORT))
- return IPPROTO_NONE;
-
- if (frpr_pullup(fin, 8) == -1)
- return IPPROTO_NONE;
- hdr = fin->fin_dp;
-
- shift = 8 + (hdr->ip6e_len << 3);
- if (shift > fin->fin_dlen) { /* Nasty extension header length? */
- fin->fin_flx |= FI_BAD;
- return IPPROTO_NONE;
- }
-
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_DSTOPTS)
- break;
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- fin->fin_dp = (char *)fin->fin_dp + shift;
- fin->fin_dlen -= shift;
-
- return hdr->ip6e_nxt;
+ return frpr_ipv6exthdr(fin, 1, IPPROTO_DSTOPTS);
}
@@ -722,7 +709,7 @@ fr_info_t *fin;
int minicmpsz = sizeof(struct icmp6_hdr);
struct icmp6_hdr *icmp6;
- if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t)) == -1)
+ if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN - sizeof(ip6_t)) == -1)
return;
if (fin->fin_dlen > 1) {
@@ -754,7 +741,6 @@ fr_info_t *fin;
}
frpr_short6(fin, minicmpsz);
-
fin->fin_flen -= fin->fin_dlen - minicmpsz;
}
@@ -766,6 +752,7 @@ fr_info_t *fin;
/* */
/* IPv6 Only */
/* Analyse the packet for IPv6/UDP properties. */
+/* Is not expected to be called for fragmented packets. */
/* ------------------------------------------------------------------------ */
static INLINE void frpr_udp6(fin)
fr_info_t *fin;
@@ -790,6 +777,7 @@ fr_info_t *fin;
/* */
/* IPv6 Only */
/* Analyse the packet for IPv6/TCP properties. */
+/* Is not expected to be called for fragmented packets. */
/* ------------------------------------------------------------------------ */
static INLINE void frpr_tcp6(fin)
fr_info_t *fin;
@@ -805,6 +793,94 @@ fr_info_t *fin;
frpr_tcpcommon(fin);
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_esp6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* Analyse the packet for ESP properties. */
+/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */
+/* even though the newer ESP packets must also have a sequence number that */
+/* is 32bits as well, it is not possible(?) to determine the version from a */
+/* simple packet header. */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_esp6(fin)
+fr_info_t *fin;
+{
+ int i;
+ frpr_short6(fin, sizeof(grehdr_t));
+
+ (void) frpr_pullup(fin, 8);
+
+ for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
+ if (ip6exthdr[i].ol_val == IPPROTO_ESP) {
+ fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ break;
+ }
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_ah6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* Analyse the packet for AH properties. */
+/* The minimum length is taken to be the combination of all fields in the */
+/* header being present and no authentication data (null algorithm used.) */
+/* ------------------------------------------------------------------------ */
+static INLINE int frpr_ah6(fin)
+fr_info_t *fin;
+{
+ authhdr_t *ah;
+ int i, shift;
+
+ frpr_short6(fin, 12);
+
+ if (frpr_pullup(fin, sizeof(*ah)) == -1)
+ return IPPROTO_NONE;
+
+ for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
+ if (ip6exthdr[i].ol_val == IPPROTO_AH) {
+ fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ break;
+ }
+
+ ah = (authhdr_t *)fin->fin_dp;
+
+ shift = (ah->ah_plen + 2) * 4;
+ fin->fin_dlen -= shift;
+ fin->fin_dp = (char*)fin->fin_dp + shift;
+
+ return ah->ah_next;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_gre6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* Analyse the packet for GRE properties. */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_gre6(fin)
+fr_info_t *fin;
+{
+ grehdr_t *gre;
+
+ frpr_short6(fin, sizeof(grehdr_t));
+
+ if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
+ return;
+
+ gre = fin->fin_dp;
+ if (GRE_REV(gre->gr_flags) == 1)
+ fin->fin_data[0] = gre->gr_call;
+}
#endif /* USE_INET6 */
@@ -822,7 +898,7 @@ static INLINE int frpr_pullup(fin, plen)
fr_info_t *fin;
int plen;
{
-#if defined(_KERNEL) && !defined(__sgi)
+#if defined(_KERNEL)
if (fin->fin_m != NULL) {
if (fin->fin_dp != NULL)
plen += (char *)fin->fin_dp -
@@ -842,25 +918,25 @@ int plen;
/* ------------------------------------------------------------------------ */
/* Function: frpr_short */
/* Returns: void */
-/* Parameters: fin(I) - pointer to packet information */
-/* min(I) - minimum size of packet */
+/* Parameters: fin(I) - pointer to packet information */
+/* xmin(I) - minimum header size */
/* */
-/* Check if a packet is "short" as defined by min. */
+/* Check if a packet is "short" as defined by xmin. The rule we are */
+/* applying here is that the packet must not be fragmented within the layer */
+/* 4 header. That is, it must not be a fragment that has its offset set to */
+/* start within the layer 4 header (hdrmin) or if it is at offset 0, the */
+/* entire layer 4 header must be present (min). */
/* ------------------------------------------------------------------------ */
-/*ARGSUSED*/
-static INLINE void frpr_short(fin, min)
+static INLINE void frpr_short(fin, xmin)
fr_info_t *fin;
-int min;
+int xmin;
{
- fr_ip_t *fi = &fin->fin_fi;
- int off;
- off = fin->fin_off;
- if (off == 0) {
- if (fin->fin_plen < fin->fin_hlen + min)
- fi->fi_flx |= FI_SHORT;
- } else if (off < min) {
- fi->fi_flx |= FI_SHORT;
+ if (fin->fin_off == 0) {
+ if (fin->fin_dlen < xmin)
+ fin->fin_flx |= FI_SHORT;
+ } else if (fin->fin_off < xmin) {
+ fin->fin_flx |= FI_SHORT;
}
}
@@ -873,7 +949,7 @@ int min;
/* IPv4 Only */
/* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */
/* except extrememly bad packets, both type and code will be present. */
-/* The expected minimum size of an ICMP packet is very much dependant on */
+/* The expected minimum size of an ICMP packet is very much dependent on */
/* the type of it. */
/* */
/* XXX - other ICMP sanity checks? */
@@ -883,12 +959,16 @@ fr_info_t *fin;
{
int minicmpsz = sizeof(struct icmp);
icmphdr_t *icmp;
+ ip_t *oip;
if (fin->fin_off != 0) {
frpr_short(fin, ICMPERR_ICMPHLEN);
return;
}
+ if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1)
+ return;
+
fr_checkv4sum(fin);
if (fin->fin_dlen > 1) {
@@ -925,20 +1005,33 @@ fr_info_t *fin;
* type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+)
*/
case ICMP_UNREACH :
+ if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) {
+ if (icmp->icmp_nextmtu < fr_icmpminfragmtu)
+ fin->fin_flx |= FI_BAD;
+ }
+ /* FALLTHRU */
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
- if ((fin->fin_m != NULL) &&
- (M_LEN(fin->fin_m) < fin->fin_plen)) {
- if (fr_coalesce(fin) != 1)
- return;
- }
fin->fin_flx |= FI_ICMPERR;
+ if (fr_coalesce(fin) != 1)
+ return;
+ /*
+ * ICMP error packets should not be generated for IP
+ * packets that are a fragment that isn't the first
+ * fragment.
+ */
+ oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN);
+ if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0)
+ fin->fin_flx |= FI_BAD;
break;
default :
break;
}
+
+ if (fin->fin_dlen >= 6) /* ID field */
+ fin->fin_data[1] = icmp->icmp_id;
}
frpr_short(fin, minicmpsz);
@@ -965,62 +1058,71 @@ fr_info_t *fin;
if (fin->fin_off != 0)
return;
+ if (frpr_pullup(fin, sizeof(*tcp)) == -1)
+ return;
tcp = fin->fin_dp;
- tlen = TCP_OFF(tcp) << 2;
-#if defined(_KERNEL) && !defined(__sgi)
- if ((fin->fin_m != NULL) &&
- (M_LEN(fin->fin_m) < tlen + fin->fin_hlen)) {
- if (fr_pullup(fin->fin_m, fin, tlen + fin->fin_hlen) == NULL)
- return;
+ if (fin->fin_dlen > 3) {
+ fin->fin_sport = ntohs(tcp->th_sport);
+ fin->fin_dport = ntohs(tcp->th_dport);
}
-#endif
+
+ if ((fin->fin_flx & FI_SHORT) != 0)
+ return;
/*
* Use of the TCP data offset *must* result in a value that is at
* least the same size as the TCP header.
*/
- if (tlen < sizeof(tcphdr_t))
+ tlen = TCP_OFF(tcp) << 2;
+ if (tlen < sizeof(tcphdr_t)) {
fin->fin_flx |= FI_BAD;
- if (!(fin->fin_flx & FI_SHORT)) {
- flags = tcp->th_flags;
- fin->fin_tcpf = tcp->th_flags;
+ return;
+ }
+ flags = tcp->th_flags;
+ fin->fin_tcpf = tcp->th_flags;
+
+ /*
+ * If the urgent flag is set, then the urgent pointer must
+ * also be set and vice versa. Good TCP packets do not have
+ * just one of these set.
+ */
+ if ((flags & TH_URG) != 0 && (tcp->th_urp == 0)) {
+ fin->fin_flx |= FI_BAD;
+ } else if ((flags & TH_URG) == 0 && (tcp->th_urp != 0)) {
+ /* Ignore this case, it shows up in "real" traffic with */
+ /* bogus values in the urgent pointer field. */
+ flags = flags; /* LINT */
+ } else if (((flags & (TH_SYN|TH_FIN)) != 0) &&
+ ((flags & (TH_RST|TH_ACK)) == TH_RST)) {
+ /* TH_FIN|TH_RST|TH_ACK seems to appear "naturally" */
+ fin->fin_flx |= FI_BAD;
+ } else if (!(flags & TH_ACK)) {
/*
- * If the urgent flag is set, then the urgent pointer must
- * also be set and vice versa. Good TCP packets do not have
- * just one of these set.
+ * If the ack bit isn't set, then either the SYN or
+ * RST bit must be set. If the SYN bit is set, then
+ * we expect the ACK field to be 0. If the ACK is
+ * not set and if URG, PSH or FIN are set, consdier
+ * that to indicate a bad TCP packet.
*/
- if (((flags & TH_URG) != 0 && (tcp->th_urp == 0)) ||
- ((flags & TH_URG) == 0 && (tcp->th_urp != 0))) {
- fin->fin_flx |= FI_BAD;
- } else if (((flags & (TH_SYN|TH_FIN)) != 0) &&
- ((flags & TH_RST) != 0)) {
- fin->fin_flx |= FI_BAD;
- } else if (!(flags & TH_ACK)) {
+ if ((flags == TH_SYN) && (tcp->th_ack != 0)) {
/*
- * If the ack bit isn't set, then either the SYN or
- * RST bit must be set. If the SYN bit is set, then
- * we expect the ACK field to be 0. If the ACK is
- * not set and if URG, PSH or FIN are set, consdier
- * that to indicate a bad TCP packet.
+ * Cisco PIX sets the ACK field to a random value.
+ * In light of this, do not set FI_BAD until a patch
+ * is available from Cisco to ensure that
+ * interoperability between existing systems is
+ * achieved.
*/
- if ((flags == TH_SYN) && (tcp->th_ack != 0)) {
- fin->fin_flx |= FI_BAD;
- } else if (!(flags & (TH_RST|TH_SYN))) {
- fin->fin_flx |= FI_BAD;
- } else if ((flags & (TH_URG|TH_PUSH|TH_FIN)) != 0) {
- fin->fin_flx |= FI_BAD;
- }
+ /*fin->fin_flx |= FI_BAD*/;
+ flags = flags; /* LINT */
+ } else if (!(flags & (TH_RST|TH_SYN))) {
+ fin->fin_flx |= FI_BAD;
+ } else if ((flags & (TH_URG|TH_PUSH|TH_FIN)) != 0) {
+ fin->fin_flx |= FI_BAD;
}
}
- if (fin->fin_dlen > 3) {
- fin->fin_sport = ntohs(tcp->th_sport);
- fin->fin_dport = ntohs(tcp->th_dport);
- }
-
-#if 0
/*
* At this point, it's not exactly clear what is to be gained by
* marking up which TCP options are and are not present. The one we
@@ -1029,30 +1131,35 @@ fr_info_t *fin;
* Now if we were to analyse the header for passive fingerprinting,
* then that might add some weight to adding this...
*/
- s = (u_char *)(tcp + 1);
- hlen = TCP_OFF(tcp) << 2;
- if (hlen == sizeof(tcphdr_t))
+ if (tlen == sizeof(tcphdr_t))
return;
+
+ if (frpr_pullup(fin, tlen) == -1)
+ return;
+
+#if 0
+ ip = fin->fin_ip;
+ s = (u_char *)(tcp + 1);
off = IP_HL(ip) << 2;
# ifdef _KERNEL
if (fin->fin_mp != NULL) {
mb_t *m = *fin->fin_mp;
- if (off + hlen > M_LEN(m))
+ if (off + tlen > M_LEN(m))
return;
}
# endif
- for (hlen -= (int)sizeof(*tcp); hlen > 0; ) {
+ for (tlen -= (int)sizeof(*tcp); tlen > 0; ) {
opt = *s;
if (opt == '\0')
break;
else if (opt == TCPOPT_NOP)
ol = 1;
else {
- if (hlen < 2)
+ if (tlen < 2)
break;
ol = (int)*(s + 1);
- if (ol < 2 || ol > hlen)
+ if (ol < 2 || ol > tlen)
break;
}
@@ -1063,7 +1170,7 @@ fr_info_t *fin;
break;
}
}
- hlen -= ol;
+ tlen -= ol;
s += ol;
}
#endif /* 0 */
@@ -1087,6 +1194,11 @@ fr_info_t *fin;
fin->fin_flx |= FI_TCPUDP;
if (!fin->fin_off && (fin->fin_dlen > 3)) {
+ if (frpr_pullup(fin, sizeof(*udp)) == -1) {
+ fin->fin_flx |= FI_SHORT;
+ return;
+ }
+
udp = fin->fin_dp;
fin->fin_sport = ntohs(udp->uh_sport);
@@ -1109,7 +1221,7 @@ fr_info_t *fin;
fr_checkv4sum(fin);
- frpr_short(fin, sizeof(struct tcphdr));
+ frpr_short(fin, sizeof(tcphdr_t));
frpr_tcpcommon(fin);
}
@@ -1129,7 +1241,7 @@ fr_info_t *fin;
fr_checkv4sum(fin);
- frpr_short(fin, sizeof(struct udphdr));
+ frpr_short(fin, sizeof(udphdr_t));
frpr_udpcommon(fin);
}
@@ -1149,15 +1261,35 @@ fr_info_t *fin;
static INLINE void frpr_esp(fin)
fr_info_t *fin;
{
- if (frpr_pullup(fin, 8) == -1)
+ if ((fin->fin_off == 0) && (frpr_pullup(fin, 8) == -1))
return;
- if (fin->fin_v == 4)
- frpr_short(fin, 8);
-#ifdef USE_INET6
- else if (fin->fin_v == 6)
- frpr_short6(fin, sizeof(grehdr_t));
-#endif
+ frpr_short(fin, 8);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_ah */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* Analyse the packet for AH properties. */
+/* The minimum length is taken to be the combination of all fields in the */
+/* header being present and no authentication data (null algorithm used.) */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_ah(fin)
+fr_info_t *fin;
+{
+ authhdr_t *ah;
+ int len;
+
+ if ((fin->fin_off == 0) && (frpr_pullup(fin, sizeof(*ah)) == -1))
+ return;
+
+ ah = (authhdr_t *)fin->fin_dp;
+
+ len = (ah->ah_plen + 2) << 2;
+ frpr_short(fin, len);
}
@@ -1171,15 +1303,18 @@ fr_info_t *fin;
static INLINE void frpr_gre(fin)
fr_info_t *fin;
{
- if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
+ grehdr_t *gre;
+
+ if ((fin->fin_off == 0) && (frpr_pullup(fin, sizeof(grehdr_t)) == -1))
return;
- if (fin->fin_v == 4)
- frpr_short(fin, sizeof(grehdr_t));
-#ifdef USE_INET6
- else if (fin->fin_v == 6)
- frpr_short6(fin, sizeof(grehdr_t));
-#endif
+ frpr_short(fin, sizeof(grehdr_t));
+
+ if (fin->fin_off == 0) {
+ gre = fin->fin_dp;
+ if (GRE_REV(gre->gr_flags) == 1)
+ fin->fin_data[0] = gre->gr_call;
+ }
}
@@ -1197,7 +1332,7 @@ fr_info_t *fin;
{
u_short optmsk = 0, secmsk = 0, auth = 0;
int hlen, ol, mv, p, i;
- struct optlist *op;
+ const struct optlist *op;
u_char *s, opt;
u_short off;
fr_ip_t *fi;
@@ -1235,22 +1370,27 @@ fr_info_t *fin;
* set packet attribute flags based on the offset and
* calculate the byte offset that it represents.
*/
- if ((off & IP_MF) != 0) {
- fi->fi_flx |= FI_FRAG;
- if (fin->fin_dlen == 0)
- fi->fi_flx |= FI_BAD;
- }
-
off &= IP_MF|IP_OFFMASK;
if (off != 0) {
fi->fi_flx |= FI_FRAG;
- if ((off & IP_MF) == 0)
- fi->fi_flx |= FI_FRAGTAIL;
off &= IP_OFFMASK;
if (off != 0) {
+ fin->fin_flx |= FI_FRAGBODY;
off <<= 3;
- if (off + fin->fin_dlen > 0xffff)
+ if ((off + fin->fin_dlen > 65535) ||
+ (fin->fin_dlen == 0) ||
+ ((ip->ip_off & IP_MF) && (fin->fin_dlen & 7))) {
+ /*
+ * The length of the packet, starting at its
+ * offset cannot exceed 65535 (0xffff) as the
+ * length of an IP packet is only 16 bits.
+ *
+ * Any fragment that isn't the last fragment
+ * must have a length greater than 0 and it
+ * must be an even multiple of 8.
+ */
fi->fi_flx |= FI_BAD;
+ }
}
}
fin->fin_off = off;
@@ -1269,6 +1409,15 @@ fr_info_t *fin;
case IPPROTO_ICMP :
frpr_icmp(fin);
break;
+ case IPPROTO_AH :
+ frpr_ah(fin);
+ break;
+ case IPPROTO_ESP :
+ frpr_esp(fin);
+ break;
+ case IPPROTO_GRE :
+ frpr_gre(fin);
+ break;
}
ip = fin->fin_ip;
@@ -1313,7 +1462,7 @@ fr_info_t *fin;
if ((opt == (u_char)op->ol_val) && (ol > 4)) {
optmsk |= op->ol_bit;
if (opt == IPOPT_SECURITY) {
- struct optlist *sp;
+ const struct optlist *sp;
u_char sec;
int j, m;
@@ -1347,7 +1496,7 @@ fr_info_t *fin;
}
/*
- *
+ *
*/
if (auth && !(auth & 0x0100))
auth &= 0xff00;
@@ -1362,7 +1511,7 @@ fr_info_t *fin;
/* Returns: int - 1 == hdr checking error, 0 == OK */
/* Parameters: hlen(I) - length of IP packet header */
/* ip(I) - pointer to the IP header */
-/* fin(IO) - pointer to packet information */
+/* fin(IO) - pointer to packet information */
/* */
/* Compact the IP header into a structure which contains just the info. */
/* which is useful for comparing IP headers with and store this information */
@@ -1391,9 +1540,10 @@ fr_info_t *fin;
if (v == 4)
frpr_ipv4hdr(fin);
#ifdef USE_INET6
- else if (v == 6)
+ else if (v == 6) {
if (frpr_ipv6hdr(fin) == -1)
return -1;
+ }
#endif
if (fin->fin_ip == NULL)
return -1;
@@ -1726,7 +1876,7 @@ u_32_t pass;
{
int rulen, portcmp, off, logged, skip;
struct frentry *fr, *fnext;
- u_32_t passt;
+ u_32_t passt, passo;
/*
* Do not allow nesting deeper than 16 levels.
@@ -1773,7 +1923,7 @@ u_32_t pass;
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
FR_VERBOSE(("%c", FR_ISSKIP(pass) ? 's' :
- FR_ISPASS(pass) ? 'p' :
+ FR_ISPASS(pass) ? 'p' :
FR_ISACCOUNT(pass) ? 'A' :
FR_ISAUTH(pass) ? 'a' :
(pass & FR_NOMATCH) ? 'n' :'b'));
@@ -1789,20 +1939,18 @@ u_32_t pass;
if (fr_ipfcheck(fin, fr, portcmp))
continue;
break;
-#if defined(IPFILTER_BPF) && defined(_KERNEL)
+#if defined(IPFILTER_BPF)
case FR_T_BPFOPC :
case FR_T_BPFOPC|FR_T_BUILTIN :
{
u_char *mc;
- int wlen;
if (*fin->fin_mp == NULL)
continue;
if (fin->fin_v != fr->fr_v)
continue;
mc = (u_char *)fin->fin_m;
- wlen = fin->fin_dlen + fin->fin_hlen;
- if (!bpf_filter(fr->fr_data, mc, wlen, 0))
+ if (!bpf_filter(fr->fr_data, mc, fin->fin_plen, 0))
continue;
break;
}
@@ -1833,13 +1981,22 @@ u_32_t pass;
passt = fr->fr_flags;
/*
+ * Allowing a rule with the "keep state" flag set to match
+ * packets that have been tagged "out of window" by the TCP
+ * state tracking is foolish as the attempt to add a new
+ * state entry to the table will fail.
+ */
+ if ((passt & FR_KEEPSTATE) && (fin->fin_flx & FI_OOW))
+ continue;
+
+ /*
* If the rule is a "call now" rule, then call the function
* in the rule, if it exists and use the results from that.
* If the function pointer is bad, just make like we ignore
* it, except for increasing the hit counter.
*/
if ((passt & FR_CALLNOW) != 0) {
- ATOMIC_INCL(fr->fr_hits);
+ ATOMIC_INC64(fr->fr_hits);
if ((fr->fr_func != NULL) &&
(fr->fr_func != (ipfunc_t)-1)) {
frentry_t *frs;
@@ -1875,6 +2032,7 @@ u_32_t pass;
}
#endif /* IPFILTER_LOG */
fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
+ passo = pass;
if (FR_ISSKIP(passt))
skip = fr->fr_arg;
else if ((passt & FR_LOGMASK) != FR_LOG)
@@ -1882,7 +2040,7 @@ u_32_t pass;
if (passt & (FR_RETICMP|FR_FAKEICMP))
fin->fin_icode = fr->fr_icode;
FR_DEBUG(("pass %#x\n", pass));
- ATOMIC_INCL(fr->fr_hits);
+ ATOMIC_INC64(fr->fr_hits);
fin->fin_rule = rulen;
(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
if (fr->fr_grp != NULL) {
@@ -1897,8 +2055,29 @@ u_32_t pass;
if (fin->fin_flx & FI_DONTCACHE)
logged = 1;
}
- if (pass & FR_QUICK)
+
+ if (pass & FR_QUICK) {
+ /*
+ * Finally, if we've asked to track state for this
+ * packet, set it up. Add state for "quick" rules
+ * here so that if the action fails we can consider
+ * the rule to "not match" and keep on processing
+ * filter rules.
+ */
+ if ((pass & FR_KEEPSTATE) &&
+ !(fin->fin_flx & FI_STATE)) {
+ int out = fin->fin_out;
+
+ if (fr_addstate(fin, NULL, 0) != NULL) {
+ ATOMIC_INCL(frstats[out].fr_ads);
+ } else {
+ ATOMIC_INCL(frstats[out].fr_bads);
+ pass = passo;
+ continue;
+ }
+ }
break;
+ }
}
if (logged)
fin->fin_flx |= FI_DONTCACHE;
@@ -1983,18 +2162,22 @@ u_32_t *passp;
* the result as if it were from the ACL's.
*/
fc = &frcache[out][CACHE_HASH(fin)];
+ READ_ENTER(&ipf_frcache);
if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
/*
- * copy cached data so we can unlock the mutex
- * earlier.
+ * copy cached data so we can unlock the mutexes earlier.
*/
bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
+ RWLOCK_EXIT(&ipf_frcache);
ATOMIC_INCL(frstats[out].fr_chit);
+
if ((fr = fin->fin_fr) != NULL) {
- ATOMIC_INCL(fr->fr_hits);
+ ATOMIC_INC64(fr->fr_hits);
pass = fr->fr_flags;
}
} else {
+ RWLOCK_EXIT(&ipf_frcache);
+
#ifdef USE_INET6
if (fin->fin_v == 6)
fin->fin_fr = ipfilter6[out][fr_active];
@@ -2003,9 +2186,13 @@ u_32_t *passp;
fin->fin_fr = ipfilter[out][fr_active];
if (fin->fin_fr != NULL)
pass = fr_scanlist(fin, fr_pass);
+
if (((pass & FR_KEEPSTATE) == 0) &&
- ((fin->fin_flx & FI_DONTCACHE) == 0))
+ ((fin->fin_flx & FI_DONTCACHE) == 0)) {
+ WRITE_ENTER(&ipf_frcache);
bcopy((char *)fin, (char *)fc, FI_COPYSIZE);
+ RWLOCK_EXIT(&ipf_frcache);
+ }
if ((pass & FR_NOMATCH)) {
ATOMIC_INCL(frstats[out].fr_nom);
}
@@ -2073,11 +2260,15 @@ u_32_t *passp;
/*
* Finally, if we've asked to track state for this packet, set it up.
*/
- if (pass & FR_KEEPSTATE) {
+ if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) {
if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads);
} else {
ATOMIC_INCL(frstats[out].fr_bads);
+ if (FR_ISPASS(pass)) {
+ pass &= ~FR_CMDMASK;
+ pass |= FR_BLOCK;
+ }
}
}
@@ -2096,7 +2287,7 @@ u_32_t *passp;
/* User space: */
/* -1 == packet blocked */
/* 1 == packet not matched */
-/* -2 == requires authantication */
+/* -2 == requires authentication */
/* Kernel: */
/* > 0 == filter error # for packet */
/* Parameters: ip(I) - pointer to start of IPv4/6 packet */
@@ -2106,7 +2297,7 @@ u_32_t *passp;
/* mp(IO) - pointer to caller's buffer pointer that holds this */
/* IP packet. */
/* Solaris & HP-UX ONLY : */
-/* qif(I) - pointer to STREAMS queue information for this */
+/* qpi(I) - pointer to STREAMS queue information for this */
/* interface & direction. */
/* */
/* fr_check() is the master function for all IPFilter packet processing. */
@@ -2123,7 +2314,7 @@ u_32_t *passp;
int fr_check(ip, hlen, ifp, out
#if defined(_KERNEL) && defined(MENTAT)
, qif, mp)
-qif_t *qif;
+void *qif;
#else
, mp)
#endif
@@ -2138,14 +2329,20 @@ int out;
*/
fr_info_t frinfo;
fr_info_t *fin = &frinfo;
- int v = IP_V(ip), len, p;
+ u_32_t pass = fr_pass;
frentry_t *fr = NULL;
+ int v = IP_V(ip);
mb_t *mc = NULL;
- u_32_t pass;
mb_t *m;
#ifdef USE_INET6
ip6_t *ip6;
#endif
+#ifdef _KERNEL
+# ifdef MENTAT
+ qpktinfo_t *qpi = qif;
+#endif
+#endif
+ SPL_INT(s);
/*
* The first part of fr_check() deals with making sure that what goes
@@ -2155,13 +2352,11 @@ int out;
* to hold all the required packet headers.
*/
#ifdef _KERNEL
-# ifdef __sgi
- char hbuf[MAX_IPV4HDR];
-# endif
# ifdef MENTAT
- if ((uintptr_t)ip & 0x3)
+ if (!OK_32PTR(ip))
return 2;
# endif
+
READ_ENTER(&ipf_global);
if (fr_running <= 0) {
@@ -2172,18 +2367,23 @@ int out;
bzero((char *)fin, sizeof(*fin));
# ifdef MENTAT
- if (qif->qf_flags & QF_GROUP)
+ if (qpi->qpi_flags & QF_GROUP)
fin->fin_flx |= FI_MBCAST;
- m = qif->qf_m;
+ m = qpi->qpi_m;
fin->fin_qfm = m;
- fin->fin_qif = qif;
+ fin->fin_qpi = qpi;
# else /* MENTAT */
m = *mp;
+
# if defined(M_MCAST)
if ((m->m_flags & M_MCAST) != 0)
fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
# endif
+# if defined(M_MLOOP)
+ if ((m->m_flags & M_MLOOP) != 0)
+ fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
+# endif
# if defined(M_BCAST)
if ((m->m_flags & M_BCAST) != 0)
fin->fin_flx |= FI_MBCAST|FI_BROADCAST;
@@ -2206,137 +2406,57 @@ int out;
}
# endif /* CSUM_DELAY_DATA */
# endif /* MENTAT */
-#else /* _KERNEL */
+#else
READ_ENTER(&ipf_global);
bzero((char *)fin, sizeof(*fin));
m = *mp;
#endif /* _KERNEL */
+ fin->fin_v = v;
+ fin->fin_m = m;
+ fin->fin_ip = ip;
+ fin->fin_mp = mp;
+ fin->fin_out = out;
+ fin->fin_ifp = ifp;
+ fin->fin_error = ENETUNREACH;
+ fin->fin_hlen = (u_short)hlen;
+ fin->fin_dp = (char *)ip + hlen;
+
+ fin->fin_ipoff = (char *)ip - MTOD(m, char *);
+
+ SPL_NET(s);
+
#ifdef USE_INET6
if (v == 6) {
- len = ntohs(((ip6_t*)ip)->ip6_plen);
+ ATOMIC_INCL(frstats[out].fr_ipv6);
/*
* Jumbo grams are quite likely too big for internal buffer
* structures to handle comfortably, for now, so just drop
- * them for now.
+ * them.
*/
- if (len == 0) {
+ ip6 = (ip6_t *)ip;
+ fin->fin_plen = ntohs(ip6->ip6_plen);
+ if (fin->fin_plen == 0) {
pass = FR_BLOCK|FR_NOMATCH;
goto filtered;
}
- len += sizeof(ip6_t);
- p = ((ip6_t *)ip)->ip6_nxt;
+ fin->fin_plen += sizeof(ip6_t);
} else
#endif
{
- p = ip->ip_p;
- len = ip->ip_len;
- }
-
- fin->fin_v = v;
- fin->fin_m = m;
- fin->fin_mp = mp;
- fin->fin_out = out;
- fin->fin_ifp = ifp;
- fin->fin_plen = len;
- fin->fin_hlen = (u_short )hlen;
- fin->fin_dp = (char *)ip + hlen;
-
- if (p == IPPROTO_TCP || p == IPPROTO_UDP ||
- (v == 4 && p == IPPROTO_ICMP)
-#ifdef USE_INET6
- || (v == 6 && p == IPPROTO_ICMPV6)
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+ ip->ip_len = ntohs(ip->ip_len);
+ ip->ip_off = ntohs(ip->ip_off);
#endif
- ) {
-#if defined(_KERNEL)
- int plen = 0, up = 0;
-
- if ((v == 6) || (ip->ip_off & IP_OFFMASK) == 0)
- switch(p)
- {
- case IPPROTO_TCP:
- plen = sizeof(tcphdr_t);
- break;
- case IPPROTO_UDP:
- plen = sizeof(udphdr_t);
- break;
- /* 96 - enough for complete ICMP error IP header */
- case IPPROTO_ICMP:
- plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
- break;
-# ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- /*
- * XXX does not take intermediate header
- * into account.
- */
- plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
- break;
-# endif
- }
-
- up = MIN(hlen + plen, len);
- if (up > M_LEN(m)) {
-# ifdef __sgi
- /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
- if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- pass = FR_BLOCK|FR_NOMATCH;
- goto filtered;
- }
- m_copydata(m, 0, up, hbuf);
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- ip = (ip_t *)hbuf;
-# else /* __ sgi */
- /*
- * Having determined that we need to pullup some data,
- * try to bring as much of the packet up into a single
- * buffer with the first pullup. This hopefully means
- * less need for doing futher pullups. Not needed for
- * Solaris because fr_precheck() does it anyway.
- *
- * The main potential for trouble here is if MLEN/MHLEN
- * become quite small, lets say < 64 bytes...but if
- * that did happen, BSD networking as a whole would be
- * slow/inefficient.
- */
-# ifdef MHLEN
- /*
- * Assume that M_PKTHDR is set and just work with what
- * is left rather than check.. Should not make any
- * real difference, anyway.
- */
- if ((MHLEN > up) && (len > up))
- up = MIN(len, MHLEN);
-# else
-# ifdef MLEN
- if ((MLEN > up) && (len > up))
- up = MIN(len, MLEN);
-# endif /* MLEN */
-# endif /* MHLEN */
- fin->fin_ip = ip;
- ip = fr_pullup(m, fin, up);
- if (ip == NULL)
- goto finished;
-# endif /* __sgi */
- }
-#else
- /*EMPTY*/
-#endif /* _KERNEL */
+ fin->fin_plen = ip->ip_len;
}
- fin->fin_error = fr_unreach;
if (fr_makefrip(hlen, ip, fin) == -1) {
READ_ENTER(&ipf_mutex);
pass = FR_BLOCK;
goto filtered;
}
- ip = fin->fin_ip;
-
- if (v == 6) {
- ATOMIC_INCL(frstats[out].fr_ipv6);
- }
/*
* For at least IPv6 packets, if a m_pullup() fails then this pointer
@@ -2353,7 +2473,7 @@ int out;
fin->fin_flx |= FI_BADSRC;
}
#endif
- if (ip->ip_ttl < fr_minttl) {
+ if (fin->fin_ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
fin->fin_flx |= FI_LOWTTL;
}
@@ -2379,8 +2499,6 @@ int out;
ATOMIC_INCL(frstats[out].fr_short);
}
- pass = fr_pass;
-
READ_ENTER(&ipf_mutex);
/*
@@ -2391,8 +2509,12 @@ int out;
* occuring until after the packet has been auth'd.
*/
fr = fr_checkauth(fin, &pass);
- if (!out)
- (void) fr_checknatin(fin, &pass);
+ if (!out) {
+ if (fr_checknatin(fin, &pass) == -1) {
+ RWLOCK_EXIT(&ipf_mutex);
+ goto finished;
+ }
+ }
if (!out)
(void) fr_acctpkt(fin, NULL);
@@ -2413,15 +2535,15 @@ int out;
*/
if (out && FR_ISPASS(pass)) {
(void) fr_acctpkt(fin, NULL);
- (void) fr_checknatout(fin, &pass);
- if ((fr_update_ipid != 0) && (v == 4)) {
+ if (fr_checknatout(fin, &pass) == -1) {
+ RWLOCK_EXIT(&ipf_mutex);
+ goto finished;
+ } else if ((fr_update_ipid != 0) && (v == 4)) {
if (fr_updateipid(fin) == -1) {
ATOMIC_INCL(frstats[1].fr_ipud);
pass &= ~FR_CMDMASK;
pass |= FR_BLOCK;
- FREE_MB_T(*mp);
- m = *mp = NULL;
} else {
ATOMIC_INCL(frstats[0].fr_ipud);
}
@@ -2429,8 +2551,9 @@ int out;
}
#ifdef IPFILTER_LOG
- if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK))
+ if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
(void) fr_dolog(fin, &pass);
+ }
#endif
if (fin->fin_state != NULL)
@@ -2442,10 +2565,11 @@ int out;
/*
* Only allow FR_DUP to work if a rule matched - it makes no sense to
* set FR_DUP as a "default" as there are no instructions about where
- * to send the packet.
+ * to send the packet. Use fin_m here because it may have changed
+ * (without an update of 'm') in prior processing.
*/
if ((fr != NULL) && (pass & FR_DUP)) {
- mc = M_DUPLICATE(m);
+ mc = M_DUPLICATE(fin->fin_m);
}
if (pass & (FR_RETRST|FR_RETICMP)) {
@@ -2485,15 +2609,10 @@ int out;
* instructions about what to do with a packet.
* Once we're finished return to our caller, freeing the packet if
* we are dropping it (* BSD ONLY *).
+ * Reassign m from fin_m as we may have a new buffer, now.
*/
-#if defined(USE_INET6) || (defined(__sgi) && defined(_KERNEL))
filtered:
-#endif
- if (FR_ISPASS(pass)) {
- ATOMIC_INCL(frstats[out].fr_pass);
- } else if (FR_ISBLOCK(pass)) {
- ATOMIC_INCL(frstats[out].fr_block);
- }
+ m = fin->fin_m;
if (fr != NULL) {
frdest_t *fdp;
@@ -2526,24 +2645,37 @@ filtered:
*/
RWLOCK_EXIT(&ipf_mutex);
+finished:
if (!FR_ISPASS(pass)) {
- if (m != NULL) {
+ ATOMIC_INCL(frstats[out].fr_block);
+ if (*mp != NULL) {
FREE_MB_T(*mp);
m = *mp = NULL;
}
- }
+ } else {
+ ATOMIC_INCL(frstats[out].fr_pass);
#if defined(_KERNEL) && defined(__sgi)
- else {
- if ((fin->fin_flx & FI_NATED) && up && (m != NULL)) {
- COPYBACK(m, 0, up, hbuf);
+ if ((fin->fin_hbuf != NULL) &&
+ (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) {
+ COPYBACK(m, 0, fin->fin_plen, fin->fin_hbuf);
}
- }
#endif
-finished:
+ }
+
+ SPL_X(s);
RWLOCK_EXIT(&ipf_global);
+
#ifdef _KERNEL
+# if OpenBSD >= 200311
+ if (FR_ISPASS(pass) && (v == 4)) {
+ ip = fin->fin_ip;
+ ip->ip_len = ntohs(ip->ip_len);
+ ip->ip_off = ntohs(ip->ip_off);
+ }
+# endif
return (FR_ISPASS(pass)) ? 0 : fin->fin_error;
#else /* _KERNEL */
+ FR_VERBOSE(("fin_flx %#x pass %#x ", fin->fin_flx, pass));
if ((pass & FR_NOMATCH) != 0)
return 1;
@@ -2668,9 +2800,10 @@ int len;
/* ------------------------------------------------------------------------ */
/* Function: fr_cksum */
/* Returns: u_short - layer 4 checksum */
-/* Parameters: m(I ) - pointer to buffer holding packet */
-/* ip(I) - pointer to IP header */
-/* l4hdr(I) - pointer to layer 4 header */
+/* Parameters: m(I ) - pointer to buffer holding packet */
+/* ip(I) - pointer to IP header */
+/* l4proto(I) - protocol to caclulate checksum for */
+/* l4hdr(I) - pointer to layer 4 header */
/* */
/* Calculates the TCP checksum for the packet held in "m", using the data */
/* in the IP header "ip" to seed it. */
@@ -2678,6 +2811,8 @@ int len;
/* NB: This function assumes we've pullup'd enough for all of the IP header */
/* and the TCP header. We also assume that data blocks aren't allocated in */
/* odd sizes. */
+/* */
+/* Expects ip_len to be in host byte order when called. */
/* ------------------------------------------------------------------------ */
u_short fr_cksum(m, ip, l4proto, l4hdr)
mb_t *m;
@@ -2708,7 +2843,7 @@ void *l4hdr;
#endif
hlen = IP_HL(ip) << 2;
slen = ip->ip_len - hlen;
- sum = htons((u_short)ip->ip_p);
+ sum = htons((u_short)l4proto);
sum += htons(slen);
sp = (u_short *)&ip->ip_src;
sum += *sp++; /* ip_src */
@@ -2720,7 +2855,7 @@ void *l4hdr;
ip6 = (ip6_t *)ip;
hlen = sizeof(*ip6);
slen = ntohs(ip6->ip6_plen);
- sum = htons((u_short)ip6->ip6_nxt);
+ sum = htons((u_short)l4proto);
sum += htons(slen);
sp = (u_short *)&ip6->ip6_src;
sum += *sp++; /* ip6_src */
@@ -2756,6 +2891,7 @@ void *l4hdr;
case IPPROTO_ICMP :
csump = &((icmphdr_t *)l4hdr)->icmp_cksum;
l4hlen = 4;
+ sum = 0;
break;
default :
break;
@@ -2777,9 +2913,9 @@ void *l4hdr;
m->b_rptr = (u_char *)ip;
sum2 = ip_cksum(m, hlen, sum); /* hlen == offset */
m->b_rptr = rp;
- }
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
sum2 = ~sum2 & 0xffff;
+ }
# else /* MENTAT */
# if defined(BSD) || defined(sun)
# if BSD >= 199103
@@ -2816,19 +2952,10 @@ void *l4hdr;
/*
* Add up IP Header portion
*/
- sp = (u_short *)&ip->ip_src;
- len -= (IP_HL(ip) << 2);
- sum = ntohs((u_short)ip->ip_p);
- sum += htons(len);
- sum += *sp++; /* ip_src */
- sum += *sp++;
- sum += *sp++; /* ip_dst */
- sum += *sp++;
-
if (sp != (u_short *)l4hdr)
sp = (u_short *)l4hdr;
- switch (ip->ip_p)
+ switch (l4proto)
{
case IPPROTO_UDP :
sum += *sp++; /* sport */
@@ -2849,6 +2976,10 @@ void *l4hdr;
sum += *sp++; /* checksum */
sum += *sp++; /* urp */
break;
+ case IPPROTO_ICMP :
+ sum = *sp++; /* type/code */
+ sum += *sp++; /* checksum */
+ break;
}
# ifdef __sgi
@@ -2875,7 +3006,7 @@ void *l4hdr;
}
# endif
- len -= l4hlen;
+ len -= (l4hlen + hlen);
if (len <= 0)
goto nodata;
@@ -2927,7 +3058,7 @@ nodata:
#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \
- defined(__sgi) )
+ defined(__sgi) ) && !defined(linux) && !defined(_AIX51)
/*
* Copyright (c) 1982, 1986, 1988, 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -2957,7 +3088,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.197 2003/07/01 18:30:18 darrenr Exp $
+ * $Id: fil.c,v 2.243.2.64 2005/08/13 05:19:59 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -3026,7 +3157,7 @@ m_copyback(m0, off, len, cp)
m = m->m_next;
}
while (len > 0) {
- mlen = min (m->m_len - off, len);
+ mlen = min(m->m_len - off, len);
bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
cp += mlen;
len -= mlen;
@@ -3075,7 +3206,7 @@ frgroup_t ***fgpp;
frgroup_t *fg, **fgp;
/*
- * Which list of groups to search in is dependant on which list of
+ * Which list of groups to search in is dependent on which list of
* rules are being operated on.
*/
fgp = &ipfgroups[unit][set];
@@ -3165,11 +3296,11 @@ minor_t unit;
int set;
{
frgroup_t *fg, **fgp;
-
+
fg = fr_findgroup(group, unit, set, &fgp);
if (fg == NULL)
return;
-
+
fg->fg_ref--;
if (fg->fg_ref == 0) {
*fgp = fg->fg_next;
@@ -3297,8 +3428,6 @@ frentry_t **listp;
/* Function: frflush */
/* Returns: int - >= 0 - number of flushed rules */
/* Parameters: unit(I) - device for which to flush rules */
-/* proto(I) - which proto rules ipv4(4), ipv6(6) */
-/* ipv4 and ipv6(0) to flush */
/* flags(I) - which set of rules to flush */
/* */
/* Calls flushlist() for all filter rules (accounting, firewall - both IPv4 */
@@ -3451,6 +3580,7 @@ u_32_t ip;
return -1;
}
+
#ifdef USE_INET6
/* ------------------------------------------------------------------------ */
/* Function: count6bits */
@@ -3476,22 +3606,25 @@ u_32_t *msk;
}
return i;
}
-#endif
+# endif
#endif /* _KERNEL */
/* ------------------------------------------------------------------------ */
/* Function: frsynclist */
/* Returns: void */
-/* Parameters: Nil */
+/* Parameters: fr(I) - start of filter list to sync interface names for */
+/* ifp(I) - interface pointer for limiting sync lookups */
/* Write Locks: ipf_mutex */
/* */
/* Walk through a list of filter rules and resolve any interface names into */
/* pointers. Where dynamic addresses are used, also update the IP address */
-/* used in the rule. */
+/* used in the rule. The interface pointer is used to limit the lookups to */
+/* a specific set of matching names if it is non-NULL. */
/* ------------------------------------------------------------------------ */
-static void frsynclist(fr)
+static void frsynclist(fr, ifp)
frentry_t *fr;
+void *ifp;
{
frdest_t *fdp;
int v, i;
@@ -3503,15 +3636,9 @@ frentry_t *fr;
* Lookup all the interface names that are part of the rule.
*/
for (i = 0; i < 4; i++) {
- if ((fr->fr_ifnames[i][1] == '\0') &&
- ((fr->fr_ifnames[i][0] == '-') ||
- (fr->fr_ifnames[i][0] == '*'))) {
- fr->fr_ifas[i] = NULL;
- } else if (fr->fr_ifnames[i][0] != '\0') {
- fr->fr_ifas[i] = GETIFP(fr->fr_ifnames[i], v);
- if (fr->fr_ifas[i] == (void *)NULL)
- fr->fr_ifas[i] = (void *)-1;
- }
+ if ((ifp != NULL) && (fr->fr_ifas[i] != ifp))
+ continue;
+ fr->fr_ifas[i] = fr_resolvenic(fr->fr_ifnames[i], v);
}
if (fr->fr_type == FR_T_IPF) {
@@ -3530,26 +3657,20 @@ frentry_t *fr;
}
fdp = &fr->fr_tifs[0];
- if (fdp->fd_ifname[0] != '\0') {
- fdp->fd_ifp = GETIFP(fdp->fd_ifname, v);
- if (fdp->fd_ifp == NULL)
- fdp->fd_ifp = (void *)-1;
- }
+ if ((ifp == NULL) || (fdp->fd_ifp == ifp))
+ fr_resolvedest(fdp, v);
fdp = &fr->fr_tifs[1];
- if (fdp->fd_ifname[0] != '\0') {
- fdp->fd_ifp = GETIFP(fdp->fd_ifname, v);
- if (fdp->fd_ifp == NULL)
- fdp->fd_ifp = (void *)-1;
- }
+ if ((ifp == NULL) || (fdp->fd_ifp == ifp))
+ fr_resolvedest(fdp, v);
fdp = &fr->fr_dif;
- if (fdp->fd_ifname[0] != '\0') {
+ if ((ifp == NULL) || (fdp->fd_ifp == ifp)) {
+ fr_resolvedest(fdp, v);
+
fr->fr_flags &= ~FR_DUP;
- fdp->fd_ifp = GETIFP(fdp->fd_ifname, v);
- if (fdp->fd_ifp == NULL)
- fdp->fd_ifp = (void *)-1;
- else
+ if ((fdp->fd_ifp != (void *)-1) &&
+ (fdp->fd_ifp != NULL))
fr->fr_flags |= FR_DUP;
}
@@ -3582,51 +3703,33 @@ frentry_t *fr;
/* filter rules, NAT entries and the state table and check if anything */
/* needs to be changed/updated. */
/* ------------------------------------------------------------------------ */
-void frsync()
+void frsync(ifp)
+void *ifp;
{
int i;
-# ifndef MENTAT
- struct ifnet *ifp;
-
-# if defined(__OpenBSD__) || ((NetBSD >= 199511) && (NetBSD < 1991011)) || \
- (defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
-# if (NetBSD >= 199905) || defined(__OpenBSD__)
- for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
-# elif defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
- IFNET_RLOCK();
- TAILQ_FOREACH(ifp, &ifnet, if_link);
-# else
- for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
-# endif
-# else
- for (ifp = ifnet; ifp; ifp = ifp->if_next)
-# endif
- {
- fr_natsync(ifp);
- fr_statesync(ifp);
- }
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
- IFNET_RUNLOCK();
-# endif
+
+# if !SOLARIS
+ fr_natsync(ifp);
+ fr_statesync(ifp);
# endif
WRITE_ENTER(&ipf_mutex);
- frsynclist(ipacct[0][fr_active]);
- frsynclist(ipacct[1][fr_active]);
- frsynclist(ipfilter[0][fr_active]);
- frsynclist(ipfilter[1][fr_active]);
- frsynclist(ipacct6[0][fr_active]);
- frsynclist(ipacct6[1][fr_active]);
- frsynclist(ipfilter6[0][fr_active]);
- frsynclist(ipfilter6[1][fr_active]);
+ frsynclist(ipacct[0][fr_active], ifp);
+ frsynclist(ipacct[1][fr_active], ifp);
+ frsynclist(ipfilter[0][fr_active], ifp);
+ frsynclist(ipfilter[1][fr_active], ifp);
+ frsynclist(ipacct6[0][fr_active], ifp);
+ frsynclist(ipacct6[1][fr_active], ifp);
+ frsynclist(ipfilter6[0][fr_active], ifp);
+ frsynclist(ipfilter6[1][fr_active], ifp);
for (i = 0; i < IPL_LOGSIZE; i++) {
frgroup_t *g;
for (g = ipfgroups[i][0]; g != NULL; g = g->fg_next)
- frsynclist(g->fg_start);
+ frsynclist(g->fg_start, ifp);
for (g = ipfgroups[i][1]; g != NULL; g = g->fg_next)
- frsynclist(g->fg_start);
+ frsynclist(g->fg_start, ifp);
}
RWLOCK_EXIT(&ipf_mutex);
}
@@ -3655,14 +3758,14 @@ size_t size;
caddr_t ca;
int err;
-#if SOLARIS
- err = copyin(src, (caddr_t)&ca, sizeof(ca));
+# if SOLARIS
+ err = COPYIN(src, (caddr_t)&ca, sizeof(ca));
if (err != 0)
return err;
-#else
+# else
bcopy(src, (caddr_t)&ca, sizeof(ca));
-#endif
- err = copyin(ca, dst, size);
+# endif
+ err = COPYIN(ca, dst, size);
return err;
}
@@ -3685,86 +3788,37 @@ size_t size;
caddr_t ca;
int err;
-#if SOLARIS
- err = copyin(dst, (caddr_t)&ca, sizeof(ca));
+# if SOLARIS
+ err = COPYIN(dst, (caddr_t)&ca, sizeof(ca));
if (err != 0)
return err;
-#else
+# else
bcopy(dst, (caddr_t)&ca, sizeof(ca));
-#endif
- err = copyout(src, ca, size);
+# endif
+ err = COPYOUT(src, ca, size);
return err;
}
-
-#else /* _KERNEL */
-
-
-/*
- * See above for description, except that all addressing is in user space.
- */
-int copyoutptr(src, dst, size)
-void *src, *dst;
-size_t size;
-{
- caddr_t ca;
-
- bcopy(dst, (char *)&ca, sizeof(ca));
- bcopy(src, ca, size);
- return 0;
-}
-
-
-/*
- * See above for description, except that all addressing is in user space.
- */
-int copyinptr(src, dst, size)
-void *src, *dst;
-size_t size;
-{
- caddr_t ca;
-
- bcopy(src, (char *)&ca, sizeof(ca));
- bcopy(ca, dst, size);
- return 0;
-}
-
-
-/*
- * return the first IP Address associated with an interface
- */
-int fr_ifpaddr(v, flags, ifptr, inp, inpmask)
-int v, flags;
-void *ifptr;
-struct in_addr *inp, *inpmask;
-{
- return 0;
-}
-
#endif
/* ------------------------------------------------------------------------ */
/* Function: fr_lock */
-/* Returns: int - 0 == success, else error */
+/* Returns: (void) */
/* 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. */
/* ------------------------------------------------------------------------ */
-int fr_lock(data, lockp)
+void fr_lock(data, lockp)
caddr_t data;
int *lockp;
{
- int arg, error;
+ int arg;
- error = COPYIN(data, (caddr_t)&arg, sizeof(arg));
- if (!error) {
- error = COPYOUT((caddr_t)lockp, data, sizeof(*lockp));
- if (!error)
- *lockp = arg;
- }
- return error;
+ BCOPYIN(data, (caddr_t)&arg, sizeof(arg));
+ BCOPYOUT((caddr_t)lockp, data, sizeof(*lockp));
+ *lockp = arg;
}
@@ -3811,7 +3865,9 @@ friostat_t *fiop;
fiop->f_logging = 0;
#endif
fiop->f_defpass = fr_pass;
- (void) strncpy(fiop->f_version, ipfilter_version, sizeof(fiop->f_version));
+ fiop->f_features = fr_features;
+ (void) strncpy(fiop->f_version, ipfilter_version,
+ sizeof(fiop->f_version));
}
@@ -3892,8 +3948,7 @@ int rev;
(rev && (icmpreplytype4[ictype] == icmp->icmp_type))) {
if (icmp->icmp_type != ICMP_ECHOREPLY)
return 1;
- if ((icmp->icmp_id == ic->ici_id) &&
- (icmp->icmp_seq == ic->ici_seq))
+ if (icmp->icmp_id == ic->ici_id)
return 1;
}
}
@@ -3903,8 +3958,7 @@ int rev;
(rev && (icmpreplytype6[ictype] == icmp->icmp_type))) {
if (icmp->icmp_type != ICMP6_ECHO_REPLY)
return 1;
- if ((icmp->icmp_id == ic->ici_id) &&
- (icmp->icmp_seq == ic->ici_seq))
+ if (icmp->icmp_id == ic->ici_id)
return 1;
}
}
@@ -3936,7 +3990,11 @@ lookupfunc_t *funcptr;
ip_pool_t *ipo;
void *ptr;
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(name, sizeof(name), "%u", number);
+#else
(void) sprintf(name, "%u", number);
+#endif
READ_ENTER(&ip_poolrw);
@@ -3994,21 +4052,16 @@ lookupfunc_t *funcptr;
/* ------------------------------------------------------------------------ */
int frrequest(unit, req, data, set, makecopy)
int unit;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003)
-u_long req;
-#else
-int req;
-#endif
+ioctlcmd_t req;
int set, makecopy;
caddr_t data;
{
frentry_t frd, *fp, *f, **fprev, **ftail;
int error = 0, in, v;
+ void *ptr, *uptr;
u_int *p, *pp;
frgroup_t *fg;
char *group;
- void *ptr;
fg = NULL;
fp = &frd;
@@ -4032,6 +4085,7 @@ caddr_t data;
return EINVAL;
v = fp->fr_v;
+ uptr = fp->fr_data;
/*
* Only filter rules for IPv4 or IPv6 are accepted.
@@ -4064,8 +4118,10 @@ caddr_t data;
* Check that the group number does exist and that its use (in/out)
* matches what the rule is.
*/
+ if (!strncmp(fp->fr_grhead, "0", FR_GROUPLEN))
+ *fp->fr_grhead = '\0';
group = fp->fr_group;
- if (!strcmp(group, "0"))
+ if (!strncmp(group, "0", FR_GROUPLEN))
*group = '\0';
if (FR_ISACCOUNT(fp->fr_flags))
@@ -4110,10 +4166,15 @@ caddr_t data;
fprev = &fg->fg_start;
}
- for (f = *fprev; f != NULL; fprev = &f->fr_next)
- if (fp->fr_collect <= f->fr_collect)
- break;
ftail = fprev;
+ for (f = *ftail; (f = *ftail) != NULL; ftail = &f->fr_next) {
+ if (fp->fr_collect <= f->fr_collect) {
+ ftail = fprev;
+ f = NULL;
+ break;
+ }
+ fprev = ftail;
+ }
/*
* Copy in extra data for the rule.
@@ -4123,9 +4184,9 @@ caddr_t data;
KMALLOCS(ptr, void *, fp->fr_dsize);
if (!ptr)
return ENOMEM;
- error = COPYIN(fp->fr_data, ptr, fp->fr_dsize);
+ error = COPYIN(uptr, ptr, fp->fr_dsize);
} else {
- ptr = fp->fr_data;
+ ptr = uptr;
error = 0;
}
if (error != 0) {
@@ -4141,7 +4202,7 @@ caddr_t data;
*/
switch (fp->fr_type & ~FR_T_BUILTIN)
{
-#if defined(IPFILTER_BPF) && defined(_KERNEL)
+#if defined(IPFILTER_BPF)
case FR_T_BPFOPC :
if (fp->fr_dsize == 0)
return EINVAL;
@@ -4154,8 +4215,17 @@ caddr_t data;
break;
#endif
case FR_T_IPF :
- if (fp->fr_dsize == 0)
+ if (fp->fr_dsize != sizeof(fripf_t))
+ return EINVAL;
+
+ /*
+ * Allowing a rule with both "keep state" and "with oow" is
+ * pointless because adding a state entry to the table will
+ * fail with the out of window (oow) flag set.
+ */
+ if ((fp->fr_flags & FR_KEEPSTATE) && (fp->fr_flx & FI_OOW))
return EINVAL;
+
switch (fp->fr_satype)
{
case FRI_BROADCAST :
@@ -4203,7 +4273,6 @@ caddr_t data;
break;
#endif
default :
-
break;
}
break;
@@ -4223,7 +4292,7 @@ caddr_t data;
/*
* Lookup all the interface names that are part of the rule.
*/
- frsynclist(fp);
+ frsynclist(fp, NULL);
fp->fr_statecnt = 0;
/*
@@ -4243,26 +4312,46 @@ caddr_t data;
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache));
- for (; (f = *ftail) != NULL; ftail = &f->fr_next)
- if ((fp->fr_cksum == f->fr_cksum) &&
- (f->fr_dsize == fp->fr_dsize) &&
- !bcmp((char *)&f->fr_dsize,
- (char *)&fp->fr_dsize, FR_CMPSIZ) &&
- (!ptr || !f->fr_data ||
+ for (; (f = *ftail) != NULL; ftail = &f->fr_next) {
+ if ((fp->fr_cksum != f->fr_cksum) ||
+ (f->fr_dsize != fp->fr_dsize))
+ continue;
+ if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func, FR_CMPSIZ))
+ continue;
+ if ((!ptr && !f->fr_data) ||
+ (ptr && f->fr_data &&
!bcmp((char *)ptr, (char *)f->fr_data, f->fr_dsize)))
break;
+ }
/*
* If zero'ing statistics, copy current to caller and zero.
*/
- if (req == (int)SIOCZRLST) {
+ if (req == (ioctlcmd_t)SIOCZRLST) {
if (f == NULL)
error = ESRCH;
else {
- error = fr_outobj(data, f, IPFOBJ_FRENTRY);
+ /*
+ * Copy and reduce lock because of impending copyout.
+ * Well we should, but if we do then the atomicity of
+ * this call and the correctness of fr_hits and
+ * fr_bytes cannot be guaranteed. As it is, this code
+ * only resets them to 0 if they are successfully
+ * copied out into user space.
+ */
+ bcopy((char *)f, (char *)fp, sizeof(*f));
+ /* MUTEX_DOWNGRADE(&ipf_mutex); */
+
+ /*
+ * When we copy this rule back out, set the data
+ * pointer to be what it was in user space.
+ */
+ fp->fr_data = uptr;
+ error = fr_outobj(data, fp, IPFOBJ_FRENTRY);
+
if (error == 0) {
- if (f->fr_dsize != 0 && f->fr_data != NULL)
- error = COPYOUT(f->fr_data, ptr,
+ if ((f->fr_dsize != 0) && (uptr != NULL))
+ error = COPYOUT(f->fr_data, uptr,
f->fr_dsize);
if (error == 0) {
f->fr_hits = 0;
@@ -4271,7 +4360,7 @@ caddr_t data;
}
}
- if (ptr != NULL && makecopy != 0) {
+ if ((ptr != NULL) && (makecopy != 0)) {
KFREES(ptr, fp->fr_dsize);
}
RWLOCK_EXIT(&ipf_mutex);
@@ -4279,11 +4368,40 @@ caddr_t data;
}
if (!f) {
- if (req == (int)SIOCINAFR || req == (int)SIOCINIFR) {
+ /*
+ * At the end of this, ftail must point to the place where the
+ * new rule is to be saved/inserted/added.
+ * For SIOCAD*FR, this should be the last rule in the group of
+ * rules that have equal fr_collect fields.
+ * For SIOCIN*FR, ...
+ */
+ if (req == (ioctlcmd_t)SIOCADAFR ||
+ req == (ioctlcmd_t)SIOCADIFR) {
+
+ for (ftail = fprev; (f = *ftail) != NULL; ) {
+ if (f->fr_collect > fp->fr_collect)
+ break;
+ ftail = &f->fr_next;
+ }
+ f = NULL;
+ ptr = NULL;
+ error = 0;
+ } else if (req == (ioctlcmd_t)SIOCINAFR ||
+ req == (ioctlcmd_t)SIOCINIFR) {
+ while ((f = *fprev) != NULL) {
+ if (f->fr_collect >= fp->fr_collect)
+ break;
+ fprev = &f->fr_next;
+ }
ftail = fprev;
if (fp->fr_hits != 0) {
- while (--fp->fr_hits && (f = *ftail))
+ while (fp->fr_hits && (f = *ftail)) {
+ if (f->fr_collect != fp->fr_collect)
+ break;
+ fprev = ftail;
ftail = &f->fr_next;
+ fp->fr_hits--;
+ }
}
f = NULL;
ptr = NULL;
@@ -4294,7 +4412,7 @@ caddr_t data;
/*
* Request to remove a rule.
*/
- if (req == (int)SIOCRMAFR || req == (int)SIOCRMIFR) {
+ if (req == (ioctlcmd_t)SIOCRMAFR || req == (ioctlcmd_t)SIOCRMIFR) {
if (!f)
error = ESRCH;
else {
@@ -4318,7 +4436,7 @@ caddr_t data;
#ifdef IPFILTER_SCAN
if (f->fr_isctag[0] != '\0' &&
(f->fr_isc != (struct ipscan *)-1))
- isc_detachfr(f);
+ ipsc_detachfr(f);
#endif
if ((fg != NULL) && (fg->fg_head != NULL))
fg->fg_head->fr_ref--;
@@ -4328,7 +4446,7 @@ caddr_t data;
}
if (*f->fr_grhead != '\0')
fr_delgroup(f->fr_grhead, unit, set);
- fr_fixskip(fprev, f, -1);
+ fr_fixskip(ftail, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
(void)fr_derefrule(&f);
@@ -4349,7 +4467,7 @@ caddr_t data;
} else
f = fp;
if (f != NULL) {
- if (fg != NULL && fg->fg_head!= NULL )
+ if (fg != NULL && fg->fg_head != NULL)
fg->fg_head->fr_ref++;
if (fp != f)
bcopy((char *)fp, (char *)f,
@@ -4357,7 +4475,8 @@ caddr_t data;
MUTEX_NUKE(&f->fr_lock);
MUTEX_INIT(&f->fr_lock, "filter rule lock");
#ifdef IPFILTER_SCAN
- if (f->fr_isctag[0] != '\0' && isc_attachfr(f))
+ if (f->fr_isctag[0] != '\0' &&
+ ipsc_attachfr(f))
f->fr_isc = (struct ipscan *)-1;
#endif
f->fr_hits = 0;
@@ -4365,9 +4484,9 @@ caddr_t data;
f->fr_ref = 1;
f->fr_next = *ftail;
*ftail = f;
- if (req == (int)SIOCINIFR ||
- req == (int)SIOCINAFR)
- fr_fixskip(fprev, f, 1);
+ if (req == (ioctlcmd_t)SIOCINIFR ||
+ req == (ioctlcmd_t)SIOCINAFR)
+ fr_fixskip(ftail, f, 1);
f->fr_grp = NULL;
group = f->fr_grhead;
if (*group != '\0') {
@@ -4442,16 +4561,15 @@ ipfunc_t funcptr;
/* */
/* Copy in a ipfunc_resolve_t structure and then fill in the missing field. */
/* This will either be the function name (if the pointer is set) or the */
-/* function pointer if the name is set. When found, fill in the details so */
-/* it can be copied back to user space. */
+/* function pointer if the name is set. When found, fill in the other one */
+/* so that the entire, complete, structure can be copied back to user space.*/
/* ------------------------------------------------------------------------ */
int fr_resolvefunc(data)
void *data;
{
ipfunc_resolve_t res, *ft;
- if (COPYIN(data, &res, sizeof(res)) != 0)
- return EFAULT;
+ BCOPYIN(data, &res, sizeof(res));
if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') {
for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++)
@@ -4468,7 +4586,7 @@ void *data;
for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++)
if (ft->ipfu_addr == res.ipfu_addr) {
(void) strncpy(res.ipfu_name, ft->ipfu_name,
- sizeof(res.ipfu_name));
+ sizeof(res.ipfu_name));
res.ipfu_init = ft->ipfu_init;
if (COPYOUT(&res, data, sizeof(res)) != 0)
return EFAULT;
@@ -4479,9 +4597,10 @@ void *data;
}
-#if !defined(_KERNEL) || (!defined(NetBSD) && !defined(OpenBSD)) || \
- ((defined(NetBSD) && (__NetBSD_Version__ < 105000000)) && \
- (defined(OpenBSD) && (OpenBSD < 200006)))
+#if !defined(_KERNEL) || (!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__FreeBSD__)) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version < 490000)) || \
+ (defined(__NetBSD__) && (__NetBSD_Version__ < 105000000)) || \
+ (defined(__OpenBSD__) && (OpenBSD < 200006))
/*
* From: NetBSD
* ppsratecheck(): packets (or events) per second limitation.
@@ -4589,7 +4708,11 @@ frentry_t *fr;
char name[FR_GROUPLEN];
iphtable_t *iph;
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(name, sizeof(name), "%d", fr->fr_arg);
+#else
(void) sprintf(name, "%d", fr->fr_arg);
+#endif
iph = fr_findhtable(IPL_LOGIPF, name);
if (iph == NULL)
return ESRCH;
@@ -4623,7 +4746,7 @@ u_32_t *passp;
fg = rval;
fin->fin_fr = fg->fg_start;
- (void) fr_scanlist(fin, *passp);
+ (void) fr_scanlist(fin, *passp);
return fin->fin_fr;
}
@@ -4651,11 +4774,21 @@ u_32_t *passp;
fg = rval;
fin->fin_fr = fg->fg_start;
- (void) fr_scanlist(fin, *passp);
+ (void) fr_scanlist(fin, *passp);
return fin->fin_fr;
}
#endif /* IPFILTER_LOOKUP */
+/*
+ * Queue functions
+ * ===============
+ * These functions manage objects on queues for efficient timeouts. There are
+ * a number of system defined queues as well as user defined timeouts. It is
+ * expected that a lock is held in the domain in which the queue belongs
+ * (i.e. either state or NAT) when calling any of these functions that prevents
+ * fr_freetimeoutqueue() from being called at the same time as any other.
+ */
+
/* ------------------------------------------------------------------------ */
/* Function: fr_addtimeoutqueue */
@@ -4669,26 +4802,35 @@ u_32_t *passp;
/* being requested. If it finds one, increments the reference counter and */
/* returns a pointer to it. If none are found, it allocates a new one and */
/* inserts it at the top of the list. */
+/* */
+/* Locking. */
+/* It is assumed that the caller of this function has an appropriate lock */
+/* held (exclusively) in the domain that encompases 'parent'. */
/* ------------------------------------------------------------------------ */
ipftq_t *fr_addtimeoutqueue(parent, seconds)
ipftq_t **parent;
u_int seconds;
{
- u_int period;
ipftq_t *ifq;
+ u_int period;
period = seconds * IPF_HZ_DIVIDE;
+
MUTEX_ENTER(&ipf_timeoutlock);
- for (ifq = *parent; ifq != NULL; ifq = ifq->ifq_next)
- if (ifq->ifq_ttl == period)
- break;
+ for (ifq = *parent; ifq != NULL; ifq = ifq->ifq_next) {
+ if (ifq->ifq_ttl == period) {
+ /*
+ * Reset the delete flag, if set, so the structure
+ * gets reused rather than freed and reallocated.
+ */
+ MUTEX_ENTER(&ifq->ifq_lock);
+ ifq->ifq_flags &= ~IFQF_DELETE;
+ ifq->ifq_ref++;
+ MUTEX_EXIT(&ifq->ifq_lock);
+ MUTEX_EXIT(&ipf_timeoutlock);
- if (ifq != NULL) {
- MUTEX_ENTER(&ifq->ifq_lock);
- ifq->ifq_ref++;
- MUTEX_EXIT(&ifq->ifq_lock);
- MUTEX_EXIT(&ipf_timeoutlock);
- return ifq;
+ return ifq;
+ }
}
KMALLOC(ifq, ipftq_t *);
@@ -4712,44 +4854,114 @@ u_int seconds;
/* ------------------------------------------------------------------------ */
/* Function: fr_deletetimeoutqueue */
-/* Returns: Nil */
-/* Parameters: difp(I) - timeout queue which is losing a reference. */
+/* Returns: int - new reference count value of the timeout queue */
+/* Parameters: ifq(I) - timeout queue which is losing a reference. */
+/* Locks: ifq->ifq_lock */
/* */
/* This routine must be called when we're discarding a pointer to a timeout */
-/* queue object. It takes care of the reference counter and free's it when */
-/* it reaches 0. */
+/* queue object, taking care of the reference counter. */
+/* */
+/* Now that this just sets a DELETE flag, it requires the expire code to */
+/* check the list of user defined timeout queues and call the free function */
+/* below (currently commented out) to stop memory leaking. It is done this */
+/* way because the locking may not be sufficient to safely do a free when */
+/* this function is called. */
/* ------------------------------------------------------------------------ */
-void fr_deletetimeoutqueue(ifq)
+int fr_deletetimeoutqueue(ifq)
ipftq_t *ifq;
{
- MUTEX_ENTER(&ipf_timeoutlock);
- MUTEX_ENTER(&ifq->ifq_lock);
ifq->ifq_ref--;
+ if ((ifq->ifq_ref == 0) && ((ifq->ifq_flags & IFQF_USER) != 0)) {
+ ifq->ifq_flags |= IFQF_DELETE;
+ }
- if ((ifq->ifq_ref == 0) && (ifq->ifq_head == NULL)) {
- /*
- * Remove from its position in the list.
- */
- *ifq->ifq_pnext = ifq->ifq_next;
- if (ifq->ifq_next != NULL)
- ifq->ifq_next->ifq_pnext = ifq->ifq_pnext;
-
- MUTEX_EXIT(&ifq->ifq_lock); /* Tru64 */
- MUTEX_DESTROY(&ifq->ifq_lock);
- KFREE(ifq);
- fr_userifqs--;
- } else {
- MUTEX_EXIT(&ifq->ifq_lock);
+ return ifq->ifq_ref;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_freetimeoutqueue */
+/* Parameters: ifq(I) - timeout queue which is losing a reference. */
+/* Returns: Nil */
+/* */
+/* Locking: */
+/* It is assumed that the caller of this function has an appropriate lock */
+/* held (exclusively) in the domain that encompases the callers "domain". */
+/* The ifq_lock for this structure should not be held. */
+/* */
+/* Remove a user definde timeout queue from the list of queues it is in and */
+/* tidy up after this is done. */
+/* ------------------------------------------------------------------------ */
+void fr_freetimeoutqueue(ifq)
+ipftq_t *ifq;
+{
+
+
+ if (((ifq->ifq_flags & IFQF_DELETE) == 0) || (ifq->ifq_ref != 0) ||
+ ((ifq->ifq_flags & IFQF_USER) == 0)) {
+ printf("fr_freetimeoutqueue(%lx) flags 0x%x ttl %d ref %d\n",
+ (u_long)ifq, ifq->ifq_flags, ifq->ifq_ttl,
+ ifq->ifq_ref);
+ return;
}
- MUTEX_EXIT(&ipf_timeoutlock);
+
+ /*
+ * Remove from its position in the list.
+ */
+ *ifq->ifq_pnext = ifq->ifq_next;
+ if (ifq->ifq_next != NULL)
+ ifq->ifq_next->ifq_pnext = ifq->ifq_pnext;
+
+ MUTEX_DESTROY(&ifq->ifq_lock);
+ fr_userifqs--;
+ KFREE(ifq);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_deletequeueentry */
+/* Returns: Nil */
+/* Parameters: tqe(I) - timeout queue entry to delete */
+/* ifq(I) - timeout queue to remove entry from */
+/* */
+/* Remove a tail queue entry from its queue and make it an orphan. */
+/* fr_deletetimeoutqueue is called to make sure the reference count on the */
+/* queue is correct. We can't, however, call fr_freetimeoutqueue because */
+/* the correct lock(s) may not be held that would make it safe to do so. */
+/* ------------------------------------------------------------------------ */
+void fr_deletequeueentry(tqe)
+ipftqent_t *tqe;
+{
+ ipftq_t *ifq;
+
+ ifq = tqe->tqe_ifq;
+ if (ifq == NULL)
+ return;
+
+ MUTEX_ENTER(&ifq->ifq_lock);
+
+ if (tqe->tqe_pnext != NULL) {
+ *tqe->tqe_pnext = tqe->tqe_next;
+ if (tqe->tqe_next != NULL)
+ tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
+ else /* we must be the tail anyway */
+ ifq->ifq_tail = tqe->tqe_pnext;
+
+ tqe->tqe_pnext = NULL;
+ tqe->tqe_ifq = NULL;
+ }
+
+ (void) fr_deletetimeoutqueue(ifq);
+
+ MUTEX_EXIT(&ifq->ifq_lock);
}
/* ------------------------------------------------------------------------ */
/* Function: fr_queuefront */
/* Returns: Nil */
-/* Parameters: tq(I) - pointer to timeout queue information */
+/* Parameters: tqe(I) - pointer to timeout queue entry */
/* */
/* Move a queue entry to the front of the queue, if it isn't already there. */
/* ------------------------------------------------------------------------ */
@@ -4759,9 +4971,11 @@ ipftqent_t *tqe;
ipftq_t *ifq;
ifq = tqe->tqe_ifq;
+ if (ifq == NULL)
+ return;
+ MUTEX_ENTER(&ifq->ifq_lock);
if (ifq->ifq_head != tqe) {
- MUTEX_ENTER(&ifq->ifq_lock);
*tqe->tqe_pnext = tqe->tqe_next;
if (tqe->tqe_next)
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
@@ -4772,15 +4986,15 @@ ipftqent_t *tqe;
ifq->ifq_head->tqe_pnext = &tqe->tqe_next;
ifq->ifq_head = tqe;
tqe->tqe_pnext = &ifq->ifq_head;
- MUTEX_EXIT(&ifq->ifq_lock);
}
+ MUTEX_EXIT(&ifq->ifq_lock);
}
/* ------------------------------------------------------------------------ */
/* Function: fr_queueback */
/* Returns: Nil */
-/* Parameters: tq(I) - pointer to timeout queue information */
+/* Parameters: tqe(I) - pointer to timeout queue entry */
/* */
/* Move a queue entry to the back of the queue, if it isn't already there. */
/* ------------------------------------------------------------------------ */
@@ -4792,19 +5006,56 @@ ipftqent_t *tqe;
ifq = tqe->tqe_ifq;
if (ifq == NULL)
return;
- if (ifq->ifq_tail != NULL && *ifq->ifq_tail != tqe) {
- MUTEX_ENTER(&ifq->ifq_lock);
- *tqe->tqe_pnext = tqe->tqe_next;
- tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
+ tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
- tqe->tqe_next = NULL;
- tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
- tqe->tqe_pnext = ifq->ifq_tail;
- *ifq->ifq_tail = tqe;
- ifq->ifq_tail = &tqe->tqe_next;
- tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
+ MUTEX_ENTER(&ifq->ifq_lock);
+ if (tqe->tqe_next == NULL) { /* at the end already ? */
MUTEX_EXIT(&ifq->ifq_lock);
+ return;
}
+
+ /*
+ * Remove from list
+ */
+ *tqe->tqe_pnext = tqe->tqe_next;
+ tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
+
+ /*
+ * Make it the last entry.
+ */
+ tqe->tqe_next = NULL;
+ tqe->tqe_pnext = ifq->ifq_tail;
+ *ifq->ifq_tail = tqe;
+ ifq->ifq_tail = &tqe->tqe_next;
+ MUTEX_EXIT(&ifq->ifq_lock);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_queueappend */
+/* Returns: Nil */
+/* Parameters: tqe(I) - pointer to timeout queue entry */
+/* ifq(I) - pointer to timeout queue */
+/* parent(I) - owing object pointer */
+/* */
+/* Add a new item to this queue and put it on the very end. */
+/* ------------------------------------------------------------------------ */
+void fr_queueappend(tqe, ifq, parent)
+ipftqent_t *tqe;
+ipftq_t *ifq;
+void *parent;
+{
+
+ MUTEX_ENTER(&ifq->ifq_lock);
+ tqe->tqe_parent = parent;
+ tqe->tqe_pnext = ifq->ifq_tail;
+ *ifq->ifq_tail = tqe;
+ ifq->ifq_tail = &tqe->tqe_next;
+ tqe->tqe_next = NULL;
+ tqe->tqe_ifq = ifq;
+ tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
+ ifq->ifq_ref++;
+ MUTEX_EXIT(&ifq->ifq_lock);
}
@@ -4826,13 +5077,15 @@ ipftq_t *oifq, *nifq;
/*
* Is the operation here going to be a no-op ?
*/
- if (oifq == nifq && *oifq->ifq_tail == tqe)
+ MUTEX_ENTER(&oifq->ifq_lock);
+ if (oifq == nifq && *oifq->ifq_tail == tqe) {
+ MUTEX_EXIT(&oifq->ifq_lock);
return;
+ }
/*
* Remove from the old queue
*/
- MUTEX_ENTER(&oifq->ifq_lock);
*tqe->tqe_pnext = tqe->tqe_next;
if (tqe->tqe_next)
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
@@ -4847,11 +5100,13 @@ ipftq_t *oifq, *nifq;
*/
if (oifq != nifq) {
tqe->tqe_ifq = NULL;
+
+ (void) fr_deletetimeoutqueue(oifq);
+
MUTEX_EXIT(&oifq->ifq_lock);
- if ((oifq->ifq_flags & IFQF_USER) != 0)
- fr_deletetimeoutqueue(oifq);
MUTEX_ENTER(&nifq->ifq_lock);
+
tqe->tqe_ifq = nifq;
nifq->ifq_ref++;
}
@@ -4917,32 +5172,47 @@ fr_info_t *fin;
#ifdef NEED_FRGETIFNAME
/* ------------------------------------------------------------------------ */
/* Function: fr_getifname */
-/* Returns: char * - pointer to interface name */
-/* Parameters: ifp(I) - pointer to network interface */
+/* Returns: char * - pointer to interface name */
+/* Parameters: ifp(I) - pointer to network interface */
+/* buffer(O) - pointer to where to store interface name */
/* */
-/* Constructs an interface name in the buffer passed. */
+/* Constructs an interface name in the buffer passed. The buffer passed is */
+/* expected to be at least LIFNAMSIZ in bytes big. If buffer is passed in */
+/* as a NULL pointer then return a pointer to a static array. */
/* ------------------------------------------------------------------------ */
char *fr_getifname(ifp, buffer)
struct ifnet *ifp;
char *buffer;
{
- static char namebuf[LIFNAMSIZ+1];
+ static char namebuf[LIFNAMSIZ];
+# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
+ defined(__sgi) || defined(linux) || defined(_AIX51) || \
+ (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
int unit, space;
char temp[20];
char *s;
+# endif
if (buffer == NULL)
buffer = namebuf;
(void) strncpy(buffer, ifp->if_name, LIFNAMSIZ);
- namebuf[LIFNAMSIZ] = '\0';
+ buffer[LIFNAMSIZ - 1] = '\0';
+# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
+ defined(__sgi) || defined(_AIX51) || \
+ (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
for (s = buffer; *s; s++)
;
unit = ifp->if_unit;
space = LIFNAMSIZ - (s - buffer);
if (space > 0) {
+# if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(temp, sizeof(temp), "%d", unit);
+# else
(void) sprintf(temp, "%d", unit);
+# endif
(void) strncpy(s, temp, space);
}
+# endif
return buffer;
}
#endif
@@ -4960,13 +5230,9 @@ char *buffer;
/* EIO if ipfilter is not running. Also checks if write perms are req'd */
/* for the device in order to execute the ioctl. */
/* ------------------------------------------------------------------------ */
-INLINE int fr_ioctlswitch(unit, data, cmd, mode)
+int fr_ioctlswitch(unit, data, cmd, mode)
int unit, mode;
-# if defined(__NetBSD__) || defined(__OpenBSD__)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
void *data;
{
int error = 0;
@@ -4990,7 +5256,8 @@ void *data;
break;
case IPL_LOGAUTH :
if (fr_running > 0) {
- if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) {
+ if ((cmd == (ioctlcmd_t)SIOCADAFR) ||
+ (cmd == (ioctlcmd_t)SIOCRMAFR)) {
if (!(mode & FWRITE)) {
error = EPERM;
} else {
@@ -5040,21 +5307,23 @@ void *data;
* This array defines the expected size of objects coming into the kernel
* for the various recognised object types.
*/
-static int fr_objbytes[] = {
- 0, /* frentry */
- sizeof(struct friostat),
- sizeof(struct fr_info),
- sizeof(struct fr_authstat),
- sizeof(struct ipfrstat),
- sizeof(struct ipnat),
- sizeof(struct natstat),
- sizeof(struct ipstate_save),
- sizeof(struct nat_save),
- sizeof(struct natlookup),
- 0, /* ipstate */
- sizeof(struct ips_stat),
- sizeof(struct frauth),
- sizeof(struct ipftune)
+#define NUM_OBJ_TYPES 14
+
+static int fr_objbytes[NUM_OBJ_TYPES][2] = {
+ { 1, sizeof(struct frentry) }, /* frentry */
+ { 0, sizeof(struct friostat) },
+ { 0, sizeof(struct fr_info) },
+ { 0, sizeof(struct fr_authstat) },
+ { 0, sizeof(struct ipfrstat) },
+ { 0, sizeof(struct ipnat) },
+ { 0, sizeof(struct natstat) },
+ { 0, sizeof(struct ipstate_save) },
+ { 1, sizeof(struct nat_save) }, /* nat_save */
+ { 0, sizeof(struct natlookup) },
+ { 1, sizeof(struct ipstate) }, /* ipstate */
+ { 0, sizeof(struct ips_stat) },
+ { 0, sizeof(struct frauth) },
+ { 0, sizeof(struct ipftune) }
};
@@ -5077,32 +5346,138 @@ int type;
ipfobj_t obj;
int error = 0;
- if ((type < 0) ||
- (type > ((sizeof(fr_objbytes)/sizeof(fr_objbytes[0])) - 1)))
+ if ((type < 0) || (type > NUM_OBJ_TYPES-1))
return EINVAL;
- (void) BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
if (obj.ipfo_type != type)
return EINVAL;
#ifndef IPFILTER_COMPAT
+ if ((fr_objbytes[type][0] & 1) != 0) {
+ if (obj.ipfo_size < fr_objbytes[type][1])
+ return EINVAL;
+ } else if (obj.ipfo_size != fr_objbytes[type][1])
+ return EINVAL;
+#else
if (obj.ipfo_rev != IPFILTER_VERSION)
+ /* XXX compatibility hook here */
+ ;
+ if ((fr_objbytes[type][0] & 1) != 0) {
+ if (obj.ipfo_size < fr_objbytes[type][1])
+ /* XXX compatibility hook here */
+ return EINVAL;
+ } else if (obj.ipfo_size != fr_objbytes[type][1])
+ /* XXX compatibility hook here */
return EINVAL;
- if ((fr_objbytes[type] != 0) && (obj.ipfo_size != fr_objbytes[type]))
+#endif
+
+ if ((fr_objbytes[type][0] & 1) != 0) {
+ error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
+ fr_objbytes[type][1]);
+ } else {
+ error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
+ obj.ipfo_size);
+ }
+ return error;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_inobjsz */
+/* Returns: int - 0 = success, else failure */
+/* Parameters: data(I) - pointer to ioctl data */
+/* ptr(I) - pointer to store real data in */
+/* type(I) - type of structure being moved */
+/* sz(I) - size of data to copy */
+/* */
+/* As per fr_inobj, except the size of the object to copy in is passed in */
+/* but it must not be smaller than the size defined for the type and the */
+/* type must allow for varied sized objects. The extra requirement here is */
+/* that sz must match the size of the object being passed in - this is not */
+/* not possible nor required in fr_inobj(). */
+/* ------------------------------------------------------------------------ */
+int fr_inobjsz(data, ptr, type, sz)
+void *data;
+void *ptr;
+int type, sz;
+{
+ ipfobj_t obj;
+ int error;
+
+ if ((type < 0) || (type > NUM_OBJ_TYPES-1))
+ return EINVAL;
+ if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1]))
+ return EINVAL;
+
+ BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+
+ if (obj.ipfo_type != type)
+ return EINVAL;
+
+#ifndef IPFILTER_COMPAT
+ if (obj.ipfo_size != sz)
return EINVAL;
#else
if (obj.ipfo_rev != IPFILTER_VERSION)
/* XXX compatibility hook here */
+ ;
+ if (obj.ipfo_size != sz)
+ /* XXX compatibility hook here */
+ return EINVAL;
+#endif
+
+ error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, sz);
+ return error;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_outobjsz */
+/* Returns: int - 0 = success, else failure */
+/* Parameters: data(I) - pointer to ioctl data */
+/* ptr(I) - pointer to store real data in */
+/* type(I) - type of structure being moved */
+/* sz(I) - size of data to copy */
+/* */
+/* As per fr_outobj, except the size of the object to copy out is passed in */
+/* but it must not be smaller than the size defined for the type and the */
+/* type must allow for varied sized objects. The extra requirement here is */
+/* that sz must match the size of the object being passed in - this is not */
+/* not possible nor required in fr_outobj(). */
+/* ------------------------------------------------------------------------ */
+int fr_outobjsz(data, ptr, type, sz)
+void *data;
+void *ptr;
+int type, sz;
+{
+ ipfobj_t obj;
+ int error;
+
+ if ((type < 0) || (type > NUM_OBJ_TYPES-1) ||
+ ((fr_objbytes[type][0] & 1) == 0) ||
+ (sz < fr_objbytes[type][1]))
return EINVAL;
- if ((fr_objbytes[type] != 0) && (obj.ipfo_size != fr_objbytes[type]))
+ BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+
+ if (obj.ipfo_type != type)
+ return EINVAL;
+
+#ifndef IPFILTER_COMPAT
+ if (obj.ipfo_size != sz)
+ return EINVAL;
+#else
+ if (obj.ipfo_rev != IPFILTER_VERSION)
+ /* XXX compatibility hook here */
+ ;
+ if (obj.ipfo_size != sz)
/* XXX compatibility hook here */
return EINVAL;
#endif
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, obj.ipfo_size);
-
+ error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, sz);
return error;
}
@@ -5126,21 +5501,29 @@ int type;
ipfobj_t obj;
int error;
- (void) BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ if ((type < 0) || (type > NUM_OBJ_TYPES-1))
+ return EINVAL;
+
+ BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
if (obj.ipfo_type != type)
return EINVAL;
#ifndef IPFILTER_COMPAT
- if (obj.ipfo_rev != IPFILTER_VERSION)
- return EINVAL;
- if ((fr_objbytes[type] != 0) && (obj.ipfo_size != fr_objbytes[type]))
+ if ((fr_objbytes[type][0] & 1) != 0) {
+ if (obj.ipfo_size < fr_objbytes[type][1])
+ return EINVAL;
+ } else if (obj.ipfo_size != fr_objbytes[type][1])
return EINVAL;
#else
if (obj.ipfo_rev != IPFILTER_VERSION)
/* XXX compatibility hook here */
- return EINVAL;
- if ((fr_objbytes[type] != 0) && (obj.ipfo_size != fr_objbytes[type]))
+ ;
+ if ((fr_objbytes[type][0] & 1) != 0) {
+ if (obj.ipfo_size < fr_objbytes[type][1])
+ /* XXX compatibility hook here */
+ return EINVAL;
+ } else if (obj.ipfo_size != fr_objbytes[type][1])
/* XXX compatibility hook here */
return EINVAL;
#endif
@@ -5223,7 +5606,11 @@ fr_info_t *fin;
}
#endif
#if !defined(_KERNEL)
- FR_DEBUG(("checkl4sum: %hx == %hx\n", sum, hdrsum));
+ if (sum == hdrsum) {
+ FR_DEBUG(("checkl4sum: %hx == %hx\n", sum, hdrsum));
+ } else {
+ FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum));
+ }
#endif
if (hdrsum == sum)
return 0;
@@ -5331,41 +5718,6 @@ struct in_addr *inp, *inpmask;
/* ------------------------------------------------------------------------ */
-/* Function: fr_coalesce */
-/* Returns: 1 == success, -1 == failure, 0 == no change */
-/* Parameters: fin(I) - pointer to packet information */
-/* */
-/* Attempt to get all of the packet data into a single, contiguous buffer. */
-/* If this call returns a failure then the buffers have also been freed. */
-/* ------------------------------------------------------------------------ */
-int fr_coalesce(fin)
-fr_info_t *fin;
-{
- if ((fin->fin_flx & FI_COALESCE) != 0)
- return 1;
-
- /*
- * If the mbuf pointers indicate that there is no mbuf to work with,
- * return but do not indicate success or failure.
- */
- if (fin->fin_m == NULL || fin->fin_mp == NULL)
- return 0;
-
-#if !defined(__sgi) && defined(_KERNEL)
- if (fr_pullup(fin->fin_m, fin, fin->fin_plen) == NULL) {
-# ifdef MENTAT
- FREE_MB_T(*fin->fin_mp);
-# endif
- fin->fin_m = NULL;
- *fin->fin_mp = NULL;
- return -1;
- }
-#endif
- return 1;
-}
-
-
-/* ------------------------------------------------------------------------ */
/* Function: fr_matchtag */
/* Returns: 0 == mismatch, 1 == match. */
/* Parameters: tag1(I) - pointer to first tag to compare */
@@ -5397,84 +5749,41 @@ ipftag_t *tag1, *tag2;
/* ------------------------------------------------------------------------ */
-/* Function: fr_pullup */
-/* Returns: NULL == pullup failed, else pointer to protocol header */
-/* Parameters: m(I) - pointer to buffer where data packet starts */
-/* fin(I) - pointer to packet information */
-/* len(I) - number of bytes to pullup */
+/* Function: fr_coalesce */
+/* Returns: 1 == success, -1 == failure, 0 == no change */
+/* Parameters: fin(I) - pointer to packet information */
/* */
-/* Attempt to move at least len bytes (from the start of the buffer) into a */
-/* single buffer for ease of access. Operating system native functions are */
-/* used to manage buffers - if necessary. If the entire packet ends up in */
-/* a single buffer, set the FI_COALESCE flag even though fr_coalesce() has */
-/* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */
-/* and ONLY if the pullup succeeds. */
-/* ------------------------------------------------------------------------ */
-#if defined(_KERNEL) && !defined(__sgi)
-void *fr_pullup(min, fin, len)
-mb_t *min;
+/* Attempt to get all of the packet data into a single, contiguous buffer. */
+/* If this call returns a failure then the buffers have also been freed. */
+/* ------------------------------------------------------------------------ */
+int fr_coalesce(fin)
fr_info_t *fin;
-int len;
{
-# ifdef MENTAT
- qif_t *qf = fin->fin_qif;
-# endif
- int out = fin->fin_out, dpoff, ipoff;
- mb_t *m = min;
- char *ip;
-
- if (m == NULL)
- return NULL;
-
if ((fin->fin_flx & FI_COALESCE) != 0)
- return MTOD(m, void *);
+ return 1;
- ipoff = (char *)fin->fin_ip - MTOD(m, char *);
- if (fin->fin_dp != NULL)
- dpoff = (char *)fin->fin_dp - (char *)fin->fin_ip;
- else
- dpoff = 0;
+ /*
+ * If the mbuf pointers indicate that there is no mbuf to work with,
+ * return but do not indicate success or failure.
+ */
+ if (fin->fin_m == NULL || fin->fin_mp == NULL)
+ return 0;
- if (M_LEN(m) < len) {
+#if defined(_KERNEL)
+ if (fr_pullup(fin->fin_m, fin, fin->fin_plen) == NULL) {
+ ATOMIC_INCL(fr_badcoalesces[fin->fin_out]);
# ifdef MENTAT
- int inc = 0;
-
- if (ipoff > 0) {
- if ((ipoff & 3) != 0) {
- inc = 4 - (ipoff & 3);
- if (m->b_rptr - inc >= m->b_datap->db_base)
- m->b_rptr -= inc;
- else
- inc = 0;
- }
- }
- if (!pullupmsg(m, len + ipoff + inc)) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return NULL;
- }
- m->b_rptr += inc;
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- qf->qf_data = MTOD(m, char *) + ipoff;
-# else
- m = m_pullup(m, len);
- *fin->fin_mp = m;
- if (m == NULL) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return NULL;
- }
- ATOMIC_INCL(frstats[out].fr_pull[0]);
-# endif /* MENTAT */
+ FREE_MB_T(*fin->fin_mp);
+# endif
+ *fin->fin_mp = NULL;
+ fin->fin_m = NULL;
+ return -1;
}
- ip = MTOD(m, char *) + ipoff;
- fin->fin_ip = (ip_t *)ip;
- if (fin->fin_dp != NULL)
- fin->fin_dp = (char *)fin->fin_ip + dpoff;
-
- if (len == fin->fin_plen)
- fin->fin_flx |= FI_COALESCE;
- return ip;
+#else
+ fin = fin; /* LINT */
+#endif
+ return 1;
}
-#endif /* _KERNEL && !__sgi */
/*
@@ -5502,10 +5811,12 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(fr_update_ipid), 0 },
{ { &fr_chksrc }, "fr_chksrc", 0, 1,
sizeof(fr_chksrc), 0 },
+ { { &fr_minttl }, "fr_minttl", 0, 1,
+ sizeof(fr_minttl), 0 },
+ { { &fr_icmpminfragmtu }, "fr_icmpminfragmtu", 0, 1,
+ sizeof(fr_icmpminfragmtu), 0 },
{ { &fr_pass }, "fr_pass", 0, 0xffffffff,
sizeof(fr_pass), 0 },
- { { &fr_unreach }, "fr_unreach", 0, 0xff,
- sizeof(fr_unreach), 0 },
/* state */
{ { &fr_tcpidletimeout }, "fr_tcpidletimeout", 1, 0x7fffffff,
sizeof(fr_tcpidletimeout), IPFT_WRDISABLED },
@@ -5527,8 +5838,10 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(fr_icmptimeout), IPFT_WRDISABLED },
{ { &fr_icmpacktimeout }, "fr_icmpacktimeout", 1, 0x7fffffff,
sizeof(fr_icmpacktimeout), IPFT_WRDISABLED },
+ { { &fr_iptimeout }, "fr_iptimeout", 1, 0x7fffffff,
+ sizeof(fr_iptimeout), IPFT_WRDISABLED },
{ { &fr_statemax }, "fr_statemax", 1, 0x7fffffff,
- sizeof(fr_statemax), IPFT_WRDISABLED },
+ sizeof(fr_statemax), 0 },
{ { &fr_statesize }, "fr_statesize", 1, 0x7fffffff,
sizeof(fr_statesize), IPFT_WRDISABLED },
{ { &fr_state_lock }, "fr_state_lock", 0, 1,
@@ -5544,6 +5857,8 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(fr_nat_lock), IPFT_RDONLY },
{ { &ipf_nattable_sz }, "ipf_nattable_sz", 1, 0x7fffffff,
sizeof(ipf_nattable_sz), IPFT_WRDISABLED },
+ { { &ipf_nattable_max }, "ipf_nattable_max", 1, 0x7fffffff,
+ sizeof(ipf_nattable_max), 0 },
{ { &ipf_natrules_sz }, "ipf_natrules_sz", 1, 0x7fffffff,
sizeof(ipf_natrules_sz), IPFT_WRDISABLED },
{ { &ipf_rdrrules_sz }, "ipf_rdrrules_sz", 1, 0x7fffffff,
@@ -5558,6 +5873,8 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(nat_logging), 0 },
{ { &fr_defnatage }, "fr_defnatage", 1, 0x7fffffff,
sizeof(fr_defnatage), IPFT_WRDISABLED },
+ { { &fr_defnatipage }, "fr_defnatipage", 1, 0x7fffffff,
+ sizeof(fr_defnatipage), IPFT_WRDISABLED },
{ { &fr_defnaticmpage }, "fr_defnaticmpage", 1, 0x7fffffff,
sizeof(fr_defnaticmpage), IPFT_WRDISABLED },
/* frag */
@@ -5575,10 +5892,144 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(ipl_logmax), IPFT_WRDISABLED },
{ { &ipl_logall }, "ipl_logall", 0, 1,
sizeof(ipl_logall), 0 },
+ { { &ipl_logsize }, "ipl_logsize", 0, 0x80000,
+ sizeof(ipl_logsize), 0 },
#endif
{ { NULL }, NULL, 0, 0 }
};
+static ipftuneable_t *ipf_tunelist = NULL;
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_findtunebycookie */
+/* Returns: NULL = search failed, else pointer to tune struct */
+/* Parameters: cookie(I) - cookie value to search for amongst tuneables */
+/* next(O) - pointer to place to store the cookie for the */
+/* "next" tuneable, if it is desired. */
+/* */
+/* This function is used to walk through all of the existing tunables with */
+/* successive calls. It searches the known tunables for the one which has */
+/* a matching value for "cookie" - ie its address. When returning a match, */
+/* the next one to be found may be returned inside next. */
+/* ------------------------------------------------------------------------ */
+static ipftuneable_t *fr_findtunebycookie(cookie, next)
+void *cookie, **next;
+{
+ ipftuneable_t *ta, **tap;
+
+ for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++)
+ if (ta == cookie) {
+ if (next != NULL) {
+ /*
+ * If the next entry in the array has a name
+ * present, then return a pointer to it for
+ * where to go next, else return a pointer to
+ * the dynaminc list as a key to search there
+ * next. This facilitates a weak linking of
+ * the two "lists" together.
+ */
+ if ((ta + 1)->ipft_name != NULL)
+ *next = ta + 1;
+ else
+ *next = &ipf_tunelist;
+ }
+ return ta;
+ }
+
+ for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next)
+ if (tap == cookie) {
+ if (next != NULL)
+ *next = &ta->ipft_next;
+ return ta;
+ }
+
+ if (next != NULL)
+ *next = NULL;
+ return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_findtunebyname */
+/* Returns: NULL = search failed, else pointer to tune struct */
+/* Parameters: name(I) - name of the tuneable entry to find. */
+/* */
+/* Search the static array of tuneables and the list of dynamic tuneables */
+/* for an entry with a matching name. If we can find one, return a pointer */
+/* to the matching structure. */
+/* ------------------------------------------------------------------------ */
+static ipftuneable_t *fr_findtunebyname(name)
+const char *name;
+{
+ ipftuneable_t *ta;
+
+ for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++)
+ if (!strcmp(ta->ipft_name, name)) {
+ return ta;
+ }
+
+ for (ta = ipf_tunelist; ta != NULL; ta = ta->ipft_next)
+ if (!strcmp(ta->ipft_name, name)) {
+ return ta;
+ }
+
+ return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_addipftune */
+/* Returns: int - 0 == success, else failure */
+/* Parameters: newtune - pointer to new tune struct to add to tuneables */
+/* */
+/* Appends the tune structure pointer to by "newtune" to the end of the */
+/* current list of "dynamic" tuneable parameters. Once added, the owner */
+/* of the object is not expected to ever change "ipft_next". */
+/* ------------------------------------------------------------------------ */
+int fr_addipftune(newtune)
+ipftuneable_t *newtune;
+{
+ ipftuneable_t *ta, **tap;
+
+ ta = fr_findtunebyname(newtune->ipft_name);
+ if (ta != NULL)
+ return EEXIST;
+
+ for (tap = &ipf_tunelist; *tap != NULL; tap = &(*tap)->ipft_next)
+ ;
+
+ newtune->ipft_next = NULL;
+ *tap = newtune;
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_delipftune */
+/* Returns: int - 0 == success, else failure */
+/* Parameters: oldtune - pointer to tune struct to remove from the list of */
+/* current dynamic tuneables */
+/* */
+/* Search for the tune structure, by pointer, in the list of those that are */
+/* dynamically added at run time. If found, adjust the list so that this */
+/* structure is no longer part of it. */
+/* ------------------------------------------------------------------------ */
+int fr_delipftune(oldtune)
+ipftuneable_t *oldtune;
+{
+ ipftuneable_t *ta, **tap;
+
+ for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next)
+ if (ta == oldtune) {
+ *tap = oldtune->ipft_next;
+ oldtune->ipft_next = NULL;
+ return 0;
+ }
+
+ return ESRCH;
+}
+
/* ------------------------------------------------------------------------ */
/* Function: fr_ipftune */
@@ -5594,16 +6045,10 @@ ipftuneable_t ipf_tuneables[] = {
/* each responsible for handling their own values being too big. */
/* ------------------------------------------------------------------------ */
int fr_ipftune(cmd, data)
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
-char *data;
+ioctlcmd_t cmd;
+void *data;
{
ipftuneable_t *ta;
- char namebuf[80];
ipftune_t tu;
void *cookie;
int error;
@@ -5613,9 +6058,8 @@ char *data;
return error;
tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0';
- ta = ipf_tuneables;
cookie = tu.ipft_cookie;
- namebuf[sizeof(namebuf) - 1] = '\0';
+ ta = NULL;
switch (cmd)
{
@@ -5630,16 +6074,11 @@ char *data;
* at the front of the list.
*/
if (cookie != NULL) {
- for (; ta->ipft_name != NULL; ta++)
- if (ta == cookie) {
- ta++;
- break;
- }
- if (ta->ipft_name == NULL)
- ta = NULL;
+ ta = fr_findtunebycookie(cookie, &tu.ipft_cookie);
+ } else {
+ ta = ipf_tuneables;
+ tu.ipft_cookie = ta + 1;
}
- cookie = ta;
- tu.ipft_cookie = cookie;
if (ta != NULL) {
/*
* Entry found, but does the data pointed to by that
@@ -5667,8 +6106,7 @@ char *data;
strlen(ta->ipft_name) + 1));
}
error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE);
- return error;
- /*NOTREACHED*/
+ break;
case SIOCIPFGET :
case SIOCIPFSET :
@@ -5676,28 +6114,23 @@ char *data;
* Search by name or by cookie value for a particular entry
* in the tuning paramter table.
*/
+ error = ESRCH;
if (cookie != NULL) {
- for (; ta->ipft_name != NULL; ta++)
- if (ta == cookie)
- break;
+ ta = fr_findtunebycookie(cookie, NULL);
+ if (ta != NULL)
+ error = 0;
} else if (tu.ipft_name[0] != '\0') {
- for (; ta->ipft_name != NULL; ta++)
- if (!strncmp(ta->ipft_name, tu.ipft_name,
- MIN(sizeof(tu.ipft_name),
- strlen(ta->ipft_name) + 1)))
- break;
- } else
- return ESRCH;
- if (ta == NULL)
- return ESRCH;
+ ta = fr_findtunebyname(tu.ipft_name);
+ if (ta != NULL)
+ error = 0;
+ }
+ if (error != 0)
+ break;
- switch (cmd)
- {
- case SIOCIPFGET :
+ if (cmd == (ioctlcmd_t)SIOCIPFGET) {
/*
* Fetch the tuning parameters for a particular value
*/
- tu.ipft_cookie = ta;
tu.ipft_vlong = 0;
if (ta->ipft_sz == sizeof(u_long))
tu.ipft_vlong = *ta->ipft_plong;
@@ -5707,29 +6140,32 @@ char *data;
tu.ipft_vshort = *ta->ipft_pshort;
else if (ta->ipft_sz == sizeof(u_char))
tu.ipft_vchar = *ta->ipft_pchar;
+ tu.ipft_cookie = ta;
tu.ipft_sz = ta->ipft_sz;
tu.ipft_min = ta->ipft_min;
tu.ipft_max = ta->ipft_max;
tu.ipft_flags = ta->ipft_flags;
error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE);
- return error;
- /*NOTREACHED*/
- case SIOCIPFSET :
+
+ } else if (cmd == (ioctlcmd_t)SIOCIPFSET) {
/*
* Set an internal parameter. The hard part here is
* getting the new value safely and correctly out of
* the kernel (given we only know its size, not type.)
*/
- {
u_long in;
if (((ta->ipft_flags & IPFT_WRDISABLED) != 0) &&
- (fr_running > 0))
- return EBUSY;
+ (fr_running > 0)) {
+ error = EBUSY;
+ break;
+ }
in = tu.ipft_vlong;
- if (in < ta->ipft_min || in > ta->ipft_max)
- return EINVAL;
+ if (in < ta->ipft_min || in > ta->ipft_max) {
+ error = EINVAL;
+ break;
+ }
if (ta->ipft_sz == sizeof(u_long)) {
tu.ipft_vlong = *ta->ipft_plong;
@@ -5745,13 +6181,217 @@ char *data;
*ta->ipft_pchar = (u_char)(in & 0xff);
}
error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE);
- return error;
- }
- /*NOTREACHED*/
}
+ break;
+
default :
+ error = EINVAL;
break;
}
- return EINVAL;
+ return error;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_initialise */
+/* Returns: int - 0 == success, < 0 == failure */
+/* Parameters: None. */
+/* */
+/* Call of the initialise functions for all the various subsystems inside */
+/* of IPFilter. If any of them should fail, return immeadiately a failure */
+/* BUT do not try to recover from the error here. */
+/* ------------------------------------------------------------------------ */
+int fr_initialise()
+{
+ int i;
+
+#ifdef IPFILTER_LOG
+ i = fr_loginit();
+ if (i < 0)
+ return -10 + i;
+#endif
+ i = fr_natinit();
+ if (i < 0)
+ return -20 + i;
+
+ i = fr_stateinit();
+ if (i < 0)
+ return -30 + i;
+
+ i = fr_authinit();
+ if (i < 0)
+ return -40 + i;
+
+ i = fr_fraginit();
+ if (i < 0)
+ return -50 + i;
+
+ i = appr_init();
+ if (i < 0)
+ return -60 + i;
+
+#ifdef IPFILTER_SYNC
+ i = ipfsync_init();
+ if (i < 0)
+ return -70 + i;
+#endif
+#ifdef IPFILTER_SCAN
+ i = ipsc_init();
+ if (i < 0)
+ return -80 + i;
+#endif
+#ifdef IPFILTER_LOOKUP
+ i = ip_lookup_init();
+ if (i < 0)
+ return -90 + i;
+#endif
+#ifdef IPFILTER_COMPILED
+ ipfrule_add();
+#endif
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_deinitialise */
+/* Returns: None. */
+/* Parameters: None. */
+/* */
+/* Call all the various subsystem cleanup routines to deallocate memory or */
+/* destroy locks or whatever they've done that they need to now undo. */
+/* The order here IS important as there are some cross references of */
+/* internal data structures. */
+/* ------------------------------------------------------------------------ */
+void fr_deinitialise()
+{
+ fr_fragunload();
+ fr_authunload();
+ fr_natunload();
+ fr_stateunload();
+#ifdef IPFILTER_SCAN
+ fr_scanunload();
+#endif
+ appr_unload();
+
+#ifdef IPFILTER_COMPILED
+ ipfrule_remove();
+#endif
+
+ (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
+ (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE);
+ (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
+ (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE);
+
+#ifdef IPFILTER_LOOKUP
+ ip_lookup_unload();
+#endif
+
+#ifdef IPFILTER_LOG
+ fr_logunload();
+#endif
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_zerostats */
+/* Returns: int - 0 = success, else failure */
+/* Parameters: data(O) - pointer to pointer for copying data back to */
+/* */
+/* Copies the current statistics out to userspace and then zero's the */
+/* current ones in the kernel. The lock is only held across the bzero() as */
+/* the copyout may result in paging (ie network activity.) */
+/* ------------------------------------------------------------------------ */
+int fr_zerostats(data)
+caddr_t data;
+{
+ friostat_t fio;
+ int error;
+
+ fr_getstat(&fio);
+ error = copyoutptr(&fio, data, sizeof(fio));
+ if (error)
+ return EFAULT;
+
+ WRITE_ENTER(&ipf_mutex);
+ bzero((char *)frstats, sizeof(*frstats) * 2);
+ RWLOCK_EXIT(&ipf_mutex);
+
+ return 0;
+}
+
+
+#ifdef _KERNEL
+/* ------------------------------------------------------------------------ */
+/* Function: fr_resolvedest */
+/* Returns: Nil */
+/* Parameters: fdp(IO) - pointer to destination information to resolve */
+/* v(I) - IP protocol version to match */
+/* */
+/* Looks up an interface name in the frdest structure pointed to by fdp and */
+/* if a matching name can be found for the particular IP protocol version */
+/* then store the interface pointer in the frdest struct. If no match is */
+/* found, then set the interface pointer to be -1 as NULL is considered to */
+/* indicate there is no information at all in the structure. */
+/* ------------------------------------------------------------------------ */
+void fr_resolvedest(fdp, v)
+frdest_t *fdp;
+int v;
+{
+ void *ifp;
+
+ ifp = NULL;
+ v = v; /* LINT */
+
+ if (*fdp->fd_ifname != '\0') {
+ ifp = GETIFP(fdp->fd_ifname, v);
+ if (ifp == NULL)
+ ifp = (void *)-1;
+ }
+ fdp->fd_ifp = ifp;
+}
+#endif /* _KERNEL */
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_resolvenic */
+/* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */
+/* pointer to interface structure for NIC */
+/* Parameters: name(I) - complete interface name */
+/* v(I) - IP protocol version */
+/* */
+/* Look for a network interface structure that firstly has a matching name */
+/* to that passed in and that is also being used for that IP protocol */
+/* version (necessary on some platforms where there are separate listings */
+/* for both IPv4 and IPv6 on the same physical NIC. */
+/* */
+/* One might wonder why name gets terminated with a \0 byte in here. The */
+/* reason is an interface name could get into the kernel structures of ipf */
+/* in any number of ways and so long as they all use the same sized array */
+/* to put the name in, it makes sense to ensure it gets null terminated */
+/* before it is used for its intended purpose - finding its match in the */
+/* kernel's list of configured interfaces. */
+/* */
+/* NOTE: This SHOULD ONLY be used with IPFilter structures that have an */
+/* array for the name that is LIFNAMSIZ bytes (at least) in length. */
+/* ------------------------------------------------------------------------ */
+void *fr_resolvenic(name, v)
+char *name;
+int v;
+{
+ void *nic;
+
+ if (name[0] == '\0')
+ return NULL;
+
+ if ((name[1] == '\0') && ((name[0] == '-') || (name[0] == '*'))) {
+ return NULL;
+ }
+
+ name[LIFNAMSIZ - 1] = '\0';
+
+ nic = GETIFP(name, v);
+ if (nic == NULL)
+ nic = (void *)-1;
+ return nic;
}
diff --git a/usr/src/common/ipf/ip_auth.c b/usr/src/uts/common/inet/ipf/ip_auth.c
index 45de581cc0..b6f0844354 100644
--- a/usr/src/common/ipf/ip_auth.c
+++ b/usr/src/uts/common/inet/ipf/ip_auth.c
@@ -31,11 +31,13 @@ struct file;
#else
# include <sys/ioctl.h>
#endif
-#include <sys/protosw.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#if defined(_KERNEL)
# include <sys/systm.h>
-# if !defined(__SVR4) && !defined(__svr4__)
+# if !defined(__SVR4) && !defined(__svr4__) && !defined(linux)
# include <sys/mbuf.h>
# endif
#endif
@@ -65,26 +67,23 @@ struct file;
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#if !defined(_KERNEL) && !defined(__osf__)
+#if !defined(_KERNEL) && !defined(__osf__) && !defined(__sgi)
# define KERNEL
# define _KERNEL
# define NOT_KERNEL
#endif
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
#ifdef NOT_KERNEL
# undef _KERNEL
# undef KERNEL
#endif
-#ifdef __sgi
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-# include <sys/hashing.h>
-# endif
-#endif
#include <netinet/tcp.h>
-#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
+#if defined(IRIX) && (IRIX < 60516) /* IRIX < 6 */
extern struct ifqueue ipintrq; /* ip packet input queue */
#else
-# if !defined(__hpux)
+# if !defined(__hpux) && !defined(linux)
# if __FreeBSD_version >= 300000
# include <net/if_var.h>
# if __FreeBSD_version >= 500042
@@ -98,17 +97,11 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#endif
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_auth.h"
-#else
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_auth.h"
-#endif
-#if !defined(MENTAT)
+#if !defined(MENTAT) && !defined(linux)
# include <net/netisr.h>
# ifdef __FreeBSD__
# include <machine/cpufunc.h>
@@ -121,19 +114,19 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
# include <sys/systm.h>
# endif
#endif
+/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.56 2003/06/28 17:01:55 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.5 2005/06/12 07:18:14 darrenr Exp $";
#endif
-#ifdef USE_MUTEXES
-extern ipfrwlock_t ipf_auth;
-extern ipfmutex_t ipf_authmx;
-# if SOLARIS
+#if SOLARIS
extern kcondvar_t ipfauthwait;
-# endif /* SOLARIS */
-#endif /* USE_MUTEXES */
+#endif /* SOLARIS */
+#if defined(linux) && defined(_KERNEL)
+wait_queue_head_t fr_authnext_linux;
+#endif
int fr_authsize = FR_NUMAUTH;
int fr_authused = 0;
@@ -161,13 +154,16 @@ int fr_authinit()
if (fr_authpkts != NULL)
bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts));
else
- return -1;
+ return -2;
MUTEX_INIT(&ipf_authmx, "ipf auth log mutex");
RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock");
#if SOLARIS && defined(_KERNEL)
cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL);
#endif
+#if defined(linux) && defined(_KERNEL)
+ init_waitqueue_head(&fr_authnext_linux);
+#endif
fr_auth_init = 1;
@@ -264,7 +260,7 @@ u_32_t *passp;
RWLOCK_EXIT(&ipf_auth);
if (passp != NULL)
*passp = pass;
- ATOMIC_INCL(fr_authstats.fas_hits);
+ ATOMIC_INC64(fr_authstats.fas_hits);
return fr;
}
i++;
@@ -273,7 +269,7 @@ u_32_t *passp;
}
fr_authstats.fas_miss++;
RWLOCK_EXIT(&ipf_auth);
- ATOMIC_INCL(fr_authstats.fas_miss);
+ ATOMIC_INC64(fr_authstats.fas_miss);
return NULL;
}
@@ -288,7 +284,7 @@ mb_t *m;
fr_info_t *fin;
{
#if defined(_KERNEL) && defined(MENTAT)
- qif_t *qif = fin->fin_qif;
+ qpktinfo_t *qpi = fin->fin_qpi;
#endif
frauth_t *fra;
#if !defined(sparc) && !defined(m68k)
@@ -343,9 +339,9 @@ fr_info_t *fin;
}
#endif
#if SOLARIS && defined(_KERNEL)
- m->b_rptr -= qif->qf_off;
+ m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
- fra->fra_q = qif->qf_q;
+ fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
cv_signal(&ipfauthwait);
#else
# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
@@ -355,7 +351,7 @@ fr_info_t *fin;
}
# endif
fr_authpkts[i] = m;
- WAKEUP(&fr_authnext);
+ WAKEUP(&fr_authnext,0);
#endif
return 1;
}
@@ -363,20 +359,14 @@ fr_info_t *fin;
int fr_auth_ioctl(data, cmd, mode)
caddr_t data;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
int mode;
{
mb_t *m;
-#if defined(_KERNEL) && !defined(MENTAT)
+#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq;
-# ifdef USE_SPL
- int s;
-# endif /* USE_SPL */
+ SPL_INT(s);
#endif
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
@@ -389,7 +379,7 @@ int mode;
error = EPERM;
break;
}
- error = fr_lock(data, &fr_auth_lock);
+ fr_lock(data, &fr_auth_lock);
break;
case SIOCATHST:
@@ -513,14 +503,17 @@ fr_authioctlloop:
# ifdef MENTAT
error = !putq(fra->fra_q, m);
# else /* MENTAT */
-# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \
- (defined(__sgi) && (IRIX >= 605) || \
- (defined(__FreeBSD__) && (__FreeBSD_version >= 500043)))
+# if defined(linux) || defined(AIX)
+# else
+# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \
+ (defined(__sgi) && (IRIX >= 60500) || defined(AIX) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 470102)))
error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
NULL);
-# else
+# else
error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
-# endif
+# endif
+# endif /* Linux */
# endif /* MENTAT */
if (error != 0)
fr_authstats.fas_sendfail++;
@@ -530,17 +523,28 @@ fr_authioctlloop:
# ifdef MENTAT
error = !putq(fra->fra_q, m);
# else /* MENTAT */
+# if defined(linux) || defined(AIX)
+# else
+# if (__FreeBSD_version >= 501000)
+ netisr_dispatch(NETISR_IP, m);
+# else
+# if (IRIX >= 60516)
+ ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd;
+# else
ifq = &ipintrq;
+# endif
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
- m_freem(m);
+ FREE_MB_T(m);
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
-# if IRIX < 605
+# if IRIX < 60500
schednetisr(NETISR_IP);
-# endif
+# endif
}
+# endif
+# endif /* Linux */
# endif /* MENTAT */
if (error != 0)
fr_authstats.fas_quefail++;
@@ -555,7 +559,7 @@ fr_authioctlloop:
/*
* If we experience an error which will result in the packet
* not being processed, make sure we advance to the next one.
- */
+ */
if (error == ENOBUFS) {
fr_authused--;
fra->fra_index = -1;
@@ -655,9 +659,7 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
-# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
if (fr_auth_lock)
return;
@@ -701,19 +703,12 @@ void fr_authexpire()
}
int fr_preauthcmd(cmd, fr, frptr)
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
frentry_t *fr, **frptr;
{
frauthent_t *fae, **faep;
int error = 0;
-# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR))
return EIO;
@@ -725,7 +720,7 @@ frentry_t *fr, **frptr;
faep = &fae->fae_next;
}
- if (cmd == SIOCRMAFR) {
+ if (cmd == (ioctlcmd_t)SIOCRMAFR) {
if (fr == NULL || frptr == NULL)
error = EINVAL;
else if (fae == NULL)
@@ -766,9 +761,9 @@ frentry_t *fr, **frptr;
/*
- * Flush held packets.
- * Must already be properly SPL'ed and Locked on &ipf_auth.
- *
+ * Flush held packets.
+ * Must already be properly SPL'ed and Locked on &ipf_auth.
+ *
*/
int fr_authflush()
{
diff --git a/usr/src/common/ipf/ip_fil_solaris.c b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c
index a4dc74c3b1..287cca861e 100644
--- a/usr/src/common/ipf/ip_fil_solaris.c
+++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c
@@ -1,16 +1,17 @@
/*
- * Copyright (C) 1999-2001, 2003 by Darren Reed.
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.36 2003/07/01 18:30:20 darrenr Exp $";
+static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.62.2.19 2005/07/13 21:40:46 darrenr Exp $";
#endif
#include <sys/types.h>
@@ -21,6 +22,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.36 2003/07/01 18:30:2
#include <sys/ioctl.h>
#include <sys/filio.h>
#include <sys/systm.h>
+#include <sys/strsubr.h>
#include <sys/cred.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
@@ -42,56 +44,54 @@ static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.36 2003/07/01 18:30:2
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
-#include "ip_compat.h"
+#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
#endif
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_auth.h"
-#include "ip_proxy.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
+#include "netinet/ip_proxy.h"
#ifdef IPFILTER_LOOKUP
-#include "ip_lookup.h"
-#endif
-#ifdef IPFILTER_COMPILED
-#include "ip_rules.h"
+# include "netinet/ip_lookup.h"
#endif
#include <inet/ip_ire.h>
#include <sys/md5.h>
-extern int fr_flags, fr_active;
+extern int fr_flags, fr_active;
#if SOLARIS2 >= 7
-extern timeout_id_t fr_timer_id;
+timeout_id_t fr_timer_id;
#else
-extern int fr_timer_id;
+int fr_timer_id;
#endif
-static int frzerostats __P((caddr_t));
-static int fr_send_ip __P((fr_info_t *fin, mblk_t *m));
+static int fr_send_ip __P((fr_info_t *fin, mblk_t *m, mblk_t **mp));
ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert;
ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock;
-ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag;
+ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ipf_frcache;
ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
kcondvar_t iplwait, ipfauthwait;
#if SOLARIS2 < 10
#if SOLARIS2 >= 7
-u_int *ip_ttl_ptr;
-u_int *ip_mtudisc;
+timeout_id_t fr_timer_id;
+u_int *ip_ttl_ptr = NULL;
+u_int *ip_mtudisc = NULL;
# if SOLARIS2 >= 8
-int *ip_forwarding;
-u_int *ip6_forwarding;
+int *ip_forwarding = NULL;
+u_int *ip6_forwarding = NULL;
# else
-u_int *ip_forwarding;
+u_int *ip_forwarding = NULL;
# endif
#else
-u_long *ip_ttl_ptr;
-u_long *ip_mtudisc;
-u_long *ip_forwarding;
+int fr_timer_id;
+u_long *ip_ttl_ptr = NULL;
+u_long *ip_mtudisc = NULL;
+u_long *ip_forwarding = NULL;
#endif
#endif
int ipf_locks_done = 0;
@@ -113,14 +113,14 @@ int ipldetach()
ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0);
- if (fr_refcnt)
- return EBUSY;
#if SOLARIS2 < 10
if (fr_control_forwarding & 2) {
- *ip_forwarding = 0;
+ if (ip_forwarding != NULL)
+ *ip_forwarding = 0;
#if SOLARIS2 >= 8
- *ip6_forwarding = 0;
+ if (ip6_forwarding != NULL)
+ *ip6_forwarding = 0;
#endif
}
#endif
@@ -129,27 +129,11 @@ int ipldetach()
cmn_err(CE_CONT, "ipldetach()\n");
#endif
- fr_fragunload();
- fr_authunload();
- fr_stateunload();
- fr_natunload();
- appr_unload();
-
-#ifdef IPFILTER_COMPILED
- ipfrule_remove();
-#endif
+ fr_deinitialise();
(void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
(void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE);
-#ifdef IPFILTER_LOOKUP
- ip_lookup_unload();
-#endif
-
-#ifdef IPFILTER_LOG
- fr_logunload();
-#endif
-
if (ipf_locks_done == 1) {
MUTEX_DESTROY(&ipf_timeoutlock);
MUTEX_DESTROY(&ipf_rw);
@@ -178,30 +162,8 @@ int iplattach __P((void))
RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock");
ipf_locks_done = 1;
-#ifdef IPFILTER_LOG
- if (fr_loginit() == -1)
- return -1;
-#endif
- if (fr_natinit() == -1)
- return -1;
- if (fr_stateinit() == -1)
- return -1;
- if (fr_authinit() == -1)
- return -1;
- if (fr_fraginit() == -1)
- return -1;
- if (appr_init() == -1)
- return -1;
-#ifdef IPFILTER_SYNC
- ipfsync_init();
-#endif
-#ifdef IPFILTER_SCAN
- isc_init();
-#endif
-#ifdef IPFILTER_LOOKUP
- if (ip_lookup_init() == -1)
+ if (fr_initialise() < 0)
return -1;
-#endif
/* Do not use private interface ip_params_arr[] in Solaris 10 */
#if SOLARIS2 < 10
@@ -215,6 +177,7 @@ int iplattach __P((void))
* of the array.
*/
+#if SOLARIS2 <= 8
for (i = 0; ; i++) {
if (!strcmp(ip_param_arr[i].ip_param_name, "ip_def_ttl")) {
ip_ttl_ptr = &ip_param_arr[i].ip_param_value;
@@ -241,11 +204,14 @@ int iplattach __P((void))
ip_forwarding != NULL)
break;
}
+#endif
if (fr_control_forwarding & 1) {
- *ip_forwarding = 1;
+ if (ip_forwarding != NULL)
+ *ip_forwarding = 1;
#if SOLARIS2 >= 8
- *ip6_forwarding = 1;
+ if (ip6_forwarding != NULL)
+ *ip6_forwarding = 1;
#endif
}
@@ -255,23 +221,6 @@ int iplattach __P((void))
}
-static int frzerostats(data)
-caddr_t data;
-{
- friostat_t fio;
- int error;
-
- fr_getstat(&fio);
- error = copyoutptr((caddr_t)&fio, data, sizeof(fio));
- if (error)
- return error;
-
- bzero((char *)frstats, sizeof(*frstats) * 2);
-
- return 0;
-}
-
-
/*
* Filter ioctl interface.
*/
@@ -305,7 +254,8 @@ int *rp;
if (unit != IPL_LOGIPF)
return EIO;
if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET &&
- cmd != SIOCIPFSET && cmd != SIOCFRENB && cmd != SIOCGETFS)
+ cmd != SIOCIPFSET && cmd != SIOCFRENB &&
+ cmd != SIOCGETFS && cmd != SIOCGETFF)
return EIO;
}
@@ -357,7 +307,7 @@ int *rp;
/* FALLTHRU */
case SIOCIPFGETNEXT :
case SIOCIPFGET :
- error = fr_ipftune(cmd, (char *)data);
+ error = fr_ipftune(cmd, (void *)data);
break;
case SIOCSETFF :
if (!(mode & FWRITE))
@@ -420,7 +370,7 @@ int *rp;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frzerostats((caddr_t)data);
+ error = fr_zerostats((caddr_t)data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
@@ -502,8 +452,7 @@ int *rp;
#endif
break;
default :
- cmn_err(CE_NOTE, "Unknown: cmd 0x%x data %p",
- cmd, (void *)data);
+ cmn_err(CE_NOTE, "Unknown: cmd 0x%x data %p", cmd, (void *)data);
error = EINVAL;
break;
}
@@ -511,41 +460,12 @@ int *rp;
return error;
}
-#ifndef IRE_ILL_CN
-ill_t *get_unit(name, v)
-char *name;
-int v;
-{
- size_t len = strlen(name) + 1; /* includes \0 */
- ill_t *il;
-#if SOLARIS2 >= 10
- ill_walk_context_t ctx;
-#endif
- int sap;
- if (v == 4)
- sap = 0x0800;
- else if (v == 6)
- sap = 0x86dd;
- else
- return NULL;
-#if SOLARIS2 >= 10
- for (il = ILL_START_WALK_ALL(&ctx); il; il = ill_next(&ctx, il))
-#else
- for (il = ill_g_head; il; il = il->ill_next)
-#endif
- if ((len == il->ill_name_length) && (il->ill_sap == sap) &&
- !strncmp(il->ill_name, name, len))
- return il;
- return NULL;
-}
-#else
-s_ill_t *get_unit(name, v)
+void *get_unit(name, v)
char *name;
int v;
{
- s_ill_t *il;
-
+ qif_t *qf;
int sap;
if (v == 4)
@@ -554,16 +474,11 @@ int v;
sap = 0x86dd;
else
return NULL;
-
- mutex_enter(&s_ill_g_head_lock);
- for (il = s_ill_g_head; il; il = il->ill_next)
- if ((il->ill_sap == sap) &&
- !strncmp(il->ill_name, name, LIFNAMSIZ))
- break;
- mutex_exit(&s_ill_g_head_lock);
- return il;
+ rw_enter(&pfil_rw, RW_READER);
+ qf = qif_iflookup(name, sap);
+ rw_exit(&pfil_rw);
+ return qf;
}
-#endif /* IRE_ILL_CN */
/*
@@ -630,7 +545,6 @@ cred_t *cp;
#endif /* IPFILTER_LOG */
-#ifdef IPFILTER_SYNC
/*
* iplread/ipllog
* both of these must operate with at least splnet() lest they be
@@ -645,11 +559,15 @@ cred_t *cp;
#ifdef IPFDEBUG
cmn_err(CE_CONT, "iplwrite(%x,%x,%x)\n", dev, uio, cp);
#endif
- if (getminor(dev) != IPL_LOGSYNC)
- return ENXIO;
- return ipfsync_write(uio);
-}
+#ifdef IPFILTER_SYNC
+ if (getminor(dev) == IPL_LOGSYNC)
+ return ipfsync_write(uio);
#endif /* IPFILTER_SYNC */
+ dev = dev; /* LINT */
+ uio = uio; /* LINT */
+ cp = cp; /* LINT */
+ return ENXIO;
+}
/*
@@ -690,7 +608,8 @@ fr_info_t *fin;
m->b_rptr += 64;
MTYPE(m) = M_DATA;
m->b_wptr = m->b_rptr + hlen;
- bzero((char *)m->b_rptr, hlen);
+ ip = (ip_t *)m->b_rptr;
+ bzero((char *)ip, hlen);
tcp2 = (struct tcphdr *)(m->b_rptr + hlen - sizeof(*tcp2));
tcp2->th_dport = tcp->th_sport;
tcp2->th_sport = tcp->th_dport;
@@ -705,10 +624,7 @@ fr_info_t *fin;
}
tcp2->th_off = sizeof(struct tcphdr) >> 2;
- /*
- * This is to get around a bug in the Solaris 2.4/2.5 TCP checksum
- * computation that is done by their put routine.
- */
+ ip->ip_v = fin->fin_v;
#ifdef USE_INET6
if (fin->fin_v == 6) {
ip6 = (ip6_t *)m->b_rptr;
@@ -721,7 +637,6 @@ fr_info_t *fin;
} else
#endif
{
- ip = (ip_t *)m->b_rptr;
ip->ip_src.s_addr = fin->fin_daddr;
ip->ip_dst.s_addr = fin->fin_saddr;
ip->ip_id = fr_nextipid(fin);
@@ -731,10 +646,9 @@ fr_info_t *fin;
ip->ip_tos = fin->fin_ip->ip_tos;
tcp2->th_sum = fr_cksum(m, ip, IPPROTO_TCP, tcp2);
}
- return fr_send_ip(fin, m);
+ return fr_send_ip(fin, m, &m);
}
-
/*
* Function: fr_send_ip
* Returns: 0: success
@@ -754,40 +668,84 @@ fr_info_t *fin;
*
* All other portions of the packet must be in on-the-wire format.
*/
-static int fr_send_ip(fin, m)
+/*ARGSUSED*/
+static int fr_send_ip(fin, m, mpp)
fr_info_t *fin;
-mblk_t *m;
+mblk_t *m, **mpp;
{
- int i;
+ qpktinfo_t qpi, *qpip;
+ fr_info_t fnew;
+ qif_t *qif;
+ ip_t *ip;
+ int i, hlen;
+
+ ip = (ip_t *)m->b_rptr;
+ bzero((char *)&fnew, sizeof(fnew));
#ifdef USE_INET6
if (fin->fin_v == 6) {
ip6_t *ip6;
- ip6 = (ip6_t *)m->b_rptr;
+ ip6 = (ip6_t *)ip;
ip6->ip6_vfc = 0x60;
ip6->ip6_hlim = 127;
+ fnew.fin_v = 6;
+ hlen = sizeof(*ip6);
} else
#endif
{
- ip_t *ip;
-
- ip = (ip_t *)m->b_rptr;
- ip->ip_v = IPVERSION;
-
+ fnew.fin_v = 4;
#if SOLARIS2 >= 10
ip->ip_ttl = 255;
- ip->ip_off = IP_DF;
+ ip->ip_off = htons(IP_DF);
#else
- ip->ip_ttl = (u_char)(*ip_ttl_ptr);
- ip->ip_off = *ip_mtudisc ? IP_DF : 0;
+ if (ip_ttl_ptr != NULL)
+ ip->ip_ttl = (u_char)(*ip_ttl_ptr);
+ else
+ ip->ip_ttl = 63;
+ if (ip_mtudisc != NULL)
+ ip->ip_off = htons(*ip_mtudisc ? IP_DF : 0);
+ else
+ ip->ip_off = htons(IP_DF);
#endif
-
+ /*
+ * The dance with byte order and ip_len/ip_off is because in
+ * fr_fastroute, it expects them to be in host byte order but
+ * ipf_cksum expects them to be in network byte order.
+ */
+ ip->ip_len = htons(ip->ip_len);
ip->ip_sum = ipf_cksum((u_short *)ip, sizeof(*ip));
-
+ ip->ip_len = ntohs(ip->ip_len);
+ ip->ip_off = ntohs(ip->ip_off);
+ hlen = sizeof(*ip);
}
- i = fr_fastroute(m, &m, fin, NULL);
+
+ qpip = fin->fin_qpi;
+ qpi.qpi_q = qpip->qpi_q;
+ qpi.qpi_off = 0;
+ qpi.qpi_name = qpip->qpi_name;
+ qif = qpip->qpi_real;
+ qpi.qpi_real = qif;
+ qpi.qpi_ill = qif->qf_ill;
+ qpi.qpi_hl = qif->qf_hl;
+ qpi.qpi_ppa = qif->qf_ppa;
+ qpi.qpi_num = qif->qf_num;
+ qpi.qpi_flags = qif->qf_flags;
+ qpi.qpi_max_frag = qif->qf_max_frag;
+ qpi.qpi_m = m;
+ qpi.qpi_data = ip;
+ fnew.fin_qpi = &qpi;
+ fnew.fin_ifp = fin->fin_ifp;
+ fnew.fin_flx = FI_NOCKSUM;
+ fnew.fin_m = m;
+ fnew.fin_ip = ip;
+ fnew.fin_mp = mpp;
+ fnew.fin_hlen = hlen;
+ fnew.fin_dp = (char *)ip + hlen;
+ (void) fr_makefrip(hlen, ip, &fnew);
+
+ i = fr_fastroute(m, mpp, &fnew, NULL);
return i;
}
@@ -799,31 +757,18 @@ int dst;
{
struct in_addr dst4;
struct icmp *icmp;
+ qpktinfo_t *qpi;
int hlen, code;
- qif_t *qif;
u_short sz;
#ifdef USE_INET6
mblk_t *mb;
#endif
mblk_t *m;
-#ifdef icmp_nextmtu
-#ifndef IRE_ILL_CN
- ill_t *il;
-#else
- s_ill_t *il;
-#endif /* IRE_ILL_CN */
-#endif
#ifdef USE_INET6
ip6_t *ip6;
#endif
ip_t *ip;
-#ifdef icmp_nextmtu
- /* lint fodder */
- il = NULL;
- il = il;
-#endif
-
if ((type < 0) || (type > ICMP_MAXTYPE))
return -1;
@@ -838,7 +783,7 @@ int dst;
return -1;
#endif
- qif = fin->fin_qif;
+ qpi = fin->fin_qpi;
#ifdef USE_INET6
mb = fin->fin_qfm;
@@ -878,16 +823,16 @@ int dst;
m->b_rptr += 64;
m->b_wptr = m->b_rptr + sz;
bzero((char *)m->b_rptr, (size_t)sz);
+ ip = (ip_t *)m->b_rptr;
+ ip->ip_v = fin->fin_v;
icmp = (struct icmp *)(m->b_rptr + hlen);
icmp->icmp_type = type & 0xff;
icmp->icmp_code = code & 0xff;
-#ifndef IRE_ILL_CN
#ifdef icmp_nextmtu
- if (type == ICMP_UNREACH && ((il = qif->qf_ill) != NULL) &&
+ if (type == ICMP_UNREACH && (qpi->qpi_max_frag != 0) &&
fin->fin_icode == ICMP_UNREACH_NEEDFRAG)
- icmp->icmp_nextmtu = htons(il->ill_max_frag);
+ icmp->icmp_nextmtu = htons(qpi->qpi_max_frag);
#endif
-#endif /* IRE_ILL_CN */
#ifdef USE_INET6
if (fin->fin_v == 6) {
@@ -895,7 +840,7 @@ int dst;
int csz;
if (dst == 0) {
- if (fr_ifpaddr(6, FRI_NORMAL, qif->qf_ill,
+ if (fr_ifpaddr(6, FRI_NORMAL, qpi->qpi_real,
(struct in_addr *)&dst6, NULL) == -1) {
FREE_MB_T(m);
return -1;
@@ -917,14 +862,13 @@ int dst;
} else
#endif
{
- ip = (ip_t *)m->b_rptr;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_ICMP;
ip->ip_id = fin->fin_ip->ip_id;
ip->ip_tos = fin->fin_ip->ip_tos;
ip->ip_len = (u_short)sz;
if (dst == 0) {
- if (fr_ifpaddr(4, FRI_NORMAL, qif->qf_ill,
+ if (fr_ifpaddr(4, FRI_NORMAL, qpi->qpi_real,
&dst4, NULL) == -1) {
FREE_MB_T(m);
return -1;
@@ -938,6 +882,7 @@ int dst;
bcopy((char *)fin->fin_ip + fin->fin_hlen,
(char *)&icmp->icmp_ip + sizeof(*fin->fin_ip), 8);
icmp->icmp_ip.ip_len = htons(icmp->icmp_ip.ip_len);
+ icmp->icmp_ip.ip_off = htons(icmp->icmp_ip.ip_off);
icmp->icmp_cksum = ipf_cksum((u_short *)icmp,
sz - sizeof(ip_t));
}
@@ -946,7 +891,7 @@ int dst;
* Need to exit out of these so we don't recursively call rw_enter
* from fr_qout.
*/
- return fr_send_ip(fin, m);
+ return fr_send_ip(fin, m, &m);
}
#ifdef IRE_ILL_CN
@@ -999,30 +944,41 @@ static void rate_limit_message(int rate, const char *message, ...)
* return the first IP Address associated with an interface
*/
/*ARGSUSED*/
-int fr_ifpaddr(v, atype, ifptr, inp, inpmask)
+int fr_ifpaddr(v, atype, qifptr, inp, inpmask)
int v, atype;
-void *ifptr;
+void *qifptr;
struct in_addr *inp, *inpmask;
{
#ifdef USE_INET6
struct sockaddr_in6 sin6, mask6;
#endif
struct sockaddr_in sin, mask;
+ qif_t *qif;
-#ifndef IRE_ILL_CN
- ill_t *ill = ifptr;
- ipif_t *ipif;
-#else
- s_ill_t *ill = ifptr;
-#endif /* IRE_ILL_CN */
-
- if ((ifptr == NULL) || (ifptr == (void *)-1))
+#ifdef USE_INET6
+#ifdef IRE_ILL_CN
+ s_ill_t *ill;
+#endif
+#endif
+ if ((qifptr == NULL) || (qifptr == (void *)-1))
return -1;
+ qif = qifptr;
+
+#ifdef USE_INET6
+#ifdef IRE_ILL_CN
+ ill = qif->qf_ill;
+#endif
+#endif
+
#ifdef USE_INET6
if (v == 6) {
-#ifndef IRE_ILL_CN
+#ifndef IRE_ILL_CN
in6_addr_t *inp6;
+ ipif_t *ipif;
+ ill_t *ill;
+
+ ill = qif->qf_ill;
/*
* First is always link local.
@@ -1062,24 +1018,22 @@ struct in_addr *inp, *inpmask;
return fr_ifpfillv6addr(atype, &sin6, &mask6, inp, inpmask);
}
#endif
-#ifndef IRE_ILL_CN
- ipif = ill->ill_ipif;
- mask.sin_addr.s_addr = ipif->ipif_net_mask;
- if (atype == FRI_BROADCAST)
-#if SOLARIS2 < 7
- sin.sin_addr.s_addr = ipif->ipif_broadcast_addr;
-#else
- sin.sin_addr.s_addr = ipif->ipif_brd_addr;
-#endif
- else if (atype == FRI_PEERADDR)
- sin.sin_addr.s_addr = ipif->ipif_pp_dst_addr;
- else
-#if SOLARIS2 < 7
- sin.sin_addr.s_addr = ipif->ipif_local_addr;
-#else
- sin.sin_addr.s_addr = ipif->ipif_lcl_addr;
-#endif
+#ifndef IRE_ILL_CN
+
+ switch (atype)
+ {
+ case FRI_BROADCAST :
+ sin.sin_addr.s_addr = QF_V4_BROADCAST(qif);
+ break;
+ case FRI_PEERADDR :
+ sin.sin_addr.s_addr = QF_V4_PEERADDR(qif);
+ break;
+ default :
+ sin.sin_addr.s_addr = QF_V4_ADDR(qif);
+ break;
+ }
+ mask.sin_addr.s_addr = QF_V4_NETMASK(qif);
#else
if (ill->netmask.in.sin_addr.s_addr == 0 ||
@@ -1101,52 +1055,6 @@ struct in_addr *inp, *inpmask;
}
-
-#ifdef IRE_ILL_CN
-/* ARGSUSED */
-#endif
-void fr_resolvdest(fdp, v)
-frdest_t *fdp;
-int v;
-{
-#ifndef IRE_ILL_CN
- ipif_t *ipif;
- ill_t *ill;
- ire_t *ire;
-
- ire = NULL;
-
- if (*fdp->fd_ifname) {
- ill = get_unit(fdp->fd_ifname, v);
- if (ill == NULL)
- ire = (ire_t *)-1;
- else if (((ipif = ill->ill_ipif) != NULL) && (v == 4)) {
-#if SOLARIS2 > 5
- ire = ire_ctable_lookup(ipif->ipif_local_addr, 0,
- IRE_LOCAL, NULL, NULL,
- MATCH_IRE_TYPE);
-#else
- ire = ire_lookup_myaddr(ipif->ipif_local_addr);
-#endif
- if (ire == NULL)
- ire = (ire_t *)-1;
- }
-#ifdef USE_INET6
- else if (((ipif = ill->ill_ipif) != NULL) && (v == 6)) {
- ire = ire_ctable_lookup_v6(&ipif->ipif_v6lcl_addr, 0,
- IRE_LOCAL, NULL, NULL,
- MATCH_IRE_TYPE);
- if (ire == NULL)
- ire = (ire_t *)-1;
- }
-#endif
- }
- fdp->fd_ifp = (struct ifnet *)ire;
-#else
-#endif /*IRE_ILL_CN */
-}
-
-
u_32_t fr_newisn(fin)
fr_info_t *fin;
{
@@ -1193,7 +1101,7 @@ fr_info_t *fin;
/* */
/* Returns the next IPv4 ID to use for this packet. */
/* ------------------------------------------------------------------------ */
-INLINE u_short fr_nextipid(fin)
+u_short fr_nextipid(fin)
fr_info_t *fin;
{
static u_short ipid = 0;
@@ -1230,7 +1138,9 @@ fr_info_t *fin;
#ifdef USE_INET6
+# ifndef IPFILTER_CKSUM
/* ARGSUSED */
+# endif
INLINE void fr_checkv6sum(fin)
fr_info_t *fin;
{
@@ -1240,3 +1150,463 @@ fr_info_t *fin;
# endif
}
#endif /* USE_INET6 */
+
+
+/*
+ * Function: fr_verifysrc
+ * Returns: int (really boolean)
+ * Parameters: fin - packet information
+ *
+ * Check whether the packet has a valid source address for the interface on
+ * which the packet arrived, implementing the "fr_chksrc" feature.
+ * Returns true iff the packet's source address is valid.
+ * Pre-Solaris 10, we call into the routing code to make the determination.
+ * On Solaris 10 and later, we have a valid address set from pfild to check
+ * against.
+ */
+int fr_verifysrc(fin)
+fr_info_t *fin;
+{
+ ire_t *dir;
+ int result;
+
+#if SOLARIS2 >= 6
+ dir = ire_route_lookup(fin->fin_saddr, 0xffffffff, 0, 0, NULL,
+ NULL, NULL, NULL, MATCH_IRE_DSTONLY|
+ MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
+#else
+ dir = ire_lookup(fin->fin_saddr);
+#endif
+
+ if (!dir)
+ return 0;
+ result = (ire_to_ill(dir) == fin->fin_ifp);
+#if SOLARIS2 >= 8
+ ire_refrele(dir);
+#endif
+ return result;
+}
+
+
+#if (SOLARIS2 < 7)
+void fr_slowtimer()
+#else
+/*ARGSUSED*/
+void fr_slowtimer __P((void *ptr))
+#endif
+{
+
+ WRITE_ENTER(&ipf_global);
+ if (fr_running <= 0) {
+ if (fr_running == -1)
+ fr_timer_id = timeout(fr_slowtimer, NULL,
+ drv_usectohz(500000));
+ else
+ fr_timer_id = NULL;
+ RWLOCK_EXIT(&ipf_global);
+ return;
+ }
+ MUTEX_DOWNGRADE(&ipf_global);
+
+ fr_fragexpire();
+ fr_timeoutstate();
+ fr_natexpire();
+ fr_authexpire();
+ fr_ticks++;
+ if (fr_running == -1 || fr_running == 1)
+ fr_timer_id = timeout(fr_slowtimer, NULL, drv_usectohz(500000));
+ else
+ fr_timer_id = NULL;
+ RWLOCK_EXIT(&ipf_global);
+}
+
+
+/*
+ * Function: fr_fastroute
+ * Returns: 0: success;
+ * -1: failed
+ * Parameters:
+ * mb: the message block where ip head starts
+ * mpp: the pointer to the pointer of the orignal
+ * packet message
+ * fin: packet information
+ * fdp: destination interface information
+ * if it is NULL, no interface information provided.
+ *
+ * This function is for fastroute/to/dup-to rules. It calls
+ * pfil_make_lay2_packet to search route, make lay-2 header
+ * ,and identify output queue for the IP packet.
+ * The destination address depends on the following conditions:
+ * 1: for fastroute rule, fdp is passed in as NULL, so the
+ * destination address is the IP Packet's destination address
+ * 2: for to/dup-to rule, if an ip address is specified after
+ * the interface name, this address is the as destination
+ * address. Otherwise IP Packet's destination address is used
+ */
+int fr_fastroute(mb, mpp, fin, fdp)
+mblk_t *mb, **mpp;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+ struct in_addr dst;
+#ifndef IRE_ILL_CN
+ size_t hlen = 0;
+ ill_t *ifp;
+ ire_t *dir;
+ u_char *s;
+ frdest_t fd;
+#ifdef USE_INET6
+ ip6_t *ip6 = (ip6_t *)fin->fin_ip;
+#endif
+#else
+ void *target = NULL;
+ char *ifname = NULL;
+#endif
+ queue_t *q = NULL;
+ mblk_t *mp = NULL;
+ qpktinfo_t *qpi;
+ frentry_t *fr;
+ qif_t *qif;
+ ip_t *ip;
+#ifndef sparc
+ u_short __iplen, __ipoff;
+#endif
+#ifdef USE_INET6
+ struct in6_addr dst6;
+#endif
+#ifndef IRE_ILL_CN
+ dir = NULL;
+#endif
+ fr = fin->fin_fr;
+ ip = fin->fin_ip;
+ qpi = fin->fin_qpi;
+
+ /*
+ * If this is a duplicate mblk then we want ip to point at that
+ * data, not the original, if and only if it is already pointing at
+ * the current mblk data.
+ */
+ if (ip == (ip_t *)qpi->qpi_m->b_rptr && qpi->qpi_m != mb)
+ ip = (ip_t *)mb->b_rptr;
+
+ /*
+ * If there is another M_PROTO, we don't want it
+ */
+ if (*mpp != mb) {
+ mp = unlinkb(*mpp);
+ freeb(*mpp);
+ *mpp = mp;
+ }
+
+#ifdef IRE_ILL_CN
+ if (fdp != NULL) {
+#else
+ /*
+ * If the fdp is NULL then there is no set route for this packet.
+ */
+ if (fdp == NULL) {
+ qif = fin->fin_ifp;
+
+ switch (fin->fin_v)
+ {
+ case 4 :
+ fd.fd_ip = ip->ip_dst;
+ break;
+#ifdef USE_INET6
+ case 6 :
+ fd.fd_ip6.in6 = ip6->ip6_dst;
+ break;
+#endif
+ }
+ fdp = &fd;
+ } else {
+#endif
+ qif = fdp->fd_ifp;
+
+ if (qif == NULL || qif == (void *)-1)
+ goto bad_fastroute;
+ }
+
+ /*
+ * In case we're here due to "to <if>" being used with
+ * "keep state", check that we're going in the correct
+ * direction.
+ */
+ if ((fr != NULL) && (fin->fin_rev != 0)) {
+ if ((qif != NULL) && (fdp == &fr->fr_tif))
+ return -1;
+ dst.s_addr = fin->fin_fi.fi_daddr;
+ } else {
+ if (fin->fin_v == 4) {
+ if (fdp && fdp->fd_ip.s_addr != 0) {
+ dst = fdp->fd_ip;
+#ifdef IRE_ILL_CN
+ target = &dst;
+#endif
+ } else
+ dst.s_addr = fin->fin_fi.fi_daddr;
+ }
+#ifdef USE_INET6
+ else if (fin->fin_v == 6) {
+ if (fdp && IP6_NOTZERO(&fdp->fd_ip)) {
+ dst6 = fdp->fd_ip6.in6;
+#ifdef IRE_ILL_CN
+ target = &dst6;
+#endif
+ } else
+ dst6 = fin->fin_dst6;
+ }
+#endif
+ else
+ goto bad_fastroute;
+ }
+
+#ifndef IRE_ILL_CN
+#if SOLARIS2 >= 6
+ if (fin->fin_v == 4) {
+ dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL,
+ NULL, NULL, MATCH_IRE_DSTONLY|
+ MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
+ }
+# ifdef USE_INET6
+ else if (fin->fin_v == 6) {
+ dir = ire_route_lookup_v6(&ip6->ip6_dst, NULL, 0, 0,
+ NULL, NULL, NULL, MATCH_IRE_DSTONLY|
+ MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
+ }
+# endif
+#else
+ dir = ire_lookup(dst.s_addr);
+#endif
+#if SOLARIS2 < 8
+ if (dir != NULL)
+ if (dir->ire_ll_hdr_mp == NULL || dir->ire_ll_hdr_length == 0)
+ dir = NULL;
+#else
+ if (dir != NULL)
+ if (dir->ire_fp_mp == NULL || dir->ire_dlureq_mp == NULL) {
+ ire_refrele(dir);
+ dir = NULL;
+ }
+#endif
+#else /* IRE_ILL_CN */
+ if (fdp && fdp->fd_ifname[0] != 0)
+ ifname = fdp->fd_ifname;
+
+ DB_CKSUMFLAGS(mb) = 0; /* disable hardware checksum */
+ mp = pfil_make_dl_packet(mb, ip, target, ifname, &q);
+ if (mp == NULL)
+ {
+ goto bad_fastroute;
+ }
+ mb = mp;
+#endif /* IRE_ILL_CN */
+
+#ifdef IRE_ILL_CN
+ if (mp != NULL) {
+#else
+ if (dir != NULL) {
+#if SOLARIS2 < 8
+ mp = dir->ire_ll_hdr_mp;
+ hlen = dir->ire_ll_hdr_length;
+#else
+ mp = dir->ire_fp_mp;
+ hlen = mp ? mp->b_wptr - mp->b_rptr : 0;
+ if (mp == NULL)
+ mp = dir->ire_dlureq_mp;
+#endif
+#endif
+ if (fin->fin_out == 0) {
+ void *saveqif;
+ u_32_t pass;
+
+ saveqif = fin->fin_ifp;
+ fin->fin_ifp = qif;
+ fin->fin_out = 1;
+ (void)fr_acctpkt(fin, &pass);
+ fin->fin_fr = NULL;
+ if (!fr || !(fr->fr_flags & FR_RETMASK))
+ (void) fr_checkstate(fin, &pass);
+
+ switch (fr_checknatout(fin, NULL))
+ {
+ /* FALLTHROUGH */
+ case 0 :
+ case 1 :
+ break;
+ case -1 :
+ goto bad_fastroute;
+ }
+
+ fin->fin_out = 0;
+ fin->fin_ifp = saveqif;
+ }
+#ifndef sparc
+ if (fin->fin_v == 4) {
+ __iplen = (u_short)ip->ip_len,
+ __ipoff = (u_short)ip->ip_off;
+
+ ip->ip_len = htons(__iplen);
+ ip->ip_off = htons(__ipoff);
+ }
+#endif
+#ifndef IRE_ILL_CN
+ ifp = qif->qf_ill;
+
+ if (mp != NULL) {
+ s = mb->b_rptr;
+ if (
+#if (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC)
+ (dohwcksum &&
+ ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC) ||
+#endif
+ (hlen && (s - mb->b_datap->db_base) >= hlen)) {
+ s -= hlen;
+ mb->b_rptr = (u_char *)s;
+ bcopy((char *)mp->b_rptr, (char *)s, hlen);
+ } else {
+ mblk_t *mp2;
+
+ mp2 = copyb(mp);
+ if (mp2 == NULL)
+ goto bad_fastroute;
+ linkb(mp2, mb);
+ mb = mp2;
+ }
+ }
+ *mpp = mb;
+
+ if (dir->ire_stq != NULL)
+ q = dir->ire_stq;
+ else if (dir->ire_rfq != NULL)
+ q = WR(dir->ire_rfq);
+ if (q != NULL)
+ q = q->q_next;
+ if (q != NULL) {
+ RWLOCK_EXIT(&ipf_global);
+#if (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC)
+ if ((fin->fin_p == IPPROTO_TCP) && dohwcksum &&
+ (ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
+ tcphdr_t *tcp;
+ u_32_t t;
+
+ tcp = (tcphdr_t *)((char *)ip + fin->fin_hlen);
+ t = ip->ip_src.s_addr;
+ t += ip->ip_dst.s_addr;
+ t += 30;
+ t = (t & 0xffff) + (t >> 16);
+ tcp->th_sum = t & 0xffff;
+ }
+#endif
+ putnext(q, mb);
+ ATOMIC_INCL(fr_frouteok[0]);
+#if SOLARIS2 >= 8
+ ire_refrele(dir);
+#endif
+ READ_ENTER(&ipf_global);
+ return 0;
+ }
+#else /* IRE_ILL_CN */
+ mb->b_queue = q;
+ *mpp = mb;
+ pfil_send_dl_packet(q, mb);
+ ATOMIC_INCL(fr_frouteok[0]);
+ return 0;
+#endif /* IRE_ILL_CN */
+ }
+bad_fastroute:
+#ifndef IRE_ILL_CN
+#if SOLARIS2 >= 8
+ if (dir != NULL)
+ ire_refrele(dir);
+#endif
+#endif
+ freemsg(mb);
+ ATOMIC_INCL(fr_frouteok[1]);
+ return -1;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_pullup */
+/* Returns: NULL == pullup failed, else pointer to protocol header */
+/* Parameters: m(I) - pointer to buffer where data packet starts */
+/* fin(I) - pointer to packet information */
+/* len(I) - number of bytes to pullup */
+/* */
+/* Attempt to move at least len bytes (from the start of the buffer) into a */
+/* single buffer for ease of access. Operating system native functions are */
+/* used to manage buffers - if necessary. If the entire packet ends up in */
+/* a single buffer, set the FI_COALESCE flag even though fr_coalesce() has */
+/* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */
+/* and ONLY if the pullup succeeds. */
+/* */
+/* We assume that 'min' is a pointer to a buffer that is part of the chain */
+/* of buffers that starts at *fin->fin_mp. */
+/* ------------------------------------------------------------------------ */
+void *fr_pullup(min, fin, len)
+mb_t *min;
+fr_info_t *fin;
+int len;
+{
+ qpktinfo_t *qpi = fin->fin_qpi;
+ int out = fin->fin_out, dpoff, ipoff;
+ mb_t *m = min;
+ char *ip;
+
+ if (m == NULL)
+ return NULL;
+
+ ip = (char *)fin->fin_ip;
+ if ((fin->fin_flx & FI_COALESCE) != 0)
+ return ip;
+
+ ipoff = fin->fin_ipoff;
+ if (fin->fin_dp != NULL)
+ dpoff = (char *)fin->fin_dp - (char *)ip;
+ else
+ dpoff = 0;
+
+ if (M_LEN(m) < len) {
+
+ /*
+ * pfil_precheck ensures the IP header is on a 32bit
+ * aligned address so simply fail if that isn't currently
+ * the case (should never happen).
+ */
+ int inc = 0;
+
+ if (ipoff > 0) {
+ if ((ipoff & 3) != 0) {
+ inc = 4 - (ipoff & 3);
+ if (m->b_rptr - inc >= m->b_datap->db_base)
+ m->b_rptr -= inc;
+ else
+ inc = 0;
+ }
+ }
+ if (pullupmsg(m, len + ipoff + inc) == 0) {
+ ATOMIC_INCL(frstats[out].fr_pull[1]);
+ FREE_MB_T(*fin->fin_mp);
+ *fin->fin_mp = NULL;
+ fin->fin_m = NULL;
+ fin->fin_ip = NULL;
+ fin->fin_dp = NULL;
+ qpi->qpi_data = NULL;
+ return NULL;
+ }
+ m->b_rptr += inc;
+ fin->fin_m = m;
+ ip = MTOD(m, char *) + ipoff;
+ qpi->qpi_data = ip;
+ }
+
+ ATOMIC_INCL(frstats[out].fr_pull[0]);
+ fin->fin_ip = (ip_t *)ip;
+ if (fin->fin_dp != NULL)
+ fin->fin_dp = (char *)fin->fin_ip + dpoff;
+
+ if (len == fin->fin_plen)
+ fin->fin_flx |= FI_COALESCE;
+ return ip;
+}
diff --git a/usr/src/common/ipf/ip_frag.c b/usr/src/uts/common/inet/ipf/ip_frag.c
index 5d5cf0ada4..29362c8a83 100644
--- a/usr/src/common/ipf/ip_frag.c
+++ b/usr/src/uts/common/inet/ipf/ip_frag.c
@@ -2,10 +2,8 @@
* Copyright (C) 1993-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,7 +40,9 @@ struct file;
#else
# include <sys/ioctl.h>
#endif
-#include <sys/protosw.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#if defined(_KERNEL)
# include <sys/systm.h>
@@ -51,7 +51,7 @@ struct file;
# endif
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# if defined(_KERNEL) && !defined(__sgi)
+# if defined(_KERNEL) && !defined(__sgi) && !defined(AIX)
# include <sys/kernel.h>
# endif
#else
@@ -70,28 +70,20 @@ struct file;
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_auth.h"
-#include "ip_proxy.h"
-#else
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_auth.h"
#include "netinet/ip_proxy.h"
-#endif
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# if defined(_KERNEL)
@@ -110,10 +102,11 @@ extern struct callout fr_slowtimer_ch;
# include <sys/timeout.h>
extern struct timeout fr_slowtimer_ch;
#endif
+/* END OF INCLUDES */
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.67 2003/06/28 17:01:57 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.5 2005/08/11 14:33:10 darrenr Exp $";
#endif
@@ -138,12 +131,6 @@ int fr_frag_lock = 0;
int fr_frag_init = 0;
u_long fr_ticks = 0;
-#ifdef USE_MUTEXES
-extern ipfrwlock_t ipf_frag, ipf_natfrag, ipf_nat, ipf_mutex, ipf_global;
-extern ipfrwlock_t ipf_ipidfrag;
-extern ipfmutex_t ipf_rw;
-#endif
-
static ipfr_t *ipfr_newfrag __P((fr_info_t *, u_32_t, ipfr_t **));
static ipfr_t *fr_fraglookup __P((fr_info_t *, ipfr_t **));
@@ -220,7 +207,7 @@ void fr_fragunload()
/* ------------------------------------------------------------------------ */
/* Function: fr_fragstats */
-/* Returns: ipfrstat_t* - pointer to struct with current frag stats */
+/* Returns: ipfrstat_t* - pointer to struct with current frag stats */
/* Parameters: Nil */
/* */
/* Updates ipfr_stats with current information and returns a pointer to it */
@@ -297,8 +284,15 @@ ipfr_t *table[];
return NULL;
}
- if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
- ATOMIC_INC(fin->fin_fr->fr_ref);
+ fra->ipfr_rule = fin->fin_fr;
+ if (fra->ipfr_rule != NULL) {
+
+ frentry_t *fr;
+
+ fr = fin->fin_fr;
+ MUTEX_ENTER(&fr->fr_lock);
+ fr->fr_ref++;
+ MUTEX_EXIT(&fr->fr_lock);
}
/*
@@ -317,7 +311,7 @@ ipfr_t *table[];
/*
* Compute the offset of the expected start of the next packet.
*/
- off = fin->fin_off >> 3;
+ off = fin->fin_off;
if (off == 0) {
fra->ipfr_seen0 = 1;
fra->ipfr_firstend = fin->fin_flen;
@@ -325,7 +319,7 @@ ipfr_t *table[];
fra->ipfr_seen0 = 0;
fra->ipfr_firstend = 0;
}
- fra->ipfr_off = off + (fin->fin_dlen >> 3);
+ fra->ipfr_off = off + fin->fin_dlen;
fra->ipfr_pass = pass;
ipfr_stats.ifs_new++;
ipfr_inuse++;
@@ -347,7 +341,7 @@ fr_info_t *fin;
ipfr_t *fra;
if (fr_frag_lock != 0)
- return NULL;
+ return -1;
WRITE_ENTER(&ipf_frag);
fra = ipfr_newfrag(fin, pass, ipfr_heads);
@@ -464,7 +458,6 @@ ipfr_t *table[];
idx += frag.ipfr_src.s_addr;
frag.ipfr_dest = fin->fin_fi.fi_dst;
idx += frag.ipfr_dst.s_addr;
-
frag.ipfr_ifp = fin->fin_ifp;
idx *= 127;
idx %= IPFT_SIZE;
@@ -502,7 +495,7 @@ ipfr_t *table[];
* because a fragmented packet is never resent with
* the same IP ID# (or shouldn't).
*/
- off = fin->fin_off >> 3;
+ off = fin->fin_off; /* same as in ipfr_newfrag() */
if (f->ipfr_seen0) {
if (off == 0) {
ATOMIC_INCL(ipfr_stats.ifs_retrans0);
@@ -534,7 +527,7 @@ ipfr_t *table[];
}
if (fin->fin_v == 6) {
- if (f->ipfr_seen0 && (off * 8 < f->ipfr_firstend))
+ if (f->ipfr_seen0 && (off < f->ipfr_firstend))
fin->fin_flx |= FI_BAD;
}
/*
@@ -542,10 +535,9 @@ ipfr_t *table[];
* last (in order), shrink expiration time.
*/
if (off == f->ipfr_off) {
-/* if (!(ip->ip_off & IP_MF))
+ if (!(fin->fin_ip->ip_off & IP_MF))
f->ipfr_ttl = fr_ticks + 1;
-*/
- f->ipfr_off = (fin->fin_dlen >> 3) + off;
+ f->ipfr_off = fin->fin_dlen + off;
} else if (f->ipfr_pass & FR_FRSTRICT)
continue;
ATOMIC_INCL(ipfr_stats.ifs_hits);
@@ -783,9 +775,7 @@ void fr_fragexpire()
{
ipfr_t **fp, *fra;
nat_t *nat;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
if (fr_frag_lock)
return;
@@ -851,7 +841,7 @@ void fr_fragexpire()
/* expectation of this being called twice per second. */
/* ------------------------------------------------------------------------ */
#if !defined(_KERNEL) || (!SOLARIS && !defined(__hpux) && !defined(__sgi) && \
- !defined(__osf__))
+ !defined(__osf__) && !defined(linux))
# if defined(_KERNEL) && ((BSD >= 199103) || defined(__sgi))
void fr_slowtimer __P((void *ptr))
# else
@@ -877,7 +867,11 @@ int fr_slowtimer()
# if (__FreeBSD_version >= 300000)
fr_slowtimer_ch = timeout(fr_slowtimer, NULL, hz/2);
# else
+# ifdef linux
+ ;
+# else
timeout(fr_slowtimer, NULL, hz/2);
+# endif
# endif /* FreeBSD */
# endif /* OpenBSD */
# endif /* NetBSD */
diff --git a/usr/src/common/ipf/ip_htable.c b/usr/src/uts/common/inet/ipf/ip_htable.c
index 37c65cc398..4ce3cc411e 100644
--- a/usr/src/common/ipf/ip_htable.c
+++ b/usr/src/uts/common/inet/ipf/ip_htable.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,7 +38,8 @@ struct file;
# include <sys/cdefs.h>
# include <sys/proc.h>
#endif
-#if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux)
+#if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux) && \
+ !defined(linux)
# include <sys/mbuf.h>
#endif
#if defined(_KERNEL)
@@ -49,20 +50,14 @@ struct file;
#include <netinet/in.h>
#include <net/if.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_lookup.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_lookup.h"
#include "netinet/ip_htable.h"
-#endif
+/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.24 2003/05/12 13:49:17 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.3 2005/05/14 05:11:38 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -80,22 +75,16 @@ static u_long ipf_nhtnodes[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 };
iphtable_t *ipf_htables[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL };
+
void fr_htable_unload()
{
iplookupflush_t fop;
- iphtable_t *iph;
- int unit;
-
- for (unit = 0; unit < IPL_LOGMAX; unit++) {
- fop.iplf_unit = unit;
- while ((iph = ipf_htables[unit]) != NULL) {
- (void)strncpy(fop.iplf_name, iph->iph_name,
- sizeof(fop.iplf_name));
- (void)fr_flushhtable(&fop);
- }
- }
+
+ fop.iplf_unit = IPL_LOGALL;
+ (void)fr_flushhtable(&fop);
}
+
int fr_gethtablestat(op)
iplookupop_t *op;
{
@@ -125,8 +114,10 @@ iplookupop_t *op;
int err, i, unit;
KMALLOC(iph, iphtable_t *);
- if (iph == NULL)
- return ENOMEM;
+ if (iph == NULL) {
+ ipht_nomem[op->iplo_unit]++;
+ return ENOMEM;
+ }
err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
if (err != 0) {
@@ -149,7 +140,11 @@ iplookupop_t *op;
i = IPHASH_ANON;
do {
i++;
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void)SNPRINTF(name, sizeof(name), "%u", i);
+#else
(void)sprintf(name, "%u", i);
+#endif
for (oiph = ipf_htables[unit]; oiph != NULL;
oiph = oiph->iph_next)
if (strncmp(oiph->iph_name, name,
@@ -220,15 +215,24 @@ iplookupop_t *op;
void fr_delhtable(iph)
iphtable_t *iph;
{
+ iphtent_t *ipe;
+ int i;
+
+ for (i = 0; i < iph->iph_size; i++)
+ while ((ipe = iph->iph_table[i]) != NULL)
+ if (fr_delhtent(iph, ipe) != 0)
+ return;
*iph->iph_pnext = iph->iph_next;
if (iph->iph_next != NULL)
iph->iph_next->iph_pnext = iph->iph_pnext;
ipf_nhtables[iph->iph_unit]--;
-
- KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
- KFREE(iph);
+
+ if (iph->iph_ref == 0) {
+ KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
+ KFREE(iph);
+ }
}
@@ -258,40 +262,19 @@ size_t fr_flushhtable(op)
iplookupflush_t *op;
{
iphtable_t *iph;
- size_t i, freed;
- iphtent_t *ipe;
-
- iph = fr_findhtable(op->iplf_unit, op->iplf_name);
- if (iph == NULL) {
- return 0;
- }
+ size_t freed;
+ int i;
freed = 0;
- *iph->iph_pnext = iph->iph_next;
- if (iph->iph_next != NULL)
- iph->iph_next->iph_pnext = iph->iph_pnext;
- for (i = 0; i < iph->iph_size; i++)
- while ((ipe = iph->iph_table[i]) != NULL) {
- *ipe->ipe_pnext = ipe->ipe_next;
- if (ipe->ipe_next != NULL)
- ipe->ipe_next->ipe_pnext = ipe->ipe_pnext;
-
- switch (iph->iph_type & ~IPHASH_ANON)
- {
- case IPHASH_GROUPMAP :
- if (ipe->ipe_ptr != NULL)
- fr_delgroup(ipe->ipe_group,
- IPL_LOGIPF, fr_active);
- break;
+ for (i = 0; i <= IPL_LOGMAX; i++) {
+ if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) {
+ while ((iph = ipf_htables[i]) != NULL) {
+ fr_delhtable(iph);
+ freed++;
}
- /* ipe_ref */
- KFREE(ipe);
- freed++;
}
-
- KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
- KFREE(iph);
+ }
return freed;
}
@@ -411,14 +394,15 @@ iphtent_t *ipe;
KFREE(ipe);
ipf_nhtnodes[iph->iph_unit]--;
-
+
return 0;
}
void *fr_iphmfindgroup(tptr, version, aptr)
-void *tptr, *aptr;
+void *tptr;
int version;
+void *aptr;
{
i6addr_t *addr;
iphtable_t *iph;
@@ -454,6 +438,15 @@ int version;
}
+/* ------------------------------------------------------------------------ */
+/* Function: fr_iphmfindip */
+/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */
+/* Parameters: tptr(I) - pointer to the pool to search */
+/* version(I) - IP protocol version (4 or 6) */
+/* aptr(I) - pointer to address information */
+/* */
+/* Search the hash table for a given address and return a search result. */
+/* ------------------------------------------------------------------------ */
int fr_iphmfindip(tptr, version, aptr)
void *tptr, *aptr;
int version;
@@ -463,8 +456,15 @@ int version;
iphtent_t *ipe;
int rval;
+ if ((version != 4)
+#ifdef USE_INET6
+ && (version != 6)
+#endif
+ )
+ return -1;
+
if (tptr == NULL || aptr == NULL)
- return 1;
+ return -1;
iph = tptr;
addr = aptr;
@@ -498,7 +498,6 @@ struct in_addr *addr;
u_int hv;
hmsk = iph->iph_masks[3];
-
msk = 0xffffffff;
maskloop:
ips = ntohl(addr->s_addr) & msk;
@@ -523,7 +522,6 @@ maskloop:
goto maskloop;
}
}
-
return ipe;
}
@@ -580,7 +578,6 @@ maskloop:
goto maskloop;
}
}
-
return ipe;
}
diff --git a/usr/src/common/ipf/ip_log.c b/usr/src/uts/common/inet/ipf/ip_log.c
index a7728cb7b8..364b2e08e5 100644
--- a/usr/src/common/ipf/ip_log.c
+++ b/usr/src/uts/common/inet/ipf/ip_log.c
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_log.c,v 2.54 2003/06/28 17:01:57 darrenr Exp $
+ * $Id: ip_log.c,v 2.75.2.7 2005/06/11 07:47:44 darrenr Exp $
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -22,144 +22,135 @@
defined(_KERNEL)
# include "opt_ipfilter_log.h"
#endif
-#ifdef __FreeBSD__
-# if !defined(IPFILTER_LKM)
-# if defined(_KERNEL)
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-# include "opt_ipfilter.h"
-# endif
-# else
-# include <osreldate.h>
+#if defined(__FreeBSD__) && !defined(IPFILTER_LKM)
+# if defined(_KERNEL)
+# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
+# include "opt_ipfilter.h"
# endif
+# else
+# include <osreldate.h>
# endif
#endif
-#ifdef IPFILTER_LOG
-# ifndef SOLARIS
-# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-# endif
-# include <sys/errno.h>
-# include <sys/types.h>
-# include <sys/file.h>
-# ifndef _KERNEL
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-# include <ctype.h>
-# define _KERNEL
+#ifndef SOLARIS
+# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#ifndef _KERNEL
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+# include <ctype.h>
+# define _KERNEL
+# define KERNEL
# ifdef __OpenBSD__
struct file;
# endif
-# include <sys/uio.h>
-# undef _KERNEL
+# include <sys/uio.h>
+# undef _KERNEL
+# undef KERNEL
+#endif
+#if __FreeBSD_version >= 220000 && defined(_KERNEL)
+# include <sys/fcntl.h>
+# include <sys/filio.h>
+#else
+# include <sys/ioctl.h>
+#endif
+#include <sys/time.h>
+#if defined(_KERNEL)
+# include <sys/systm.h>
+# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000)
+# include <sys/proc.h>
# endif
-# if __FreeBSD_version >= 220000 && defined(_KERNEL)
-# include <sys/fcntl.h>
-# include <sys/filio.h>
+#endif /* _KERNEL */
+#if !SOLARIS && !defined(__hpux) && !defined(linux)
+# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
+# include <sys/dirent.h>
# else
-# include <sys/ioctl.h>
+# include <sys/dir.h>
# endif
-# include <sys/time.h>
-# if defined(_KERNEL)
-# include <sys/systm.h>
-# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000)
-# include <sys/proc.h>
-# endif
-# endif /* _KERNEL */
-# if !SOLARIS && !defined(__hpux)
-# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
-# include <sys/dirent.h>
-# else
-# include <sys/dir.h>
-# endif
-# include <sys/mbuf.h>
-# else
-# if !defined(__hpux) && defined(_KERNEL)
-# include <sys/filio.h>
-# include <sys/cred.h>
-# include <sys/ddi.h>
-# include <sys/sunddi.h>
-# include <sys/ksynch.h>
-# include <sys/kmem.h>
-# include <sys/mkdev.h>
-# include <sys/dditypes.h>
-# include <sys/cmn_err.h>
-# endif /* !__hpux */
-# endif /* !SOLARIS && !__hpux */
+# include <sys/mbuf.h>
+#else
+# if !defined(__hpux) && defined(_KERNEL)
+# include <sys/filio.h>
+# include <sys/cred.h>
+# include <sys/ddi.h>
+# include <sys/sunddi.h>
+# include <sys/ksynch.h>
+# include <sys/kmem.h>
+# include <sys/mkdev.h>
+# include <sys/dditypes.h>
+# include <sys/cmn_err.h>
+# endif /* !__hpux */
+#endif /* !SOLARIS && !__hpux */
+#if !defined(linux)
# include <sys/protosw.h>
-# include <sys/socket.h>
+#endif
+#include <sys/socket.h>
-# include <net/if.h>
-# ifdef sun
-# include <net/af.h>
-# endif
-# if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-# endif
-# include <net/route.h>
-# include <netinet/in.h>
-# ifdef __sgi
-# include <sys/ddi.h>
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-# include <sys/hashing.h>
-# endif
-# endif
-# if !defined(__hpux) && !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
-# include <netinet/in_var.h>
-# endif
-# include <netinet/in_systm.h>
-# include <netinet/ip.h>
-# include <netinet/tcp.h>
-# include <netinet/udp.h>
-# include <netinet/ip_icmp.h>
-# ifdef USE_INET6
-# include <netinet/icmp6.h>
+#include <net/if.h>
+#ifdef sun
+# include <net/af.h>
+#endif
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
+#include <net/route.h>
+#include <netinet/in.h>
+#ifdef __sgi
+# include <sys/ddi.h>
+# ifdef IFF_DRVRLOCK /* IRIX6 */
+# include <sys/hashing.h>
# endif
+#endif
+#if !defined(__hpux) && !defined(linux) && \
+ !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
+# include <netinet/in_var.h>
+#endif
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifdef USE_INET6
+# include <netinet/icmp6.h>
+#endif
+#if !defined(linux)
# include <netinet/ip_var.h>
-# ifndef _KERNEL
-# include <syslog.h>
-# endif
-# include <netinet/tcpip.h>
-#if SOLARIS2 >= 10
-# include "ip_compat.h"
-# include "ip_fil.h"
-# include "ip_nat.h"
-# include "ip_frag.h"
-# include "ip_state.h"
-# include "ip_auth.h"
-#else
-# include "netinet/ip_compat.h"
-# include "netinet/ip_fil.h"
-# include "netinet/ip_nat.h"
-# include "netinet/ip_frag.h"
-# include "netinet/ip_state.h"
-# include "netinet/ip_auth.h"
#endif
-# if (__FreeBSD_version >= 300000) || defined(__NetBSD__)
-# include <sys/malloc.h>
-# endif
+#ifndef _KERNEL
+# include <syslog.h>
+#endif
+#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
+#include "netinet/ip_fil.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
+#if (__FreeBSD_version >= 300000) || defined(__NetBSD__)
+# include <sys/malloc.h>
+#endif
+/* END OF INCLUDES */
-# if defined(__hpux) && defined(_KERNEL) && (HPUXREV >= 1111)
-# define IPL_SELECT
-# endif
+#ifdef IPFILTER_LOG
# if defined(IPL_SELECT)
-# include <machine/sys/user.h>
-# include <sys/kthread_iface.h>
-# define READ_COLLISION 0x001
+# include <machine/sys/user.h>
+# include <sys/kthread_iface.h>
+# define READ_COLLISION 0x001
-struct {
- kthread *read_waiter;
- int state;
-} iplog_ss[IPL_LOGMAX+1];
+iplog_select_t iplog_ss[IPL_LOGMAX+1];
extern int selwait;
# endif /* IPL_SELECT */
-# ifdef USE_MUTEXES
-extern ipfmutex_t ipl_mutex;
-# if SOLARIS
+# if defined(linux) && defined(_KERNEL)
+wait_queue_head_t iplh_linux[IPL_LOGSIZE];
+# endif
+# if SOLARIS
extern kcondvar_t iplwait;
-# endif
# endif
iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE];
@@ -170,6 +161,10 @@ int ipl_buffer_sz;
int ipl_logmax = IPL_LOGMAX;
int ipl_logall = 0;
int ipl_log_init = 0;
+int ipl_logsize = IPFILTER_LOGSIZE;
+int ipl_magic[IPL_LOGSIZE] = { IPL_MAGIC, IPL_MAGIC_NAT, IPL_MAGIC_STATE,
+ IPL_MAGIC, IPL_MAGIC, IPL_MAGIC,
+ IPL_MAGIC, IPL_MAGIC };
/* ------------------------------------------------------------------------ */
@@ -194,6 +189,9 @@ int fr_loginit()
iplog_ss[i].read_waiter = 0;
iplog_ss[i].state = 0;
# endif
+# if defined(linux) && defined(_KERNEL)
+ init_waitqueue_head(iplh_linux + i);
+# endif
}
# if SOLARIS && defined(_KERNEL)
@@ -256,20 +254,17 @@ u_int flags;
ipflog_t ipfl;
u_char p;
mb_t *m;
-# if SOLARIS && defined(_KERNEL)
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
# ifndef IRE_ILL_CN
- ill_t *ifp;
+ qif_t *ifp;
# else
s_ill_t *ifp;
# endif /* IRE_ILL_CN */
# else
-# if defined(__hpux) && defined(_KERNEL)
- ifinfo_t *ifp;
-# else
struct ifnet *ifp;
-# endif
-# endif /* SOLARIS */
+# endif /* SOLARIS || __hpux */
+ ipfl.fl_nattag.ipt_num[0] = 0;
m = fin->fin_m;
ifp = fin->fin_ifp;
hlen = fin->fin_hlen;
@@ -286,7 +281,7 @@ u_int flags;
struct icmp *icmp;
icmp = (struct icmp *)fin->fin_dp;
-
+
/*
* For ICMP, if the packet is an error packet, also
* include the information about the packet which
@@ -333,32 +328,27 @@ u_int flags;
* Get the interface number and name to which this packet is
* currently associated.
*/
-# if SOLARIS && defined(_KERNEL)
- ipfl.fl_unit = (u_char)0;
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
+ ipfl.fl_unit = (u_int)0;
(void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname));
# else
-# if defined(__hpux) && defined(_KERNEL)
- ipfl.fl_unit = (u_char)ifp->ifi_ppa;
- bcopy(IFNAME(ifp), ipfl.fl_ifname,
- MIN(ifp->ifi_name_length, sizeof(ipfl.fl_ifname)));
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
+ COPYIFNAME(ifp, ipfl.fl_ifname);
# else
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- (void) strncpy(ipfl.fl_ifname, ifp->if_xname, sizeof(ipfl.fl_ifname));
-# else
- ipfl.fl_unit = (u_char)ifp->if_unit;
-# if defined(_KERNEL)
+ ipfl.fl_unit = (u_int)ifp->if_unit;
+# if defined(_KERNEL)
if ((ipfl.fl_ifname[0] = ifp->if_name[0]))
if ((ipfl.fl_ifname[1] = ifp->if_name[1]))
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
ipfl.fl_ifname[3] = ifp->if_name[3];
-# else
- (void) strncpy(ipfl.fl_ifname, ifp->if_name, LIFNAMSIZ);
- ipfl.fl_ifname[LIFNAMSIZ - 1] = '\0';
-# endif
+# else
+ (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname));
+ ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0';
# endif
-# endif /* __hpux */
-# endif /* SOLARIS */
+# endif
+# endif /* __hpux || SOLARIS */
mlen = fin->fin_plen - hlen;
if (!ipl_logall) {
mlen = (flags & FR_LOGBODY) ? MIN(mlen, 128) : 0;
@@ -373,11 +363,14 @@ u_int flags;
(void) strncpy(ipfl.fl_group, fin->fin_group, FR_GROUPLEN);
if (fin->fin_fr != NULL) {
ipfl.fl_loglevel = fin->fin_fr->fr_loglevel;
- ipfl.fl_tag = fin->fin_fr->fr_logtag;
+ ipfl.fl_logtag = fin->fin_fr->fr_logtag;
} else {
ipfl.fl_loglevel = 0xffff;
- ipfl.fl_tag = FR_NOLOGTAG;
+ ipfl.fl_logtag = FR_NOLOGTAG;
}
+ if (fin->fin_nattag != NULL)
+ bcopy(fin->fin_nattag, (void *)&ipfl.fl_nattag,
+ sizeof(ipfl.fl_nattag));
ipfl.fl_flags = flags;
ipfl.fl_dir = fin->fin_out;
ipfl.fl_lflags = fin->fin_flx;
@@ -427,11 +420,12 @@ void **items;
size_t *itemsz;
int *types, cnt;
{
- caddr_t buf, s;
+ caddr_t buf, ptr;
iplog_t *ipl;
size_t len;
int i;
-
+ SPL_INT(s);
+
/*
* Check to see if this log record has a CRC which matches the last
* record logged. If it does, just up the count on the previous one
@@ -439,7 +433,7 @@ int *types, cnt;
*/
if (ipl_suppress) {
MUTEX_ENTER(&ipl_mutex);
- if (fin != NULL) {
+ if ((fin != NULL) && (fin->fin_off == 0)) {
if ((ipll[dev] != NULL) &&
bcmp((char *)fin, (char *)&iplcrc[dev],
FI_LCSIZE) == 0) {
@@ -463,24 +457,27 @@ int *types, cnt;
* check that we have space to record this information and can
* allocate that much.
*/
+ KMALLOCS(buf, caddr_t, len);
+ if (buf == NULL)
+ return -1;
+ SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
- if ((iplused[dev] + len) > IPFILTER_LOGSIZE) {
+ if ((iplused[dev] + len) > ipl_logsize) {
MUTEX_EXIT(&ipl_mutex);
- return 0;
+ SPL_X(s);
+ KFREES(buf, len);
+ return -1;
}
iplused[dev] += len;
MUTEX_EXIT(&ipl_mutex);
-
- KMALLOCS(buf, caddr_t, len);
- if (!buf)
- return 0;
+ SPL_X(s);
/*
* advance the log pointer to the next empty record and deduct the
* amount of space we're going to use.
*/
ipl = (iplog_t *)buf;
- ipl->ipl_magic = IPL_MAGIC;
+ ipl->ipl_magic = ipl_magic[dev];
ipl->ipl_count = 1;
ipl->ipl_next = NULL;
ipl->ipl_dsize = len;
@@ -495,14 +492,15 @@ int *types, cnt;
* Loop through all the items to be logged, copying each one to the
* buffer. Use bcopy for normal data or the mb_t copyout routine.
*/
- for (i = 0, s = buf + sizeof(*ipl); i < cnt; i++) {
+ for (i = 0, ptr = buf + sizeof(*ipl); i < cnt; i++) {
if (types[i] == 0) {
- bcopy(items[i], s, itemsz[i]);
+ bcopy(items[i], ptr, itemsz[i]);
} else if (types[i] == 1) {
- COPYDATA(items[i], 0, itemsz[i], s);
+ COPYDATA(items[i], 0, itemsz[i], ptr);
}
- s += itemsz[i];
+ ptr += itemsz[i];
}
+ SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
ipll[dev] = ipl;
*iplh[dev] = ipl;
@@ -517,12 +515,13 @@ int *types, cnt;
MUTEX_EXIT(&ipl_mutex);
# else
MUTEX_EXIT(&ipl_mutex);
- WAKEUP(&iplh[dev]);
+ WAKEUP(iplh,dev);
# endif
+ SPL_X(s);
# ifdef IPL_SELECT
iplog_input_ready(dev);
# endif
- return 1;
+ return 0;
}
@@ -545,9 +544,7 @@ struct uio *uio;
size_t dlen, copied;
int error = 0;
iplog_t *ipl;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
/*
* Sanity checks. Make sure the minor # is valid and we're copying
@@ -558,9 +555,9 @@ struct uio *uio;
if (uio->uio_resid == 0)
return 0;
if ((uio->uio_resid < sizeof(iplog_t)) ||
- (uio->uio_resid > IPFILTER_LOGSIZE))
+ (uio->uio_resid > ipl_logsize))
return EINVAL;
-
+
/*
* Lock the log so we can snapshot the variables. Wait for a signal
* if the log is empty.
@@ -597,7 +594,7 @@ struct uio *uio;
# else
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
- error = SLEEP(&iplh[unit], "ipl sleep");
+ error = SLEEP(unit + iplh, "ipl sleep");
# endif /* __osf__ */
# endif /* __hpux */
if (error)
@@ -611,7 +608,7 @@ struct uio *uio;
uio->uio_rw = UIO_READ;
# endif
- for (copied = 0; ((ipl = iplt[unit]) != NULL); copied += dlen) {
+ for (copied = 0; (ipl = iplt[unit]) != NULL; copied += dlen) {
dlen = ipl->ipl_dsize;
if (dlen > uio->uio_resid)
break;
@@ -620,30 +617,27 @@ struct uio *uio;
*/
iplt[unit] = ipl->ipl_next;
iplused[unit] -= dlen;
- if (iplt[unit] == NULL) {
- iplh[unit] = &iplt[unit];
- ipll[unit] = NULL;
- }
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
if (error) {
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
- iplused[unit] += dlen;
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
- ipll[unit] = ipl;
- if (iplh[unit] == &iplt[unit]) {
- *iplh[unit] = ipl;
- iplh[unit] = &ipl->ipl_next;
- }
+ iplused[unit] += dlen;
break;
}
+ MUTEX_ENTER(&ipl_mutex);
KFREES((caddr_t)ipl, dlen);
SPL_NET(s);
- MUTEX_ENTER(&ipl_mutex);
}
+ if (!iplt[unit]) {
+ iplused[unit] = 0;
+ iplh[unit] = &iplt[unit];
+ ipll[unit] = NULL;
+ }
+
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
return error;
@@ -662,7 +656,9 @@ minor_t unit;
{
iplog_t *ipl;
int used;
+ SPL_INT(s);
+ SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
while ((ipl = iplt[unit]) != NULL) {
iplt[unit] = ipl->ipl_next;
@@ -674,6 +670,7 @@ minor_t unit;
iplused[unit] = 0;
bzero((char *)&iplcrc[unit], FI_CSIZE);
MUTEX_EXIT(&ipl_mutex);
+ SPL_X(s);
return used;
}
#endif /* IPFILTER_LOG */
diff --git a/usr/src/common/ipf/ip_lookup.c b/usr/src/uts/common/inet/ipf/ip_lookup.c
index dcbe0a4e8a..299dadf0bb 100644
--- a/usr/src/common/ipf/ip_lookup.c
+++ b/usr/src/uts/common/inet/ipf/ip_lookup.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -15,6 +15,9 @@
# define KERNEL 1
# define _KERNEL 1
#endif
+#if defined(__osf__)
+# define _PROTO_NET_H_
+#endif
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/types.h>
@@ -36,6 +39,13 @@ struct file;
# undef _KERNEL
#endif
#include <sys/socket.h>
+#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
+# ifdef __osf__
+# include <net/radix.h>
+# endif
+# include "radix_ipf_local.h"
+# define _RADIX_H_
+#endif
#include <net/if.h>
#if defined(__FreeBSD__)
# include <sys/cdefs.h>
@@ -49,28 +59,18 @@ struct file;
#endif
#include <netinet/in.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_pool.h"
-#include "ip_htable.h"
-#include "ip_lookup.h"
-#else
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
#include "netinet/ip_lookup.h"
-#endif
+/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.21 2003/06/28 17:01:57 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.7 2005/06/12 07:18:20 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
-# ifdef USE_MUTEXES
-ipfrwlock_t ip_poolrw;
-# endif
int ip_lookup_inited = 0;
static int iplookup_addnode __P((caddr_t));
@@ -81,8 +81,16 @@ static int iplookup_stats __P((caddr_t));
static int iplookup_flush __P((caddr_t));
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_init */
+/* Returns: int - 0 = success, else error */
+/* Parameters: Nil */
+/* */
+/* Initialise all of the subcomponents of the lookup infrstructure. */
+/* ------------------------------------------------------------------------ */
int ip_lookup_init()
{
+
if (ip_pool_init() == -1)
return -1;
@@ -94,6 +102,15 @@ int ip_lookup_init()
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_unload */
+/* Returns: int - 0 = success, else error */
+/* Parameters: Nil */
+/* */
+/* Free up all pool related memory that has been allocated whilst IPFilter */
+/* has been running. Also, do any other deinitialisation required such */
+/* ip_lookup_init() can be called again, safely. */
+/* ------------------------------------------------------------------------ */
void ip_lookup_unload()
{
ip_pool_fini();
@@ -106,19 +123,25 @@ void ip_lookup_unload()
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_ioctl */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */
+/* space. */
+/* cmd(I) - ioctl command number */
+/* mode(I) - file mode bits used with open */
+/* */
+/* Handle ioctl commands sent to the ioctl device. For the most part, this */
+/* involves just calling another function to handle the specifics of each */
+/* command. */
+/* ------------------------------------------------------------------------ */
int ip_lookup_ioctl(data, cmd, mode)
caddr_t data;
-# if defined(__NetBSD__) || defined(__OpenBSD__)
-u_long cmd;
-# else
-int cmd;
-# endif
+ioctlcmd_t cmd;
int mode;
{
int err;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
mode = mode; /* LINT */
@@ -127,12 +150,14 @@ int mode;
switch (cmd)
{
case SIOCLOOKUPADDNODE :
+ case SIOCLOOKUPADDNODEW :
WRITE_ENTER(&ip_poolrw);
err = iplookup_addnode(data);
RWLOCK_EXIT(&ip_poolrw);
break;
case SIOCLOOKUPDELNODE :
+ case SIOCLOOKUPDELNODEW :
WRITE_ENTER(&ip_poolrw);
err = iplookup_delnode(data);
RWLOCK_EXIT(&ip_poolrw);
@@ -151,6 +176,7 @@ int mode;
break;
case SIOCLOOKUPSTAT :
+ case SIOCLOOKUPSTATW :
WRITE_ENTER(&ip_poolrw);
err = iplookup_stats(data);
RWLOCK_EXIT(&ip_poolrw);
@@ -171,6 +197,15 @@ int mode;
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_addnode */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to data from ioctl call */
+/* */
+/* Add a new data node to a lookup structure. First, check to see if the */
+/* parent structure refered to by name exists and if it does, then go on to */
+/* add a node to it. */
+/* ------------------------------------------------------------------------ */
static int iplookup_addnode(data)
caddr_t data;
{
@@ -181,17 +216,13 @@ caddr_t data;
ip_pool_t *p;
int err;
- err = COPYIN(data, &op, sizeof(op));
- if (err != 0)
- return EFAULT;
+ err = 0;
+ BCOPYIN(data, &op, sizeof(op));
op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
switch (op.iplo_type)
{
case IPLT_POOL :
-# if defined(_KERNEL) && defined(__osf__)
- return ENOTSUP;
-# else
if (op.iplo_size != sizeof(node))
return EINVAL;
@@ -213,7 +244,6 @@ caddr_t data;
return EEXIST;
err = ip_pool_insert(p, &node.ipn_addr,
&node.ipn_mask, node.ipn_info);
-# endif
break;
case IPLT_HASH :
@@ -238,6 +268,14 @@ caddr_t data;
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_delnode */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to data from ioctl call */
+/* */
+/* Delete a node from a lookup table by first looking for the table it is */
+/* in and then deleting the entry that gets found. */
+/* ------------------------------------------------------------------------ */
static int iplookup_delnode(data)
caddr_t data;
{
@@ -248,17 +286,14 @@ caddr_t data;
ip_pool_t *p;
int err;
- err = COPYIN(data, &op, sizeof(op));
- if (err != 0)
- return EFAULT;
+ err = 0;
+ BCOPYIN(data, &op, sizeof(op));
+
op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
switch (op.iplo_type)
{
case IPLT_POOL :
-# if defined(_KERNEL) && defined(__osf__)
- return ENOTSUP;
-# else
if (op.iplo_size != sizeof(node))
return EINVAL;
@@ -270,17 +305,11 @@ caddr_t data;
if (!p)
return ESRCH;
- /*
- * add an entry to a pool - return an error if it already
- * exists remove an entry from a pool - if it exists
- * - in both cases, the pool *must* exist!
- */
m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask);
if (m == NULL)
return ENOENT;
err = ip_pool_remove(p, m);
break;
-# endif
case IPLT_HASH :
if (op.iplo_size != sizeof(hte))
@@ -304,33 +333,33 @@ caddr_t data;
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_addtable */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to data from ioctl call */
+/* */
+/* Create a new lookup table, if one doesn't already exist using the name */
+/* for this one. */
+/* ------------------------------------------------------------------------ */
static int iplookup_addtable(data)
caddr_t data;
{
iplookupop_t op;
int err;
- err = COPYIN(data, &op, sizeof(op));
- if (err != 0)
- return EFAULT;
+ err = 0;
+ BCOPYIN(data, &op, sizeof(op));
+
op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
- /*
- * create a new pool - fail if one already exists with
- * the same #
- */
switch (op.iplo_type)
{
case IPLT_POOL :
-# if defined(_KERNEL) && defined(__osf__)
- return ENOTSUP;
-# else
if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL)
err = EEXIST;
else
err = ip_pool_create(&op);
break;
-# endif
case IPLT_HASH :
if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL)
@@ -361,9 +390,7 @@ caddr_t data;
iplookupop_t op;
int err;
- err = COPYIN(data, &op, sizeof(op));
- if (err != 0)
- return EFAULT;
+ BCOPYIN(data, &op, sizeof(op));
op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
if (op.iplo_arg & IPLT_ANON)
@@ -376,12 +403,8 @@ caddr_t data;
switch (op.iplo_type)
{
case IPLT_POOL :
-# if defined(_KERNEL) && defined(__osf__)
- return ENOTSUP;
-# else
err = ip_pool_destroy(&op);
break;
-# endif
case IPLT_HASH :
err = fr_removehtable(&op);
@@ -409,7 +432,7 @@ caddr_t data;
int err;
err = 0;
- (void)BCOPYIN(data, &op, sizeof(op));
+ BCOPYIN(data, &op, sizeof(op));
switch (op.iplo_type)
{
@@ -440,16 +463,11 @@ caddr_t data;
static int iplookup_flush(data)
caddr_t data;
{
- iphtable_t *iph, *iphn;
- int err, unit, type, i;
- iplookupflush_t flush, opf;
- ip_pool_t *p, *q;
- iplookupop_t op;
- size_t num;
+ int err, unit, num, type;
+ iplookupflush_t flush;
- err = COPYIN(data, &flush, sizeof(flush));
- if (err != 0)
- return EFAULT;
+ err = 0;
+ BCOPYIN(data, &flush, sizeof(flush));
flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
@@ -457,69 +475,18 @@ caddr_t data;
if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL))
return EINVAL;
- /*
- * Flush all ?
- * Or flush n except where n == -1 (all pools)
- */
type = flush.iplf_type;
err = EINVAL;
num = 0;
if (type == IPLT_POOL || type == IPLT_ALL) {
-# if defined(_KERNEL) && defined(__osf__)
- err = ENOTSUP;
-# else
err = 0;
- if (flush.iplf_arg != IPLT_ALL) {
- op.iplo_unit = unit;
- (void)strncpy(op.iplo_name, flush.iplf_name,
- sizeof(op.iplo_name));
- err = ip_pool_destroy(&op);
- if (err == 0)
- num++;
- } else {
- for (i = 0; i <= IPL_LOGMAX; i++) {
- if (unit != IPLT_ALL && i != unit)
- continue;
- for (q = ip_pool_list[i]; (p = q) != NULL; ) {
- op.iplo_unit = i;
- (void)strncpy(op.iplo_name, p->ipo_name,
- sizeof(op.iplo_name));
- q = p->ipo_next;
- err = ip_pool_destroy(&op);
- if (err == 0)
- num++;
- else
- break;
- }
- }
- }
-# endif
+ num = ip_pool_flush(&flush);
}
if (type == IPLT_HASH || type == IPLT_ALL) {
err = 0;
- if (flush.iplf_arg != IPLT_ALL) {
- opf.iplf_unit = unit;
- (void)strncpy(opf.iplf_name, flush.iplf_name,
- sizeof(opf.iplf_name));
- num += fr_flushhtable(&opf);
- }
- else {
- for (i = 0; i <= IPL_LOGMAX; i++) {
- if (unit != IPLT_ALL && i != unit)
- continue;
- for (iphn = ipf_htables[i];
- (iph = iphn) != NULL; ) {
- opf.iplf_unit = i;
- (void)strncpy(opf.iplf_name,
- iph->iph_name,
- sizeof(opf.iplf_name));
- iphn = iph->iph_next;
- num += fr_flushhtable(&opf);
- }
- }
- }
+ num += fr_flushhtable(&flush);
}
if (err == 0) {
@@ -543,6 +510,7 @@ void *ptr;
case IPLT_POOL :
ip_pool_deref(ptr);
break;
+
case IPLT_HASH :
fr_derefhtable(ptr);
break;
@@ -556,11 +524,7 @@ void *ptr;
/*ARGSUSED*/
int ip_lookup_ioctl(data, cmd, mode)
caddr_t data;
-# if defined(__NetBSD__) || defined(__OpenBSD__)
-u_long cmd;
-# else
-int cmd;
-# endif
+ioctlcmd_t cmd;
int mode;
{
return EIO;
diff --git a/usr/src/common/ipf/ip_nat.c b/usr/src/uts/common/inet/ipf/ip_nat.c
index 2df59b40a2..8814553e20 100644
--- a/usr/src/common/ipf/ip_nat.c
+++ b/usr/src/uts/common/inet/ipf/ip_nat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1995-2004 by Darren Reed.
+ * Copyright (C) 1995-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
@@ -41,8 +41,12 @@ struct file;
#else
# include <sys/ioctl.h>
#endif
-#include <sys/fcntl.h>
-#include <sys/protosw.h>
+#if !defined(AIX)
+# include <sys/fcntl.h>
+#endif
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#if defined(_KERNEL)
# include <sys/systm.h>
@@ -77,52 +81,39 @@ struct file;
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#ifdef __sgi
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-#include <sys/hashing.h>
-#include <netinet/in_var.h>
-# endif
-#endif
-
#ifdef RFC1825
# include <vpn/md5.h>
# include <vpn/ipsec.h>
extern struct ifnet vpnif;
#endif
-#include <netinet/ip_var.h>
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
-
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#else
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
-#endif
#ifdef IPFILTER_SYNC
#include "netinet/ip_sync.h"
#endif
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
+/* END OF INCLUDES */
+
#undef SOCKADDR_IN
#define SOCKADDR_IN struct sockaddr_in
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.162 2003/07/01 18:30:20 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.42 2005/08/11 19:51:36 darrenr Exp $";
#endif
@@ -151,6 +142,7 @@ static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.162 2003/07/01 18:30:20 darre
nat_t **nat_table[2] = { NULL, NULL },
*nat_instances = NULL;
ipnat_t *nat_list = NULL;
+u_int ipf_nattable_max = NAT_TABLE_MAX;
u_int ipf_nattable_sz = NAT_TABLE_SZ;
u_int ipf_natrules_sz = NAT_SIZE;
u_int ipf_rdrrules_sz = RDR_SIZE;
@@ -174,13 +166,14 @@ int nat_logging = 0;
#endif
u_long fr_defnatage = DEF_NAT_AGE,
+ fr_defnatipage = 120, /* 60 seconds */
fr_defnaticmpage = 6; /* 3 seconds */
natstat_t nat_stats;
int fr_nat_lock = 0;
int fr_nat_init = 0;
-extern ipfmutex_t ipf_rw, ipf_natio, ipf_nat_new;
-extern ipfrwlock_t ipf_nat;
+#if SOLARIS
extern int pfil_delayed_copy;
+#endif
static int nat_flushtable __P((void));
static int nat_clearlist __P((void));
@@ -202,10 +195,9 @@ static void nat_hostmapdel __P((struct hostmap *));
static INLINE int nat_icmpquerytype4 __P((int));
static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int));
static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int));
-static INLINE int nat_icmperrortype4 __P((int));
static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
tcphdr_t *, nat_t **, int));
-static INLINE void nat_resolverule __P((ipnat_t *));
+static void nat_resolverule __P((ipnat_t *));
static nat_t *fr_natclone __P((fr_info_t *, nat_t *));
static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
static INLINE int nat_wildok __P((nat_t *, int, int, int, int));
@@ -232,37 +224,38 @@ int fr_natinit()
if (nat_table[1] != NULL)
bzero((char *)nat_table[1], ipf_nattable_sz * sizeof(nat_t *));
else
- return -1;
+ return -2;
KMALLOCS(nat_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_natrules_sz);
if (nat_rules != NULL)
bzero((char *)nat_rules, ipf_natrules_sz * sizeof(ipnat_t *));
else
- return -1;
+ return -3;
KMALLOCS(rdr_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_rdrrules_sz);
if (rdr_rules != NULL)
bzero((char *)rdr_rules, ipf_rdrrules_sz * sizeof(ipnat_t *));
else
- return -1;
+ return -4;
KMALLOCS(maptable, hostmap_t **, sizeof(hostmap_t *) * ipf_hostmap_sz);
if (maptable != NULL)
bzero((char *)maptable, sizeof(hostmap_t *) * ipf_hostmap_sz);
else
- return -1;
+ return -5;
KMALLOCS(nat_stats.ns_bucketlen[0], u_long *,
ipf_nattable_sz * sizeof(u_long));
if (nat_stats.ns_bucketlen[0] == NULL)
- return -1;
+ return -6;
bzero((char *)nat_stats.ns_bucketlen[0],
ipf_nattable_sz * sizeof(u_long));
KMALLOCS(nat_stats.ns_bucketlen[1], u_long *,
ipf_nattable_sz * sizeof(u_long));
if (nat_stats.ns_bucketlen[1] == NULL)
- return -1;
+ return -7;
+
bzero((char *)nat_stats.ns_bucketlen[1],
ipf_nattable_sz * sizeof(u_long));
@@ -280,16 +273,19 @@ int fr_natinit()
nat_tqb[IPF_TCPS_CLOSED].ifq_ttl = fr_tcplastack;
nat_tqb[IPF_TCP_NSTATES - 1].ifq_next = &nat_udptq;
nat_udptq.ifq_ttl = fr_defnatage;
+ nat_udptq.ifq_ref = 1;
nat_udptq.ifq_head = NULL;
nat_udptq.ifq_tail = &nat_udptq.ifq_head;
MUTEX_INIT(&nat_udptq.ifq_lock, "nat ipftq udp tab");
nat_udptq.ifq_next = &nat_icmptq;
nat_icmptq.ifq_ttl = fr_defnaticmpage;
+ nat_icmptq.ifq_ref = 1;
nat_icmptq.ifq_head = NULL;
nat_icmptq.ifq_tail = &nat_icmptq.ifq_head;
MUTEX_INIT(&nat_icmptq.ifq_lock, "nat icmp ipftq tab");
nat_icmptq.ifq_next = &nat_iptq;
- nat_iptq.ifq_ttl = fr_defnaticmpage;
+ nat_iptq.ifq_ttl = fr_defnatipage;
+ nat_iptq.ifq_ref = 1;
nat_iptq.ifq_head = NULL;
nat_iptq.ifq_tail = &nat_iptq.ifq_head;
MUTEX_INIT(&nat_iptq.ifq_lock, "nat ip ipftq tab");
@@ -349,6 +345,7 @@ ipnat_t *n;
np = &(*np)->in_rnext;
n->in_rnext = NULL;
n->in_prnext = np;
+ n->in_hv = hv;
*np = n;
}
@@ -380,6 +377,7 @@ ipnat_t *n;
np = &(*np)->in_mnext;
n->in_mnext = NULL;
n->in_pmnext = np;
+ n->in_hv = hv;
*np = n;
}
@@ -428,7 +426,7 @@ ipnat_t *n;
/* */
/* Check if an ip address has already been allocated for a given mapping */
/* that is not doing port based translation. If is not yet allocated, then */
-/* create a new entry. */
+/* create a new entry if a non-NULL NAT rule pointer has been supplied. */
/* ------------------------------------------------------------------------ */
static struct hostmap *nat_hostmap(np, src, dst, map, port)
ipnat_t *np;
@@ -618,11 +616,7 @@ u_32_t n;
/* Processes an ioctl call made to operate on the IP Filter NAT device. */
/* ------------------------------------------------------------------------ */
int fr_nat_ioctl(data, cmd, mode)
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
caddr_t data;
int mode;
{
@@ -642,13 +636,13 @@ int mode;
#endif
nat = NULL; /* XXX gcc -Wuninitialized */
- if (cmd == (int)SIOCADNAT) {
+ if (cmd == (ioctlcmd_t)SIOCADNAT) {
KMALLOC(nt, ipnat_t *);
} else {
nt = NULL;
}
- if ((cmd == (int)SIOCADNAT) || (cmd == (int)SIOCRMNAT)) {
+ if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) {
if (mode & NAT_SYSSPACE) {
bcopy(data, (char *)&natd, sizeof(natd));
error = 0;
@@ -656,8 +650,8 @@ int mode;
error = fr_inobj(data, &natd, IPFOBJ_IPNAT);
}
- } else if (cmd == (int)SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
- (void) BCOPYIN(data, &arg, sizeof(arg));
+ } else if (cmd == (ioctlcmd_t)SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
+ BCOPYIN(data, &arg, sizeof(arg));
}
if (error != 0)
@@ -666,8 +660,10 @@ int mode;
/*
* For add/delete, look to see if the NAT entry is already present
*/
- if ((cmd == (int)SIOCADNAT) || (cmd == (int)SIOCRMNAT)) {
+ if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) {
nat = &natd;
+ if (nat->in_v == 0) /* For backward compat. */
+ nat->in_v = 4;
nat->in_flags &= IPN_USERFLAGS;
if ((nat->in_redir & NAT_MAPBLK) == 0) {
if ((nat->in_flags & IPN_SPLIT) == 0)
@@ -693,7 +689,7 @@ int mode;
error = EPERM;
else {
tmp = ipflog_clear(IPL_LOGNAT);
- (void) BCOPYOUT((char *)&tmp, (char *)data, sizeof(tmp));
+ BCOPYOUT((char *)&tmp, (char *)data, sizeof(tmp));
}
break;
}
@@ -701,17 +697,17 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else {
- (void) BCOPYIN((char *)data, (char *)&nat_logging,
+ BCOPYIN((char *)data, (char *)&nat_logging,
sizeof(nat_logging));
}
break;
case SIOCGETLG :
- (void) BCOPYOUT((char *)&nat_logging, (char *)data,
- sizeof(nat_logging));
+ BCOPYOUT((char *)&nat_logging, (char *)data,
+ sizeof(nat_logging));
break;
case FIONREAD :
arg = iplused[IPL_LOGNAT];
- (void) BCOPYOUT(&arg, data, sizeof(arg));
+ BCOPYOUT(&arg, data, sizeof(arg));
break;
#endif
case SIOCADNAT :
@@ -755,6 +751,7 @@ int mode;
nat_stats.ns_list = nat_list;
nat_stats.ns_maptable = maptable;
nat_stats.ns_nattab_sz = ipf_nattable_sz;
+ nat_stats.ns_nattab_max = ipf_nattable_max;
nat_stats.ns_rultab_sz = ipf_natrules_sz;
nat_stats.ns_rdrtab_sz = ipf_rdrrules_sz;
nat_stats.ns_hostmap_sz = ipf_hostmap_sz;
@@ -771,10 +768,11 @@ int mode;
}
error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP);
if (error == 0) {
- if (nat_lookupredir(&nl)) {
+ if (nat_lookupredir(&nl) != NULL) {
error = fr_outobj(data, &nl, IPFOBJ_NATLOOKUP);
- } else
+ } else {
error = ESRCH;
+ }
}
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
@@ -797,23 +795,24 @@ int mode;
else
error = EINVAL;
if (getlock) {
- MUTEX_DOWNGRADE(&ipf_nat);
+ RWLOCK_EXIT(&ipf_nat);
}
if (error == 0) {
- (void) BCOPYOUT(&ret, data, sizeof(ret));
- }
- if (getlock) {
- RWLOCK_EXIT(&ipf_nat);
+ BCOPYOUT(&ret, data, sizeof(ret));
}
break;
case SIOCPROXY :
error = appr_ioctl(data, cmd, mode);
break;
case SIOCSTLCK :
- error = fr_lock(data, &fr_nat_lock);
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ } else {
+ fr_lock(data, &fr_nat_lock);
+ }
break;
case SIOCSTPUT :
- if ((mode & FWRITE) != 0) {
+ if (fr_nat_lock && (mode & FWRITE)) {
error = fr_natputent(data, getlock);
} else {
error = EACCES;
@@ -878,6 +877,9 @@ int getlock;
return ENOENT;
}
+ if ((n->in_age[0] == 0) && (n->in_age[1] != 0))
+ return EINVAL;
+
n->in_use = 0;
if (n->in_redir & NAT_MAPBLK)
n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk);
@@ -887,8 +889,11 @@ int getlock;
n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip);
else if (n->in_flags & IPN_SPLIT)
n->in_space = 2;
- else
+ else if (n->in_outmsk != 0)
n->in_space = ~ntohl(n->in_outmsk);
+ else
+ n->in_space = 1;
+
/*
* Calculate the number of valid IP addresses in the output
* mapping range. In all cases, the range is inclusive of
@@ -905,6 +910,7 @@ int getlock;
n->in_space -= 1;
} else
n->in_space = 1;
+
if ((n->in_outmsk != 0xffffffff) && (n->in_outmsk != 0) &&
((n->in_flags & (IPN_IPRANGE|IPN_SPLIT)) == 0))
n->in_nip = ntohl(n->in_outip) + 1;
@@ -949,6 +955,7 @@ int getlock;
n->in_space = 0xffffffff;
}
}
+
/* Otherwise, these fields are preset */
if (getlock) {
@@ -973,7 +980,9 @@ int getlock;
}
n = NULL;
nat_stats.ns_rules++;
+#if SOLARIS
pfil_delayed_copy = 0;
+#endif
if (getlock) {
RWLOCK_EXIT(&ipf_nat); /* WRITE */
}
@@ -991,31 +1000,18 @@ int getlock;
/* from information passed to the kernel, then add it to the appropriate */
/* NAT rule table(s). */
/* ------------------------------------------------------------------------ */
-static INLINE void nat_resolverule(n)
+static void nat_resolverule(n)
ipnat_t *n;
{
- if (!strncmp(n->in_ifnames[0], "*", LIFNAMSIZ)) {
- n->in_ifps[0] = NULL;
- } else if (!strncmp(n->in_ifnames[0], "-", LIFNAMSIZ)) {
- n->in_ifps[0] = (void *)-1;
- } else {
- n->in_ifps[0] = (void *)GETIFP(n->in_ifnames[0], 4);
- if (n->in_ifps[0] == NULL)
- n->in_ifps[0] = (void *)-1;
- }
+ n->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
+ n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4);
+
+ n->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
if (n->in_ifnames[1][0] == '\0') {
(void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ);
n->in_ifps[1] = n->in_ifps[0];
} else {
- if (!strncmp(n->in_ifnames[1], "*", LIFNAMSIZ)) {
- n->in_ifps[1] = NULL;
- } else if (!strncmp(n->in_ifnames[1], "-", LIFNAMSIZ)) {
- n->in_ifps[1] = (void *)-1;
- } else {
- n->in_ifps[1] = (void *)GETIFP(n->in_ifnames[1], 4);
- if (n->in_ifps[1] == NULL)
- n->in_ifps[1] = (void *)-1;
- }
+ n->in_ifps[1] = fr_resolvenic(n->in_ifnames[0], 4);
}
if (n->in_plabel[0] != '\0') {
@@ -1052,11 +1048,17 @@ int getlock;
rdr_masks = 0;
}
- if (n->in_tqehead[0] != NULL)
- fr_deletetimeoutqueue(n->in_tqehead[0]);
+ if (n->in_tqehead[0] != NULL) {
+ if (fr_deletetimeoutqueue(n->in_tqehead[0]) == 0) {
+ fr_freetimeoutqueue(n->in_tqehead[1]);
+ }
+ }
- if (n->in_tqehead[1] != NULL)
- fr_deletetimeoutqueue(n->in_tqehead[1]);
+ if (n->in_tqehead[1] != NULL) {
+ if (fr_deletetimeoutqueue(n->in_tqehead[1]) == 0) {
+ fr_freetimeoutqueue(n->in_tqehead[1]);
+ }
+ }
*np = n->in_next;
@@ -1065,8 +1067,10 @@ int getlock;
appr_free(n->in_apr);
KFREE(n);
nat_stats.ns_rules--;
+#if SOLARIS
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
+#endif
} else {
n->in_flags |= IPN_DELETE;
n->in_next = NULL;
@@ -1095,7 +1099,7 @@ caddr_t data;
nat_t *nat, *n;
natget_t ng;
- (void) BCOPYIN(data, &ng, sizeof(ng));
+ BCOPYIN(data, &ng, sizeof(ng));
nat = ng.ng_ptr;
if (!nat) {
@@ -1105,7 +1109,7 @@ caddr_t data;
* Empty list so the size returned is 0. Simple.
*/
if (nat == NULL) {
- (void) BCOPYOUT(&ng, data, sizeof(ng));
+ BCOPYOUT(&ng, data, sizeof(ng));
return 0;
}
} else {
@@ -1126,14 +1130,13 @@ caddr_t data;
*/
ng.ng_sz = sizeof(nat_save_t);
aps = nat->nat_aps;
- if ((aps != NULL) && (aps->aps_data != 0)) {
- ng.ng_sz += sizeof(ap_session_t);
- ng.ng_sz += aps->aps_psiz;
- if (ng.ng_sz > 4)
- ng.ng_sz -= 4; /* XXX - sizeof(ipn_data) */
+ if (aps != NULL) {
+ ng.ng_sz += sizeof(ap_session_t) - 4;
+ if (aps->aps_data != 0)
+ ng.ng_sz += aps->aps_psiz;
}
- (void) BCOPYOUT(&ng, data, sizeof(ng));
+ BCOPYOUT(&ng, data, sizeof(ng));
return 0;
}
@@ -1151,22 +1154,30 @@ caddr_t data;
static int fr_natgetent(data)
caddr_t data;
{
+ int error, outsize;
ap_session_t *aps;
- nat_save_t ipn;
+ nat_save_t *ipn, ipns;
nat_t *n, *nat;
- int error;
- error = fr_inobj(data, &ipn, IPFOBJ_NATSAVE);
+ error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE);
if (error != 0)
return error;
- nat = ipn.ipn_next;
+ if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920))
+ return EINVAL;
+
+ KMALLOCS(ipn, nat_save_t *, ipns.ipn_dsize);
+ if (ipn == NULL)
+ return ENOMEM;
+
+ ipn->ipn_dsize = ipns.ipn_dsize;
+ nat = ipns.ipn_next;
if (nat == NULL) {
nat = nat_instances;
if (nat == NULL) {
if (nat_instances == NULL)
- return ENOENT;
- return 0;
+ error = ENOENT;
+ goto finished;
}
} else {
/*
@@ -1177,43 +1188,32 @@ caddr_t data;
for (n = nat_instances; n; n = n->nat_next)
if (n == nat)
break;
- if (n == NULL)
- return ESRCH;
+ if (n == NULL) {
+ error = ESRCH;
+ goto finished;
+ }
}
+ ipn->ipn_next = nat->nat_next;
/*
- * Copy out the NAT structure.
+ * Copy the NAT structure.
*/
- error = copyoutptr((char *)nat,
- (char *)data + offsetof(struct nat_save, ipn_nat),
- sizeof(struct nat));
- if (error != 0)
- return error;
+ bcopy((char *)nat, &ipn->ipn_nat, sizeof(*nat));
/*
* If we have a pointer to the NAT rule it belongs to, save that too.
*/
- if (nat->nat_ptr != NULL) {
- error = copyoutptr((char *)nat->nat_ptr,
- (char *)data +
- offsetof(struct nat_save, ipn_ipnat),
- sizeof(struct ipnat));
- if (error != 0)
- return error;
- }
+ if (nat->nat_ptr != NULL)
+ bcopy((char *)nat->nat_ptr, (char *)&ipn->ipn_ipnat,
+ sizeof(ipn->ipn_ipnat));
/*
* If we also know the NAT entry has an associated filter rule,
* save that too.
*/
- if (nat->nat_fr != NULL) {
- error = copyoutptr((char *)nat->nat_fr,
- (char *)data +
- offsetof(struct nat_save, ipn_rule),
- sizeof(struct frentry));
- if (error != 0)
- return error;
- }
+ if (nat->nat_fr != NULL)
+ bcopy((char *)nat->nat_fr, (char *)&ipn->ipn_fr,
+ sizeof(ipn->ipn_fr));
/*
* Last but not least, if there is an application proxy session set
@@ -1221,31 +1221,31 @@ caddr_t data;
* private data saved along side it by the proxy.
*/
aps = nat->nat_aps;
+ outsize = ipn->ipn_dsize - sizeof(*ipn) + sizeof(ipn->ipn_data);
if (aps != NULL) {
- ipn.ipn_dsize = sizeof(*aps);
- if (aps->aps_data)
- ipn.ipn_dsize += aps->aps_psiz;
- error = copyoutptr((char *)&ipn.ipn_dsize,
- (char *)data +
- offsetof(struct nat_save, ipn_dsize),
- sizeof(ipn.ipn_dsize));
- if (error != 0)
- return error;
-
- error = copyoutptr((char *)aps, (char *)data +
- offsetof(struct nat_save, ipn_data),
- sizeof(*aps));
- if (error != 0)
- return error;
-
- if (aps->aps_psiz > 0) {
- error = copyoutptr((char *)aps->aps_data,
- (char *)data + sizeof(*aps) +
- offsetof(struct nat_save, ipn_data),
- aps->aps_psiz);
- if (error != 0)
- return error;
+ char *s;
+
+ if (outsize < sizeof(*aps)) {
+ error = ENOBUFS;
+ goto finished;
}
+
+ s = ipn->ipn_data;
+ bcopy((char *)aps, s, sizeof(*aps));
+ s += sizeof(*aps);
+ outsize -= sizeof(*aps);
+ if ((aps->aps_data != NULL) && (outsize >= aps->aps_psiz))
+ bcopy(aps->aps_data, s, aps->aps_psiz);
+ else
+ error = ENOBUFS;
+ }
+ if (error == 0) {
+ error = fr_outobjsz(data, ipn, IPFOBJ_NATSAVE, ipns.ipn_dsize);
+ }
+
+finished:
+ if (ipn != NULL) {
+ KFREES(ipn, ipns.ipn_dsize);
}
return error;
}
@@ -1254,8 +1254,10 @@ caddr_t data;
/* ------------------------------------------------------------------------ */
/* Function: fr_natputent */
/* Returns: int - 0 == success, != 0 is the error value. */
-/* Parameters: data(I) - pointer to natget structure with NAT structure */
-/* information to load into the kernel. */
+/* Parameters: data(I) - pointer to natget structure with NAT */
+/* structure information to load into the kernel */
+/* getlock(I) - flag indicating whether or not a write lock */
+/* on ipf_nat is already held. */
/* */
/* Handle SIOCSTPUT. */
/* Loads a NAT table entry from user space, including a NAT rule, proxy and */
@@ -1277,22 +1279,36 @@ int getlock;
if (error != 0)
return error;
+ /*
+ * Initialise early because of code at junkput label.
+ */
+ in = NULL;
+ aps = NULL;
nat = NULL;
- if (ipn.ipn_dsize != 0) {
- KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize -
- sizeof(ipn.ipn_data));
+ ipnn = NULL;
+
+ /*
+ * New entry, copy in the rest of the NAT entry if it's size is more
+ * than just the nat_t structure.
+ */
+ fr = NULL;
+ if (ipn.ipn_dsize > sizeof(ipn)) {
+ if (ipn.ipn_dsize > 81920) {
+ error = ENOMEM;
+ goto junkput;
+ }
+
+ KMALLOCS(ipnn, nat_save_t *, ipn.ipn_dsize);
if (ipnn == NULL)
return ENOMEM;
- /* XXX should use fr_inobj */
- error = copyinptr(data, ipnn, sizeof(ipn) + ipn.ipn_dsize -
- sizeof(ipn.ipn_data));
+ error = fr_inobjsz(data, ipnn, IPFOBJ_NATSAVE, ipn.ipn_dsize);
if (error != 0) {
error = EFAULT;
goto junkput;
}
} else
- ipnn = NULL;
+ ipnn = &ipn;
KMALLOC(nat, nat_t *);
if (nat == NULL) {
@@ -1300,40 +1316,33 @@ int getlock;
goto junkput;
}
- bcopy((char *)&ipn.ipn_nat, (char *)nat, sizeof(*nat));
+ bcopy((char *)&ipnn->ipn_nat, (char *)nat, sizeof(*nat));
/*
* Initialize all these so that nat_delete() doesn't cause a crash.
*/
- MUTEX_NUKE(&nat->nat_lock);
- nat->nat_phnext[0] = NULL;
- nat->nat_phnext[1] = NULL;
- fr = nat->nat_fr;
- nat->nat_fr = NULL;
- aps = nat->nat_aps;
- nat->nat_aps = NULL;
- in = nat->nat_ptr;
- nat->nat_ptr = NULL;
- nat->nat_hm = NULL;
- nat->nat_data = NULL;
+ bzero((char *)nat, offsetof(struct nat, nat_tqe));
+ nat->nat_tqe.tqe_pnext = NULL;
+ nat->nat_tqe.tqe_next = NULL;
+ nat->nat_tqe.tqe_ifq = NULL;
+ nat->nat_tqe.tqe_parent = nat;
/*
* Restore the rule associated with this nat session
*/
+ in = ipnn->ipn_nat.nat_ptr;
if (in != NULL) {
KMALLOC(in, ipnat_t *);
+ nat->nat_ptr = in;
if (in == NULL) {
error = ENOMEM;
goto junkput;
}
- nat->nat_ptr = in;
- bcopy((char *)&ipn.ipn_ipnat, (char *)in, sizeof(*in));
+ bzero((char *)in, offsetof(struct ipnat, in_next6));
+ bcopy((char *)&ipnn->ipn_ipnat, (char *)in, sizeof(*in));
in->in_use = 1;
in->in_flags |= IPN_DELETE;
- in->in_next = NULL;
- in->in_rnext = NULL;
- in->in_prnext = NULL;
- in->in_mnext = NULL;
- in->in_pmnext = NULL;
+
+ ATOMIC_INC(nat_stats.ns_rules);
nat_resolverule(in);
}
@@ -1346,7 +1355,7 @@ int getlock;
if (nat->nat_dir == NAT_OUTBOUND) {
fin.fin_data[0] = ntohs(nat->nat_oport);
fin.fin_data[1] = ntohs(nat->nat_outport);
- fin.fin_ifp = nat->nat_ifps[0];
+ fin.fin_ifp = nat->nat_ifps[1];
if (getlock) {
READ_ENTER(&ipf_nat);
}
@@ -1362,12 +1371,12 @@ int getlock;
} else if (nat->nat_dir == NAT_INBOUND) {
fin.fin_data[0] = ntohs(nat->nat_inport);
fin.fin_data[1] = ntohs(nat->nat_oport);
- fin.fin_ifp = nat->nat_ifps[1];
+ fin.fin_ifp = nat->nat_ifps[0];
if (getlock) {
READ_ENTER(&ipf_nat);
}
n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p,
- nat->nat_inip, nat->nat_oip);
+ nat->nat_outip, nat->nat_oip);
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
@@ -1384,19 +1393,24 @@ int getlock;
* Restore ap_session_t structure. Include the private data allocated
* if it was there.
*/
+ aps = nat->nat_aps;
if (aps != NULL) {
KMALLOC(aps, ap_session_t *);
+ nat->nat_aps = aps;
if (aps == NULL) {
error = ENOMEM;
goto junkput;
}
- nat->nat_aps = aps;
- aps->aps_next = ap_sess_list;
- ap_sess_list = aps;
bcopy(ipnn->ipn_data, (char *)aps, sizeof(*aps));
- if (in)
+ if (in != NULL)
aps->aps_apr = in->in_apr;
+ else
+ aps->aps_apr = NULL;
if (aps->aps_psiz != 0) {
+ if (aps->aps_psiz > 81920) {
+ error = ENOMEM;
+ goto junkput;
+ }
KMALLOCS(aps->aps_data, void *, aps->aps_psiz);
if (aps->aps_data == NULL) {
error = ENOMEM;
@@ -1414,34 +1428,34 @@ int getlock;
* If there was a filtering rule associated with this entry then
* build up a new one.
*/
+ fr = nat->nat_fr;
if (fr != NULL) {
- if (nat->nat_flags & SI_NEWFR) {
+ if ((nat->nat_flags & SI_NEWFR) != 0) {
KMALLOC(fr, frentry_t *);
nat->nat_fr = fr;
if (fr == NULL) {
error = ENOMEM;
goto junkput;
}
- bcopy((char *)&ipn.ipn_fr, (char *)fr, sizeof(*fr));
+ ipnn->ipn_nat.nat_fr = fr;
+ fr->fr_ref = 1;
+ (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE);
+ bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr));
MUTEX_NUKE(&fr->fr_lock);
MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
- ipn.ipn_nat.nat_fr = fr;
- (void) fr_outobj(&ipn, data, IPFOBJ_NATSAVE);
} else {
- if (getlock) {
- READ_ENTER(&ipf_nat);
- }
+ READ_ENTER(&ipf_nat);
for (n = nat_instances; n; n = n->nat_next)
if (n->nat_fr == fr)
break;
+
if (n != NULL) {
MUTEX_ENTER(&fr->fr_lock);
fr->fr_ref++;
MUTEX_EXIT(&fr->fr_lock);
}
- if (getlock) {
- RWLOCK_EXIT(&ipf_nat);
- }
+ RWLOCK_EXIT(&ipf_nat);
+
if (!n) {
error = ESRCH;
goto junkput;
@@ -1449,24 +1463,34 @@ int getlock;
}
}
+ if (ipnn != &ipn) {
+ KFREES(ipnn, ipn.ipn_dsize);
+ ipnn = NULL;
+ }
+
if (getlock) {
WRITE_ENTER(&ipf_nat);
}
- error = nat_insert(nat);
+ error = nat_insert(nat, nat->nat_rev);
+ if ((error == 0) && (aps != NULL)) {
+ aps->aps_next = ap_sess_list;
+ ap_sess_list = aps;
+ }
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
- if (error == 0) {
- if (ipnn != NULL) {
- KFREES(ipnn, sizeof (ipn) + ipn.ipn_dsize);
- }
- return (0);
- }
+
+ if (error == 0)
+ return 0;
+
error = ENOMEM;
junkput:
- if (ipnn != NULL) {
- KFREES(ipnn, sizeof (ipn) + ipn.ipn_dsize);
+ if (fr != NULL)
+ (void) fr_derefrule(&fr);
+
+ if ((ipnn != NULL) && (ipnn != &ipn)) {
+ KFREES(ipnn, ipn.ipn_dsize);
}
if (nat != NULL) {
if (aps != NULL) {
@@ -1482,7 +1506,7 @@ junkput:
}
KFREE(nat);
}
- return (error);
+ return error;
}
@@ -1500,9 +1524,7 @@ static void nat_delete(nat, logtype)
struct nat *nat;
int logtype;
{
- ipftqent_t *tqe;
struct ipnat *ipn;
- ipftq_t *ifq;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
@@ -1547,18 +1569,7 @@ int logtype;
nat->nat_me = NULL;
}
- tqe = &nat->nat_tqe;
- ifq = tqe->tqe_ifq;
- if (ifq != NULL) {
- *tqe->tqe_pnext = tqe->tqe_next;
- if (tqe->tqe_next)
- tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
- else
- ifq->ifq_tail = tqe->tqe_pnext;
- tqe->tqe_ifq = NULL;
- if ((ifq->ifq_flags & IFQF_USER) != 0)
- fr_deletetimeoutqueue(ifq);
- }
+ fr_deletequeueentry(&nat->nat_tqe);
nat->nat_ref--;
if (nat->nat_ref > 0) {
@@ -1591,8 +1602,10 @@ int logtype;
appr_free(ipn->in_apr);
KFREE(ipn);
nat_stats.ns_rules--;
+#if SOLARIS
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
+#endif
}
}
@@ -1682,7 +1695,9 @@ static int nat_clearlist()
}
i++;
}
+#if SOLARIS
pfil_delayed_copy = 1;
+#endif
nat_masks = 0;
rdr_masks = 0;
return i;
@@ -1699,6 +1714,8 @@ static int nat_clearlist()
/* */
/* Given an empty NAT structure, populate it with new information about a */
/* new NAT session, as defined by the matching NAT rule. */
+/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/
+/* to the new IP address for the translation. */
/* ------------------------------------------------------------------------ */
static INLINE int nat_newmap(fin, nat, ni)
fr_info_t *fin;
@@ -1910,9 +1927,9 @@ natinfo_t *ni;
nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst,
nat->nat_outip, 0);
- /*
+ /*
* The ICMP checksum does not have a pseudo header containing
- * the IP addresses
+ * the IP addresses
*/
ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr));
ni->nai_sum2 = LONG_SUM(in.s_addr);
@@ -1921,15 +1938,18 @@ natinfo_t *ni;
ni->nai_sum2 += ntohs(port);
}
- if (flags & IPN_TCPUDPICMP) {
+ if (flags & IPN_TCPUDP) {
nat->nat_inport = sport;
nat->nat_outport = port; /* sport */
nat->nat_oport = dport;
((tcphdr_t *)fin->fin_dp)->th_sport = port;
- } if (flags & IPN_ICMPQUERY) {
+ } else if (flags & IPN_ICMPQUERY) {
((icmphdr_t *)fin->fin_dp)->icmp_id = port;
+ nat->nat_inport = port;
+ nat->nat_outport = port;
}
- ni->nai_ip.s_addr = htonl(in.s_addr);
+
+ ni->nai_ip.s_addr = in.s_addr;
ni->nai_port = port;
ni->nai_nport = dport;
return 0;
@@ -1945,6 +1965,8 @@ natinfo_t *ni;
/* ni(I) - pointer to structure with misc. information needed */
/* to create new NAT entry. */
/* */
+/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/
+/* to the new IP address for the translation. */
/* ------------------------------------------------------------------------ */
static INLINE int nat_newrdr(fin, nat, ni)
fr_info_t *fin;
@@ -1960,7 +1982,7 @@ natinfo_t *ni;
move = 1;
hm = NULL;
- in = ni->nai_ip;
+ in.s_addr = 0;
np = ni->nai_np;
flags = ni->nai_flags;
sport = ni->nai_sport;
@@ -1978,7 +2000,7 @@ natinfo_t *ni;
hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in,
(u_32_t)dport);
if (hm != NULL) {
- ni->nai_ip.s_addr = hm->hm_mapip.s_addr;
+ in.s_addr = ntohl(hm->hm_mapip.s_addr);
np = hm->hm_ipnat;
ni->nai_np = np;
move = 0;
@@ -2031,8 +2053,9 @@ natinfo_t *ni;
/*
* map the address block in a 1:1 fashion
*/
- in.s_addr |= ntohl(fin->fin_daddr & ~np->in_inmsk);
-
+ in.s_addr = np->in_inip;
+ in.s_addr |= fin->fin_daddr & ~np->in_inmsk;
+ in.s_addr = ntohl(in.s_addr);
} else {
in.s_addr = ntohl(np->in_inip);
}
@@ -2044,7 +2067,8 @@ natinfo_t *ni;
* Whilst not optimized for the case where
* pmin == pmax, the gain is not significant.
*/
- if (np->in_pmin != np->in_pmax) {
+ if (((np->in_flags & IPN_FIXEDDPORT) == 0) &&
+ (np->in_pmin != np->in_pmax)) {
nport = ntohs(dport) - ntohs(np->in_pmin) +
ntohs(np->in_pnext);
nport = htons(nport);
@@ -2070,7 +2094,7 @@ natinfo_t *ni;
ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport);
ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport);
- ni->nai_ip.s_addr = htonl(in.s_addr);
+ ni->nai_ip.s_addr = in.s_addr;
ni->nai_nport = nport;
ni->nai_port = sport;
@@ -2081,6 +2105,8 @@ natinfo_t *ni;
((tcphdr_t *)fin->fin_dp)->th_dport = nport;
} else if (flags & IPN_ICMPQUERY) {
((icmphdr_t *)fin->fin_dp)->icmp_id = nport;
+ nat->nat_inport = nport;
+ nat->nat_outport = nport;
}
return move;
@@ -2122,9 +2148,14 @@ int direction;
u_32_t sumd;
int move;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC)
- qif_t *qf = fin->fin_qif;
+ qpktinfo_t *qpi = fin->fin_qpi;
#endif
+ if (nat_stats.ns_inuse >= ipf_nattable_max) {
+ nat_stats.ns_memfail++;
+ return NULL;
+ }
+
move = 1;
nflags = np->in_flags & flags;
nflags &= NAT_FROMRULE;
@@ -2137,6 +2168,17 @@ int direction;
KMALLOC(nat, nat_t *);
if (nat == NULL) {
nat_stats.ns_memfail++;
+ /*
+ * Try to automatically tune the max # of entries in the
+ * table allowed to be less than what will cause kmem_alloc()
+ * to fail and try to eliminate panics due to out of memory
+ * conditions arising.
+ */
+ if (ipf_nattable_max > ipf_nattable_sz) {
+ ipf_nattable_max = nat_stats.ns_inuse - 100;
+ printf("ipf_nattable_max reduced to %d\n",
+ ipf_nattable_max);
+ }
return NULL;
}
@@ -2147,15 +2189,15 @@ int direction;
} else if (flags & IPN_ICMPQUERY) {
/*
* In the ICMP query NAT code, we translate the ICMP id fields
- * to make them unique. This is indepedent of the ICMP type
- * (e.g. in the unlikely event that a host sends an echo and
- * an tstamp request with the same id, both packets will have
+ * to make them unique. This is indepedent of the ICMP type
+ * (e.g. in the unlikely event that a host sends an echo and
+ * an tstamp request with the same id, both packets will have
* their ip address/id field changed in the same way).
*/
/* The icmp_id field is used by the sender to identify the
- * process making the icmp request. (the receiver justs
- * copies it back in its response). So, it closely matches
- * the concept of source port. We overlay sport, so we can
+ * process making the icmp request. (the receiver justs
+ * copies it back in its response). So, it closely matches
+ * the concept of source port. We overlay sport, so we can
* maximally reuse the existing code.
*/
ni.nai_sport = ((icmphdr_t *)fin->fin_dp)->icmp_id;
@@ -2165,7 +2207,9 @@ int direction;
bzero((char *)nat, sizeof(*nat));
nat->nat_flags = flags;
- MUTEX_ENTER(&ipf_nat_new);
+ if ((flags & NAT_SLAVE) == 0) {
+ MUTEX_ENTER(&ipf_nat_new);
+ }
/*
* Search the current table for a match.
@@ -2179,34 +2223,30 @@ int direction;
natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
- MUTEX_EXIT(&ipf_nat_new);
- return natl;
+ nat = natl;
+ goto done;
}
move = nat_newmap(fin, nat, &ni);
- if (move == -1) {
- MUTEX_EXIT(&ipf_nat_new);
+ if (move == -1)
goto badnat;
- }
np = ni.nai_np;
in = ni.nai_ip;
} else {
- /*
+ /*
* NAT_INBOUND is used only for redirects rules
*/
natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
- MUTEX_EXIT(&ipf_nat_new);
- return natl;
+ nat = natl;
+ goto done;
}
move = nat_newrdr(fin, nat, &ni);
- if (move == -1) {
- MUTEX_EXIT(&ipf_nat_new);
+ if (move == -1)
goto badnat;
- }
np = ni.nai_np;
in = ni.nai_ip;
@@ -2235,14 +2275,14 @@ int direction;
CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd);
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC)
- if ((flags & IPN_TCPUDP) && dohwcksum &&
+ if ((flags & IPN_TCP) && dohwcksum &&
#ifndef IRE_ILL_CN
- (((ill_t *)qf->qf_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
-#else
- (((s_ill_t *)qf->qf_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
+ (((ill_t *)qpi->qpi_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
+#else
+ (((s_ill_t *)qpi->qpi_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
#endif /* IRE_ILL_CN */
if (direction == NAT_OUTBOUND)
- ni.nai_sum1 = LONG_SUM(ntohl(in.s_addr));
+ ni.nai_sum1 = LONG_SUM(in.s_addr);
else
ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr));
ni.nai_sum1 += LONG_SUM(ntohl(fin->fin_daddr));
@@ -2259,7 +2299,7 @@ int direction;
else
ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr));
- ni.nai_sum2 = LONG_SUM(ntohl(in.s_addr));
+ ni.nai_sum2 = LONG_SUM(in.s_addr);
CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd);
nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
@@ -2272,22 +2312,22 @@ int direction;
}
if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) {
- if ((hm = nat->nat_hm) != NULL)
- nat_hostmapdel(hm);
- MUTEX_EXIT(&ipf_nat_new);
- KFREE(nat);
- return NULL;
+ goto badnat;
}
if (flags & SI_WILDP)
nat_stats.ns_wilds++;
- MUTEX_EXIT(&ipf_nat_new);
- return nat;
+ goto done;
badnat:
nat_stats.ns_badnat++;
if ((hm = nat->nat_hm) != NULL)
nat_hostmapdel(hm);
KFREE(nat);
- return NULL;
+ nat = NULL;
+done:
+ if ((flags & NAT_SLAVE) == 0) {
+ MUTEX_EXIT(&ipf_nat_new);
+ }
+ return nat;
}
@@ -2317,12 +2357,7 @@ int direction;
np = ni->nai_np;
- if (np->in_ifps[0] != NULL) {
- (void) COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]);
- }
- if (np->in_ifps[1] != NULL) {
- (void) COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]);
- }
+ COPYIFNAME(fin->fin_ifp, nat->nat_ifnames[0]);
#ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0)
nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat);
@@ -2330,8 +2365,7 @@ int direction;
nat->nat_me = natsave;
nat->nat_dir = direction;
- nat->nat_ifps[0] = np->in_ifps[0];
- nat->nat_ifps[1] = np->in_ifps[1];
+ nat->nat_ifps[0] = fin->fin_ifp;
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
@@ -2342,9 +2376,9 @@ int direction;
if (appr_new(fin, nat) == -1)
return -1;
- if (nat_logging)
- nat_log(nat, (u_int)np->in_redir);
- if (nat_insert(nat) == 0) {
+ if (nat_insert(nat, fin->fin_rev) == 0) {
+ if (nat_logging)
+ nat_log(nat, (u_int)np->in_redir);
np->in_use++;
if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
@@ -2362,20 +2396,20 @@ int direction;
/* ------------------------------------------------------------------------ */
-/* Function: nat_insert */
-/* Returns: int - 0 == sucess, -1 == failure */
-/* Parameters: nat(I) - pointer to NAT structure */
-/* Write Lock: ipf_nat */
+/* Function: nat_insert */
+/* Returns: int - 0 == sucess, -1 == failure */
+/* Parameters: nat(I) - pointer to NAT structure */
+/* rev(I) - flag indicating forward/reverse direction of packet */
+/* Write Lock: ipf_nat */
/* */
/* Insert a NAT entry into the hash tables for searching and add it to the */
/* list of active NAT entries. Adjust global counters when complete. */
/* ------------------------------------------------------------------------ */
-int nat_insert(nat)
+int nat_insert(nat, rev)
nat_t *nat;
+int rev;
{
- ipftqent_t *tqe;
u_int hv1, hv2;
- ipftq_t *ifq;
nat_t **natp;
/*
@@ -2399,49 +2433,32 @@ nat_t *nat;
}
if (nat_stats.ns_bucketlen[0][hv1] >= fr_nat_maxbucket ||
- nat_stats.ns_bucketlen[1][hv2] >= fr_nat_maxbucket)
+ nat_stats.ns_bucketlen[1][hv2] >= fr_nat_maxbucket) {
return -1;
+ }
nat->nat_hv[0] = hv1;
nat->nat_hv[1] = hv2;
MUTEX_INIT(&nat->nat_lock, "nat entry lock");
+ nat->nat_rev = rev;
nat->nat_ref = 1;
nat->nat_bytes[0] = 0;
nat->nat_pkts[0] = 0;
nat->nat_bytes[1] = 0;
nat->nat_pkts[1] = 0;
- if (nat->nat_ptr != NULL)
- ifq = nat->nat_ptr->in_tqehead[0];
- else
- ifq = NULL;
- if (ifq == NULL) {
- if (nat->nat_p == IPPROTO_UDP)
- ifq = &nat_udptq;
- else if (nat->nat_p == IPPROTO_ICMP)
- ifq = &nat_icmptq;
- else if (nat->nat_p == IPPROTO_TCP)
- ifq = nat_tqb;
- else
- ifq = &nat_iptq;
- }
- tqe = &nat->nat_tqe;
- tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
- tqe->tqe_ifq = ifq;
- tqe->tqe_parent = nat;
- tqe->tqe_next = NULL;
-
- nat->nat_ifnames[0][sizeof(nat->nat_ifnames[0]) - 1] = '\0';
- if (nat->nat_ifnames[0][0] != '\0') {
- nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0], 4);
- }
- nat->nat_ifnames[1][sizeof(nat->nat_ifnames[1]) - 1] = '\0';
- if (nat->nat_ifnames[1][0] != '\0') {
- nat->nat_ifps[1] = GETIFP(nat->nat_ifnames[1], 4);
+
+ nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0';
+ nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4);
+
+ if (nat->nat_ifnames[1][0] !='\0') {
+ nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
+ nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4);
} else {
(void) strncpy(nat->nat_ifnames[1], nat->nat_ifnames[0],
- sizeof(nat->nat_ifnames[1]));
+ LIFNAMSIZ);
+ nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[1] = nat->nat_ifps[0];
}
@@ -2467,11 +2484,7 @@ nat_t *nat;
*natp = nat;
nat_stats.ns_bucketlen[1][hv2]++;
- MUTEX_ENTER(&ifq->ifq_lock);
- tqe->tqe_pnext = ifq->ifq_tail;
- *ifq->ifq_tail = tqe;
- ifq->ifq_tail = &tqe->tqe_next;
- MUTEX_EXIT(&ifq->ifq_lock);
+ fr_setnatqueue(nat, rev);
nat_stats.ns_added++;
nat_stats.ns_inuse++;
@@ -2486,44 +2499,36 @@ nat_t *nat;
/* dir(I) - direction of packet (in/out) */
/* */
/* Check if the ICMP error message is related to an existing TCP, UDP or */
-/* ICMP query nat entry. */
+/* ICMP query nat entry. It is assumed that the packet is already of the */
+/* the required length. */
/* ------------------------------------------------------------------------ */
nat_t *nat_icmperrorlookup(fin, dir)
fr_info_t *fin;
int dir;
{
- int flags = 0, type, minlen;
- icmphdr_t *icmp, *orgicmp;
+ int flags = 0, minlen;
+ icmphdr_t *orgicmp;
tcphdr_t *tcp = NULL;
+ u_short data[2];
+ nat_t *nat;
ip_t *oip;
u_int p;
- icmp = fin->fin_dp;
/*
* Does it at least have the return (basic) IP header ?
* Only a basic IP header (no options) should be with an ICMP error
- * header.
- */
- if (fin->fin_hlen != sizeof(ip_t) ||
- (fin->fin_plen < ICMPERR_MINPKTLEN))
- return NULL;
-
- type = icmp->icmp_type;
-
- /*
- * If it's not an error type, then return.
+ * header. Also, if it's not an error type, then return.
*/
- if (!nat_icmperrortype4(type))
+ if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR))
return NULL;
/*
- * Check packet size
+ * Check packet size
*/
oip = (ip_t *)((char *)fin->fin_dp + 8);
minlen = IP_HL(oip) << 2;
- if (minlen < sizeof(ip_t))
- return NULL;
- if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen)
+ if ((minlen < sizeof(ip_t)) ||
+ (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen))
return NULL;
/*
* Is the buffer big enough for all of it ? It's the size of the IP
@@ -2542,13 +2547,17 @@ int dir;
# if defined(MENTAT)
if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr)
return NULL;
-# else
+# else
if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN >
(char *)fin->fin_ip + M_LEN(m))
- return NULL;
-# endif
- }
+ return NULL;
+# endif
+ }
#endif
+
+ if (fin->fin_daddr != oip->ip_src.s_addr)
+ return NULL;
+
p = oip->ip_p;
if (p == IPPROTO_TCP)
flags = IPN_TCP;
@@ -2559,25 +2568,30 @@ int dir;
/* see if this is related to an ICMP query */
if (nat_icmpquerytype4(orgicmp->icmp_type)) {
- flags = IPN_ICMPQUERY;
+ data[0] = fin->fin_data[0];
+ data[1] = fin->fin_data[1];
+ fin->fin_data[0] = 0;
+ fin->fin_data[1] = orgicmp->icmp_id;
+
+ flags = IPN_ICMPERR|IPN_ICMPQUERY;
/*
* NOTE : dir refers to the direction of the original
* ip packet. By definition the icmp error
* message flows in the opposite direction.
*/
if (dir == NAT_INBOUND)
- return nat_inlookup(fin, flags, p, oip->ip_dst,
- oip->ip_src);
+ nat = nat_inlookup(fin, flags, p, oip->ip_dst,
+ oip->ip_src);
else
- return nat_outlookup(fin, flags, p, oip->ip_dst,
- oip->ip_src);
+ nat = nat_outlookup(fin, flags, p, oip->ip_dst,
+ oip->ip_src);
+ fin->fin_data[0] = data[0];
+ fin->fin_data[1] = data[1];
+ return nat;
}
}
if (flags & IPN_TCPUDP) {
- u_short data[2];
- nat_t *nat;
-
minlen += 8; /* + 64bits of data to get ports */
if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen)
return NULL;
@@ -2628,12 +2642,13 @@ int dir;
struct in_addr in;
icmphdr_t *icmp;
int flags, dlen;
- udphdr_t *udp;
+ u_short *csump;
tcphdr_t *tcp;
nat_t *nat;
ip_t *oip;
+ void *dp;
- if ((fin->fin_flx & (FI_SHORT|FI_FRAGTAIL)))
+ if ((fin->fin_flx & (FI_SHORT|FI_FRAGBODY)))
return NULL;
/*
* nat_icmperrorlookup() will return NULL for `defective' packets.
@@ -2641,20 +2656,28 @@ int dir;
if ((fin->fin_v != 4) || !(nat = nat_icmperrorlookup(fin, dir)))
return NULL;
+ tcp = NULL;
+ csump = NULL;
flags = 0;
sumd2 = 0;
*nflags = IPN_ICMPERR;
icmp = fin->fin_dp;
oip = (ip_t *)&icmp->icmp_ip;
- if (oip->ip_p == IPPROTO_TCP)
+ dp = (((char *)oip) + (IP_HL(oip) << 2));
+ if (oip->ip_p == IPPROTO_TCP) {
+ tcp = (tcphdr_t *)dp;
+ csump = (u_short *)&tcp->th_sum;
flags = IPN_TCP;
- else if (oip->ip_p == IPPROTO_UDP)
+ } else if (oip->ip_p == IPPROTO_UDP) {
+ udphdr_t *udp;
+
+ udp = (udphdr_t *)dp;
+ tcp = (tcphdr_t *)dp;
+ csump = (u_short *)&udp->uh_sum;
flags = IPN_UDP;
- else if (oip->ip_p == IPPROTO_ICMP)
+ } else if (oip->ip_p == IPPROTO_ICMP)
flags = IPN_ICMPQUERY;
- udp = (udphdr_t *)((((char *)oip) + (IP_HL(oip) << 2)));
- tcp = (tcphdr_t *)udp;
- dlen = fin->fin_plen - ((char *)udp - (char *)fin->fin_ip);
+ dlen = fin->fin_plen - ((char *)dp - (char *)fin->fin_ip);
/*
* Need to adjust ICMP header to include the real IP#'s and
@@ -2693,140 +2716,78 @@ int dir;
CALC_SUMD(sum1, sum2, sumd);
- if (nat->nat_dir == NAT_OUTBOUND) {
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
- /* Fix icmp cksum : IP Addr + Cksum */
- sumd2 = (sumd << 1);
+ /*
+ * Fix IP checksum of the offending IP packet to adjust for
+ * the change in the IP address.
+ *
+ * Normally, you would expect that the ICMP checksum of the
+ * ICMP error message needs to be adjusted as well for the
+ * IP address change in oip.
+ * However, this is a NOP, because the ICMP checksum is
+ * calculated over the complete ICMP packet, which includes the
+ * changed oip IP addresses and oip->ip_sum. However, these
+ * two changes cancel each other out (if the delta for
+ * the IP address is x, then the delta for ip_sum is minus x),
+ * so no change in the icmp_cksum is necessary.
+ *
+ * Be careful that nat_dir refers to the direction of the
+ * offending IP packet (oip), not to its ICMP response (icmp)
+ */
+ fix_datacksum(&oip->ip_sum, sumd);
+ /* Fix icmp cksum : IP Addr + Cksum */
+ sumd2 = (sumd >> 16);
+ /*
+ * Fix UDP pseudo header checksum to compensate for the
+ * IP address change.
+ */
+ if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && (*csump != 0)) {
/*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
+ * The UDP checksum is optional, only adjust it
+ * if it has been set.
*/
- if ((oip->ip_p == IPPROTO_UDP) && (udp->uh_sum != 0)) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set.
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
/*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
+ * Fix ICMP checksum to compensate the UDP
+ * checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
+ sumd2 = sumd << 1;
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ }
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
+ /*
+ * Fix TCP pseudo header checksum to compensate for the
+ * IP address change. Before we can do the change, we
+ * must make sure that oip is sufficient large to hold
+ * the TCP checksum (normally it does not!).
+ * 18 = offsetof(tcphdr_t, th_sum) + 2
+ */
+ else if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
- /*
- * Fix ICMP checksum to compensate the TCP checksum
- * adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
- } else {
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
- /* Fix icmp cksum : IP Addr + Cksum */
- sumd2 = (sumd << 1);
-
-/* XXX FV : without having looked at Solaris source code, it seems unlikely
- * that SOLARIS would compensate this in the kernel (a body of an IP packet
- * in the data section of an ICMP packet). I have the feeling that this should
- * be unconditional, but I'm not in a position to check.
- */
-#if !SOLARIS && !defined(__sgi)
/*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
- */
- if ((oip->ip_p == IPPROTO_UDP) && (udp->uh_sum != 0)) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
-
- /*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
+ * Fix ICMP checksum to compensate the TCP
+ * checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
-
- /*
- * Fix ICMP checksum to compensate the TCP checksum
- * adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
-#endif
+ sumd2 = sumd << 1;
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ } else {
+ if (nat->nat_dir == NAT_OUTBOUND)
+ sumd2 = ~sumd2;
+ else
+ sumd2 = ~sumd2 + 1;
}
- if ((flags & IPN_TCPUDP) != 0) {
+ if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) {
+ int mode = 0;
+
/*
* Step 2 :
* For offending TCP/UDP IP packets, translate the ports as
@@ -2842,58 +2803,67 @@ int dir;
*
* To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not
- * available. OSses like Solaris return enough bytes to
+ * available. Some OSses like Solaris return enough bytes to
* include the TCP checksum. So we have to check if the
* ip->ip_len actually holds the TCP checksum of the oip!
*/
- if (nat->nat_oport == tcp->th_dport) {
+ if (nat->nat_oport == tcp->th_dport) {
if (tcp->th_sport != nat->nat_inport) {
- /*
- * Fix ICMP checksum to compensate port
- * adjustment.
- */
- sum1 = ntohs(tcp->th_sport);
- sum2 = ntohs(nat->nat_inport);
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- tcp->th_sport = nat->nat_inport;
+ mode = 1;
+ sum1 = ntohs(nat->nat_inport);
+ sum2 = ntohs(tcp->th_sport);
+ }
+ } else if (tcp->th_sport == nat->nat_oport) {
+ mode = 2;
+ sum1 = ntohs(nat->nat_outport);
+ sum2 = ntohs(tcp->th_dport);
+ }
- /*
- * Fix udp checksum to compensate port
- * adjustment. NOTE : the offending IP packet
- * flows the other direction compared to the
- * ICMP message.
- *
- * The UDP checksum is optional, only adjust
- * it if it has been set.
- */
- if ((oip->ip_p == IPPROTO_UDP) &&
- (udp->uh_sum != 0)) {
+ if (mode == 1) {
+ /*
+ * Fix ICMP checksum to compensate port adjustment.
+ */
+ tcp->th_sport = htons(sum1);
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
+ /*
+ * Fix udp checksum to compensate port adjustment.
+ * NOTE : the offending IP packet flows the other
+ * direction compared to the ICMP message.
+ *
+ * The UDP checksum is optional, only adjust it if
+ * it has been set.
+ */
+ if ((oip->ip_p == IPPROTO_UDP) &&
+ (dlen >= 8) && (*csump != 0)) {
+ sumd = sum1 - sum2;
+ sumd2 += sumd;
- /*
- * Fix ICMP checksum to compenstate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
/*
- * Fix TCP checksum (if present) to compensate
- * port adjustment. NOTE : the offending IP
- * packet flows the other direction compared to
- * the ICMP message.
+ * Fix ICMP checksum to compenstate
+ * UDP checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ }
+
+ /*
+ * Fix TCP checksum (if present) to compensate port
+ * adjustment. NOTE : the offending IP packet flows
+ * the other direction compared to the ICMP message.
+ */
+ if (oip->ip_p == IPPROTO_TCP) {
+ if (dlen >= 18) {
+ sumd = sum1 - sum2;
+ sumd2 += sumd;
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
@@ -2901,57 +2871,55 @@ int dir;
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
+ } else {
+ sumd = sum2 - sum1 + 1;
+ sumd2 += sumd;
}
}
- } else {
- if (tcp->th_dport != nat->nat_outport) {
- udphdr_t *udp = (udphdr_t *)tcp;
+ } else if (mode == 2) {
+ /*
+ * Fix ICMP checksum to compensate port adjustment.
+ */
+ tcp->th_dport = htons(sum1);
- /*
- * Fix ICMP checksum to compensate port
- * adjustment.
- */
- sum1 = ntohs(tcp->th_dport);
- sum2 = ntohs(nat->nat_outport);
- CALC_SUMD(sum1, sum2, sumd);
+ /*
+ * Fix UDP checksum to compensate port adjustment.
+ * NOTE : the offending IP packet flows the other
+ * direction compared to the ICMP message.
+ *
+ * The UDP checksum is optional, only adjust
+ * it if it has been set.
+ */
+ if ((oip->ip_p == IPPROTO_UDP) &&
+ (dlen >= 8) && (*csump != 0)) {
+ sumd = sum1 - sum2;
sumd2 += sumd;
- tcp->th_dport = nat->nat_outport;
-
- /*
- * Fix UDP checksum to compensate port
- * adjustment. NOTE : the offending IP
- * packet flows the other direction compared
- * to the ICMP message.
- *
- * The UDP checksum is optional, only adjust
- * it if it has been set.
- */
- if ((oip->ip_p == IPPROTO_UDP) &&
- (udp->uh_sum != 0)) {
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd2;
- }
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
/*
- * Fix TCP checksum (if present) to compensate
- * port adjustment. NOTE : the offending IP
- * packet flows the other direction compared to
- * the ICMP message.
+ * Fix ICMP checksum to compensate
+ * UDP checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ }
+
+ /*
+ * Fix TCP checksum (if present) to compensate port
+ * adjustment. NOTE : the offending IP packet flows
+ * the other direction compared to the ICMP message.
+ */
+ if (oip->ip_p == IPPROTO_TCP) {
+ if (dlen >= 18) {
+ sumd = sum1 - sum2;
+ sumd2 += sumd;
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
+ sum1 = ntohs(*csump);
+ fix_datacksum(csump, sumd);
+ sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
@@ -2959,31 +2927,33 @@ int dir;
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
+ } else {
+ if (nat->nat_dir == NAT_INBOUND)
+ sumd = sum2 - sum1;
+ else
+ sumd = sum2 - sum1 + 1;
+ sumd2 += sumd;
}
}
}
if (sumd2 != 0) {
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- if (nat->nat_dir == NAT_OUTBOUND) {
- fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
- } else {
- fix_incksum(fin, &icmp->icmp_cksum, sumd2);
- }
+ fix_incksum(fin, &icmp->icmp_cksum, sumd2);
}
- } else if ((flags & IPN_ICMPQUERY) != 0) {
+ } else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) {
icmphdr_t *orgicmp;
/*
* XXX - what if this is bogus hl and we go off the end ?
* In this case, nat_icmperrorlookup() will have returned NULL.
*/
- orgicmp = (icmphdr_t *)udp;
+ orgicmp = (icmphdr_t *)dp;
if (nat->nat_dir == NAT_OUTBOUND) {
if (orgicmp->icmp_id != nat->nat_inport) {
- /*
+ /*
* Fix ICMP checksum (of the offening ICMP
* query packet) to compensate the change
* in the ICMP id of the offending ICMP
@@ -2993,7 +2963,7 @@ int dir;
* a delta (say x) and you compensate that
* in origicmp->icmp_cksum with a delta
* minus x, you don't have to adjust the
- * overall icmp->icmp_cksum
+ * overall icmp->icmp_cksum
*/
sum1 = ntohs(orgicmp->icmp_id);
sum2 = ntohs(nat->nat_inport);
@@ -3040,7 +3010,6 @@ u_int flags, p;
struct in_addr src , mapdst;
{
u_short sport, dport;
- grehdr_t *gre;
ipnat_t *ipn;
u_int sflags;
nat_t *nat;
@@ -3053,17 +3022,29 @@ struct in_addr src , mapdst;
ifp = fin->fin_ifp;
else
ifp = NULL;
+ sport = 0;
+ dport = 0;
dst = mapdst.s_addr;
sflags = flags & NAT_TCPUDPICMP;
- if ((flags & IPN_TCPUDP) != 0) {
+
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
sport = htons(fin->fin_data[0]);
dport = htons(fin->fin_data[1]);
- gre = NULL;
- } else {
- gre = (p == IPPROTO_GRE) ? fin->fin_dp : NULL;
- sport = 0;
- dport = 0;
+ break;
+ case IPPROTO_ICMP :
+ if (flags & IPN_ICMPERR)
+ sport = fin->fin_data[1];
+ else
+ dport = fin->fin_data[1];
+ break;
+ default :
+ break;
}
+
+
if ((flags & SI_WILDP) != 0)
goto find_in_wild_ports;
@@ -3071,24 +3052,40 @@ struct in_addr src , mapdst;
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
- if (nat->nat_ifps[0] != NULL) {
- if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
- continue;
- } else if (ifp != NULL)
- nat->nat_ifps[0] = ifp;
-
nflags = nat->nat_flags;
+ if (ifp != NULL) {
+ if (nat->nat_dir == NAT_REDIRECT) {
+ if (ifp != nat->nat_ifps[0])
+ continue;
+ } else {
+ if (ifp != nat->nat_ifps[1])
+ continue;
+ }
+ }
+
if (nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst &&
- (((p == 0) && (sflags == (nat->nat_flags & IPN_TCPUDPICMP)))
+ (((p == 0) &&
+ (sflags == (nat->nat_flags & IPN_TCPUDPICMP)))
|| (p == nat->nat_p))) {
switch (p)
{
+#if 0
case IPPROTO_GRE :
- if (gre->gr_call != nat->nat_gre.gs_call)
+ if (nat->nat_call[1] != fin->fin_data[0])
continue;
break;
+#endif
+ case IPPROTO_ICMP :
+ if ((flags & IPN_ICMPERR) != 0) {
+ if (nat->nat_outport != sport)
+ continue;
+ } else {
+ if (nat->nat_outport != dport)
+ continue;
+ }
+ break;
case IPPROTO_TCP :
case IPPROTO_UDP :
if (nat->nat_oport != sport)
@@ -3130,11 +3127,15 @@ find_in_wild_ports:
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
- if (nat->nat_ifps[0] != NULL) {
- if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
- continue;
- } else if (ifp != NULL)
- nat->nat_ifps[0] = ifp;
+ if (ifp != NULL) {
+ if (nat->nat_dir == NAT_REDIRECT) {
+ if (ifp != nat->nat_ifps[0])
+ continue;
+ } else {
+ if (ifp != nat->nat_ifps[1])
+ continue;
+ }
+ }
if (nat->nat_p != fin->fin_p)
continue;
@@ -3270,25 +3271,30 @@ struct in_addr src , dst;
int nflags;
void *ifp;
u_int hv;
- frentry_t *fr;
-
- fr = fin->fin_fr;
-
- if ((fr != NULL) && !(fr->fr_flags & FR_DUP) &&
- fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1)
- ifp = fr->fr_tif.fd_ifp;
- else
- ifp = fin->fin_ifp;
+ ifp = fin->fin_ifp;
srcip = src.s_addr;
sflags = flags & IPN_TCPUDPICMP;
- if ((flags & IPN_TCPUDP) != 0) {
- sport = ntohs(fin->fin_data[0]);
- dport = ntohs(fin->fin_data[1]);
- } else {
- sport = 0;
- dport = 0;
+ sport = 0;
+ dport = 0;
+
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ sport = htons(fin->fin_data[0]);
+ dport = htons(fin->fin_data[1]);
+ break;
+ case IPPROTO_ICMP :
+ if (flags & IPN_ICMPERR)
+ sport = fin->fin_data[1];
+ else
+ dport = fin->fin_data[1];
+ break;
+ default :
+ break;
}
+
if ((flags & SI_WILDP) != 0)
goto find_out_wild_ports;
@@ -3296,22 +3302,30 @@ struct in_addr src , dst;
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
- if (nat->nat_ifps[1] != NULL) {
- if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
- continue;
- } else if (ifp != NULL)
- nat->nat_ifps[1] = ifp;
-
nflags = nat->nat_flags;
+ if (ifp != NULL) {
+ if (nat->nat_dir == NAT_REDIRECT) {
+ if (ifp != nat->nat_ifps[1])
+ continue;
+ } else {
+ if (ifp != nat->nat_ifps[0])
+ continue;
+ }
+ }
+
if (nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
(((p == 0) && (sflags == (nflags & NAT_TCPUDPICMP)))
|| (p == nat->nat_p))) {
switch (p)
{
+#if 0
case IPPROTO_GRE :
+ if (nat->nat_call[1] != fin->fin_data[0])
+ continue;
break;
+#endif
case IPPROTO_TCP :
case IPPROTO_UDP :
if (nat->nat_oport != dport)
@@ -3353,11 +3367,15 @@ find_out_wild_ports:
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
- if (nat->nat_ifps[1] != NULL) {
- if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
- continue;
- } else if (ifp != NULL)
- nat->nat_ifps[1] = ifp;
+ if (ifp != NULL) {
+ if (nat->nat_dir == NAT_REDIRECT) {
+ if (ifp != nat->nat_ifps[1])
+ continue;
+ } else {
+ if (ifp != nat->nat_ifps[0])
+ continue;
+ }
+ }
if (nat->nat_p != fin->fin_p)
continue;
@@ -3414,8 +3432,13 @@ natlookup_t *np;
nat_t *nat;
bzero((char *)&fi, sizeof(fi));
- fi.fin_data[0] = ntohs(np->nl_inport);
- fi.fin_data[1] = ntohs(np->nl_outport);
+ if (np->nl_flags & IPN_IN) {
+ fi.fin_data[0] = ntohs(np->nl_realport);
+ fi.fin_data[1] = ntohs(np->nl_outport);
+ } else {
+ fi.fin_data[0] = ntohs(np->nl_inport);
+ fi.fin_data[1] = ntohs(np->nl_outport);
+ }
if (np->nl_flags & IPN_TCP)
fi.fin_p = IPPROTO_TCP;
else if (np->nl_flags & IPN_UDP)
@@ -3424,28 +3447,41 @@ natlookup_t *np;
fi.fin_p = IPPROTO_ICMP;
/*
- * If nl_inip is non null, this is a lookup based on the real
- * ip address. Else, we use the fake.
+ * We can do two sorts of lookups:
+ * - IPN_IN: we have the `real' and `out' address, look for `in'.
+ * - default: we have the `in' and `out' address, look for `real'.
*/
- if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p,
- np->nl_inip, np->nl_outip))) {
-
- if ((np->nl_flags & IPN_FINDFORWARD) != 0) {
- fr_info_t fin;
- bzero((char *)&fin, sizeof(fin));
- fin.fin_p = nat->nat_p;
- fin.fin_data[0] = ntohs(nat->nat_outport);
- fin.fin_data[1] = ntohs(nat->nat_oport);
- if (nat_inlookup(&fin, np->nl_flags, fin.fin_p,
- nat->nat_outip,
- nat->nat_oip) != NULL) {
- np->nl_flags &= ~IPN_FINDFORWARD;
- }
+ if (np->nl_flags & IPN_IN) {
+ if ((nat = nat_inlookup(&fi, np->nl_flags, fi.fin_p,
+ np->nl_realip, np->nl_outip))) {
+ np->nl_inip = nat->nat_inip;
+ np->nl_inport = nat->nat_inport;
}
+ } else {
+ /*
+ * If nl_inip is non null, this is a lookup based on the real
+ * ip address. Else, we use the fake.
+ */
+ if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p,
+ np->nl_inip, np->nl_outip))) {
+
+ if ((np->nl_flags & IPN_FINDFORWARD) != 0) {
+ fr_info_t fin;
+ bzero((char *)&fin, sizeof(fin));
+ fin.fin_p = nat->nat_p;
+ fin.fin_data[0] = ntohs(nat->nat_outport);
+ fin.fin_data[1] = ntohs(nat->nat_oport);
+ if (nat_inlookup(&fin, np->nl_flags, fin.fin_p,
+ nat->nat_outip,
+ nat->nat_oip) != NULL) {
+ np->nl_flags &= ~IPN_FINDFORWARD;
+ }
+ }
- np->nl_realip = nat->nat_outip;
- np->nl_realport = nat->nat_outport;
- }
+ np->nl_realip = nat->nat_outip;
+ np->nl_realport = nat->nat_outport;
+ }
+ }
return nat;
}
@@ -3494,7 +3530,7 @@ ipnat_t *np;
ft = &np->in_tuc;
if (!(fin->fin_flx & FI_TCPUDP) ||
- (fin->fin_flx & (FI_SHORT|FI_FRAGTAIL))) {
+ (fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) {
if (ft->ftu_scmp || ft->ftu_dcmp)
return 0;
return 1;
@@ -3572,20 +3608,21 @@ int fr_checknatout(fin, passp)
fr_info_t *fin;
u_32_t *passp;
{
+ struct ifnet *ifp, *sifp;
icmphdr_t *icmp = NULL;
tcphdr_t *tcp = NULL;
+ int rval, natfailed;
ipnat_t *np = NULL;
- struct ifnet *ifp, *sifp;
u_int nflags = 0;
u_32_t ipa, iph;
int natadd = 1;
frentry_t *fr;
nat_t *nat;
- int rval;
- if (nat_list == NULL || fr_nat_lock != 0)
+ if (nat_stats.ns_rules == 0 || fr_nat_lock != 0)
return 0;
+ natfailed = 0;
fr = fin->fin_fr;
sifp = fin->fin_ifp;
if ((fr != NULL) && !(fr->fr_flags & FR_DUP) &&
@@ -3648,7 +3685,11 @@ maskloop:
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
for (np = nat_rules[hv]; np; np = np->in_mnext)
{
- if ((np->in_ifps[1] && (np->in_ifps[1] != ifp)))
+ if ((np->in_ifps[0] && (np->in_ifps[0] != ifp)))
+ continue;
+ if (np->in_v != fin->fin_v)
+ continue;
+ if (np->in_p && (np->in_p != fin->fin_p))
continue;
if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags))
continue;
@@ -3674,7 +3715,8 @@ maskloop:
NAT_OUTBOUND))) {
np->in_hits++;
break;
- }
+ } else
+ natfailed = -1;
}
if ((np == NULL) && (nmsk != 0)) {
while (nmsk) {
@@ -3700,7 +3742,7 @@ maskloop:
fin->fin_nat = nat;
}
} else
- rval = 0;
+ rval = natfailed;
RWLOCK_EXIT(&ipf_nat);
if (rval == -1) {
@@ -3751,32 +3793,39 @@ u_32_t nflags;
/*
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
+ * This is only done for STREAMS based IP implementations where the
+ * checksum has already been calculated by IP. In all other cases,
+ * IPFilter is called before the checksum needs calculating so there
+ * is no call to modify whatever is in the header now.
*/
- if (nflags == IPN_ICMPERR) {
- u_32_t s1, s2, sumd;
-
- s1 = LONG_SUM(ntohl(fin->fin_saddr));
- s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
- CALC_SUMD(s1, s2, sumd);
-
- if (fin->fin_v == 4) {
+ if (fin->fin_v == 4) {
+ if (nflags == IPN_ICMPERR) {
+ u_32_t s1, s2, sumd;
+
+ s1 = LONG_SUM(ntohl(fin->fin_saddr));
+ s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
+ CALC_SUMD(s1, s2, sumd);
+ fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd);
+ }
+#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \
+ defined(linux) || defined(BRIDGE_IPF)
+ else {
+ /*
+ * Strictly speaking, this isn't necessary on BSD
+ * kernels because they do checksum calculation after
+ * this code has run BUT if ipfilter is being used
+ * to do NAT as a bridge, that code doesn't exist.
+ */
if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd);
+ fix_outcksum(fin, &fin->fin_ip->ip_sum,
+ nat->nat_ipsumd);
else
- fix_incksum(fin, &fin->fin_ip->ip_sum, sumd);
+ fix_incksum(fin, &fin->fin_ip->ip_sum,
+ nat->nat_ipsumd);
}
- }
-#if !defined(_KERNEL) || (defined(MENTAT) || defined(__sgi))
- else if (fin->fin_v == 4) {
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(fin, &fin->fin_ip->ip_sum,
- nat->nat_ipsumd);
- else
- fix_incksum(fin, &fin->fin_ip->ip_sum,
- nat->nat_ipsumd);
- }
#endif
- fin->fin_ip->ip_src = nat->nat_outip;
+ }
+
if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) {
if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
tcp = fin->fin_dp;
@@ -3793,8 +3842,13 @@ u_32_t nflags;
csump = nat_proto(fin, nat, nflags);
}
+ fin->fin_ip->ip_src = nat->nat_outip;
+
nat_update(fin, nat, np);
+ /*
+ * The above comments do not hold for layer 4 (or higher) checksums...
+ */
if (csump != NULL) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(fin, csump, nat->nat_sumd[1]);
@@ -3818,7 +3872,7 @@ u_32_t nflags;
i = appr_check(fin, nat);
if (i == 0)
i = 1;
- } else
+ } else
i = 1;
ATOMIC_INCL(nat_stats.ns_mapped[1]);
fin->fin_flx |= FI_NATED;
@@ -3846,6 +3900,7 @@ fr_info_t *fin;
u_32_t *passp;
{
u_int nflags, natadd;
+ int rval, natfailed;
struct ifnet *ifp;
struct in_addr in;
icmphdr_t *icmp;
@@ -3854,9 +3909,8 @@ u_32_t *passp;
ipnat_t *np;
nat_t *nat;
u_32_t iph;
- int rval;
- if (nat_list == NULL || fr_nat_lock != 0)
+ if (nat_stats.ns_rules == 0 || fr_nat_lock != 0)
return 0;
tcp = NULL;
@@ -3864,6 +3918,7 @@ u_32_t *passp;
dport = 0;
natadd = 1;
nflags = 0;
+ natfailed = 0;
ifp = fin->fin_ifp;
if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) {
@@ -3925,6 +3980,8 @@ maskloop:
for (np = rdr_rules[hv]; np; np = np->in_rnext) {
if (np->in_ifps[0] && (np->in_ifps[0] != ifp))
continue;
+ if (np->in_v != fin->fin_v)
+ continue;
if (np->in_p && (np->in_p != fin->fin_p))
continue;
if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags))
@@ -3951,7 +4008,8 @@ maskloop:
if (nat != NULL) {
np->in_hits++;
break;
- }
+ } else
+ natfailed = -1;
}
if ((np == NULL) && (rmsk != 0)) {
@@ -3978,7 +4036,7 @@ maskloop:
fin->fin_state = nat->nat_state;
}
} else
- rval = 0;
+ rval = natfailed;
RWLOCK_EXIT(&ipf_nat);
if (rval == -1) {
@@ -4058,8 +4116,15 @@ u_32_t nflags;
/*
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
+ * Why only do this for some platforms on inbound packets ?
+ * Because for those that it is done, IP processing is yet to happen
+ * and so the IPv4 header checksum has not yet been evaluated.
+ * Perhaps it should always be done for the benefit of things like
+ * fast forwarding (so that it doesn't need to be recomputed) but with
+ * header checksum offloading, perhaps it is a moot point.
*/
-#if !defined(_KERNEL) || (defined(MENTAT) || defined(__sgi) || defined(__osf__))
+#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \
+ defined(__osf__) || defined(linux)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd);
else
@@ -4084,6 +4149,9 @@ u_32_t nflags;
nat_update(fin, nat, np);
+ /*
+ * The above comments do not hold for layer 4 (or higher) checksums...
+ */
if (csump != NULL) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(fin, csump, nat->nat_sumd[0]);
@@ -4107,8 +4175,10 @@ u_32_t nflags;
/* nat(I) - pointer to NAT structure */
/* nflags(I) - NAT flags set for this packet */
/* */
-/* Make special protocol timeout adjustments and return a pointer to the */
-/* checksum location for updating. */
+/* Return the pointer to the checksum field for each protocol so understood.*/
+/* If support for making other changes to a protocol header is required, */
+/* that is not strictly 'address' translation, such as clamping the MSS in */
+/* TCP down to a specific value, then do it from here. */
/* ------------------------------------------------------------------------ */
u_short *nat_proto(fin, nat, nflags)
fr_info_t *fin;
@@ -4172,9 +4242,25 @@ u_int nflags;
/* ------------------------------------------------------------------------ */
void fr_natunload()
{
+ ipftq_t *ifq, *ifqnext;
+
(void) nat_clearlist();
(void) nat_flushtable();
+ /*
+ * Proxy timeout queues are not cleaned here because although they
+ * exist on the NAT list, appr_unload is called after fr_natunload
+ * and the proxies actually are responsible for them being created.
+ * Should the proxy timeouts have their own list? There's no real
+ * justification as this is the only complication.
+ */
+ for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) {
+ ifqnext = ifq->ifq_next;
+ if (((ifq->ifq_flags & IFQF_PROXY) == 0) &&
+ (fr_deletetimeoutqueue(ifq) == 0))
+ fr_freetimeoutqueue(ifq);
+ }
+
if (nat_table[0] != NULL) {
KFREES(nat_table[0], sizeof(nat_t *) * ipf_nattable_sz);
nat_table[0] = NULL;
@@ -4238,10 +4324,8 @@ void fr_natexpire()
{
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
int i;
+ SPL_INT(s);
SPL_NET(s);
WRITE_ENTER(&ipf_nat);
@@ -4265,6 +4349,15 @@ void fr_natexpire()
}
}
+ for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) {
+ ifqnext = ifq->ifq_next;
+
+ if (((ifq->ifq_flags & IFQF_DELETE) != 0) &&
+ (ifq->ifq_ref == 0)) {
+ fr_freetimeoutqueue(ifq);
+ }
+ }
+
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}
@@ -4283,13 +4376,10 @@ void *ifp;
{
u_32_t sum1, sum2, sumd;
struct in_addr in;
- ipnat_t *np;
ipnat_t *n;
nat_t *nat;
void *ifp2;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
if (fr_running <= 0)
return;
@@ -4311,12 +4401,12 @@ void *ifp;
for (nat = nat_instances; nat; nat = nat->nat_next) {
if ((nat->nat_flags & IPN_TCP) != 0)
continue;
- np = nat->nat_ptr;
- if ((np == NULL) ||
- (np->in_outip != 0) || (np->in_outmsk != 0xffffffff))
+ n = nat->nat_ptr;
+ if ((n == NULL) ||
+ (n->in_outip != 0) || (n->in_outmsk != 0xffffffff))
continue;
if (((ifp == NULL) || (ifp == nat->nat_ifps[0]) ||
- (ifp == nat->nat_ifps[1]))) {
+ (ifp == nat->nat_ifps[1]))) {
nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0], 4);
if (nat->nat_ifnames[1][0] != '\0') {
nat->nat_ifps[1] = GETIFP(nat->nat_ifnames[1],
@@ -4326,6 +4416,7 @@ void *ifp;
ifp2 = nat->nat_ifps[0];
if (ifp2 == NULL)
continue;
+
/*
* Change the map-to address to be the same as the
* new one.
@@ -4349,25 +4440,18 @@ void *ifp;
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
nat->nat_sumd[1] = nat->nat_sumd[0];
}
-
}
for (n = nat_list; (n != NULL); n = n->in_next) {
- if ((ifp == NULL) || (n->in_ifps[0] == ifp)) {
- n->in_ifps[0] = (void *)GETIFP(n->in_ifnames[0], 4);
- if (n->in_ifps[0] == NULL)
- n->in_ifps[0] = (void *)-1;
- }
- if ((ifp == NULL) || (n->in_ifps[1] == ifp)) {
- n->in_ifps[1] = (void *)GETIFP(n->in_ifnames[1], 4);
- if (n->in_ifps[1] == NULL)
- n->in_ifps[1] = (void *)-1;
- }
+ if ((ifp == NULL) || (n->in_ifps[0] == ifp))
+ n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4);
+ if ((ifp == NULL) || (n->in_ifps[1] == ifp))
+ n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4);
}
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}
-
+
/* ------------------------------------------------------------------------ */
/* Function: nat_icmpquerytype4 */
@@ -4390,9 +4474,9 @@ int icmptype;
* altough it seems silly to call a reply a query, this is exactly
* as it is defined in the IPv4 specification
*/
-
+
switch (icmptype)
- {
+ {
case ICMP_ECHOREPLY:
case ICMP_ECHO:
@@ -4405,32 +4489,7 @@ int icmptype;
case ICMP_MASKREQ:
case ICMP_MASKREPLY:
return 1;
- default:
- return 0;
- }
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* Function: nat_icmperrortype4 */
-/* Returns: int - 1 == success, 0 == failure */
-/* Parameters: icmptype(I) - ICMP type number */
-/* */
-/* Tests to see if the ICMP type number passed is an error type or not. */
-/* ------------------------------------------------------------------------ */
-static INLINE int nat_icmperrortype4(icmptype)
-int icmptype;
-{
-
- switch (icmptype)
- {
- case ICMP_SOURCEQUENCH :
- case ICMP_PARAMPROB :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_UNREACH :
- return 1;
- default:
+ default:
return 0;
}
}
@@ -4449,11 +4508,14 @@ struct nat *nat;
u_int type;
{
#ifdef IPFILTER_LOG
+# ifndef LARGE_NAT
struct ipnat *np;
+ int rulen;
+# endif
struct natlog natl;
void *items[1];
size_t sizes[1];
- int rulen, types[1];
+ int types[1];
natl.nl_inip = nat->nat_inip;
natl.nl_outip = nat->nat_outip;
@@ -4498,7 +4560,7 @@ u_int type;
void nat_ifdetach(ifp)
void *ifp;
{
- frsync();
+ frsync(ifp);
return;
}
#endif
@@ -4552,13 +4614,31 @@ nat_t *nat;
MUTEX_NUKE(&clone->nat_lock);
+ clone->nat_aps = NULL;
+ /*
+ * Initialize all these so that nat_delete() doesn't cause a crash.
+ */
+ clone->nat_tqe.tqe_pnext = NULL;
+ clone->nat_tqe.tqe_next = NULL;
+ clone->nat_tqe.tqe_ifq = NULL;
+ clone->nat_tqe.tqe_parent = clone;
+
+ clone->nat_flags &= ~SI_CLONE;
+ clone->nat_flags |= SI_CLONED;
+
+ if (clone->nat_hm)
+ clone->nat_hm->hm_ref++;
+
+ if (nat_insert(clone, fin->fin_rev) == -1) {
+ KFREE(clone);
+ return NULL;
+ }
np = clone->nat_ptr;
if (np != NULL) {
+ if (nat_logging)
+ nat_log(clone, (u_int)np->in_redir);
np->in_use++;
}
- clone->nat_flags &= ~SI_CLONE;
- clone->nat_flags |= SI_CLONED;
-
fr = clone->nat_fr;
if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
@@ -4566,33 +4646,37 @@ nat_t *nat;
MUTEX_EXIT(&fr->fr_lock);
}
- if (nat_insert(clone) == -1) {
- KFREE(clone);
- return NULL;
- }
-
+ /*
+ * Because the clone is created outside the normal loop of things and
+ * TCP has special needs in terms of state, initialise the timeout
+ * state of the new NAT from here.
+ */
if (clone->nat_p == IPPROTO_TCP) {
- (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, clone->nat_flags);
+ (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb,
+ clone->nat_flags);
}
+#ifdef IPFILTER_SYNC
+ clone->nat_sync = ipfsync_new(SMC_NAT, fin, clone);
+#endif
if (nat_logging)
nat_log(clone, NL_CLONE);
return clone;
}
-/* -------------------------------------------------------------------- */
-/* Function: nat_wildok */
-/* Returns: int - 1 == packet's ports match wildcards */
-/* 0 == packet's ports don't match wildcards */
-/* Parameters: nat(I) - NAT entry */
-/* sport(I) - source port */
-/* dport(I) - destination port */
-/* flags(I) - wildcard flags */
-/* dir(I) - packet direction */
-/* */
-/* Use NAT entry and packet direction to determine which combination of */
-/* wildcard flags should be used. */
-/* -------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------ */
+/* Function: nat_wildok */
+/* Returns: int - 1 == packet's ports match wildcards */
+/* 0 == packet's ports don't match wildcards */
+/* Parameters: nat(I) - NAT entry */
+/* sport(I) - source port */
+/* dport(I) - destination port */
+/* flags(I) - wildcard flags */
+/* dir(I) - packet direction */
+/* */
+/* Use NAT entry and packet direction to determine which combination of */
+/* wildcard flags should be used. */
+/* ------------------------------------------------------------------------ */
static INLINE int nat_wildok(nat, sport, dport, flags, dir)
nat_t *nat;
int sport;
@@ -4687,17 +4771,17 @@ u_short *csump;
if (cp + 1 >= ep)
break;
advance = cp[1];
- if (cp + advance > ep)
+ if ((cp + advance > ep) || (advance <= 0))
break;
switch (opt)
{
case TCPOPT_MAXSEG:
if (advance != 4)
break;
- mss = cp[0] * 256 + cp[1];
+ mss = cp[2] * 256 + cp[3];
if (mss > maxmss) {
- cp[0] = maxmss / 256;
- cp[1] = maxmss & 0xff;
+ cp[2] = maxmss / 256;
+ cp[3] = maxmss & 0xff;
CALC_SUMD(mss, maxmss, sumd);
fix_outcksum(fin, csump, sumd);
}
@@ -4711,3 +4795,55 @@ u_short *csump;
}
}
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_setnatqueue */
+/* Returns: Nil */
+/* Parameters: nat(I)- pointer to NAT structure */
+/* rev(I) - forward(0) or reverse(1) direction */
+/* Locks: ipf_nat (read or write) */
+/* */
+/* Put the NAT entry on its default queue entry, using rev as a helped in */
+/* determining which queue it should be placed on. */
+/* ------------------------------------------------------------------------ */
+void fr_setnatqueue(nat, rev)
+nat_t *nat;
+int rev;
+{
+ ipftq_t *oifq, *nifq;
+
+ if (nat->nat_ptr != NULL)
+ nifq = nat->nat_ptr->in_tqehead[rev];
+ else
+ nifq = NULL;
+
+ if (nifq == NULL) {
+ switch (nat->nat_p)
+ {
+ case IPPROTO_UDP :
+ nifq = &nat_udptq;
+ break;
+ case IPPROTO_ICMP :
+ nifq = &nat_icmptq;
+ break;
+ case IPPROTO_TCP :
+ nifq = nat_tqb + nat->nat_tqe.tqe_state[rev];
+ break;
+ default :
+ nifq = &nat_iptq;
+ break;
+ }
+ }
+
+ oifq = nat->nat_tqe.tqe_ifq;
+ /*
+ * If it's currently on a timeout queue, move it from one queue to
+ * another, else put it on the end of the newly determined queue.
+ */
+ if (oifq != NULL)
+ fr_movequeue(&nat->nat_tqe, oifq, nifq);
+ else
+ fr_queueappend(&nat->nat_tqe, nifq, nat);
+ return;
+}
diff --git a/usr/src/common/ipf/ip_pool.c b/usr/src/uts/common/inet/ipf/ip_pool.c
index a9b42cd0fe..e3aace93df 100644
--- a/usr/src/common/ipf/ip_pool.c
+++ b/usr/src/uts/common/inet/ipf/ip_pool.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -15,6 +15,9 @@
# define KERNEL 1
# define _KERNEL 1
#endif
+#if defined(__osf__)
+# define _PROTO_NET_H_
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -56,28 +59,45 @@ struct file;
# include <sys/malloc.h>
#endif
+#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \
+ defined(__hpux) || defined(__sgi))
+# ifdef __osf__
+# include <net/radix.h>
+# endif
+# include "radix_ipf_local.h"
+# define _RADIX_H_
+#endif
#include <net/if.h>
#include <netinet/in.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_pool.h"
-#else
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_pool.h"
+
+#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \
+ ((BSD >= 198911) && !defined(__osf__) && \
+ !defined(__hpux) && !defined(__sgi))
+static int rn_freenode __P((struct radix_node *, void *));
#endif
+
/* END OF INCLUDES */
#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_pool.c,v 2.45 2003/11/12 09:34:31 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.14 2005/06/12 07:18:26 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
+# ifndef RADIX_NODE_HEAD_LOCK
+# define RADIX_NODE_HEAD_LOCK(x) ;
+# endif
+# ifndef RADIX_NODE_HEAD_UNLOCK
+# define RADIX_NODE_HEAD_UNLOCK(x) ;
+# endif
+
ip_pool_stat_t ipoolstat;
+ipfrwlock_t ip_poolrw;
/*
* Binary tree routines from Sedgewick and enhanced to do ranges of addresses.
@@ -101,7 +121,6 @@ ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL,
#ifdef TEST_POOL
-ipfrwlock_t ip_poolrw;
void treeprint __P((ip_pool_t *));
int
@@ -227,9 +246,10 @@ ip_pool_t *ipo;
/* ------------------------------------------------------------------------ */
int ip_pool_init()
{
+
bzero((char *)&ipoolstat, sizeof(ipoolstat));
-#if !defined(_KERNEL) || (BSD < 199306)
+#if (!defined(_KERNEL) || (BSD < 199306))
rn_init();
#endif
return 0;
@@ -263,11 +283,12 @@ void ip_pool_fini()
}
}
-#if !defined(_KERNEL) || (BSD < 199306)
+#if (!defined(_KERNEL) || (BSD < 199306))
rn_fini();
#endif
}
+
/* ------------------------------------------------------------------------ */
/* Function: ip_pool_statistics */
/* Returns: int - 0 = success, else error */
@@ -291,7 +312,11 @@ iplookupop_t *op;
for (i = 0; i < IPL_LOGSIZE; i++)
stats.ipls_list[i] = ip_pool_list[i];
} else if (unit >= 0 && unit < IPL_LOGSIZE) {
- stats.ipls_list[unit] = ip_pool_list[unit];
+ if (op->iplo_name[0] != '\0')
+ stats.ipls_list[unit] = ip_pool_find(unit,
+ op->iplo_name);
+ else
+ stats.ipls_list[unit] = ip_pool_list[unit];
} else
err = EINVAL;
if (err == 0)
@@ -300,6 +325,7 @@ iplookupop_t *op;
}
+
/* ------------------------------------------------------------------------ */
/* Function: ip_pool_find */
/* Returns: int - 0 = success, else error */
@@ -315,7 +341,7 @@ char *name;
ip_pool_t *p;
for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next)
- if (strcmp(p->ipo_name, name) == 0)
+ if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0)
break;
return p;
}
@@ -325,7 +351,7 @@ char *name;
/* Function: ip_pool_findeq */
/* Returns: int - 0 = success, else error */
/* Parameters: ipo(I) - pointer to the pool getting the new node. */
-/* addr(I) - */
+/* addr(I) - pointer to address information to delete */
/* mask(I) - */
/* */
/* Searches for an exact match of an entry in the pool. */
@@ -335,15 +361,20 @@ ip_pool_t *ipo;
addrfamily_t *addr, *mask;
{
struct radix_node *n;
+ SPL_INT(s);
+ SPL_NET(s);
+ RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head);
+ RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
+ SPL_X(s);
return (ip_pool_node_t *)n;
}
/* ------------------------------------------------------------------------ */
/* Function: ip_pool_search */
-/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve match */
+/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */
/* Parameters: tptr(I) - pointer to the pool to search */
/* version(I) - IP protocol version (4 or 6) */
/* dptr(I) - pointer to address information */
@@ -385,7 +416,9 @@ void *dptr;
READ_ENTER(&ip_poolrw);
+ RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head);
+ RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) {
m = (ip_pool_node_t *)rn;
@@ -435,8 +468,10 @@ int info;
bcopy(mask, &x->ipn_mask, sizeof(*mask));
x->ipn_mask.adf_len = sizeof(x->ipn_mask);
+ RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask,
ipo->ipo_head, x->ipn_nodes);
+ RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
#ifdef DEBUG_POOL
printf("Added %p at %p\n", x, rn);
#endif
@@ -496,11 +531,22 @@ iplookupop_t *op;
ip_pool_t *p;
poolnum = IPOOL_ANON;
+
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void)SNPRINTF(name, sizeof(name), "%x", poolnum);
+#else
(void)sprintf(name, "%x", poolnum);
+#endif
+
for (p = ip_pool_list[unit]; p != NULL; ) {
- if (strcmp(name, p->ipo_name) == 0) {
+ if (strncmp(name, p->ipo_name,
+ sizeof(p->ipo_name)) == 0) {
poolnum++;
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void)SNPRINTF(name, sizeof(name), "%x", poolnum);
+#else
(void)sprintf(name, "%x", poolnum);
+#endif
p = ip_pool_list[unit];
} else
p = p->ipo_next;
@@ -556,11 +602,13 @@ ip_pool_node_t *ipe;
if (n == NULL)
return ENOENT;
+ RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask,
ipo->ipo_head);
+ RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
KFREE(n);
- ipoolstat.ipls_nodes--;
+ ipoolstat.ipls_nodes--;
return 0;
}
@@ -597,6 +645,47 @@ iplookupop_t *op;
/* ------------------------------------------------------------------------ */
+/* Function: ip_pool_flush */
+/* Returns: int - number of pools deleted */
+/* Parameters: fp(I) - which pool(s) to flush */
+/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */
+/* */
+/* Free all pools associated with the device that matches the unit number */
+/* passed in with operation. */
+/* */
+/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */
+/* may not be initialised, we can't use an ASSERT to enforce the locking */
+/* assertion that one of the two (ip_poolrw,ipf_global) is held. */
+/* ------------------------------------------------------------------------ */
+int ip_pool_flush(fp)
+iplookupflush_t *fp;
+{
+ int i, num = 0, unit, err;
+ ip_pool_t *p, *q;
+ iplookupop_t op;
+
+ unit = fp->iplf_unit;
+
+ for (i = 0; i <= IPL_LOGMAX; i++) {
+ if (unit != IPLT_ALL && i != unit)
+ continue;
+ for (q = ip_pool_list[i]; (p = q) != NULL; ) {
+ op.iplo_unit = i;
+ (void)strncpy(op.iplo_name, p->ipo_name,
+ sizeof(op.iplo_name));
+ q = p->ipo_next;
+ err = ip_pool_destroy(&op);
+ if (err == 0)
+ num++;
+ else
+ break;
+ }
+ }
+ return num;
+}
+
+
+/* ------------------------------------------------------------------------ */
/* Function: ip_pool_free */
/* Returns: void */
/* Parameters: ipo(I) - pointer to pool structure */
@@ -615,16 +704,20 @@ ip_pool_t *ipo;
{
ip_pool_node_t *n;
+ RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
while ((n = ipo->ipo_list) != NULL) {
ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask,
ipo->ipo_head);
+
*n->ipn_pnext = n->ipn_next;
if (n->ipn_next)
n->ipn_next->ipn_pnext = n->ipn_pnext;
+
KFREE(n);
ipoolstat.ipls_nodes--;
}
+ RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
ipo->ipo_list = NULL;
if (ipo->ipo_next != NULL)
@@ -658,7 +751,8 @@ ip_pool_t *ipo;
}
-# if defined(_KERNEL) && (BSD > 199306)
+# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \
+ !defined(__hpux) && !defined(__sgi))
static int
rn_freenode(struct radix_node *n, void *p)
{
@@ -678,13 +772,15 @@ rn_freehead(rnh)
struct radix_node_head *rnh;
{
- (void)rn_walktree(rnh, rn_freenode, rnh);
+ RADIX_NODE_HEAD_LOCK(rnh);
+ (*rnh->rnh_walktree)(rnh, rn_freenode, rnh);
rnh->rnh_addaddr = NULL;
rnh->rnh_deladdr = NULL;
rnh->rnh_matchaddr = NULL;
rnh->rnh_lookup = NULL;
rnh->rnh_walktree = NULL;
+ RADIX_NODE_HEAD_UNLOCK(rnh);
Free(rnh);
}
diff --git a/usr/src/common/ipf/ip_proxy.c b/usr/src/uts/common/inet/ipf/ip_proxy.c
index 3d31d6a2b2..99f8a14b88 100644
--- a/usr/src/common/ipf/ip_proxy.c
+++ b/usr/src/uts/common/inet/ipf/ip_proxy.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -20,7 +20,9 @@
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
-#include <sys/fcntl.h>
+#if !defined(AIX)
+# include <sys/fcntl.h>
+#endif
#if !defined(_KERNEL) && !defined(__KERNEL__)
# include <stdio.h>
# include <string.h>
@@ -33,11 +35,14 @@ struct file;
# include <sys/uio.h>
# undef _KERNEL
#endif
-#include <sys/protosw.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#if defined(_KERNEL)
# if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \
- !defined(__OpenBSD__) && !defined(__hpux)
+ !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) && \
+ !defined(AIX)
# include <sys/ctype.h>
# endif
# include <sys/systm.h>
@@ -73,70 +78,49 @@ struct file;
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#ifndef linux
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
-
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#else
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
-#endif
-
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
-#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.49 2003/06/14 02:56:40 darrenr Exp $";
+#include "netinet/ip_ftp_pxy.c"
+#include "netinet/ip_rcmd_pxy.c"
+# include "netinet/ip_pptp_pxy.c"
+#if defined(_KERNEL)
+# include "netinet/ip_irc_pxy.c"
+# include "netinet/ip_raudio_pxy.c"
+# include "netinet/ip_h323_pxy.c"
+# include "netinet/ip_netbios_pxy.c"
#endif
+#include "netinet/ip_ipsec_pxy.c"
+#include "netinet/ip_rpcb_pxy.c"
+/* END OF INCLUDES */
-static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.14 2005/06/18 02:41:33 darrenr Exp $";
+#endif
+static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
#define AP_SESS_SIZE 53
-#if SOLARIS2 >= 10
-#include "ip_ftp_pxy.c"
#if defined(_KERNEL)
-#include "ip_irc_pxy.c"
-#include "ip_rcmd_pxy.c"
-#include "ip_raudio_pxy.c"
-#include "ip_h323_pxy.c"
-#ifdef IPFILTER_PRO
-#include "ip_msnrpc_pxy.c"
-#endif
-#include "ip_netbios_pxy.c"
-#endif
-#include "ip_ipsec_pxy.c"
-#include "ip_rpcb_pxy.c"
+int ipf_proxy_debug = 0;
#else
-#include "netinet/ip_ftp_pxy.c"
-#if defined(_KERNEL)
-#include "netinet/ip_irc_pxy.c"
-#include "netinet/ip_rcmd_pxy.c"
-#include "netinet/ip_raudio_pxy.c"
-#include "netinet/ip_h323_pxy.c"
-#ifdef IPFILTER_PRO
-#include "netinet/ip_msnrpc_pxy.c"
-#endif
-#include "netinet/ip_netbios_pxy.c"
-#endif
-#include "netinet/ip_ipsec_pxy.c"
-#include "netinet/ip_rpcb_pxy.c"
+int ipf_proxy_debug = 2;
#endif
-
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
aproxy_t *ap_proxylist = NULL;
@@ -168,7 +152,12 @@ aproxy_t ap_proxies[] = {
#ifdef IPF_IPSEC_PROXY
{ NULL, "ipsec", (char)IPPROTO_UDP, 0, 0,
ippr_ipsec_init, ippr_ipsec_fini, ippr_ipsec_new, ippr_ipsec_del,
- NULL, ippr_ipsec_out, NULL, NULL },
+ ippr_ipsec_inout, ippr_ipsec_inout, ippr_ipsec_match, NULL },
+#endif
+#ifdef IPF_PPTP_PROXY
+ { NULL, "pptp", (char)IPPROTO_TCP, 0, 0,
+ ippr_pptp_init, ippr_pptp_fini, ippr_pptp_new, ippr_pptp_del,
+ ippr_pptp_inout, ippr_pptp_inout, NULL, NULL },
#endif
#ifdef IPF_H323_PROXY
{ NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, ippr_h323_fini,
@@ -201,14 +190,22 @@ aproxy_t *ap;
for (a = ap_proxies; a->apr_p; a++)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
- sizeof(ap->apr_label)))
+ sizeof(ap->apr_label))) {
+ if (ipf_proxy_debug > 1)
+ printf("appr_add: %s/%d already present (B)\n",
+ a->apr_label, a->apr_p);
return -1;
+ }
for (a = ap_proxylist; a->apr_p; a = a->apr_next)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
- sizeof(ap->apr_label)))
+ sizeof(ap->apr_label))) {
+ if (ipf_proxy_debug > 1)
+ printf("appr_add: %s/%d already present (D)\n",
+ a->apr_label, a->apr_p);
return -1;
+ }
ap->apr_next = ap_proxylist;
ap_proxylist = ap;
if (ap->apr_init != NULL)
@@ -229,12 +226,22 @@ ap_ctl_t *ctl;
int error;
a = appr_lookup(ctl->apc_p, ctl->apc_label);
- if (a == NULL)
+ if (a == NULL) {
+ if (ipf_proxy_debug > 1)
+ printf("appr_ctl: can't find %s/%d\n",
+ ctl->apc_label, ctl->apc_p);
error = ESRCH;
- else if (a->apr_ctl == NULL)
+ } else if (a->apr_ctl == NULL) {
+ if (ipf_proxy_debug > 1)
+ printf("appr_ctl: no ctl function for %s/%d\n",
+ ctl->apc_label, ctl->apc_p);
error = ENXIO;
- else
+ } else {
error = (*a->apr_ctl)(a, ctl);
+ if ((error != 0) && (ipf_proxy_debug > 1))
+ printf("appr_ctl: %s/%d ctl error %d\n",
+ a->apr_label, a->apr_p, error);
+ }
return error;
}
@@ -253,10 +260,16 @@ aproxy_t *ap;
if (a == ap) {
a->apr_flags |= APR_DELETE;
*app = a->apr_next;
- if (ap->apr_ref != 0)
+ if (ap->apr_ref != 0) {
+ if (ipf_proxy_debug > 2)
+ printf("appr_del: orphaning %s/%d\n",
+ ap->apr_label, ap->apr_p);
return 1;
+ }
return 0;
}
+ if (ipf_proxy_debug > 1)
+ printf("appr_del: proxy %lx not found\n", (u_long)ap);
return -1;
}
@@ -283,12 +296,8 @@ ipnat_t *nat;
int appr_ioctl(data, cmd, mode)
caddr_t data;
+ioctlcmd_t cmd;
int mode;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
{
ap_ctl_t ctl;
caddr_t ptr;
@@ -320,7 +329,8 @@ int cmd;
if (error == 0)
error = appr_ctl(&ctl);
- if (ctl.apc_dsize > 0 && ptr != NULL && ctl.apc_data == ptr) {
+ if ((ctl.apc_dsize > 0) && (ptr != NULL) &&
+ (ctl.apc_data == ptr)) {
KFREES(ptr, ctl.apc_dsize);
}
break;
@@ -342,17 +352,37 @@ nat_t *nat;
{
aproxy_t *apr;
ipnat_t *ipn;
+ int result;
ipn = nat->nat_ptr;
- if (ipn == NULL)
+ if (ipf_proxy_debug > 8)
+ printf("appr_match(%lx,%lx) aps %lx ptr %lx\n",
+ (u_long)fin, (u_long)nat, (u_long)nat->nat_aps,
+ (u_long)ipn);
+
+ if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_match: flx 0x%x (BAD|SHORT)\n",
+ fin->fin_flx);
return -1;
+ }
+
apr = ipn->in_apr;
- if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
- (nat->nat_aps == NULL))
+ if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_match:apr %lx apr_flags 0x%x\n",
+ (u_long)apr, apr ? apr->apr_flags : 0);
return -1;
- if (apr->apr_match != NULL)
- if ((*apr->apr_match)(fin, nat->nat_aps, nat) != 0)
+ }
+
+ if (apr->apr_match != NULL) {
+ result = (*apr->apr_match)(fin, nat->nat_aps, nat);
+ if (result != 0) {
+ if (ipf_proxy_debug > 4)
+ printf("appr_match: result %d\n", result);
return -1;
+ }
+ }
return 0;
}
@@ -369,18 +399,34 @@ nat_t *nat;
register ap_session_t *aps;
aproxy_t *apr;
- if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL))
+ if (ipf_proxy_debug > 8)
+ printf("appr_new(%lx,%lx) \n", (u_long)fin, (u_long)nat);
+
+ if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_new: nat_ptr %lx nat_aps %lx\n",
+ (u_long)nat->nat_ptr, (u_long)nat->nat_aps);
return -1;
+ }
apr = nat->nat_ptr->in_apr;
- if (!apr || (apr->apr_flags & APR_DELETE) ||
- (fin->fin_p != apr->apr_p))
+ if ((apr->apr_flags & APR_DELETE) ||
+ (fin->fin_p != apr->apr_p)) {
+ if (ipf_proxy_debug > 2)
+ printf("appr_new: apr_flags 0x%x p %d/%d\n",
+ apr->apr_flags, fin->fin_p, apr->apr_p);
return -1;
+ }
KMALLOC(aps, ap_session_t *);
- if (!aps)
+ if (!aps) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_new: malloc failed (%lu)\n",
+ (u_long)sizeof(ap_session_t));
return -1;
+ }
+
bzero((char *)aps, sizeof(*aps));
aps->aps_p = fin->fin_p;
aps->aps_data = NULL;
@@ -392,6 +438,9 @@ nat_t *nat;
KFREES(aps->aps_data, aps->aps_psiz);
}
KFREE(aps);
+ if (ipf_proxy_debug > 2)
+ printf("appr_new: new(%lx) failed\n",
+ (u_long)apr->apr_new);
return -1;
}
aps->aps_nat = nat;
@@ -413,10 +462,10 @@ int appr_check(fin, nat)
fr_info_t *fin;
nat_t *nat;
{
-#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
-#if defined(ICK_VALID)
+#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
+# if defined(ICK_VALID)
mb_t *m;
-#endif
+# endif
int dosum = 1;
#endif
tcphdr_t *tcp = NULL;
@@ -430,14 +479,17 @@ nat_t *nat;
u_32_t s1, s2, sd;
#endif
- if (fin->fin_flx & FI_BAD)
+ if (fin->fin_flx & FI_BAD) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_check: flx 0x%x (BAD)\n", fin->fin_flx);
return -1;
+ }
#ifndef IPFILTER_CKSUM
if ((fin->fin_out == 0) && (fr_checkl4sum(fin) == -1)) {
-# if PROXY_DEBUG || !defined(_KERNEL)
- printf("proxy l4 checksum failure\n");
-# endif
+ if (ipf_proxy_debug > 0)
+ printf("appr_check: l4 checksum failure %d\n",
+ fin->fin_p);
if (fin->fin_p == IPPROTO_TCP)
frstats[fin->fin_out].fr_tcpbad++;
return -1;
@@ -450,9 +502,14 @@ nat_t *nat;
* If there is data in this packet to be proxied then try and
* get it all into the one buffer, else drop it.
*/
+#if defined(MENTAT) || defined(HAVE_M_PULLDOWN)
if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE))
- if (fr_coalesce(fin) == -1)
+ if (fr_coalesce(fin) == -1) {
+ if (ipf_proxy_debug > 0)
+ printf("appr_check: fr_coalesce failed %x\n", fin->fin_flx);
return -1;
+ }
+#endif
ip = fin->fin_ip;
switch (fin->fin_p)
@@ -490,16 +547,14 @@ nat_t *nat;
}
rv = APR_EXIT(err);
- if (rv == 1) {
-#if PROXY_DEBUG || !defined(_KERNEL)
- printf("proxy says bad packet received\n");
-#endif
+ if (((ipf_proxy_debug > 0) && (rv != 0)) ||
+ (ipf_proxy_debug > 8))
+ printf("appr_check: out %d err %x rv %d\n",
+ fin->fin_out, err, rv);
+ if (rv == 1)
return -1;
- }
+
if (rv == 2) {
-#if PROXY_DEBUG || !defined(_KERNEL)
- printf("proxy says free app proxy data\n");
-#endif
appr_free(apr);
nat->nat_aps = NULL;
return -1;
@@ -567,6 +622,9 @@ char *name;
{
aproxy_t *ap;
+ if (ipf_proxy_debug > 8)
+ printf("appr_lookup(%d,%s)\n", pr, name);
+
for (ap = ap_proxies; ap->apr_p; ap++)
if ((ap->apr_p == pr) &&
!strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
@@ -580,6 +638,8 @@ char *name;
ap->apr_ref++;
return ap;
}
+ if (ipf_proxy_debug > 2)
+ printf("appr_lookup: failed for %d/%s\n", pr, name);
return NULL;
}
@@ -648,10 +708,10 @@ int inc;
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel])) {
-#if PROXY_DEBUG
- printf("proxy out switch set seq %d -> %d %x > %x\n",
- sel, !sel, seq1, aps->aps_seqmin[!sel]);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("proxy out switch set seq %d -> %d %x > %x\n",
+ sel, !sel, seq1,
+ aps->aps_seqmin[!sel]);
sel = aps->aps_sel[out] = !sel;
}
@@ -668,11 +728,10 @@ int inc;
if (inc && (seq1 > aps->aps_seqmin[!sel])) {
aps->aps_seqmin[sel] = seq1 + nlen - 1;
aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc;
-#if PROXY_DEBUG
- printf("proxy seq set %d at %x to %d + %d\n", sel,
- aps->aps_seqmin[sel], aps->aps_seqoff[sel],
- inc);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("proxy seq set %d at %x to %d + %d\n",
+ sel, aps->aps_seqmin[sel],
+ aps->aps_seqoff[sel], inc);
}
/***/
@@ -683,10 +742,10 @@ int inc;
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel])) {
-#if PROXY_DEBUG
- printf("proxy out switch set ack %d -> %d %x > %x\n",
- sel, !sel, seq1, aps->aps_ackmin[!sel]);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("proxy out switch set ack %d -> %d %x > %x\n",
+ sel, !sel, seq1,
+ aps->aps_ackmin[!sel]);
sel = aps->aps_sel[1 - out] = !sel;
}
@@ -702,10 +761,9 @@ int inc;
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel])) {
-#if PROXY_DEBUG
- printf("proxy in switch set ack %d -> %d %x > %x\n",
- sel, !sel, seq1, aps->aps_ackmin[!sel]);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("proxy in switch set ack %d -> %d %x > %x\n",
+ sel, !sel, seq1, aps->aps_ackmin[!sel]);
sel = aps->aps_sel[out] = !sel;
}
@@ -722,11 +780,11 @@ int inc;
if (inc && (seq1 > aps->aps_ackmin[!sel])) {
aps->aps_ackmin[!sel] = seq1 + nlen - 1;
aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc;
-#if PROXY_DEBUG
- printf("proxy ack set %d at %x to %d + %d\n", !sel,
- aps->aps_seqmin[!sel], aps->aps_seqoff[sel],
- inc);
-#endif
+
+ if (ipf_proxy_debug > 7)
+ printf("proxy ack set %d at %x to %d + %d\n",
+ !sel, aps->aps_seqmin[!sel],
+ aps->aps_seqoff[sel], inc);
}
/***/
@@ -737,19 +795,17 @@ int inc;
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel])) {
-#if PROXY_DEBUG
- printf("proxy in switch set seq %d -> %d %x > %x\n",
- sel, !sel, seq1, aps->aps_seqmin[!sel]);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("proxy in switch set seq %d -> %d %x > %x\n",
+ sel, !sel, seq1, aps->aps_seqmin[!sel]);
sel = aps->aps_sel[1 - out] = !sel;
}
if (aps->aps_seqoff[sel] != 0) {
-#if PROXY_DEBUG
- printf("sel %d seqoff %d seq1 %x seqmin %x\n", sel,
- aps->aps_seqoff[sel], seq1,
- aps->aps_seqmin[sel]);
-#endif
+ if (ipf_proxy_debug > 7)
+ printf("sel %d seqoff %d seq1 %x seqmin %x\n",
+ sel, aps->aps_seqoff[sel], seq1,
+ aps->aps_seqmin[sel]);
if (seq1 > aps->aps_seqmin[sel]) {
seq2 = aps->aps_seqoff[sel];
tcp->th_ack = htonl(seq1 - seq2);
@@ -757,10 +813,10 @@ int inc;
}
}
}
-#if PROXY_DEBUG
- printf("appr_fixseqack: seq %lx ack %lx\n", ntohl(tcp->th_seq),
- ntohl(tcp->th_ack));
-#endif
+
+ if (ipf_proxy_debug > 8)
+ printf("appr_fixseqack: seq %x ack %x\n",
+ ntohl(tcp->th_seq), ntohl(tcp->th_ack));
return ch ? 2 : 0;
}
diff --git a/usr/src/common/ipf/ip_state.c b/usr/src/uts/common/inet/ipf/ip_state.c
index d4e59521ed..9a5586a208 100644
--- a/usr/src/common/ipf/ip_state.c
+++ b/usr/src/uts/common/inet/ipf/ip_state.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,11 +48,12 @@ struct file;
# include <sys/ioctl.h>
#endif
#include <sys/time.h>
-#include <sys/protosw.h>
+#if !defined(linux)
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
#if defined(_KERNEL)
# include <sys/systm.h>
-# include <sys/cmn_err.h>
# if !defined(__SVR4) && !defined(__svr4__)
# include <sys/mbuf.h>
# endif
@@ -76,31 +77,21 @@ struct file;
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/ip_var.h>
-#if !defined(__hpux)
+#if !defined(linux)
+# include <netinet/ip_var.h>
+#endif
+#if !defined(__hpux) && !defined(linux)
# include <netinet/tcp_fsm.h>
#endif
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#else
#include "netinet/ip_compat.h"
-#endif
#include <netinet/tcpip.h>
-#if SOLARIS2 >= 10
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#else
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
-#endif
#ifdef IPFILTER_SYNC
#include "netinet/ip_sync.h"
#endif
@@ -117,10 +108,12 @@ struct file;
# include <sys/systm.h>
# endif
#endif
+/* END OF INCLUDES */
+
#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.157 2003/07/01 18:30:21 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.36 2005/08/11 19:58:03 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@@ -128,16 +121,12 @@ static u_long *ips_seed = NULL;
static int ips_num = 0;
static u_long ips_last_force_flush = 0;
ips_stat_t ips_stats;
-#ifdef USE_MUTEXES
-extern ipfrwlock_t ipf_state, ipf_mutex;
-extern ipfmutex_t ipf_rw, ipf_stinsert;
-#endif
#ifdef USE_INET6
static ipstate_t *fr_checkicmp6matchingstate __P((fr_info_t *));
#endif
static ipstate_t *fr_matchsrcdst __P((fr_info_t *, ipstate_t *, i6addr_t *,
- i6addr_t *, tcphdr_t *));
+ i6addr_t *, tcphdr_t *, u_32_t));
static ipstate_t *fr_checkicmpmatchingstate __P((fr_info_t *));
static int fr_state_flush __P((int, int));
static ips_stat_t *fr_statetstats __P((void));
@@ -159,15 +148,16 @@ int fr_stgetent __P((caddr_t));
#define DOUBLE_HASH(x) (((x) + ips_seed[(x) % fr_statesize]) % fr_statesize)
u_long fr_tcpidletimeout = FIVE_DAYS,
- fr_tcpclosewait = IPF_TTLVAL(TCP_MSL),
- fr_tcplastack = IPF_TTLVAL(TCP_MSL),
- fr_tcptimeout = IPF_TTLVAL(TCP_MSL),
+ fr_tcpclosewait = IPF_TTLVAL(2 * TCP_MSL),
+ fr_tcplastack = IPF_TTLVAL(2 * TCP_MSL),
+ fr_tcptimeout = IPF_TTLVAL(2 * TCP_MSL),
fr_tcpclosed = IPF_TTLVAL(60),
fr_tcphalfclosed = IPF_TTLVAL(2 * 3600), /* 2 hours */
fr_udptimeout = IPF_TTLVAL(120),
fr_udpacktimeout = IPF_TTLVAL(12),
fr_icmptimeout = IPF_TTLVAL(60),
- fr_icmpacktimeout = IPF_TTLVAL(6);
+ fr_icmpacktimeout = IPF_TTLVAL(6),
+ fr_iptimeout = IPF_TTLVAL(60);
int fr_statemax = IPSTATE_MAX,
fr_statesize = IPSTATE_SIZE;
int fr_state_doflush = 0,
@@ -178,6 +168,7 @@ int fr_state_doflush = 0,
ipftq_t ips_tqtqb[IPF_TCP_NSTATES],
ips_udptq,
ips_udpacktq,
+ ips_iptq,
ips_icmptq,
ips_icmpacktq,
*ips_utqe = NULL;
@@ -208,7 +199,7 @@ int fr_stateinit()
KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed));
if (ips_seed == NULL)
- return -1;
+ return -2;
for (i = 0; i < fr_statesize; i++) {
/*
* XXX - ips_seed[X] should be a random number of sorts.
@@ -257,28 +248,38 @@ int fr_stateinit()
fr_sttab_init(ips_tqtqb);
ips_tqtqb[IPF_TCP_NSTATES - 1].ifq_next = &ips_udptq;
ips_udptq.ifq_ttl = (u_long)fr_udptimeout;
+ ips_udptq.ifq_ref = 1;
ips_udptq.ifq_head = NULL;
ips_udptq.ifq_tail = &ips_udptq.ifq_head;
MUTEX_INIT(&ips_udptq.ifq_lock, "ipftq udp tab");
ips_udptq.ifq_next = &ips_udpacktq;
ips_udpacktq.ifq_ttl = (u_long)fr_udpacktimeout;
+ ips_udpacktq.ifq_ref = 1;
ips_udpacktq.ifq_head = NULL;
ips_udpacktq.ifq_tail = &ips_udpacktq.ifq_head;
MUTEX_INIT(&ips_udpacktq.ifq_lock, "ipftq udpack tab");
ips_udpacktq.ifq_next = &ips_icmptq;
ips_icmptq.ifq_ttl = (u_long)fr_icmptimeout;
+ ips_icmptq.ifq_ref = 1;
ips_icmptq.ifq_head = NULL;
ips_icmptq.ifq_tail = &ips_icmptq.ifq_head;
MUTEX_INIT(&ips_icmptq.ifq_lock, "ipftq icmp tab");
ips_icmptq.ifq_next = &ips_icmpacktq;
ips_icmpacktq.ifq_ttl = (u_long)fr_icmpacktimeout;
+ ips_icmpacktq.ifq_ref = 1;
ips_icmpacktq.ifq_head = NULL;
ips_icmpacktq.ifq_tail = &ips_icmpacktq.ifq_head;
MUTEX_INIT(&ips_icmpacktq.ifq_lock, "ipftq icmpack tab");
- ips_icmpacktq.ifq_next = NULL;
+ ips_icmpacktq.ifq_next = &ips_iptq;
+ ips_iptq.ifq_ttl = (u_long)fr_iptimeout;
+ ips_iptq.ifq_ref = 1;
+ ips_iptq.ifq_head = NULL;
+ ips_iptq.ifq_tail = &ips_iptq.ifq_head;
+ MUTEX_INIT(&ips_iptq.ifq_lock, "ipftq ip tab");
+ ips_iptq.ifq_next = NULL;
RWLOCK_INIT(&ipf_state, "ipf IP state rwlock");
- MUTEX_INIT(&ipf_stinsert, "ipf stat insert mutex");
+ MUTEX_INIT(&ipf_stinsert, "ipf state insert mutex");
fr_state_init = 1;
ips_last_force_flush = fr_ticks;
@@ -296,11 +297,27 @@ int fr_stateinit()
/* ------------------------------------------------------------------------ */
void fr_stateunload()
{
+ ipftq_t *ifq, *ifqnext;
ipstate_t *is;
WRITE_ENTER(&ipf_state);
while ((is = ips_list) != NULL)
fr_delstate(is, 0);
+
+ /*
+ * Proxy timeout queues are not cleaned here because although they
+ * exist on the state list, appr_unload is called after fr_stateunload
+ * and the proxies actually are responsible for them being created.
+ * Should the proxy timeouts have their own list? There's no real
+ * justification as this is the only complicationA
+ */
+ for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) {
+ ifqnext = ifq->ifq_next;
+ if (((ifq->ifq_flags & IFQF_PROXY) == 0) &&
+ (fr_deletetimeoutqueue(ifq) == 0))
+ fr_freetimeoutqueue(ifq);
+ }
+
ips_stats.iss_inuse = 0;
ips_num = 0;
@@ -310,7 +327,7 @@ void fr_stateunload()
MUTEX_DESTROY(&ips_icmptq.ifq_lock);
MUTEX_DESTROY(&ips_udpacktq.ifq_lock);
MUTEX_DESTROY(&ips_icmpacktq.ifq_lock);
- fr_state_init = 0;
+ MUTEX_DESTROY(&ips_iptq.ifq_lock);
}
if (ips_table != NULL) {
@@ -335,8 +352,8 @@ void fr_stateunload()
if (fr_state_init == 1) {
fr_state_init = 0;
+ RW_DESTROY(&ipf_state);
MUTEX_DESTROY(&ipf_stinsert);
- MUTEX_INIT(&ipf_stinsert, "ipf stat insert mutex");
}
}
@@ -408,11 +425,7 @@ caddr_t data;
/* ------------------------------------------------------------------------ */
int fr_state_ioctl(data, cmd, mode)
caddr_t data;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
int mode;
{
int arg, ret, error = 0;
@@ -429,23 +442,23 @@ int mode;
* Flush the state table
*/
case SIOCIPFFL :
- (void) BCOPYIN(data, (char *)&arg, sizeof(arg));
+ BCOPYIN(data, (char *)&arg, sizeof(arg));
if (arg == 0 || arg == 1) {
WRITE_ENTER(&ipf_state);
ret = fr_state_flush(arg, 4);
RWLOCK_EXIT(&ipf_state);
- (void) BCOPYOUT((char *)&ret, data, sizeof(ret));
+ BCOPYOUT((char *)&ret, data, sizeof(ret));
} else
error = EINVAL;
break;
#ifdef USE_INET6
case SIOCIPFL6 :
- (void) BCOPYIN(data, (char *)&arg, sizeof(arg));
+ BCOPYIN(data, (char *)&arg, sizeof(arg));
if (arg == 0 || arg == 1) {
WRITE_ENTER(&ipf_state);
ret = fr_state_flush(arg, 6);
RWLOCK_EXIT(&ipf_state);
- (void) BCOPYOUT((char *)&ret, data, sizeof(ret));
+ BCOPYOUT((char *)&ret, data, sizeof(ret));
} else
error = EINVAL;
break;
@@ -461,7 +474,7 @@ int mode;
int tmp;
tmp = ipflog_clear(IPL_LOGSTATE);
- (void) BCOPYOUT((char *)&tmp, data, sizeof(tmp));
+ BCOPYOUT((char *)&tmp, data, sizeof(tmp));
}
break;
/*
@@ -471,7 +484,7 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else {
- (void) BCOPYIN((char *)data, (char *)&ipstate_logging,
+ BCOPYIN((char *)data, (char *)&ipstate_logging,
sizeof(ipstate_logging));
}
break;
@@ -479,15 +492,15 @@ int mode;
* Return the current state of logging.
*/
case SIOCGETLG :
- (void) BCOPYOUT((char *)&ipstate_logging, (char *)data,
- sizeof(ipstate_logging));
+ BCOPYOUT((char *)&ipstate_logging, (char *)data,
+ sizeof(ipstate_logging));
break;
/*
* Return the number of bytes currently waiting to be read.
*/
case FIONREAD :
arg = iplused[IPL_LOGSTATE]; /* returned in an int */
- (void) BCOPYOUT((char *)&arg, data, sizeof(arg));
+ BCOPYOUT((char *)&arg, data, sizeof(arg));
break;
#endif
/*
@@ -501,13 +514,17 @@ int mode;
* means no packets match).
*/
case SIOCSTLCK :
- error = fr_lock(data, &fr_state_lock);
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ } else {
+ fr_lock(data, &fr_state_lock);
+ }
break;
/*
* Add an entry to the current state table.
*/
case SIOCSTPUT :
- if (!fr_state_lock) {
+ if (!fr_state_lock || !(mode &FWRITE)) {
error = EACCES;
break;
}
@@ -575,7 +592,8 @@ caddr_t data;
}
ips.ips_next = isn->is_next;
bcopy((char *)isn, (char *)&ips.ips_is, sizeof(ips.ips_is));
- if (isn->is_rule)
+ ips.ips_rule = isn->is_rule;
+ if (isn->is_rule != NULL)
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
error = fr_outobj(data, &ips, IPFOBJ_STATESAVE);
@@ -600,7 +618,7 @@ caddr_t data;
{
ipstate_t *is, *isn;
ipstate_save_t ips;
- int error, out, i;
+ int error, i;
frentry_t *fr;
char *name;
@@ -613,12 +631,23 @@ caddr_t data;
return ENOMEM;
bcopy((char *)&ips.ips_is, (char *)isn, sizeof(*isn));
- MUTEX_NUKE(&isn->is_lock);
+ bzero((char *)isn, offsetof(struct ipstate, is_pkts));
+ isn->is_sti.tqe_pnext = NULL;
+ isn->is_sti.tqe_next = NULL;
+ isn->is_sti.tqe_ifq = NULL;
+ isn->is_sti.tqe_parent = isn;
+ isn->is_ifp[0] = NULL;
+ isn->is_ifp[1] = NULL;
+ isn->is_ifp[2] = NULL;
+ isn->is_ifp[3] = NULL;
isn->is_sync = NULL;
- fr = isn->is_rule;
+ fr = ips.ips_rule;
+
if (fr == NULL) {
- fr_stinsert(isn);
+ READ_ENTER(&ipf_state);
+ fr_stinsert(isn, 0);
MUTEX_EXIT(&isn->is_lock);
+ RWLOCK_EXIT(&ipf_state);
return 0;
}
@@ -629,7 +658,6 @@ caddr_t data;
return ENOMEM;
}
bcopy((char *)&ips.ips_fr, (char *)fr, sizeof(*fr));
- out = fr->fr_flags & FR_OUTQUE ? 1 : 0;
isn->is_rule = fr;
ips.ips_is.is_rule = fr;
MUTEX_NUKE(&fr->fr_lock);
@@ -640,26 +668,17 @@ caddr_t data;
*/
for (i = 0; i < 4; i++) {
name = fr->fr_ifnames[i];
- if ((name[1] == '\0') &&
- ((name[0] == '-') || (name[0] == '*'))) {
- fr->fr_ifas[i] = NULL;
- } else if (*name != '\0') {
- fr->fr_ifas[i] = GETIFP(name, fr->fr_v);
- if (fr->fr_ifas[i] == NULL)
- fr->fr_ifas[i] = (void *)-1;
- else {
- (void) COPYIFNAME(fr->fr_ifas[i],
- isn->is_ifname[i]);
- }
- }
- isn->is_ifp[out] = fr->fr_ifas[i];
+ fr->fr_ifas[i] = fr_resolvenic(name, fr->fr_v);
+ name = isn->is_ifname[i];
+ isn->is_ifp[i] = fr_resolvenic(name, isn->is_v);
}
+ fr->fr_ref = 0;
fr->fr_dsize = 0;
fr->fr_data = NULL;
- fr_resolvdest(&fr->fr_tif, fr->fr_v);
- fr_resolvdest(&fr->fr_dif, fr->fr_v);
+ fr_resolvedest(&fr->fr_tif, fr->fr_v);
+ fr_resolvedest(&fr->fr_dif, fr->fr_v);
/*
* send a copy back to userland of what we ended up
@@ -672,58 +691,71 @@ caddr_t data;
KFREE(fr);
return EFAULT;
}
+ READ_ENTER(&ipf_state);
+ fr_stinsert(isn, 0);
+ MUTEX_EXIT(&isn->is_lock);
+ RWLOCK_EXIT(&ipf_state);
+
} else {
+ READ_ENTER(&ipf_state);
for (is = ips_list; is; is = is->is_next)
- if (is->is_rule == fr)
+ if (is->is_rule == fr) {
+ fr_stinsert(isn, 0);
+ MUTEX_EXIT(&isn->is_lock);
break;
- if (!is) {
+ }
+
+ if (is == NULL) {
KFREE(isn);
- return ESRCH;
+ isn = NULL;
}
+ RWLOCK_EXIT(&ipf_state);
+
+ return (isn == NULL) ? ESRCH : 0;
}
- fr_stinsert(isn);
- MUTEX_EXIT(&isn->is_lock);
+
return 0;
}
/* ------------------------------------------------------------------------ */
-/* Function: fr_stinsert */
-/* Returns: Nil */
-/* Parameters: is(I) - pointer to state structure */
+/* Function: fr_stinsert */
+/* Returns: Nil */
+/* Parameters: is(I) - pointer to state structure */
+/* rev(I) - flag indicating forward/reverse direction of packet */
/* */
/* Inserts a state structure into the hash table (for lookups) and the list */
/* of state entries (for enumeration). Resolves all of the interface names */
/* to pointers and adjusts running stats for the hash table as appropriate. */
-/* */
-/* NOTE: Holds a lock for is_lock mutex upon return. */
-/* */
+/* */
+/* Locking: it is assumed that some kind of lock on ipf_state is held. */
+/* Exits with is_lock initialised and held. */
/* ------------------------------------------------------------------------ */
-void fr_stinsert(is)
+void fr_stinsert(is, rev)
ipstate_t *is;
+int rev;
{
+ frentry_t *fr;
u_int hv;
- char *name;
int i;
- is->is_sti.tqe_parent = is;
-
MUTEX_INIT(&is->is_lock, "ipf state entry");
- MUTEX_ENTER(&is->is_lock);
+
+ fr = is->is_rule;
+ if (fr != NULL) {
+ MUTEX_ENTER(&fr->fr_lock);
+ fr->fr_ref++;
+ fr->fr_statecnt++;
+ MUTEX_EXIT(&fr->fr_lock);
+ }
/*
* Look up all the interface names in the state entry.
*/
for (i = 0; i < 4; i++) {
- name = is->is_ifname[i];
- if ((name[1] == '\0') &&
- ((name[0] == '-') || (name[0] == '*'))) {
- is->is_ifp[0] = NULL;
- } else if (*name != '\0') {
- is->is_ifp[i] = GETIFP(name, is->is_v);
- if (is->is_ifp[i] == NULL)
- is->is_ifp[i] = (void *)-1;
- }
+ if (is->is_ifp[i] != NULL)
+ continue;
+ is->is_ifp[i] = fr_resolvenic(is->is_ifname[i], is->is_v);
}
/*
@@ -733,6 +765,12 @@ ipstate_t *is;
hv = is->is_hv % fr_statesize;
is->is_hv = hv;
+ /*
+ * We need to get both of these locks...the first because it is
+ * possible that once the insert is complete another packet might
+ * come along, match the entry and want to update it.
+ */
+ MUTEX_ENTER(&is->is_lock);
MUTEX_ENTER(&ipf_stinsert);
/*
@@ -754,6 +792,8 @@ ipstate_t *is;
ips_stats.iss_bucketlen[hv]++;
ips_num++;
MUTEX_EXIT(&ipf_stinsert);
+
+ fr_setstatequeue(is, rev);
}
@@ -781,12 +821,14 @@ u_int flags;
frentry_t *fr;
tcphdr_t *tcp;
grehdr_t *gre;
- ipftq_t *ifq;
void *ifp;
int out;
if (fr_state_lock ||
- (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGTAIL|FI_BAD|FI_OOW)))
+ (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD)))
+ return NULL;
+
+ if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN))
return NULL;
fr = fin->fin_fr;
@@ -813,12 +855,10 @@ u_int flags;
ic = NULL;
tcp = NULL;
- ifq = NULL;
out = fin->fin_out;
is = &ips;
bzero((char *)is, sizeof(*is));
is->is_die = 1 + fr_ticks;
- is->is_flags = flags & IS_INHERITED;
/*
* Copy and calculate...
@@ -864,15 +904,11 @@ u_int flags;
case IPPROTO_ICMPV6 :
ic = fin->fin_dp;
- if ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0)
- return NULL;
-
switch (ic->icmp_type)
{
case ICMP6_ECHO_REQUEST :
is->is_icmp.ici_type = ic->icmp_type;
hv += (is->is_icmp.ici_id = ic->icmp_id);
- hv += (is->is_icmp.ici_seq = ic->icmp_seq);
break;
case ICMP6_MEMBERSHIP_QUERY :
case ND_ROUTER_SOLICIT :
@@ -884,7 +920,6 @@ u_int flags;
return NULL;
}
ATOMIC_INCL(ips_stats.iss_icmp);
- ifq = &ips_icmptq;
break;
#endif
case IPPROTO_ICMP :
@@ -898,13 +933,11 @@ u_int flags;
case ICMP_MASKREQ :
is->is_icmp.ici_type = ic->icmp_type;
hv += (is->is_icmp.ici_id = ic->icmp_id);
- hv += (is->is_icmp.ici_seq = ic->icmp_seq);
break;
default :
return NULL;
}
ATOMIC_INCL(ips_stats.iss_icmp);
- ifq = &ips_icmptq;
break;
case IPPROTO_GRE :
@@ -912,9 +945,10 @@ u_int flags;
is->is_gre.gs_flags = gre->gr_flags;
is->is_gre.gs_ptype = gre->gr_ptype;
- is->is_gre.gs_call = gre->gr_call;
- hv += is->is_gre.gs_call;
- ifq = &ips_udptq;
+ if (GRE_REV(is->is_gre.gs_flags) == 1) {
+ is->is_call[0] = fin->fin_data[0];
+ is->is_call[1] = fin->fin_data[1];
+ }
break;
case IPPROTO_TCP :
@@ -937,6 +971,12 @@ u_int flags;
* If this is a real packet then initialise fields in the
* state information structure from the TCP header information.
*/
+
+ is->is_maxdwin = 1;
+ is->is_maxswin = ntohs(tcp->th_win);
+ if (is->is_maxswin == 0)
+ is->is_maxswin = 1;
+
if ((fin->fin_flx & FI_IGNORE) == 0) {
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
(TCP_OFF(tcp) << 2) +
@@ -963,15 +1003,15 @@ u_int flags;
}
if ((tcp->th_flags & TH_OPENING) == TH_SYN)
- is->is_flags |= IS_TCPFSM;
+ flags |= IS_TCPFSM;
+ else {
+ is->is_maxdwin = is->is_maxswin * 2;
+ is->is_dend = ntohl(tcp->th_ack);
+ is->is_maxdend = ntohl(tcp->th_ack);
+ is->is_maxdwin *= 2;
+ }
}
- is->is_maxdwin = 1;
- is->is_maxswin = ntohs(tcp->th_win);
- if (is->is_maxswin == 0)
- is->is_maxswin = 1;
-
- ifq = ips_tqtqb;
/*
* If we're creating state for a starting connection, start the
* timer on it as we'll never see an error if it fails to
@@ -990,16 +1030,15 @@ u_int flags;
hv += tcp->th_sport;
}
ATOMIC_INCL(ips_stats.iss_udp);
- ifq = &ips_udptq;
break;
default :
- ifq = &ips_udptq;
break;
}
hv = DOUBLE_HASH(hv);
is->is_hv = hv;
is->is_rule = fr;
+ is->is_flags = flags & IS_INHERITED;
/*
* Look for identical state.
@@ -1029,19 +1068,17 @@ u_int flags;
*/
if (fr != NULL) {
(void) strncpy(is->is_group, fr->fr_group, FR_GROUPLEN);
- MUTEX_ENTER(&fr->fr_lock);
- fr->fr_ref++;
- fr->fr_statecnt++;
- MUTEX_EXIT(&fr->fr_lock);
if (fr->fr_age[0] != 0) {
is->is_tqehead[0] = fr_addtimeoutqueue(&ips_utqe,
fr->fr_age[0]);
- is->is_tqehead[1] = is->is_tqehead[0];
is->is_sti.tqe_flags |= TQE_RULEBASED;
}
- if (fr->fr_age[0] != 0 && fr->fr_age[1] != fr->fr_age[0])
+ if (fr->fr_age[1] != 0) {
is->is_tqehead[1] = fr_addtimeoutqueue(&ips_utqe,
fr->fr_age[1]);
+ is->is_sti.tqe_flags |= TQE_RULEBASED;
+ }
+
is->is_tag = fr->fr_logtag;
is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1];
@@ -1050,15 +1087,15 @@ u_int flags;
if (((ifp = fr->fr_ifas[1]) != NULL) &&
(ifp != (void *)-1)) {
- (void) COPYIFNAME(ifp, is->is_ifname[(out << 1) + 1]);
+ COPYIFNAME(ifp, is->is_ifname[(out << 1) + 1]);
}
if (((ifp = fr->fr_ifas[2]) != NULL) &&
(ifp != (void *)-1)) {
- (void) COPYIFNAME(ifp, is->is_ifname[(1 - out) << 1]);
+ COPYIFNAME(ifp, is->is_ifname[(1 - out) << 1]);
}
if (((ifp = fr->fr_ifas[3]) != NULL) &&
(ifp != (void *)-1)) {
- (void) COPYIFNAME(ifp, is->is_ifname[((1 - out) << 1) + 1]);
+ COPYIFNAME(ifp, is->is_ifname[((1 - out) << 1) + 1]);
}
} else {
pass = fr_flags;
@@ -1067,10 +1104,15 @@ u_int flags;
is->is_ifp[out << 1] = fin->fin_ifp;
if (fin->fin_ifp != NULL) {
- (void) COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
+ COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
}
- is->is_ref = 1;
+ /*
+ * It may seem strange to set is_ref to 2, but fr_check() will call
+ * fr_statederef() after calling fr_addstate() and the idea is to
+ * have it exist at the end of fr_check() with is_ref == 1.
+ */
+ is->is_ref = 2;
is->is_pass = pass;
is->is_pkts[0] = 0, is->is_bytes[0] = 0;
is->is_pkts[1] = 0, is->is_bytes[1] = 0;
@@ -1078,33 +1120,31 @@ u_int flags;
is->is_pkts[3] = 0, is->is_bytes[3] = 0;
if ((fin->fin_flx & FI_IGNORE) == 0) {
is->is_pkts[out] = 1;
- is->is_bytes[out] = fin->fin_dlen + fin->fin_hlen;
+ is->is_bytes[out] = fin->fin_plen;
is->is_flx[out][0] = fin->fin_flx & FI_CMP;
+ is->is_flx[out][0] &= ~FI_OOW;
}
if (pass & FR_STSTRICT)
is->is_flags |= IS_STRICT;
+ if (pass & FR_STATESYNC)
+ is->is_flags |= IS_STATESYNC;
+
/*
* We want to check everything that is a property of this packet,
* but we don't (automatically) care about it's fragment status as
* this may change.
*/
is->is_v = fin->fin_v;
- if (is->is_v == 6) { /* Only IPv6 has fragment options */
- /*
- * XXX - This magic value 0x08 comes from ip6exthdr[]. In time
- * the flag values for IPv6 extension headers should be given a
- * symbolic name rather than used like this.
- */
- is->is_opt[0] = fin->fin_optmsk & ~(0x08);
- is->is_optmsk[0] = 0xffffffff & ~(0x08);
- } else {
- is->is_opt[0] = fin->fin_optmsk;
- is->is_optmsk[0] = 0xffffffff;
+ is->is_opt[0] = fin->fin_optmsk;
+ is->is_optmsk[0] = 0xffffffff;
+ is->is_optmsk[1] = 0xffffffff;
+ if (is->is_v == 6) {
+ is->is_opt[0] &= ~0x8;
+ is->is_optmsk[0] &= ~0x8;
+ is->is_optmsk[1] &= ~0x8;
}
- is->is_opt[1] = 0;
- is->is_optmsk[1] = 0;
is->is_sec = fin->fin_secmsk;
is->is_secmsk = 0xffff;
is->is_auth = fin->fin_auth;
@@ -1120,19 +1160,8 @@ u_int flags;
READ_ENTER(&ipf_state);
is->is_me = stsave;
- fr_stinsert(is);
- /*
- * Add the state entry to the end of this timeout queue.
- */
- MUTEX_ENTER(&ifq->ifq_lock);
- is->is_sti.tqe_pnext = ifq->ifq_tail;
- *ifq->ifq_tail = &is->is_sti;
- ifq->ifq_tail = &is->is_sti.tqe_next;
- is->is_sti.tqe_next = NULL;
- is->is_sti.tqe_ifq = ifq;
- is->is_sti.tqe_die = fr_ticks + ifq->ifq_ttl;
- MUTEX_EXIT(&ifq->ifq_lock);
+ fr_stinsert(is, fin->fin_rev);
if (fin->fin_p == IPPROTO_TCP) {
/*
@@ -1141,19 +1170,25 @@ u_int flags;
* connect.
*/
(void) fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags);
+ MUTEX_EXIT(&is->is_lock);
#ifdef IPFILTER_SCAN
- (void) isc_attachis(is);
+ if ((is->is_flags & SI_CLONE) == 0)
+ (void) ipsc_attachis(is);
#endif
+ } else {
+ MUTEX_EXIT(&is->is_lock);
}
#ifdef IPFILTER_SYNC
- is->is_sync = ipfsync_new(SMC_STATE, fin, is);
+ if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0))
+ is->is_sync = ipfsync_new(SMC_STATE, fin, is);
#endif
if (ipstate_logging)
ipstate_log(is, ISL_NEW);
- MUTEX_EXIT(&is->is_lock);
RWLOCK_EXIT(&ipf_state);
+ fin->fin_state = is;
fin->fin_rev = IP6_NEQ(&is->is_dst, &fin->fin_daddr);
+ fin->fin_flx |= FI_STATE;
if (fin->fin_flx & FI_FRAG)
(void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
@@ -1180,13 +1215,14 @@ tcpdata_t *td;
char buf[64], *s, opt;
mb_t *m = NULL;
- off = fin->fin_hlen + sizeof(*tcp);
- len = (TCP_OFF(tcp) << 2) - sizeof(*tcp);
- if (fin->fin_plen < off + len)
+ len = (TCP_OFF(tcp) << 2);
+ if (fin->fin_dlen < len)
return 0;
+ len -= sizeof(*tcp);
+
+ off = fin->fin_plen - fin->fin_dlen + sizeof(*tcp) + fin->fin_ipoff;
m = fin->fin_m;
- off += (char *)fin->fin_ip - MTOD(m, char *);
mlen = MSGDSIZE(m) - off;
if (len > mlen) {
len = mlen;
@@ -1267,7 +1303,8 @@ ipstate_t *is;
tcpdata_t *fdata, *tdata;
source = !fin->fin_rev;
- if (source && (ntohs(is->is_sport) != fin->fin_data[0]))
+ if (((is->is_flags & IS_TCPFSM) != 0) && (source == 1) &&
+ (ntohs(is->is_sport) != fin->fin_data[0]))
source = 0;
fdata = &is->is_tcp.ts_data[!source];
tdata = &is->is_tcp.ts_data[source];
@@ -1276,7 +1313,7 @@ ipstate_t *is;
if (fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags)) {
#ifdef IPFILTER_SCAN
if (is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER)) {
- isc_packet(fin, is);
+ ipsc_packet(fin, is);
if (FR_ISBLOCK(is->is_pass)) {
MUTEX_EXIT(&is->is_lock);
return 1;
@@ -1329,6 +1366,7 @@ ipstate_t *is;
fr_checknewisn(fin, is);
}
+ ret = 1;
} else
fin->fin_flx |= FI_OOW;
MUTEX_EXIT(&is->is_lock);
@@ -1361,7 +1399,7 @@ ipstate_t *is;
if (((i == 0) && !(is->is_flags & IS_ISNSYN)) ||
((i == 1) && !(is->is_flags & IS_ISNACK))) {
- old = tcp->th_seq;
+ old = ntohl(tcp->th_seq);
new = fr_newisn(fin);
is->is_isninc[i] = new - old;
CALC_SUMD(old, new, sumd);
@@ -1376,8 +1414,8 @@ ipstate_t *is;
/* Function: fr_tcpinwindow */
/* Returns: int - 1 == packet inside TCP "window", 0 == not inside. */
/* Parameters: fin(I) - pointer to packet information */
-/* fdata(I) - pointer to tcp state informatio (reverse) */
-/* tdata(I) - pointer to tcp state informatio (forward) */
+/* fdata(I) - pointer to tcp state informatio (forward) */
+/* tdata(I) - pointer to tcp state informatio (reverse) */
/* tcp(I) - pointer to TCP packet header */
/* */
/* Given a packet has matched addresses and ports, check to see if it is */
@@ -1428,8 +1466,8 @@ int flags;
tdata->td_winscale = 0;
tdata->td_winflags = 0;
}
- }
-
+ }
+
end = seq + fin->fin_dlen - (TCP_OFF(tcp) << 2) +
((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0);
@@ -1525,7 +1563,6 @@ tcphdr_t *tcp;
ipstate_t *is;
{
ipstate_t *clone;
- frentry_t *fr;
u_32_t send;
if (ips_num == fr_statemax) {
@@ -1565,21 +1602,22 @@ ipstate_t *is;
clone->is_maxswin = 1;
}
- fr = clone->is_rule;
- if (fr != NULL) {
- MUTEX_ENTER(&fr->fr_lock);
- fr->fr_ref++;
- fr->fr_statecnt++;
- MUTEX_EXIT(&fr->fr_lock);
- }
clone->is_flags &= ~SI_CLONE;
clone->is_flags |= SI_CLONED;
- fr_stinsert(clone);
- clone->is_ref = 1;
+ fr_stinsert(clone, fin->fin_rev);
+ clone->is_ref = 2;
if (clone->is_p == IPPROTO_TCP) {
- (void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb, clone->is_flags);
+ (void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb,
+ clone->is_flags);
}
MUTEX_EXIT(&clone->is_lock);
+#ifdef IPFILTER_SCAN
+ (void) ipsc_attachis(is);
+#endif
+#ifdef IPFILTER_SYNC
+ if (is->is_flags & IS_STATESYNC)
+ clone->is_sync = ipfsync_new(SMC_STATE, fin, clone);
+#endif
return clone;
}
@@ -1597,28 +1635,31 @@ ipstate_t *is;
/* ret gets set to one if the match succeeds, else remains 0. If it is */
/* still 0 after the test. no match. */
/* ------------------------------------------------------------------------ */
-static ipstate_t *fr_matchsrcdst(fin, is, src, dst, tcp)
+static ipstate_t *fr_matchsrcdst(fin, is, src, dst, tcp, cmask)
fr_info_t *fin;
ipstate_t *is;
i6addr_t *src, *dst;
tcphdr_t *tcp;
+u_32_t cmask;
{
int ret = 0, rev, out, flags, flx = 0, idx;
u_short sp, dp;
+ u_32_t cflx;
void *ifp;
rev = IP6_NEQ(&is->is_dst, dst);
ifp = fin->fin_ifp;
out = fin->fin_out;
- flags = is->is_flags & (SI_WILDA);
+ flags = is->is_flags;
sp = 0;
dp = 0;
if (tcp != NULL) {
- flags = is->is_flags;
- sp = tcp->th_sport;
- dp = tcp->th_dport;
- if (!rev) {
+ sp = htons(fin->fin_sport);
+ dp = ntohs(fin->fin_dport);
+ }
+ if (!rev) {
+ if (tcp != NULL) {
if (!(flags & SI_W_SPORT) && (sp != is->is_sport))
rev = 1;
else if (!(flags & SI_W_DPORT) && (dp != is->is_dport))
@@ -1646,19 +1687,28 @@ tcphdr_t *tcp;
*/
if (rev == 0) {
if ((IP6_EQ(&is->is_dst, dst) || (flags & SI_W_DADDR)) &&
- (IP6_EQ(&is->is_src, src) || (flags & SI_W_SADDR)) &&
- (!tcp || ((sp == is->is_sport || flags & SI_W_SPORT) &&
- (dp == is->is_dport || flags & SI_W_DPORT)))) {
- ret = 1;
+ (IP6_EQ(&is->is_src, src) || (flags & SI_W_SADDR))) {
+ if (tcp) {
+ if ((sp == is->is_sport || flags & SI_W_SPORT)&&
+ (dp == is->is_dport || flags & SI_W_DPORT))
+ ret = 1;
+ } else {
+ ret = 1;
+ }
}
} else {
if ((IP6_EQ(&is->is_dst, src) || (flags & SI_W_DADDR)) &&
- (IP6_EQ(&is->is_src, dst) || (flags & SI_W_SADDR)) &&
- (!tcp || ((sp == is->is_dport || flags & SI_W_DPORT) &&
- (dp == is->is_sport || flags & SI_W_SPORT)))) {
- ret = 1;
+ (IP6_EQ(&is->is_src, dst) || (flags & SI_W_SADDR))) {
+ if (tcp) {
+ if ((dp == is->is_sport || flags & SI_W_SPORT)&&
+ (sp == is->is_dport || flags & SI_W_DPORT))
+ ret = 1;
+ } else {
+ ret = 1;
+ }
}
}
+
if (ret == 0)
return NULL;
@@ -1733,12 +1783,13 @@ tcphdr_t *tcp;
}
}
- flx = fin->fin_flx & FI_CMP;
+ flx = fin->fin_flx & cmask;
+ cflx = is->is_flx[out][rev];
/*
* Match up any flags set from IP options.
*/
- if ((is->is_flx[out][rev] && (flx != is->is_flx[out][rev])) ||
+ if ((cflx && (flx != (cflx & cmask))) ||
((fin->fin_optmsk & is->is_optmsk[rev]) != is->is_opt[rev]) ||
((fin->fin_secmsk & is->is_secmsk) != is->is_sec) ||
((fin->fin_auth & is->is_authmsk) != is->is_auth))
@@ -1756,9 +1807,12 @@ tcphdr_t *tcp;
if ((flags & (SI_W_SPORT|SI_W_DPORT))) {
if ((flags & SI_CLONE) != 0) {
- is = fr_stclone(fin, tcp, is);
- if (is == NULL)
+ ipstate_t *clone;
+
+ clone = fr_stclone(fin, tcp, is);
+ if (clone == NULL)
return NULL;
+ is = clone;
} else {
ATOMIC_DECL(ips_stats.iss_wild);
}
@@ -1766,19 +1820,19 @@ tcphdr_t *tcp;
if ((flags & SI_W_SPORT) != 0) {
if (rev == 0) {
is->is_sport = sp;
- is->is_send = htonl(tcp->th_seq);
+ is->is_send = ntohl(tcp->th_seq);
} else {
is->is_sport = dp;
- is->is_send = htonl(tcp->th_ack);
+ is->is_send = ntohl(tcp->th_ack);
}
is->is_maxsend = is->is_send + 1;
} else if ((flags & SI_W_DPORT) != 0) {
if (rev == 0) {
is->is_dport = dp;
- is->is_dend = htonl(tcp->th_ack);
+ is->is_dend = ntohl(tcp->th_ack);
} else {
is->is_dport = sp;
- is->is_dend = htonl(tcp->th_seq);
+ is->is_dend = ntohl(tcp->th_seq);
}
is->is_maxdend = is->is_dend + 1;
}
@@ -1791,12 +1845,10 @@ tcphdr_t *tcp;
if (is->is_flx[out][rev] == 0) {
is->is_flx[out][rev] = flx;
- if (is->is_v == 6) { /* Only IPv6 has fragment options */
- is->is_opt[rev] = fin->fin_optmsk & ~(0x08);
- is->is_optmsk[rev] = 0xffffffff & ~(0x08);
- } else {
- is->is_opt[rev] = fin->fin_optmsk;
- is->is_optmsk[rev] = 0xffffffff;
+ is->is_opt[rev] = fin->fin_optmsk;
+ if (is->is_v == 6) {
+ is->is_opt[rev] &= ~0x8;
+ is->is_optmsk[rev] &= ~0x8;
}
}
@@ -1807,7 +1859,7 @@ tcphdr_t *tcp;
if (is->is_ifp[idx] == NULL &&
(*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) {
is->is_ifp[idx] = ifp;
- (void) COPYIFNAME(fin->fin_ifp, is->is_ifname[idx]);
+ COPYIFNAME(ifp, is->is_ifname[idx]);
}
fin->fin_rev = rev;
return is;
@@ -1831,34 +1883,28 @@ fr_info_t *fin;
ipstate_t *is, **isp;
u_short sport, dport;
u_char pr;
+ int backward, i, oi;
i6addr_t dst, src;
struct icmp *ic;
u_short savelen;
icmphdr_t *icmp;
- int backward, i;
fr_info_t ofin;
tcphdr_t *tcp;
- int type, len;
+ int len;
ip_t *oip;
u_int hv;
/*
* Does it at least have the return (basic) IP header ?
+ * Is it an actual recognised ICMP error type?
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
if ((fin->fin_v != 4) || (fin->fin_hlen != sizeof(ip_t)) ||
- (fin->fin_plen < ICMPERR_MINPKTLEN))
+ (fin->fin_plen < ICMPERR_MINPKTLEN) ||
+ !(fin->fin_flx & FI_ICMPERR))
return NULL;
ic = fin->fin_dp;
- type = ic->icmp_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&
- (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) &&
- (type != ICMP_PARAMPROB))
- return NULL;
oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
/*
@@ -1921,7 +1967,7 @@ fr_info_t *fin;
*/
savelen = oip->ip_len;
oip->ip_len = len;
- oip->ip_off = htons(oip->ip_off);
+ oip->ip_off = ntohs(oip->ip_off);
ofin.fin_flx = FI_NOCKSUM;
ofin.fin_v = 4;
@@ -1949,8 +1995,6 @@ fr_info_t *fin;
switch (oip->ip_p)
{
case IPPROTO_ICMP :
- icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2));
-
/*
* an ICMP error can only be generated as a result of an
* ICMP query, not as the response on an ICMP error
@@ -1958,39 +2002,52 @@ fr_info_t *fin;
* XXX theoretically ICMP_ECHOREP and the other reply's are
* ICMP query's as well, but adding them here seems strange XXX
*/
- if ((icmp->icmp_type != ICMP_ECHO) &&
- (icmp->icmp_type != ICMP_TSTAMP) &&
- (icmp->icmp_type != ICMP_IREQ) &&
- (icmp->icmp_type != ICMP_MASKREQ))
+ if ((ofin.fin_flx & FI_ICMPERR) != 0)
return NULL;
/*
* perform a lookup of the ICMP packet in the state table
*/
+ icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2));
hv = (pr = oip->ip_p);
src.in4 = oip->ip_src;
hv += src.in4.s_addr;
dst.in4 = oip->ip_dst;
hv += dst.in4.s_addr;
hv += icmp->icmp_id;
- hv += icmp->icmp_seq;
hv = DOUBLE_HASH(hv);
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) {
isp = &is->is_hnext;
- if ((is->is_p != pr) || (is->is_v != 4) ||
- (is->is_pass & FR_NOICMPERR))
+ if ((is->is_p != pr) || (is->is_v != 4))
continue;
- is = fr_matchsrcdst(&ofin, is, &src, &dst, NULL);
- if (is != NULL &&
- fr_matchicmpqueryreply(is->is_v, &is->is_icmp,
- icmp, fin->fin_rev)) {
- backward = IP6_NEQ(&is->is_src, &dst);
- i = (backward << 1) + fin->fin_out;
+ if (is->is_pass & FR_NOICMPERR)
+ continue;
+ is = fr_matchsrcdst(&ofin, is, &src, &dst,
+ NULL, FI_ICMPCMP);
+ if (is != NULL) {
+ if ((is->is_pass & FR_NOICMPERR) != 0) {
+ RWLOCK_EXIT(&ipf_state);
+ return NULL;
+ }
+ /*
+ * i : the index of this packet (the icmp
+ * unreachable)
+ * oi : the index of the original packet found
+ * in the icmp header (i.e. the packet
+ * causing this icmp)
+ * backward : original packet was backward
+ * compared to the state
+ */
+ backward = IP6_NEQ(&is->is_src, &src);
+ fin->fin_rev = !backward;
+ i = (!backward << 1) + fin->fin_out;
+ oi = (backward << 1) + ofin.fin_out;
+ if (is->is_icmppkts[i] > is->is_pkts[oi])
+ continue;
ips_stats.iss_hits++;
- is->is_pkts[i]++;
- is->is_bytes[i] += fin->fin_plen;
+ is->is_icmppkts[i]++;
return is;
}
}
@@ -2029,13 +2086,25 @@ fr_info_t *fin;
* short flag is set.
*/
if ((is->is_p == pr) && (is->is_v == 4) &&
- !(is->is_pass & FR_NOICMPERR) &&
- (is = fr_matchsrcdst(&ofin, is, &src, &dst, tcp))) {
- backward = IP6_NEQ(&is->is_dst, &src);
- i = (backward << 1) + fin->fin_out;
+ (is = fr_matchsrcdst(&ofin, is, &src, &dst,
+ tcp, FI_ICMPCMP))) {
+ /*
+ * i : the index of this packet (the icmp unreachable)
+ * oi : the index of the original packet found in the
+ * icmp header (i.e. the packet causing this icmp)
+ * backward : original packet was backward compared to
+ * the state
+ */
+ backward = IP6_NEQ(&is->is_src, &src);
+ fin->fin_rev = !backward;
+ i = (!backward << 1) + fin->fin_out;
+ oi = (backward << 1) + ofin.fin_out;
+
+ if (((is->is_pass & FR_NOICMPERR) != 0) ||
+ (is->is_icmppkts[i] > is->is_pkts[oi]))
+ break;
ips_stats.iss_hits++;
- is->is_pkts[i]++;
- is->is_bytes[i] += fin->fin_plen;
+ is->is_icmppkts[i]++;
/*
* we deliberately do not touch the timeouts
* for the accompanying state table entry.
@@ -2119,8 +2188,8 @@ ipftq_t **ifqp;
u_short dport, sport;
i6addr_t src, dst;
struct icmp *ic;
- grehdr_t *gre;
ipftq_t *ifq;
+ int oow;
is = NULL;
ifq = NULL;
@@ -2157,13 +2226,11 @@ ipftq_t **ifqp;
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
- tcp = NULL;
tryagain = 0;
if (v == 6) {
if ((ic->icmp_type == ICMP6_ECHO_REQUEST) ||
(ic->icmp_type == ICMP6_ECHO_REPLY)) {
hv += ic->icmp_id;
- hv += ic->icmp_seq;
}
}
READ_ENTER(&ipf_state);
@@ -2173,16 +2240,14 @@ icmp6again:
isp = &is->is_hnext;
if ((is->is_p != pr) || (is->is_v != v))
continue;
- is = fr_matchsrcdst(fin, is, &src, &dst, NULL);
+ is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
if (is != NULL &&
fr_matchicmpqueryreply(v, &is->is_icmp,
ic, fin->fin_rev)) {
- if (!(is->is_sti.tqe_flags & TQE_RULEBASED)) {
- if (fin->fin_rev)
- ifq = &ips_icmpacktq;
- else
- ifq = &ips_icmptq;
- }
+ if (fin->fin_rev)
+ ifq = &ips_icmpacktq;
+ else
+ ifq = &ips_icmptq;
break;
}
}
@@ -2203,6 +2268,12 @@ icmp6again:
/*
* No matching icmp state entry. Perhaps this is a
* response to another state entry.
+ *
+ * XXX With some ICMP6 packets, the "other" address is already
+ * in the packet, after the ICMP6 header, and this could be
+ * used in place of the multicast address. However, taking
+ * advantage of this requires some significant code changes
+ * to handle the specific types where that is the case.
*/
if ((ips_stats.iss_wild != 0) && (v == 6) && (tryagain == 0) &&
!IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_src.in6)) {
@@ -2224,7 +2295,6 @@ icmp6again:
case IPPROTO_ICMP :
if (v == 4) {
hv += ic->icmp_id;
- hv += ic->icmp_seq;
}
hv = DOUBLE_HASH(hv);
READ_ENTER(&ipf_state);
@@ -2232,16 +2302,14 @@ icmp6again:
isp = &is->is_hnext;
if ((is->is_p != pr) || (is->is_v != v))
continue;
- is = fr_matchsrcdst(fin, is, &src, &dst, NULL);
+ is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
if (is != NULL &&
fr_matchicmpqueryreply(v, &is->is_icmp,
ic, fin->fin_rev)) {
- if (!(is->is_sti.tqe_flags & TQE_RULEBASED)) {
- if (fin->fin_rev)
- ifq = &ips_icmpacktq;
- else
- ifq = &ips_icmptq;
- }
+ if (fin->fin_rev)
+ ifq = &ips_icmpacktq;
+ else
+ ifq = &ips_icmptq;
break;
}
}
@@ -2250,27 +2318,6 @@ icmp6again:
}
break;
- case IPPROTO_GRE :
- gre = fin->fin_dp;
- hv += gre->gr_call;
- tcp = NULL;
- ifqp = NULL;
- hv = DOUBLE_HASH(hv);
- READ_ENTER(&ipf_state);
- for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) {
- isp = &is->is_hnext;
- if ((is->is_p != IPPROTO_GRE) || (is->is_v != v) ||
- (is->is_gre.gs_call != gre->gr_call))
- continue;
- is = fr_matchsrcdst(fin, is, &src, &dst, NULL);
- if (is != NULL)
- break;
- }
- if (is == NULL) {
- RWLOCK_EXIT(&ipf_state);
- }
- break;
-
case IPPROTO_TCP :
case IPPROTO_UDP :
ifqp = NULL;
@@ -2278,6 +2325,7 @@ icmp6again:
hv += sport;
dport = htons(fin->fin_data[1]);
hv += dport;
+ oow = 0;
tryagain = 0;
READ_ENTER(&ipf_state);
retry_tcpudp:
@@ -2286,9 +2334,17 @@ retry_tcpudp:
isp = &is->is_hnext;
if ((is->is_p != pr) || (is->is_v != v))
continue;
- is = fr_matchsrcdst(fin, is, &src, &dst, tcp);
- if (is != NULL)
+ fin->fin_flx &= ~FI_OOW;
+ is = fr_matchsrcdst(fin, is, &src, &dst, tcp, FI_CMP);
+ if (is != NULL) {
+ if (pr == IPPROTO_TCP) {
+ if (!fr_tcpstate(fin, tcp, is)) {
+ oow |= fin->fin_flx & FI_OOW;
+ continue;
+ }
+ }
break;
+ }
}
if (is != NULL) {
if (tryagain &&
@@ -2309,20 +2365,30 @@ retry_tcpudp:
WRITE_ENTER(&ipf_state);
goto retry_tcpudp;
}
+ fin->fin_flx |= oow;
break;
+#if 0
+ case IPPROTO_GRE :
+ gre = fin->fin_dp;
+ if (GRE_REV(gre->gr_flags) == 1) {
+ hv += gre->gr_call;
+ }
+ /* FALLTHROUGH */
+#endif
default :
- tcp = NULL;
ifqp = NULL;
- hv = DOUBLE_HASH(hv);
+ hvm = DOUBLE_HASH(hv);
READ_ENTER(&ipf_state);
- for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) {
+ for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) {
isp = &is->is_hnext;
if ((is->is_p != pr) || (is->is_v != v))
continue;
- is = fr_matchsrcdst(fin, is, &src, &dst, NULL);
- if (is != NULL)
+ is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
+ if (is != NULL) {
+ ifq = &ips_iptq;
break;
+ }
}
if (is == NULL) {
RWLOCK_EXIT(&ipf_state);
@@ -2330,6 +2396,9 @@ retry_tcpudp:
break;
}
+ if ((is != NULL) && ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) &&
+ (is->is_tqehead[fin->fin_rev] != NULL))
+ ifq = is->is_tqehead[fin->fin_rev];
if (ifq != NULL && ifqp != NULL)
*ifqp = ifq;
return is;
@@ -2351,7 +2420,7 @@ fr_info_t *fin;
ipstate_t *is;
ipftq_t *ifq;
{
- ipftqent_t *tqe;
+ ipftqent_t *tqe;
int i, pass;
i = (fin->fin_rev << 1) + fin->fin_out;
@@ -2360,22 +2429,21 @@ ipftq_t *ifq;
* For TCP packets, ifq == NULL. For all others, check if this new
* queue is different to the last one it was on and move it if so.
*/
- MUTEX_ENTER(&is->is_lock);
tqe = &is->is_sti;
+ MUTEX_ENTER(&is->is_lock);
if ((tqe->tqe_flags & TQE_RULEBASED) != 0)
ifq = is->is_tqehead[fin->fin_rev];
- if (ifq != NULL) {
+ if (ifq != NULL)
fr_movequeue(tqe, tqe->tqe_ifq, ifq);
- is->is_die = ifq->ifq_ttl + fr_ticks;
- }
is->is_pkts[i]++;
is->is_bytes[i] += fin->fin_plen;
MUTEX_EXIT(&is->is_lock);
#ifdef IPFILTER_SYNC
- ipfsync_update(SMC_STATE, fin, is->is_sync);
+ if (is->is_flags & IS_STATESYNC)
+ ipfsync_update(SMC_STATE, fin, is->is_sync);
#endif
ATOMIC_INCL(ips_stats.iss_hits);
@@ -2412,7 +2480,7 @@ u_32_t *passp;
u_int pass;
if (fr_state_lock || (ips_list == NULL) ||
- (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGTAIL|FI_BAD)))
+ (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD)))
return NULL;
is = NULL;
@@ -2460,14 +2528,11 @@ u_32_t *passp;
case IPPROTO_TCP :
if (is == NULL)
break;
- if ((fin->fin_out == 0) && (is->is_pass & FR_NEWISN))
- fr_fixinisn(fin, is);
- if (!fr_tcpstate(fin, tcp, is)) {
- RWLOCK_EXIT(&ipf_state);
- is = NULL;
- } else {
- if ((fin->fin_out == 1) && (is->is_pass & FR_NEWISN))
+ if (is->is_pass & FR_NEWISN) {
+ if (fin->fin_out == 0)
+ fr_fixinisn(fin, is);
+ else if (fin->fin_out == 1)
fr_fixoutisn(fin, is);
}
break;
@@ -2485,18 +2550,18 @@ u_32_t *passp;
matched:
fr = is->is_rule;
- if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) {
- if (fin->fin_nattag == NULL)
- return NULL;
- if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0)
- return NULL;
- }
-
- fin->fin_rule = is->is_rulen;
if (fr != NULL) {
+ if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) {
+ if (fin->fin_nattag == NULL)
+ return NULL;
+ if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0)
+ return NULL;
+ }
(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
fin->fin_icode = fr->fr_icode;
}
+
+ fin->fin_rule = is->is_rulen;
pass = is->is_pass;
fr_updatestate(fin, is, ifq);
if (fin->fin_out == 1)
@@ -2531,18 +2596,23 @@ ipstate_t *is;
{
tcphdr_t *tcp;
int rev;
+ u_32_t seq;
tcp = fin->fin_dp;
rev = fin->fin_rev;
if ((is->is_flags & IS_ISNSYN) != 0) {
if (rev == 0) {
- tcp->th_seq += is->is_isninc[0];
+ seq = ntohl(tcp->th_seq);
+ seq += is->is_isninc[0];
+ tcp->th_seq = htonl(seq);
fix_outcksum(fin, &tcp->th_sum, is->is_sumd[0]);
}
}
if ((is->is_flags & IS_ISNACK) != 0) {
if (rev == 1) {
- tcp->th_seq += is->is_isninc[1];
+ seq = ntohl(tcp->th_seq);
+ seq += is->is_isninc[1];
+ tcp->th_seq = htonl(seq);
fix_outcksum(fin, &tcp->th_sum, is->is_sumd[1]);
}
}
@@ -2564,18 +2634,23 @@ ipstate_t *is;
{
tcphdr_t *tcp;
int rev;
+ u_32_t ack;
tcp = fin->fin_dp;
rev = fin->fin_rev;
if ((is->is_flags & IS_ISNSYN) != 0) {
if (rev == 1) {
- tcp->th_ack -= is->is_isninc[0];
+ ack = ntohl(tcp->th_ack);
+ ack -= is->is_isninc[0];
+ tcp->th_ack = htonl(ack);
fix_incksum(fin, &tcp->th_sum, is->is_sumd[0]);
}
}
if ((is->is_flags & IS_ISNACK) != 0) {
if (rev == 0) {
- tcp->th_ack -= is->is_isninc[1];
+ ack = ntohl(tcp->th_ack);
+ ack -= is->is_isninc[1];
+ tcp->th_ack = htonl(ack);
fix_incksum(fin, &tcp->th_sum, is->is_sumd[1]);
}
}
@@ -2590,6 +2665,9 @@ ipstate_t *is;
/* Walk through all state entries and if an interface pointer match is */
/* found then look it up again, based on its name in case the pointer has */
/* changed since last time. */
+/* */
+/* If ifp is passed in as being non-null then we are only doing updates for */
+/* existing, matching, uses of it. */
/* ------------------------------------------------------------------------ */
void fr_statesync(ifp)
void *ifp;
@@ -2612,12 +2690,9 @@ void *ifp;
* Look up all the interface names in the state entry.
*/
for (i = 0; i < 4; i++) {
- if (is->is_ifp[i] == ifp) {
- is->is_ifp[i] = GETIFP(is->is_ifname[i],
- is->is_v);
- if (is->is_ifp[i] == NULL)
- is->is_ifp[i] = (void *)-1;
- }
+ if (ifp == NULL || ifp == is->is_ifp[i])
+ is->is_ifp[i] = fr_resolvenic(is->is_ifname[i],
+ is->is_v);
}
}
RWLOCK_EXIT(&ipf_state);
@@ -2639,8 +2714,6 @@ static void fr_delstate(is, why)
ipstate_t *is;
int why;
{
- ipftqent_t *tqe;
- ipftq_t *ifq;
ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
@@ -2648,24 +2721,27 @@ int why;
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
*/
- *is->is_pnext = is->is_next;
-
- if (is->is_next != NULL)
- is->is_next->is_pnext = is->is_pnext;
+ if (is->is_pnext != NULL) {
+ *is->is_pnext = is->is_next;
+ if (is->is_next != NULL)
+ is->is_next->is_pnext = is->is_pnext;
- is->is_pnext = NULL;
- is->is_next = NULL;
+ is->is_pnext = NULL;
+ is->is_next = NULL;
+ }
- *is->is_phnext = is->is_hnext;
- if (is->is_hnext != NULL)
- is->is_hnext->is_phnext = is->is_phnext;
- if (ips_table[is->is_hv] == NULL)
- ips_stats.iss_inuse--;
- ips_stats.iss_bucketlen[is->is_hv]--;
+ if (is->is_phnext != NULL) {
+ *is->is_phnext = is->is_hnext;
+ if (is->is_hnext != NULL)
+ is->is_hnext->is_phnext = is->is_phnext;
+ if (ips_table[is->is_hv] == NULL)
+ ips_stats.iss_inuse--;
+ ips_stats.iss_bucketlen[is->is_hv]--;
- is->is_phnext = NULL;
- is->is_hnext = NULL;
+ is->is_phnext = NULL;
+ is->is_hnext = NULL;
+ }
/*
* Because ips_stats.iss_wild is a count of entries in the state
@@ -2676,26 +2752,15 @@ int why;
if (!(is->is_flags & SI_CLONED)) {
ATOMIC_DECL(ips_stats.iss_wild);
}
+ is->is_flags &= ~(SI_WILDP|SI_WILDA);
}
-
/*
* Next, remove it from the timeout queue it is in.
*/
- tqe = &is->is_sti;
- ifq = tqe->tqe_ifq;
- if (tqe->tqe_pnext != NULL) {
- *tqe->tqe_pnext = tqe->tqe_next;
- if (tqe->tqe_next != NULL)
- tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
- else /* we must be the tail anyway */
- ifq->ifq_tail = tqe->tqe_pnext;
- tqe->tqe_pnext = NULL;
- tqe->tqe_ifq = NULL;
- }
+ fr_deletequeueentry(&is->is_sti);
- if ((ifq->ifq_flags & IFQF_USER) != 0)
- fr_deletetimeoutqueue(ifq);
+ is->is_me = NULL;
/*
* If it is still in use by something else, do not go any further,
@@ -2705,12 +2770,21 @@ int why;
if (is->is_ref > 0)
return;
+ if (is->is_tqehead[0] != NULL) {
+ if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0)
+ fr_freetimeoutqueue(is->is_tqehead[0]);
+ }
+ if (is->is_tqehead[1] != NULL) {
+ if (fr_deletetimeoutqueue(is->is_tqehead[1]) == 0)
+ fr_freetimeoutqueue(is->is_tqehead[1]);
+ }
+
#ifdef IPFILTER_SYNC
if (is->is_sync)
ipfsync_del(is->is_sync);
#endif
#ifdef IPFILTER_SCAN
- (void) isc_detachis(is);
+ (void) ipsc_detachis(is);
#endif
if (ipstate_logging != 0 && why != 0)
@@ -2742,9 +2816,7 @@ void fr_timeoutstate()
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
ipstate_t *is;
-#if defined(USE_SPL) && defined(_KERNEL)
- int s;
-#endif
+ SPL_INT(s);
SPL_NET(s);
WRITE_ENTER(&ipf_state);
@@ -2768,10 +2840,21 @@ void fr_timeoutstate()
fr_delstate(is, ISL_EXPIRE);
}
}
+
+ for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) {
+ ifqnext = ifq->ifq_next;
+
+ if (((ifq->ifq_flags & IFQF_DELETE) != 0) &&
+ (ifq->ifq_ref == 0)) {
+ fr_freetimeoutqueue(ifq);
+ }
+ }
+
if (fr_state_doflush) {
(void) fr_state_flush(2, 0);
fr_state_doflush = 0;
}
+
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
}
@@ -2803,9 +2886,7 @@ int which, proto;
int delete, removed;
long try, maxtick;
u_long interval;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
removed = 0;
@@ -2955,6 +3036,8 @@ force_flush_skipped:
/* */
/* dir == 0 : a packet from source to dest */
/* dir == 1 : a packet from dest to source */
+/* */
+/* Locking: it is assumed that the parent of the tqe structure is locked. */
/* ------------------------------------------------------------------------ */
int fr_tcp_age(tqe, fin, tqtab, flags)
ipftqent_t *tqe;
@@ -2971,7 +3054,7 @@ int flags;
rval = 0;
dir = fin->fin_rev;
tcpflags = tcp->th_flags;
- dlen = fin->fin_plen - fin->fin_hlen - (TCP_OFF(tcp) << 2);
+ dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
if (tcpflags & TH_RST) {
if (!(tcpflags & TH_PUSH) && !dlen)
@@ -3011,13 +3094,20 @@ int flags;
* we saw an A, guess 'dir' is in ESTABLISHED
* mode
*/
- if (ostate == IPF_TCPS_CLOSED) {
+ switch (ostate)
+ {
+ case IPF_TCPS_CLOSED :
+ case IPF_TCPS_SYN_RECEIVED :
nstate = IPF_TCPS_HALF_ESTAB;
rval = 1;
- } else if (ostate == IPF_TCPS_ESTABLISHED ||
- ostate == IPF_TCPS_HALF_ESTAB) {
+ break;
+ case IPF_TCPS_HALF_ESTAB :
+ case IPF_TCPS_ESTABLISHED :
nstate = IPF_TCPS_ESTABLISHED;
rval = 1;
+ break;
+ default :
+ break;
}
}
/*
@@ -3038,9 +3128,10 @@ int flags;
* the timeout here to fr_tcptimeout because a
* connection connect timeout does not renew
* after every packet that is sent. We need to
- * set newage to something to indicate the
- * packet has passed the check for its flags
- * being valid in the TCP FSM.
+ * set rval so as to indicate the packet has
+ * passed the check for its flags being valid
+ * in the TCP FSM. Setting rval to 2 has the
+ * result of not resetting the timeout.
*/
rval = 2;
} else if ((tcpflags & (TH_SYN|TH_FIN|TH_ACK)) ==
@@ -3237,9 +3328,6 @@ int flags;
(u_long)tcp, tcpflags, (u_long)tqe,
nstate, ostate);
# endif
-# ifdef DIAGNOSTIC
- panic("invalid TCP state");
-# endif
#else
abort();
#endif
@@ -3288,10 +3376,14 @@ u_int type;
* structure used for logging.
*/
ipsl.isl_type = type;
- ipsl.isl_pkts[0] = is->is_pkts[0], ipsl.isl_bytes[0] = is->is_bytes[0];
- ipsl.isl_pkts[1] = is->is_pkts[1], ipsl.isl_bytes[1] = is->is_bytes[1];
- ipsl.isl_pkts[2] = is->is_pkts[2], ipsl.isl_bytes[2] = is->is_bytes[2];
- ipsl.isl_pkts[3] = is->is_pkts[3], ipsl.isl_bytes[3] = is->is_bytes[3];
+ ipsl.isl_pkts[0] = is->is_pkts[0] + is->is_icmppkts[0];
+ ipsl.isl_bytes[0] = is->is_bytes[0];
+ ipsl.isl_pkts[1] = is->is_pkts[1] + is->is_icmppkts[1];
+ ipsl.isl_bytes[1] = is->is_bytes[1];
+ ipsl.isl_pkts[2] = is->is_pkts[2] + is->is_icmppkts[2];
+ ipsl.isl_bytes[2] = is->is_bytes[2];
+ ipsl.isl_pkts[3] = is->is_pkts[3] + is->is_icmppkts[3];
+ ipsl.isl_bytes[3] = is->is_bytes[3];
ipsl.isl_src = is->is_src;
ipsl.isl_dst = is->is_dst;
ipsl.isl_p = is->is_p;
@@ -3321,7 +3413,11 @@ u_int type;
sizes[0] = sizeof(ipsl);
types[0] = 0;
- (void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
+ if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) {
+ ATOMIC_INCL(ips_stats.iss_logged);
+ } else {
+ ATOMIC_INCL(ips_stats.iss_logfail);
+ }
#endif
}
@@ -3341,7 +3437,7 @@ static ipstate_t *fr_checkicmp6matchingstate(fin)
fr_info_t *fin;
{
struct icmp6_hdr *ic6, *oic;
- int type, backward, i;
+ int backward, i;
ipstate_t *is, **isp;
u_short sport, dport;
i6addr_t dst, src;
@@ -3355,20 +3451,15 @@ fr_info_t *fin;
/*
* Does it at least have the return (basic) IP header ?
+ * Is it an actual recognised ICMP error type?
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
- if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN))
+ if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN) ||
+ !(fin->fin_flx & FI_ICMPERR))
return NULL;
ic6 = fin->fin_dp;
- type = ic6->icmp6_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP6_DST_UNREACH) && (type != ICMP6_PACKET_TOO_BIG) &&
- (type != ICMP6_TIME_EXCEEDED) && (type != ICMP6_PARAM_PROB))
- return NULL;
oip6 = (ip6_t *)((char *)ic6 + ICMPERR_ICMPHLEN);
if (fin->fin_plen < sizeof(*oip6))
@@ -3433,7 +3524,7 @@ fr_info_t *fin;
(oic->icmp6_id == ic->ici_id) &&
(oic->icmp6_seq == ic->ici_seq) &&
(is = fr_matchsrcdst(&ofin, is, &src,
- &dst, NULL))) {
+ &dst, NULL, FI_ICMPCMP))) {
/*
* in the state table ICMP query's are stored
* with the type of the corresponding ICMP
@@ -3444,9 +3535,9 @@ fr_info_t *fin;
(ic->ici_type - 1 == oic->icmp6_type )) {
ips_stats.iss_hits++;
backward = IP6_NEQ(&is->is_dst, &src);
+ fin->fin_rev = !backward;
i = (backward << 1) + fin->fin_out;
- is->is_pkts[i]++;
- is->is_bytes[i] += fin->fin_plen;
+ is->is_icmppkts[i]++;
return is;
}
}
@@ -3490,13 +3581,13 @@ fr_info_t *fin;
if ((is->is_p != pr) || (is->is_v != 6) ||
(is->is_pass & FR_NOICMPERR))
continue;
- is = fr_matchsrcdst(&ofin, is, &src, &dst, tcp);
+ is = fr_matchsrcdst(&ofin, is, &src, &dst, tcp, FI_ICMPCMP);
if (is != NULL) {
ips_stats.iss_hits++;
backward = IP6_NEQ(&is->is_dst, &src);
+ fin->fin_rev = !backward;
i = (backward << 1) + fin->fin_out;
- is->is_pkts[i]++;
- is->is_bytes[i] += fin->fin_plen;
+ is->is_icmppkts[i]++;
/*
* we deliberately do not touch the timeouts
* for the accompanying state table entry.
@@ -3525,6 +3616,7 @@ ipftq_t *tqp;
for (i = IPF_TCP_NSTATES - 1; i >= 0; i--) {
tqp[i].ifq_ttl = 0;
+ tqp[i].ifq_ref = 1;
tqp[i].ifq_head = NULL;
tqp[i].ifq_tail = &tqp[i].ifq_head;
tqp[i].ifq_next = tqp + i + 1;
@@ -3536,14 +3628,14 @@ ipftq_t *tqp;
tqp[IPF_TCPS_SYN_SENT].ifq_ttl = fr_tcptimeout;
tqp[IPF_TCPS_SYN_RECEIVED].ifq_ttl = fr_tcptimeout;
tqp[IPF_TCPS_ESTABLISHED].ifq_ttl = fr_tcpidletimeout;
- tqp[IPF_TCPS_CLOSE_WAIT].ifq_ttl = fr_tcpclosewait;
+ tqp[IPF_TCPS_CLOSE_WAIT].ifq_ttl = fr_tcphalfclosed;
tqp[IPF_TCPS_FIN_WAIT_1].ifq_ttl = fr_tcphalfclosed;
tqp[IPF_TCPS_CLOSING].ifq_ttl = fr_tcptimeout;
tqp[IPF_TCPS_LAST_ACK].ifq_ttl = fr_tcplastack;
tqp[IPF_TCPS_FIN_WAIT_2].ifq_ttl = fr_tcpclosewait;
tqp[IPF_TCPS_TIME_WAIT].ifq_ttl = fr_tcptimeout;
tqp[IPF_TCPS_HALF_ESTAB].ifq_ttl = fr_tcptimeout;
-}
+}
/* ------------------------------------------------------------------------ */
@@ -3556,9 +3648,9 @@ ipftq_t *tqp;
/* ------------------------------------------------------------------------ */
void fr_sttab_destroy(tqp)
ipftq_t *tqp;
-{
+{
int i;
-
+
for (i = IPF_TCP_NSTATES - 1; i >= 0; i--)
MUTEX_DESTROY(&tqp[i].ifq_lock);
}
@@ -3623,28 +3715,92 @@ ipstate_t **isp;
fin = fin; /* LINT */
is = *isp;
*isp = NULL;
- MUTEX_ENTER(&is->is_lock);
+ WRITE_ENTER(&ipf_state);
is->is_ref--;
if (is->is_ref == 0) {
- MUTEX_EXIT(&is->is_lock);
- WRITE_ENTER(&ipf_state);
+ is->is_ref++; /* To counter ref-- in fr_delstate() */
fr_delstate(is, ISL_EXPIRE);
- RWLOCK_EXIT(&ipf_state);
#ifndef _KERNEL
#if 0
} else if (((fin->fin_out == 1) || (eol == 1)) &&
((ostate == IPF_TCPS_LAST_ACK) &&
(nstate == IPF_TCPS_TIME_WAIT))) {
+ ;
#else
} else if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
(is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) {
#endif
- MUTEX_EXIT(&is->is_lock);
- WRITE_ENTER(&ipf_state);
fr_delstate(is, ISL_ORPHAN);
- RWLOCK_EXIT(&ipf_state);
#endif
- } else {
- MUTEX_EXIT(&is->is_lock);
}
+ RWLOCK_EXIT(&ipf_state);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: fr_setstatequeue */
+/* Returns: Nil */
+/* Parameters: is(I) - pointer to state structure */
+/* rev(I) - forward(0) or reverse(1) direction */
+/* Locks: ipf_state (read or write) */
+/* */
+/* Put the state entry on its default queue entry, using rev as a helped in */
+/* determining which queue it should be placed on. */
+/* ------------------------------------------------------------------------ */
+void fr_setstatequeue(is, rev)
+ipstate_t *is;
+int rev;
+{
+ ipftq_t *oifq, *nifq;
+
+
+ if ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0)
+ nifq = is->is_tqehead[rev];
+ else
+ nifq = NULL;
+
+ if (nifq == NULL) {
+ switch (is->is_p)
+ {
+#ifdef USE_INET6
+ case IPPROTO_ICMPV6 :
+ if (rev == 1)
+ nifq = &ips_icmpacktq;
+ else
+ nifq = &ips_icmptq;
+ break;
+#endif
+ case IPPROTO_ICMP :
+ if (rev == 1)
+ nifq = &ips_icmpacktq;
+ else
+ nifq = &ips_icmptq;
+ break;
+ case IPPROTO_TCP :
+ nifq = ips_tqtqb + is->is_state[rev];
+ break;
+
+ case IPPROTO_UDP :
+ if (rev == 1)
+ nifq = &ips_udpacktq;
+ else
+ nifq = &ips_udptq;
+ break;
+
+ default :
+ nifq = &ips_iptq;
+ break;
+ }
+ }
+
+ oifq = is->is_sti.tqe_ifq;
+ /*
+ * If it's currently on a timeout queue, move it from one queue to
+ * another, else put it on the end of the newly determined queue.
+ */
+ if (oifq != NULL)
+ fr_movequeue(&is->is_sti, oifq, nifq);
+ else
+ fr_queueappend(&is->is_sti, nifq, is);
+ return;
}
diff --git a/usr/src/common/ipf/ipf.h b/usr/src/uts/common/inet/ipf/ipf.h
index c912a298d8..8ae3352883 100644
--- a/usr/src/common/ipf/ipf.h
+++ b/usr/src/uts/common/inet/ipf/ipf.h
@@ -1,8 +1,12 @@
/*
- * Copyright (C) 1993-2001, 2003, 2004 by Darren Reed.
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
+ *
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * @(#)ipf.h 1.12 6/5/96
+ * $Id: ipf.h,v 2.71.2.7 2005/06/12 07:18:31 darrenr Exp $
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -11,6 +15,12 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#if defined(__osf__)
+# define radix_mask ipf_radix_mask
+# define radix_node ipf_radix_node
+# define radix_node_head ipf_radix_node_head
+#endif
+
#include <sys/param.h>
#include <sys/types.h>
#include <sys/file.h>
@@ -41,38 +51,26 @@ struct file;
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
#ifndef TCP_PAWS_IDLE /* IRIX */
# include <netinet/tcp.h>
#endif
#include <netinet/udp.h>
-#ifndef _KERNEL
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <netdb.h>
#include <stdlib.h>
+#include <stddef.h>
#include <stdio.h>
#if !defined(__SVR4) && !defined(__svr4__) && defined(sun)
# include <strings.h>
#endif
#include <string.h>
#include <unistd.h>
-#endif
-#if SOLARIS2 >= 10
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
-#include "ip_proxy.h"
-#include "ip_auth.h"
-#include "ip_lookup.h"
-#include "ip_pool.h"
-#include "ip_htable.h"
-#else
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
@@ -82,7 +80,12 @@ struct file;
#include "netinet/ip_auth.h"
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
+#ifdef IPFILTER_SCAN
+#include "netinet/ip_scan.h"
+#endif
#include "netinet/ip_htable.h"
+#ifdef IPFILTER_SYNC
+#include "netinet/ip_sync.h"
#endif
#include "opts.h"
@@ -146,22 +149,22 @@ typedef struct alist_s {
#define al_1 al_addr
#define al_2 al_mask
+
+typedef struct {
+ u_short fb_c;
+ u_char fb_t;
+ u_char fb_f;
+ u_32_t fb_k;
+} fakebpf_t;
+
+
#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
+ (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \
+ SOLARIS || defined(__sgi) || defined(__osf__) || defined(linux)
# include <stdarg.h>
-typedef u_long ioctlcmd_t;
typedef int (* ioctlfunc_t) __P((int, ioctlcmd_t, ...));
#else
-# if SOLARIS || defined(__sgi) || defined(__osf__)
-#ifndef _KERNEL
-# include <stdarg.h>
-#endif
-typedef int ioctlcmd_t;
-typedef int (* ioctlfunc_t) __P((int, ioctlcmd_t, ...));
-# else
-typedef int ioctlcmd_t;
typedef int (* ioctlfunc_t) __P((dev_t, ioctlcmd_t, void *));
-# endif
#endif
typedef void (* addfunc_t) __P((int, ioctlfunc_t, void *));
typedef int (* copyfunc_t) __P((void *, void *, size_t));
@@ -183,9 +186,7 @@ extern char *icmpcodes[MAX_ICMPCODE + 1];
extern char *icmptypes[MAX_ICMPTYPE + 1];
extern int use_inet6;
extern int lineNum;
-#ifdef USE_INET6
extern struct ipopt_names v6ionames[];
-#endif
extern int addicmp __P((char ***, struct frentry *, int));
@@ -196,21 +197,17 @@ extern void binprint __P((void *, size_t));
extern void initparse __P((void));
extern u_32_t buildopts __P((char *, char *, int));
extern int checkrev __P((char *));
-#ifdef USE_INET6
extern int count6bits __P((u_32_t *));
-#endif
extern int count4bits __P((u_32_t));
extern int extras __P((char ***, struct frentry *, int));
extern char *fac_toname __P((int));
extern int fac_findname __P((char *));
extern void fill6bits __P((int, u_int *));
extern int gethost __P((char *, u_32_t *));
-extern int getport __P((struct frentry *, char *));
+extern int getport __P((struct frentry *, char *, u_short *));
extern int getportproto __P((char *, int));
extern int getproto __P((char *));
-#ifndef _KERNEL
extern char *getline __P((char *, size_t, FILE *, int *));
-#endif
extern int genmask __P((char *, u_32_t *));
extern char *getnattype __P((struct ipnat *));
extern char *getsumd __P((u_32_t));
@@ -218,23 +215,23 @@ extern u_32_t getoptbyname __P((char *));
extern u_32_t getoptbyvalue __P((int));
extern u_32_t getv6optbyname __P((char *));
extern u_32_t getv6optbyvalue __P((int));
+extern void hexdump __P((FILE *, void *, int, int));
extern int hostmask __P((char ***, char *, char *, u_32_t *, u_32_t *, int));
extern int hostnum __P((u_32_t *, char *, int, char *));
extern int icmpcode __P((char *));
extern int icmpidnum __P((char *, u_short *, int));
extern void initparse __P((void));
+extern void ipf_dotuning __P((int, char *, ioctlfunc_t));
extern void ipf_addrule __P((int, ioctlfunc_t, void *));
extern int ipf_parsefile __P((int, addfunc_t, ioctlfunc_t *, char *));
-#ifndef _KERNEL
extern int ipf_parsesome __P((int, addfunc_t, ioctlfunc_t *, FILE *));
-extern int ipmon_parsesome __P((FILE *));
-extern int ipnat_parsesome __P((int, addfunc_t, ioctlfunc_t, FILE *));
-extern int ippool_parsesome __P((int, FILE *, ioctlfunc_t));
-#endif
extern int ipmon_parsefile __P((char *));
+extern int ipmon_parsesome __P((FILE *));
extern void ipnat_addrule __P((int, ioctlfunc_t, void *));
extern int ipnat_parsefile __P((int, addfunc_t, ioctlfunc_t, char *));
+extern int ipnat_parsesome __P((int, addfunc_t, ioctlfunc_t, FILE *));
extern int ippool_parsefile __P((int, char *, ioctlfunc_t));
+extern int ippool_parsesome __P((int, FILE *, ioctlfunc_t));
extern int kmemcpywrap __P((void *, void *, size_t));
extern char *kvatoname __P((ipfunc_t, ioctlfunc_t));
extern int load_hash __P((struct iphtable_s *, struct iphtent_s *,
@@ -260,8 +257,9 @@ extern void print_toif __P((char *, struct frdest *));
extern void printaps __P((ap_session_t *, int));
extern void printbuf __P((char *, int, int));
extern void printfr __P((struct frentry *, ioctlfunc_t));
-extern struct iphtable_s *printhash __P((struct iphtable_s *,
- copyfunc_t, int));
+extern void printtunable __P((ipftune_t *));
+extern struct iphtable_s *printhash __P((struct iphtable_s *, copyfunc_t,
+ char *, int));
extern struct iphtent_s *printhashnode __P((struct iphtable_s *,
struct iphtent_s *,
copyfunc_t, int));
@@ -272,8 +270,10 @@ extern void printlookup __P((i6addr_t *addr, i6addr_t *mask));
extern void printmask __P((int, u_32_t *));
extern void printpacket __P((struct ip *));
extern void printpacket6 __P((struct ip *));
-extern struct ip_pool_s *printpool __P((struct ip_pool_s *, copyfunc_t, int));
+extern struct ip_pool_s *printpool __P((struct ip_pool_s *, copyfunc_t,
+ char *, int));
extern struct ip_pool_node *printpoolnode __P((struct ip_pool_node *, int));
+extern void printproto __P((struct protoent *, int, struct ipnat *));
extern void printportcmp __P((int, struct frpcmp *));
extern void optprint __P((u_short *, u_long, u_long));
#ifdef USE_INET6
@@ -293,9 +293,10 @@ extern void printC __P((int));
extern void emit __P((int, int, void *, struct frentry *));
extern u_char secbit __P((int));
extern u_char seclevel __P((char *));
+extern void printfraginfo __P((char *, struct ipfr *));
extern void printifname __P((char *, char *, void *));
extern char *hostname __P((int, void *));
-extern struct ipstate *printstate __P((struct ipstate *, int));
+extern struct ipstate *printstate __P((struct ipstate *, int, u_long));
extern void printsbuf __P((char *));
extern void printnat __P((struct ipnat *, int));
extern void printactivenat __P((struct nat *, int));
diff --git a/usr/src/common/ipf/ipmon.h b/usr/src/uts/common/inet/ipf/ipmon.h
index b523aef2e9..765a646954 100644
--- a/usr/src/common/ipf/ipmon.h
+++ b/usr/src/uts/common/inet/ipf/ipmon.h
@@ -4,59 +4,71 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ipmon.h,v 2.6 2002/12/27 16:07:15 darrenr Exp $
+ * $Id: ipmon.h,v 2.8 2003/07/25 22:16:20 darrenr Exp $
*/
-typedef struct action {
- struct action *a_next;
+typedef struct ipmon_action {
+ struct ipmon_action *ac_next;
int ac_mflag; /* collection of things to compare */
+ int ac_dflag; /* flags to compliment the doing fields */
+ int ac_syslog; /* = 1 to syslog rules. */
+ char *ac_savefile; /* filename to save log records to */
+ FILE *ac_savefp;
int ac_direction;
char ac_group[FR_GROUPLEN];
+ char ac_nattag[16];
+ u_32_t ac_logtag;
+ int ac_type; /* nat/state/ipf */
int ac_proto;
int ac_rule;
int ac_packet;
int ac_second;
int ac_result;
- int ac_tag;
u_32_t ac_sip;
u_32_t ac_smsk;
u_32_t ac_dip;
u_32_t ac_dmsk;
u_short ac_sport;
u_short ac_dport;
- char *ac_exec;
- char *ac_run;
+ char *ac_exec; /* execute argument */
+ char *ac_run; /* actual command that gets run */
char *ac_iface;
/*
* used with ac_packet/ac_second
*/
struct timeval ac_last;
int ac_pktcnt;
-} action_t;
+} ipmon_action_t;
#define ac_lastsec ac_last.tv_sec
#define ac_lastusec ac_last.tv_usec
+/*
+ * Flags indicating what fields to do matching upon (ac_mflag).
+ */
#define IPMAC_DIRECTION 0x0001
#define IPMAC_DSTIP 0x0002
#define IPMAC_DSTPORT 0x0004
#define IPMAC_EVERY 0x0008
-#define IPMAC_EXECUTE 0x0010
-#define IPMAC_GROUP 0x0020
-#define IPMAC_INTERFACE 0x0040
-#define IPMAC_PROTOCOL 0x0080
-#define IPMAC_RESULT 0x0100
-#define IPMAC_RULE 0x0200
-#define IPMAC_SRCIP 0x0400
-#define IPMAC_SRCPORT 0x0800
-#define IPMAC_TAG 0x1000
+#define IPMAC_GROUP 0x0010
+#define IPMAC_INTERFACE 0x0020
+#define IPMAC_LOGTAG 0x0040
+#define IPMAC_NATTAG 0x0080
+#define IPMAC_PROTOCOL 0x0100
+#define IPMAC_RESULT 0x0200
+#define IPMAC_RULE 0x0400
+#define IPMAC_SRCIP 0x0800
+#define IPMAC_SRCPORT 0x1000
+#define IPMAC_TYPE 0x2000
+#define IPMAC_WITH 0x4000
#define IPMR_BLOCK 1
#define IPMR_PASS 2
#define IPMR_NOMATCH 3
-#define IPMR_SHORT 4
-#define IPMR_LOG 5
+#define IPMR_LOG 4
+
+#define IPMDO_SAVERAW 0x0001
#define OPT_SYSLOG 0x001
#define OPT_RESOLVE 0x002
@@ -78,5 +90,5 @@ typedef struct action {
extern int load_config __P((char *));
extern void dumphex __P((FILE *, int, char *, int));
-extern void check_action __P((char *, int, char *));
+extern int check_action __P((char *, char *, int, int));
extern char *getword __P((int));
diff --git a/usr/src/common/ipf/ipt.h b/usr/src/uts/common/inet/ipf/ipt.h
index 938e40041e..938e40041e 100644
--- a/usr/src/common/ipf/ipt.h
+++ b/usr/src/uts/common/inet/ipf/ipt.h
diff --git a/usr/src/common/ipf/Makefile b/usr/src/uts/common/inet/ipf/netinet/Makefile
index ed15db9165..e64d612f4c 100644
--- a/usr/src/common/ipf/Makefile
+++ b/usr/src/uts/common/inet/ipf/netinet/Makefile
@@ -1,13 +1,13 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/common/netinet/Makefile
+# uts/common/inet/ipf/netinet/Makefile
#
# include global definitions
-include ../../Makefile.master
+include ../../../../../Makefile.master
HDRS= ipl.h ip_compat.h ip_fil.h ip_icmp.h ip_nat.h ip_proxy.h ip_state.h
diff --git a/usr/src/common/ipf/ip_auth.h b/usr/src/uts/common/inet/ipf/netinet/ip_auth.h
index 45e1055b1e..3892778270 100644
--- a/usr/src/common/ipf/ip_auth.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_auth.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_auth.h,v 2.15 2002/11/02 15:42:21 darrenr Exp $
+ * $Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@@ -58,13 +58,7 @@ extern void fr_authunload __P((void));
extern int fr_authflush __P((void));
extern mb_t **fr_authpkts;
extern int fr_newauth __P((mb_t *, fr_info_t *));
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-extern int fr_preauthcmd __P((u_long, frentry_t *, frentry_t **));
-extern int fr_auth_ioctl __P((caddr_t, u_long, int));
-#else
-extern int fr_preauthcmd __P((int, frentry_t *, frentry_t **));
-extern int fr_auth_ioctl __P((caddr_t, int, int));
-#endif
+extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **));
+extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int));
#endif /* __IP_AUTH_H__ */
diff --git a/usr/src/common/ipf/ip_compat.h b/usr/src/uts/common/inet/ipf/netinet/ip_compat.h
index 56262aff10..43368d9937 100644
--- a/usr/src/common/ipf/ip_compat.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_compat.h
@@ -1,34 +1,18 @@
/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (C) 1999-2001, 2003 by Darren Reed.
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
+ * @(#)ip_compat.h 1.8 1/14/96
+ * $Id: ip_compat.h,v 2.142.2.30 2005/08/11 15:13:49 darrenr Exp $
+ *
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
+
#ifndef __IP_COMPAT_H__
#define __IP_COMPAT_H__
@@ -56,25 +40,33 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#if (SOLARIS2 >= 8) && (SOLARIS2 < 10)
+#if SOLARIS2 >= 8
# ifndef USE_INET6
# define USE_INET6
# endif
#endif
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
- !defined(_KERNEL)
+ !defined(_KERNEL) && !defined(USE_INET6) && !defined(NOINET6)
# define USE_INET6
#endif
#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000) && \
- !defined(_KERNEL)
+ !defined(_KERNEL) && !defined(USE_INET6)
# define USE_INET6
+# define IPFILTER_M_IPFILTER
#endif
-#if defined(OpenBSD) && (OpenBSD >= 200206) && !defined(_KERNEL)
+#if defined(OpenBSD) && (OpenBSD >= 200206) && \
+ !defined(_KERNEL) && !defined(USE_INET6)
# define USE_INET6
#endif
#if defined(__osf__)
# define USE_INET6
#endif
+#if defined(linux) && (!defined(_KERNEL) || defined(CONFIG_IPV6))
+# define USE_INET6
+#endif
+#if defined(HPUXREV) && (HPUXREV >= 1111)
+# define USE_INET6
+#endif
#if defined(BSD) && (BSD < 199103) && defined(__osf__)
# undef BSD
@@ -125,18 +117,20 @@ struct ether_addr {
/*
* This is a workaround for <sys/uio.h> troubles on FreeBSD and OpenBSD.
*/
-#ifndef _KERNEL
-# define ADD_KERNEL
-# define _KERNEL
-# define KERNEL
-#endif
-#ifdef __OpenBSD__
+#ifndef linux
+# ifndef _KERNEL
+# define ADD_KERNEL
+# define _KERNEL
+# define KERNEL
+# endif
+# ifdef __OpenBSD__
struct file;
-#endif
-#include <sys/uio.h>
-#ifdef ADD_KERNEL
-# undef _KERNEL
-# undef KERNEL
+# endif
+# include <sys/uio.h>
+# ifdef ADD_KERNEL
+# undef _KERNEL
+# undef KERNEL
+# endif
#endif
@@ -177,6 +171,9 @@ struct file;
# undef IPOPT_LSRR
# undef IPOPT_RR
# undef IPOPT_SSRR
+# ifdef i386
+# define _SYS_PROMIF_H
+# endif
# include <inet/ip.h>
# undef COPYOUT
# include <inet/ip_ire.h>
@@ -184,8 +181,9 @@ struct file;
# undef _KERNEL
# endif
# if SOLARIS2 >= 8
+# define SNPRINTF snprintf
+
# include <inet/ip_if.h>
-# include <inet/ip6.h>
# define ipif_local_addr ipif_lcl_addr
/* Only defined in private include file */
# ifndef V4_PART_OF_V6
@@ -208,8 +206,8 @@ typedef unsigned int u_32_t;
# ifdef _KERNEL
# define KRWLOCK_T krwlock_t
# define KMUTEX_T kmutex_t
-# include "pfil.h"
# include "qif.h"
+# include "pfil.h"
# if SOLARIS2 >= 6
# if SOLARIS2 == 6
# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1)
@@ -235,31 +233,19 @@ typedef unsigned int u_32_t;
# define READ_ENTER(x) rw_enter(&(x)->ipf_lk, RW_READER)
# define WRITE_ENTER(x) rw_enter(&(x)->ipf_lk, RW_WRITER)
# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk)
-# if SOLARIS2 >= 6
-# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, NULL, \
- RW_DRIVER, NULL)
-# else
# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y), \
RW_DRIVER, NULL)
-# endif /* SOLARIS2 >= 6 */
-
# define RWLOCK_EXIT(x) rw_exit(&(x)->ipf_lk)
# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk)
-
-# if SOLARIS2 >= 6
-# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, NULL, \
- MUTEX_DRIVER, NULL)
-# else
# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, (y), \
MUTEX_DRIVER, NULL)
-# endif /* SOLARIS2 >= 6 */
# define MUTEX_DESTROY(x) mutex_destroy(&(x)->ipf_lk)
# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
# define MUTEX_EXIT(x) mutex_exit(&(x)->ipf_lk)
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
-# define BCOPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
-# define BCOPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) (void) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) (void) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
@@ -276,29 +262,25 @@ typedef unsigned int u_32_t;
# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
-#ifndef IRE_ILL_CN
-extern ill_t *get_unit __P((char *, int));
+extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x) ((ill_t *)x)->ill_name
+# define IFNAME(x) ((qif_t *)x)->qf_name
# define COPYIFNAME(x, b) \
- strncpy(b, ((ill_t *)x)->ill_name, LIFNAMSIZ)
-#else
+ (void) strncpy(b, ((qif_t *)x)->qf_name, \
+ LIFNAMSIZ)
+#ifdef IRE_ILL_CN
extern kmutex_t s_ill_g_head_lock;
extern struct s_ill_s *s_ill_g_head; /* ILL List Head */
-extern s_ill_t *get_unit __P((char *, int));
-# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x) ((s_ill_t *)x)->ill_name
-# define COPYIFNAME(x, b) \
- strncpy(b, ((s_ill_t *)x)->ill_name, LIFNAMSIZ)
#endif /* IRE_ILL_CN */
# define GETKTIME(x) uniqtime((struct timeval *)x)
# define MSGDSIZE(x) msgdsize(x)
# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr)
# define M_DUPLICATE(x) dupmsg((x))
-# define MTOD(m,t) (t)((m)->b_rptr)
+# define MTOD(m,t) ((t)((m)->b_rptr))
# define MTYPE(m) ((m)->b_datap->db_type)
# define FREE_MB_T(m) freemsg(m)
-# define CACHE_HASH(x) (((qif_t *)(x)->fin_qif)->qf_num & 7)
+# define m_next b_cont
+# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
# define IPF_PANIC(x,y) if (x) { printf y; cmn_err(CE_PANIC, "ipf_panic"); }
typedef mblk_t mb_t;
# endif /* _KERNEL */
@@ -313,6 +295,10 @@ typedef mblk_t mb_t;
# endif
# endif
+# if SOLARIS2 < 6
+typedef struct uio uio_t;
+# endif
+typedef int ioctlcmd_t;
# define OS_RECOGNISED 1
@@ -327,8 +313,28 @@ typedef mblk_t mb_t;
# include <sys/spinlock.h>
# include <sys/lock.h>
# include <sys/stream.h>
+# ifdef USE_INET6
+# include <netinet/if_ether.h>
+# include <netinet/ip6.h>
+# include <netinet/icmp6.h>
+typedef struct ip6_hdr ip6_t;
+# endif
# ifdef _KERNEL
+# define SNPRINTF sprintf
+# if (HPUXREV >= 1111)
+# define IPL_SELECT
+# ifdef IPL_SELECT
+# include <machine/sys/user.h>
+# include <sys/kthread_iface.h>
+# define READ_COLLISION 0x01
+
+typedef struct iplog_select_s {
+ kthread_t *read_waiter;
+ int state;
+} iplog_select_t;
+# endif
+# endif
# define GETKTIME(x) uniqtime((struct timeval *)x)
@@ -346,63 +352,82 @@ typedef mblk_t mb_t;
* According to /usr/include/sys/spinlock.h on HP-UX 11.00, these functions
* are available. Attempting to use them actually results in unresolved
* symbols when it comes time to load the module.
+ * This has been fixed! Yipee!
*/
-# if 0
+# if 1
# ifdef __LP64__
-# define ATOMIC_INCL(x) lock_and_incr_int64(&ipf_rw, x, 1)
-# define ATOMIC_DECL(x) lock_and_incr_int64(&ipf_rw, x, -1)
+# define ATOMIC_INCL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1)
+# define ATOMIC_DECL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1)
# else
-# define ATOMIC_INCL(x) lock_and_incr_int32(&ipf_rw, x, 1)
-# define ATOMIC_DECL(x) lock_and_incr_int32(&ipf_rw, x, -1)
+# define ATOMIC_INCL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1)
+# define ATOMIC_DECL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1)
# endif
-# define ATOMIC_INC64(x) lock_and_incr_int64(&ipf_rw, x, 1)
-# define ATOMIC_INC32(x) lock_and_incr_int32(&ipf_rw, x, 1)
-# define ATOMIC_INC16(x) lock_and_incr_int16(&ipf_rw, x, 1)
-# define ATOMIC_DEC64(x) lock_and_incr_int64(&ipf_rw, x, -1)
-# define ATOMIC_DEC32(x) lock_and_incr_int32(&ipf_rw, x, -1)
-# define ATOMIC_DEC16(x) lock_and_incr_int16(&ipf_rw, x, -1)
+# define ATOMIC_INC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1)
+# define ATOMIC_INC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1)
+# define ATOMIC_INC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), 1)
+# define ATOMIC_DEC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1)
+# define ATOMIC_DEC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1)
+# define ATOMIC_DEC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), -1)
# else /* 0 */
-# define ATOMIC_INC(x) { spinlock(&ipf_rw); (x)++; \
- spinunlock(&ipf_rw); }
-# define ATOMIC_DEC(x) { spinlock(&ipf_rw); (x)--; \
- spinunlock(&ipf_rw); }
+# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
# endif
# define ip_cksum ip_csuma
# define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c)
# define USE_MUTEXES
# define MUTEX_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, (y))
# define MUTEX_ENTER(x) spinlock(&(x)->ipf_lk)
-# define MUTEX_EXIT(x) spinunlock(&(x)->ipf_lk)
+# define MUTEX_EXIT(x) spinunlock(&(x)->ipf_lk);
# define MUTEX_DESTROY(x)
-# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
+# define MUTEX_NUKE(x) bzero((char *)(x), sizeof(*(x)))
+# define KMUTEX_T lock_t
+# define kmutex_t lock_t /* for pfil.h */
+# define krwlock_t lock_t /* for pfil.h */
/*
* The read-write lock implementation in HP-UX 11.0 is crippled - it can
* only be used by threads working in a user context!
+ * This has been fixed! Yipee! (Or at least it does in 11.00, not 11.11..)
*/
-# if 0
+# if HPUXREV < 1111
# define MUTEX_DOWNGRADE(x) lock_write_to_read(x)
-# define KRWLOCK_T struct rwlock
+# define KRWLOCK_T struct rw_lock
# define READ_ENTER(x) lock_read(&(x)->ipf_lk)
# define WRITE_ENTER(x) lock_write(&(x)->ipf_lk)
-# define RWLOCK_INIT(x, y) lock_init3(&(x)->ipf_lk, 0, 1, 0, y)
+# if HPUXREV >= 1111
+# define RWLOCK_INIT(x, y) rwlock_init4(&(x)->ipf_lk, 0, RWLCK_CANSLEEP, 0, y)
+# else
+# define RWLOCK_INIT(x, y) lock_init3(&(x)->ipf_lk, 0, 1, 0, 0, y)
+# endif
# define RWLOCK_EXIT(x) lock_done(&(x)->ipf_lk)
# else
# define KRWLOCK_T lock_t
# define KMUTEX_T lock_t
-# define kmutex_t lock_t /* for pfil.h */
-# define krwlock_t lock_t /* for pfil.h */
-# define READ_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk)
-# define WRITE_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk)
+# define READ_ENTER(x) MUTEX_ENTER(x)
+# define WRITE_ENTER(x) MUTEX_ENTER(x)
# define MUTEX_DOWNGRADE(x)
# define RWLOCK_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, y)
-# define RWLOCK_EXIT(x) spinunlock(&(x)->ipf_lk)
+# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# endif
# define RW_DESTROY(x)
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
-# if HPUXREV > 1100
-# define BCOPYIN(a,b,c) memcpy((caddr_t)(a), (caddr_t)(b), (c))
-# define BCOPYOUT(a,b,c) memcpy((caddr_t)(a), (caddr_t)(b), (c))
+# if HPUXREV >= 1111
+# define BCOPYIN(a,b,c) 0; bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) 0; bcopy((caddr_t)(a), (caddr_t)(b), (c))
# else
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
@@ -411,19 +436,19 @@ typedef mblk_t mb_t;
# define SPL_IMP(x) ;
# undef SPL_X
# define SPL_X(x) ;
-extern ifinfo_t *get_unit __P((char *, int));
+extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x, b) ((ifinfo_t *)x)->ifi_name
+# define IFNAME(x, b) ((ill_t *)x)->ill_name
# define COPYIFNAME(x, b) \
- strncpy(b, ((ifinfo_t *)x)->ifi_name, \
- LIFNAMSIZ)
+ (void) strncpy(b, ((qif_t *)x)->qf_name, \
+ LIFNAMSIZ)
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) { lock_t *_l = get_sleep_lock((caddr_t)id); \
sleep(id, PZERO+1); \
spinunlock(_l); \
}
-# define WAKEUP(id) { lock_t *_l = get_sleep_lock((caddr_t)id); \
- wakeup(id); \
+# define WAKEUP(id,x) { lock_t *_l = get_sleep_lock((caddr_t)id); \
+ wakeup(id + x); \
spinunlock(_l); \
}
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT)
@@ -433,16 +458,17 @@ extern ifinfo_t *get_unit __P((char *, int));
# define MSGDSIZE(x) msgdsize(x)
# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr)
# define M_DUPLICATE(x) dupmsg((x))
-# define MTOD(m,t) (t)((m)->b_rptr)
+# define MTOD(m,t) ((t)((m)->b_rptr))
# define MTYPE(m) ((m)->b_datap->db_type)
# define FREE_MB_T(m) freemsg(m)
+# define m_next b_cont
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
typedef mblk_t mb_t;
-# define CACHE_HASH(x) (((qif_t *)(x)->fin_qif)->qf_num & 7)
+# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
-# include "pfil.h"
# include "qif.h"
+# include "pfil.h"
# else /* _KERNEL */
@@ -465,6 +491,8 @@ typedef u_long ulong;
# define ALIGN16(ptr) (ptr)
# endif
+typedef struct uio uio_t;
+typedef int ioctlcmd_t;
typedef int minor_t;
typedef unsigned int u_32_t;
# define U_32_T 1
@@ -478,6 +506,10 @@ typedef unsigned int u_32_t;
/* ----------------------------------------------------------------------- */
#ifdef __sgi
# undef MENTAT
+# if IRIX < 60500
+typedef struct uio uio_t;
+# endif
+typedef int ioctlcmd_t;
typedef u_int32_t u_32_t;
# define U_32_T 1
@@ -519,7 +551,7 @@ typedef struct {
# define ATOMIC_DEC32(x) atomicAddUint(&(x), -1)
# define ATOMIC_DEC16 ATOMIC_DEC
# undef MUTEX_INIT
-# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk,
+# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, \
MUTEX_DEFAULT, y)
# undef MUTEX_ENTER
# define MUTEX_ENTER(x) mutex_lock(&(x)->ipf_lk, 0)
@@ -555,7 +587,7 @@ typedef struct {
# define BCOPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0)
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) sleep((id), PZERO+1)
-# define WAKEUP(id) wakeup(id)
+# define WAKEUP(id,x) wakeup(id+x)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define GETIFP(n,v) ifunit(n)
@@ -564,6 +596,7 @@ typedef struct {
# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
+# define USE_SPL 1
# define SPL_IMP(x) (x) = splimp()
# define SPL_NET(x) (x) = splnet()
# define SPL_X(x) (void) splx(x)
@@ -577,6 +610,10 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
typedef struct mbuf mb_t;
+# else
+# undef RW_DESTROY
+# undef MUTEX_INIT
+# undef MUTEX_DESTROY
# endif /* _KERNEL */
# define OS_RECOGNISED 1
@@ -588,11 +625,6 @@ typedef struct mbuf mb_t;
/* ----------------------------------------------------------------------- */
#ifdef __osf__
# undef MENTAT
-/*
- * Really, any arch where sizeof(long) != sizeof(int).
- */
-typedef unsigned int u_32_t;
-# define U_32_T 1
# include <kern/lock.h>
# include <sys/sysmacros.h>
@@ -636,16 +668,17 @@ typedef unsigned int u_32_t;
# define MTOD(m,t) mtod(m,t)
# define GETIFP(n, v) ifunit(n)
# define GET_MINOR getminor
-# define WAKEUP wakeup
+# define WAKEUP(id,x) wakeup(id + x)
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFILT, M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFILT, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFILT, \
+ ((c) > 4096) ? M_WAITOK : M_NOWAIT)
# define KFREE(x) FREE((x), M_PFILT)
# define KFREES(x,s) FREE((x), M_PFILT)
-# define MSGDSIZE(x) (x)->m_pkthdr.len
+# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x) microtime((struct timeval *)x)
@@ -660,8 +693,10 @@ typedef struct mbuf mb_t;
# define IP_HL(x) ((x)->ip_vhl & 0xf)
# define IP_V_A(x,y) (x)->ip_vhl |= (((y) << 4) & 0xf0)
# define IP_HL_A(x,y) (x)->ip_vhl |= ((y) & 0xf)
+# define TCP_X2(x) ((x)->th_xoff & 0xf)
+# define TCP_X2_A(x,y) (x)->th_xoff |= ((y) & 0xf)
# define TCP_OFF(x) ((x)->th_xoff >> 4)
-# define TCP_OFF_A(x,y) (x)->th_xoff = ((y) << 4)
+# define TCP_OFF_A(x,y) (x)->th_xoff |= (((y) << 4) & 0xf0)
# endif
/*
@@ -676,6 +711,13 @@ struct ip6_ext {
u_char ip6e_len;
};
+typedef int ioctlcmd_t;
+/*
+ * Really, any arch where sizeof(long) != sizeof(int).
+ */
+typedef unsigned int u_32_t;
+# define U_32_T 1
+
# define OS_RECOGNISED 1
#endif /* __osf__ */
@@ -684,38 +726,48 @@ struct ip6_ext {
/* ----------------------------------------------------------------------- */
#ifdef __NetBSD__
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
+# include "bpfilter.h"
# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 104110000)
# include "opt_inet.h"
# endif
# ifdef INET6
# define USE_INET6
# endif
+# if (__NetBSD_Version__ >= 105000000)
+# define HAVE_M_PULLDOWN 1
+# endif
# endif
# ifdef _KERNEL
-# define MSGDSIZE(x) (x)->m_pkthdr.len
+# define MSGDSIZE(x) mbufchainlen(x)
# 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 IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
+# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
typedef struct mbuf mb_t;
# endif /* _KERNEL */
# if (NetBSD <= 1991011) && (NetBSD >= 199606)
# define IFNAME(x) ((struct ifnet *)x)->if_xname
# define COPYIFNAME(x, b) \
- strncpy(b, ((struct ifnet *)x)->if_xname, \
- LIFNAMSIZ)
+ (void) strncpy(b, \
+ ((struct ifnet *)x)->if_xname, \
+ LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
+typedef struct uio uio_t;
+typedef u_long ioctlcmd_t;
typedef int minor_t;
typedef u_int32_t u_32_t;
# define U_32_T 1
-
# define OS_RECOGNISED 1
#endif /* __NetBSD__ */
@@ -724,29 +776,70 @@ typedef u_int32_t u_32_t;
/* F R E E B S D */
/* ----------------------------------------------------------------------- */
#ifdef __FreeBSD__
-# if defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(KLD_MODULE)
+# if defined(_KERNEL)
+# if (__FreeBSD_version >= 500000)
+# include "opt_bpf.h"
+# else
+# include "bpf.h"
+# endif
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000)
# include "opt_inet6.h"
# endif
-# ifdef INET6
-#error foo
+# if defined(INET6) && !defined(USE_INET6)
# define USE_INET6
# endif
# endif
-# if defined(_KERNEL) /* XXX When *isn't* this defined? */
+# if defined(_KERNEL)
+# if (__FreeBSD_version >= 400000)
+/*
+ * When #define'd, the 5.2.1 kernel panics when used with the ftp proxy.
+ * There may be other, safe, kernels but this is not extensively tested yet.
+ */
+# define HAVE_M_PULLDOWN
+# endif
+# if !defined(IPFILTER_LKM) && (__FreeBSD_version >= 300000)
+# include "opt_ipfilter.h"
+# endif
+# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+
# if (__FreeBSD_version >= 500043)
-# include "opt_pfil.h"
-# endif /* __FreeBSD_version */
-# ifdef PFIL_HOOKS
# define NETBSD_PF
-# endif /* PFIL_HOOKS */
+# endif
# endif /* _KERNEL */
# if (__FreeBSD_version >= 500043)
# include <sys/mutex.h>
+# 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
-# define KRWLOCK_T struct mtx
+# if 1
+# define KRWLOCK_T struct mtx
+# else
+# define KRWLOCK_T struct sx
+# endif
+# endif
+
+# if (__FreeBSD_version >= 501113)
+# include <net/if_var.h>
+# define IFNAME(x) ((struct ifnet *)x)->if_xname
+# define COPYIFNAME(x, b) \
+ (void) strncpy(b, \
+ ((struct ifnet *)x)->if_xname, \
+ LIFNAMSIZ)
+# endif
+# if (__FreeBSD_version >= 500043)
+# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7)
+# else
+# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
+ ((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
# ifdef _KERNEL
@@ -761,47 +854,62 @@ typedef u_int32_t u_32_t;
# if (__FreeBSD_version >= 500043)
# define USE_MUTEXES
# define MUTEX_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define WRITE_ENTER(x) mtx_lock(&(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)
-# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk)
# define MUTEX_EXIT(x) mtx_unlock(&(x)->ipf_lk)
# define MUTEX_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\
MTX_DEF)
# define MUTEX_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
-# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
+# 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 1
+# 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)
+# 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); }
# define ATOMIC_DEC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)--; \
mtx_unlock(&ipf_rw.ipf_lk); }
-# if 0
-# define ATOMIC_INCL(x) atomic_add_long(x, 1)
-# define ATOMIC_INC64(x) atomic_add_(x, 1)
-# define ATOMIC_INC32(x) atomic_add_(x, 1)
-# define ATOMIC_INC16(x) atomic_add_short(x, 1)
-# define ATOMIC_DECL(x) atomic_subtrct_long(x, -1)
-# define ATOMIC_DEC64(x) atomic_subtrct_(x, -1)
-# define ATOMIC_DEC32(x) atomic_subtrct_(x, -1)
-# define ATOMIC_DEC16(x) atomic_subtrct_short(x, -1)
-# endif
+# define ATOMIC_INCL(x) atomic_add_long(&(x), 1)
+# define ATOMIC_INC64(x) ATOMIC_INC(x)
+# define ATOMIC_INC32(x) atomic_add_32(&(x), 1)
+# define ATOMIC_INC16(x) atomic_add_16(&(x), 1)
+# define ATOMIC_DECL(x) atomic_add_long(&(x), -1)
+# define ATOMIC_DEC64(x) ATOMIC_DEC(x)
+# define ATOMIC_DEC32(x) atomic_add_32(&(x), -1)
+# define ATOMIC_DEC16(x) atomic_add_16(&(x), -1)
# define SPL_X(x) ;
# define SPL_NET(x) ;
# define SPL_IMP(x) ;
extern int in_cksum __P((struct mbuf *, int));
# endif /* __FreeBSD_version >= 500043 */
-# define MSGDSIZE(x) (x)->m_pkthdr.len
+# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
-# if (__FreeBSD_version >= 500043)
-# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7)
-# else
-# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
- ((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
-# endif
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
typedef struct mbuf mb_t;
# endif /* _KERNEL */
@@ -816,6 +924,12 @@ typedef struct mbuf mb_t;
# endif
# endif
+# if (__FreeBSD_version >= 300000)
+typedef u_long ioctlcmd_t;
+# else
+typedef int ioctlcmd_t;
+# endif
+typedef struct uio uio_t;
typedef int minor_t;
typedef u_int32_t u_32_t;
# define U_32_T 1
@@ -833,8 +947,25 @@ typedef u_int32_t u_32_t;
# endif
# ifdef _KERNEL
+# if !defined(IPFILTER_LKM)
+# include "bpfilter.h"
+# endif
+# if (OpenBSD >= 200311)
+# define SNPRINTF snprintf
+# if defined(USE_INET6)
+# include "netinet6/in6_var.h"
+# include "netinet6/nd6.h"
+# endif
+# endif
+# if (OpenBSD >= 200012)
+# define HAVE_M_PULLDOWN 1
+# endif
+# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
# define GETKTIME(x) microtime((struct timeval *)x)
-# define MSGDSIZE(x) (x)->m_pkthdr.len
+# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -843,14 +974,17 @@ typedef struct mbuf mb_t;
# if (OpenBSD >= 199603)
# define IFNAME(x, b) ((struct ifnet *)x)->if_xname
# define COPYIFNAME(x, b) \
- strncpy(b, ((struct ifnet *)x)->if_xname, \
- LIFNAMSIZ)
+ (void) strncpy(b, \
+ ((struct ifnet *)x)->if_xname, \
+ LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
+typedef struct uio uio_t;
+typedef u_long ioctlcmd_t;
typedef int minor_t;
typedef u_int32_t u_32_t;
# define U_32_T 1
@@ -869,7 +1003,7 @@ typedef u_int32_t u_32_t;
# ifdef _KERNEL
# define GETKTIME(x) microtime((struct timeval *)x)
-# define MSGDSIZE(x) (x)->m_pkthdr.len
+# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
@@ -877,6 +1011,11 @@ typedef u_int32_t u_32_t;
typedef struct mbuf mb_t;
# endif /* _KERNEL */
+# if (_BSDI_VERSION >= 199701)
+typedef u_long ioctlcmd_t;
+# else
+typedef int ioctlcmd_t;
+# endif
typedef u_int32_t u_32_t;
# define U_32_T 1
@@ -899,7 +1038,7 @@ typedef u_int32_t u_32_t;
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define SLEEP(id, n) sleep((id), PZERO+1)
-# define WAKEUP(id) wakeup(id)
+# define WAKEUP(id,x) wakeup(id + x)
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -909,6 +1048,8 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
typedef struct mbuf mb_t;
# endif
+typedef struct uio uio_t;
+typedef int ioctlcmd_t;
typedef int minor_t;
typedef unsigned int u_32_t;
# define U_32_T 1
@@ -917,11 +1058,276 @@ typedef unsigned int u_32_t;
#endif /* SunOS 4 */
+/* ----------------------------------------------------------------------- */
+/* L I N U X */
+/* ----------------------------------------------------------------------- */
+#if defined(linux) && !defined(OS_RECOGNISED)
+#include <linux/config.h>
+#include <linux/version.h>
+# if LINUX >= 20600
+# define HDR_T_PRIVATE 1
+# endif
+# undef USE_INET6
+# ifdef USE_INET6
+struct ip6_ext {
+ u_char ip6e_nxt;
+ u_char ip6e_len;
+};
+# endif
+
+# ifdef _KERNEL
+# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYIN(a,b,c) copy_from_user((caddr_t)(b), (caddr_t)(a), (c))
+# define COPYOUT(a,b,c) copy_to_user((caddr_t)(b), (caddr_t)(a), (c))
+# define FREE_MB_T(m) kfree_skb(m)
+# define GETKTIME(x) do_gettimeofday((struct timeval *)x)
+# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
+# define WAKEUP(x,y) wake_up(x##_linux + y)
+# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
+# define USE_MUTEXES
+# define KRWLOCK_T rwlock_t
+# define KMUTEX_T spinlock_t
+# define MUTEX_INIT(x,y) spin_lock_init(&(x)->ipf_lk)
+# define MUTEX_ENTER(x) spin_lock(&(x)->ipf_lk)
+# define MUTEX_EXIT(x) spin_unlock(&(x)->ipf_lk)
+# define MUTEX_DESTROY(x) do { } while (0)
+# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk))
+# define READ_ENTER(x) ipf_read_enter(x)
+# define WRITE_ENTER(x) ipf_write_enter(x)
+# define RWLOCK_INIT(x,y) rwlock_init(&(x)->ipf_lk)
+# define RW_DESTROY(x) do { } while (0)
+# define RWLOCK_EXIT(x) ipf_rw_exit(x)
+# define MUTEX_DOWNGRADE(x) ipf_rw_downgrade(x)
+# define ATOMIC_INCL(x) MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_DECL(x) MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_INC64(x) MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_INC32(x) MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_INC16(x) MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_DEC64(x) MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_DEC32(x) MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw)
+# define ATOMIC_DEC16(x) MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw)
+# define SPL_IMP(x) do { } while (0)
+# define SPL_NET(x) do { } while (0)
+# define SPL_X(x) do { } while (0)
+# define IFNAME(x) ((struct net_device*)x)->name
+# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
+ ((struct net_device *)fin->fin_ifp)->ifindex) & 7)
+typedef struct sk_buff mb_t;
+extern void m_copydata __P((mb_t *, int, int, caddr_t));
+extern void m_copyback __P((mb_t *, int, int, caddr_t));
+extern void m_adj __P((mb_t *, int));
+extern mb_t *m_pullup __P((mb_t *, int));
+# define mbuf sk_buff
+
+# define mtod(m, t) ((t)(m)->data)
+# define m_len len
+# define m_next next
+# define M_DUPLICATE(m) skb_clone((m), in_interrupt() ? GFP_ATOMIC : \
+ GFP_KERNEL)
+# define MSGDSIZE(m) (m)->len
+# define M_LEN(m) (m)->len
+
+# define splnet(x) ;
+# define printf printk
+# define bcopy(s,d,z) memmove(d, s, z)
+# define bzero(s,z) memset(s, 0, z)
+# define bcmp(a,b,z) memcmp(a, b, z)
+
+# define ifnet net_device
+# define if_xname name
+# define if_unit ifindex
+
+# define KMALLOC(x,t) (x) = (t)kmalloc(sizeof(*(x)), \
+ in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
+# define KFREE(x) kfree(x)
+# define KMALLOCS(x,t,s) (x) = (t)kmalloc((s), \
+ in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
+# define KFREES(x,s) kfree(x)
+
+# define GETIFP(n,v) dev_get_by_name(n)
+
+# else
+# include <net/ethernet.h>
+
+struct mbuf {
+};
+
+# ifndef _NET_ROUTE_H
+struct rtentry {
+};
+# endif
+
+struct ifnet {
+ char if_xname[IFNAMSIZ];
+ int if_unit;
+ int (* if_output) __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *));
+ struct ifaddr *if_addrlist;
+};
+# define IFNAME(x) ((struct ifnet *)x)->if_xname
+
+# endif /* _KERNEL */
+
+# define COPYIFNAME(x, b) \
+ (void) strncpy(b, \
+ ((struct ifnet *)x)->if_xname, \
+ LIFNAMSIZ)
+
+# include <linux/fs.h>
+# define FWRITE FMODE_WRITE
+# define FREAD FMODE_READ
+
+# define __USE_MISC 1
+# define __FAVOR_BSD 1
+
+typedef struct uio {
+ struct iovec *uio_iov;
+ void *uio_file;
+ char *uio_buf;
+ int uio_iovcnt;
+ int uio_offset;
+ size_t uio_resid;
+ int uio_rw;
+} uio_t;
+
+extern int uiomove __P((caddr_t, size_t, int, struct uio *));
+
+# define UIO_READ 1
+# define UIO_WRITE 2
+
+typedef u_long ioctlcmd_t;
+typedef int minor_t;
+typedef u_int32_t u_32_t;
+# define U_32_T 1
+
+# define OS_RECOGNISED 1
+
+#endif
+
+
+/* ----------------------------------------------------------------------- */
+/* A I X */
+/* ----------------------------------------------------------------------- */
+#if defined(_AIX51)
+# undef MENTAT
+
+# include <sys/lock.h>
+# include <sys/sysmacros.h>
+
+# ifdef _KERNEL
+# define rw_read_locked(x) 0
+# include <net/net_globals.h>
+# include <net/net_malloc.h>
+# define KMUTEX_T simple_lock_t
+# define KRWLOCK_T complex_lock_t
+# define USE_MUTEXES 1
+# define USE_SPL 1
+# define READ_ENTER(x) lock_read((x)->ipf_lk)
+# define WRITE_ENTER(x) lock_write((x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) lock_write_to_read((x)->ipf_lk)
+# define RWLOCK_INIT(x, y) lock_alloc(&(x)->ipf_lk, \
+ LOCK_ALLOC_PIN, \
+ (u_short)y, 0); \
+ lock_init((x)->ipf_lk, TRUE)
+# define RWLOCK_EXIT(x) lock_done((x)->ipf_lk)
+# define RW_DESTROY(x) lock_free(&(x)->ipf_lk)
+# define MUTEX_ENTER(x) simple_lock((x)->ipf_lk)
+# define MUTEX_INIT(x, y) lock_alloc(&(x)->ipf_lk, \
+ LOCK_ALLOC_PIN, \
+ (u_short)y, 0); \
+ simple_lock_init((x)->ipf_lk)
+# define MUTEX_DESTROY(x) lock_free(&(x)->ipf_lk)
+# define MUTEX_EXIT(x) simple_unlock((x)->ipf_lk)
+# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk))
+# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define SPL_NET(x) x = splnet()
+# define SPL_IMP(x) x = splimp()
+# undef SPL_X
+# define SPL_X(x) splx(x)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
+extern void* getifp __P((char *, int));
+# define GETIFP(n, v) getifp(n, v)
+# define GET_MINOR minor
+# define SLEEP(id, n) sleepx((id), PZERO+1, 0)
+# define WAKEUP(id,x) wakeup(id)
+# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, \
+ ((c) > 4096) ? M_WAITOK : M_NOWAIT)
+# define KFREE(x) FREE((x), M_TEMP)
+# define KFREES(x,s) FREE((x), M_TEMP)
+# define MSGDSIZE(x) mbufchainlen(x)
+# define M_LEN(x) (x)->m_len
+# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define GETKTIME(x)
+# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
+ ((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
+# define IPF_PANIC(x,y)
+typedef struct mbuf mb_t;
+# endif /* _KERNEL */
+
+/*
+ * These are from's Solaris' #defines for little endian.
+ */
+#if !defined(IP6F_MORE_FRAG)
+# define IP6F_MORE_FRAG 0x0100
+#endif
+#if !defined(IP6F_RESERVED_MASK)
+# define IP6F_RESERVED_MASK 0x0600
+#endif
+#if !defined(IP6F_OFF_MASK)
+# define IP6F_OFF_MASK 0xf8ff
+#endif
+
+struct ip6_ext {
+ u_char ip6e_nxt;
+ u_char ip6e_len;
+};
+
+typedef int ioctlcmd_t;
+typedef int minor_t;
+/*
+ * Really, any arch where sizeof(long) != sizeof(int).
+ */
+typedef unsigned int u_32_t;
+# define U_32_T 1
+
+# define OS_RECOGNISED 1
+#endif /* _AIX51 */
+
#ifndef OS_RECOGNISED
#error ip_compat.h does not recognise this platform/OS.
#endif
+
/* ----------------------------------------------------------------------- */
/* G E N E R I C */
/* ----------------------------------------------------------------------- */
@@ -929,59 +1335,133 @@ typedef unsigned int u_32_t;
#endif
/*
+ * For BSD kernels, if bpf is in the kernel, enable ipfilter to use bpf in
+ * filter rules.
+ */
+#if !defined(IPFILTER_BPF) && ((NBPF > 0) || (NBPFILTER > 0) || (DEV_BPF > 0))
+# define IPFILTER_BPF
+#endif
+
+/*
* Userland locking primitives
*/
typedef struct {
+ char *eMm_owner;
+ char *eMm_heldin;
u_int eMm_magic;
int eMm_held;
- char *eMm_owner;
int eMm_heldat;
- char *eMm_heldin;
+#ifdef __hpux
+ char eMm_fill[8];
+#endif
} eMmutex_t;
typedef struct {
- u_int eMrw_magic;
- int eMrw_read;
- int eMrw_write;
char *eMrw_owner;
- int eMrw_heldat;
char *eMrw_heldin;
+ u_int eMrw_magic;
+ short eMrw_read;
+ short eMrw_write;
+ int eMrw_heldat;
+#ifdef __hpux
+ char eMm_fill[24];
+#endif
} eMrwlock_t;
typedef union {
#ifdef KMUTEX_T
- KMUTEX_T ipf_lk;
+ struct {
+ KMUTEX_T ipf_slk;
+ char *ipf_lname;
+ } ipf_lkun_s;
#endif
eMmutex_t ipf_emu;
} ipfmutex_t;
typedef union {
#ifdef KRWLOCK_T
- KRWLOCK_T ipf_lk;
+ struct {
+ KRWLOCK_T ipf_slk;
+ char *ipf_lname;
+ int ipf_sr;
+ int ipf_sw;
+ u_int ipf_magic;
+ } ipf_lkun_s;
#endif
eMrwlock_t ipf_emu;
} ipfrwlock_t;
+#define ipf_lk ipf_lkun_s.ipf_slk
+#define ipf_lname ipf_lkun_s.ipf_lname
+#define ipf_isr ipf_lkun_s.ipf_sr
+#define ipf_isw ipf_lkun_s.ipf_sw
+#define ipf_magic ipf_lkun_s.ipf_magic
+
+#if !defined(__GNUC__) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version >= 503000))
+# ifndef INLINE
+# define INLINE
+# endif
+#else
+# define INLINE __inline__
+#endif
+
+#if defined(linux) && defined(_KERNEL)
+extern INLINE void ipf_read_enter __P((ipfrwlock_t *));
+extern INLINE void ipf_write_enter __P((ipfrwlock_t *));
+extern INLINE void ipf_rw_exit __P((ipfrwlock_t *));
+extern INLINE void ipf_rw_downgrade __P((ipfrwlock_t *));
+#endif
+
+/*
+ * In a non-kernel environment, there are a lot of macros that need to be
+ * filled in to be null-ops or to point to some compatibility function,
+ * somewhere in userland.
+ */
#ifndef _KERNEL
typedef struct mb_s {
struct mb_s *mb_next;
int mb_len;
u_long mb_buf[2048];
} mb_t;
+# undef m_next
+# define m_next mb_next
# define MSGDSIZE(x) (x)->mb_len /* XXX - from ipt.c */
# define M_LEN(x) (x)->mb_len
# define M_DUPLICATE(x) (x)
# define GETKTIME(x) gettimeofday((struct timeval *)(x), NULL)
-# define MTOD(m, t) (t)((m)->mb_buf)
+# undef MTOD
+# define MTOD(m, t) ((t)(m)->mb_buf)
# define FREE_MB_T(x)
+# define SLEEP(x,y) 1;
+# define WAKEUP(x,y) ;
+# define IPF_PANIC(x,y) ;
+# define PANIC(x,y) ;
+# define SPL_NET(x) ;
+# define SPL_IMP(x) ;
+# define SPL_X(x) ;
+# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a))
+# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
+# define KFREE(x) free(x)
+# define KFREES(x,s) free(x)
+# define GETIFP(x, v) get_unit(x,v)
+# define COPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
+# define COPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
+# define BCOPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
+# define BCOPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
+# define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \
+ (b), (l))
+# 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)
+extern void m_copydata __P((mb_t *, int, int, caddr_t));
+extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
# ifndef CACHE_HASH
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
-# if 0
-# define KMUTEX_T eMmutex_t
-# endif
# define MUTEX_DESTROY(x) eMmutex_destroy(&(x)->ipf_emu)
# define MUTEX_ENTER(x) eMmutex_enter(&(x)->ipf_emu, \
__FILE__, __LINE__)
@@ -989,9 +1469,6 @@ typedef struct mb_s {
# define MUTEX_INIT(x,y) eMmutex_init(&(x)->ipf_emu, y)
# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
-# if 0
-# define KRWLOCK_T eMrwlock_t
-# endif
# define MUTEX_DOWNGRADE(x) eMrwlock_downgrade(&(x)->ipf_emu, \
__FILE__, __LINE__)
# define READ_ENTER(x) eMrwlock_read_enter(&(x)->ipf_emu, \
@@ -1020,10 +1497,15 @@ extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int));
#define MAX_IPV4HDR ((0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8)
-# ifndef IP_OFFMASK
-# define IP_OFFMASK 0x1fff
-# endif
+#ifndef IP_OFFMASK
+# define IP_OFFMASK 0x1fff
+#endif
+
+/*
+ * On BSD's use quad_t as a guarantee for getting at least a 64bit sized
+ * object.
+ */
#if BSD > 199306
# define USE_QUAD_T
# define U_QUAD_T u_quad_t
@@ -1036,11 +1518,13 @@ extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int));
#ifdef USE_INET6
# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
- defined(__osf__)
+ defined(__osf__) || defined(linux)
# include <netinet/ip6.h>
# include <netinet/icmp6.h>
-# if defined(_KERNEL) && !defined(__osf__)
-# include <netinet6/ip6_var.h>
+# if !defined(linux)
+# if defined(_KERNEL) && !defined(__osf__)
+# include <netinet6/ip6_var.h>
+# endif
# endif
typedef struct ip6_hdr ip6_t;
# endif
@@ -1058,15 +1542,6 @@ typedef struct ip6_hdr ip6_t;
# define COPYDATA m_copydata
# define COPYBACK m_copyback
# endif
-#else
-# define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \
- (b), (l))
-# define COPYBACK(m, o, l, b) bcopy((b), \
- MTOD((mb_t *)m, char *) + (o), \
- (l))
-#endif
-
-#ifdef _KERNEL
# if (BSD >= 199306) || defined(__FreeBSD__)
# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \
defined(__FreeBSD__) || (defined(OpenBSD) && (OpenBSD < 200206)) || \
@@ -1090,32 +1565,29 @@ extern vm_map_t kmem_map;
# ifdef IPFILTER_M_IPFILTER
# include <sys/malloc.h>
MALLOC_DECLARE(M_IPFILTER);
-# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IPFILTER, \
- M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IPFILTER, \
- M_NOWAIT)
-# define KFREE(x) FREE((x), M_IPFILTER)
-# define KFREES(x,s) FREE((x), M_IPFILTER)
+# define _M_IPF M_IPFILTER
# else /* IPFILTER_M_IPFILTER */
# ifdef M_PFIL
-# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFIL, M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
-# define KFREE(x) FREE((x), M_PFIL)
-# define KFREES(x,s) FREE((x), M_PFIL)
-# else /* M_PFIL */
-# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
-# define KFREE(x) FREE((x), M_TEMP)
-# define KFREES(x,s) FREE((x), M_TEMP)
+# define _M_IPF M_PFIL
+# else
+# ifdef M_IPFILTER
+# define _M_IPF M_IPFILTER
+# else
+# define _M_IPF M_TEMP
+# endif /* M_IPFILTER */
# endif /* M_PFIL */
# endif /* IPFILTER_M_IPFILTER */
+# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), _M_IPF, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), _M_IPF, M_NOWAIT)
+# 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 SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
-# define WAKEUP(id) wakeup(id)
+# define WAKEUP(id,x) wakeup(id+x)
# define GETIFP(n, v) ifunit(n)
# endif /* (Free)BSD */
-# if !defined(USE_MUTEXES)
+# if !defined(USE_MUTEXES) && !defined(SPL_NET)
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199407)) || \
(defined(OpenBSD) && (OpenBSD >= 200006))
# define SPL_NET(x) x = splsoftnet()
@@ -1150,27 +1622,7 @@ MALLOC_DECLARE(M_IPFILTER);
# ifndef GET_MINOR
# define GET_MINOR(x) minor(x)
# endif
-# define PANIC(x,y) /* if (x) panic y */
-#else /* _KERNEL */
-# define SLEEP(x,y) 1;
-# define WAKEUP(x) ;
-# define IPF_PANIC(x,y) ;
-# define PANIC(x,y) ;
-# define SPL_NET(x) ;
-# define SPL_IMP(x) ;
-# define SPL_X(x) ;
-# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a))
-# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
-# define KFREE(x) free(x)
-# define KFREES(x,s) free(x)
-# define GETIFP(x, v) get_unit(x,v)
-# define COPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
-# define COPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
-# define BCOPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
-# define BCOPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
-# define UIOMOVE(a,b,c,d) ipfuiomove(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 *));
+# define PANIC(x,y) if (x) panic y
#endif /* _KERNEL */
#ifndef IFNAME
@@ -1183,7 +1635,29 @@ extern char *fr_getifname __P((struct ifnet *, char *));
fr_getifname((struct ifnet *)x, b)
#endif
+#ifndef ASSERT
+# define ASSERT(x)
+#endif
+/*
+ * Because the ctype(3) posix definition, if used "safely" in code everywhere,
+ * would mean all normal code that walks through strings needed casts. Yuck.
+ */
+#define ISALNUM(x) isalnum((u_char)(x))
+#define ISALPHA(x) isalpha((u_char)(x))
+#define ISASCII(x) isascii((u_char)(x))
+#define ISDIGIT(x) isdigit((u_char)(x))
+#define ISPRINT(x) isprint((u_char)(x))
+#define ISSPACE(x) isspace((u_char)(x))
+#define ISUPPER(x) isupper((u_char)(x))
+#define ISXDIGIT(x) isxdigit((u_char)(x))
+#define ISLOWER(x) islower((u_char)(x))
+#define TOUPPER(x) toupper((u_char)(x))
+#define TOLOWER(x) tolower((u_char)(x))
+
+/*
+ * If mutexes aren't being used, turn all the mutex functions into null-ops.
+ */
#if !defined(USE_MUTEXES)
# define USE_SPL 1
# undef RW_DESTROY
@@ -1207,9 +1681,15 @@ extern char *fr_getifname __P((struct ifnet *, char *));
# define ATOMIC_DEC(x) (x)--
#endif
+#if defined(USE_SPL) && defined(_KERNEL)
+# define SPL_INT(x) int x
+#else
+# define SPL_INT(x)
+#endif
+
/*
- * Build some macros and #defines to enable the same code to compile anywhere
- * Well, that's the idea, anyway :-)
+ * If there are no atomic operations for bit sizes defined, define them to all
+ * use a generic one that works for all sizes.
*/
#ifndef ATOMIC_INCL
# define ATOMIC_INCL ATOMIC_INC
@@ -1222,8 +1702,10 @@ extern char *fr_getifname __P((struct ifnet *, char *));
# define ATOMIC_DEC16 ATOMIC_DEC
#endif
+#ifndef HDR_T_PRIVATE
typedef struct tcphdr tcphdr_t;
typedef struct udphdr udphdr_t;
+#endif
typedef struct icmp icmphdr_t;
typedef struct ip ip_t;
typedef struct ether_header ether_header_t;
@@ -1240,6 +1722,11 @@ typedef struct tcpiphdr tcpiphdr_t;
# define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
+/*
+ * This set of macros has been brought about because on Tru64 it is not
+ * possible to easily assign or examine values in a structure that are
+ * bit fields.
+ */
#ifndef IP_V
# define IP_V(x) (x)->ip_v
#endif
@@ -1252,6 +1739,12 @@ typedef struct tcpiphdr tcpiphdr_t;
#ifndef IP_HL_A
# define IP_HL_A(x,y) (x)->ip_hl = (y)
#endif
+#ifndef TCP_X2
+# define TCP_X2(x) (x)->th_x2
+#endif
+#ifndef TCP_X2_A
+# define TCP_X2_A(x,y) (x)->th_x2 = (y)
+#endif
#ifndef TCP_OFF
# define TCP_OFF(x) (x)->th_off
#endif
@@ -1313,17 +1806,23 @@ typedef struct tcpiphdr tcpiphdr_t;
*/
#undef IPOPT_RR
#define IPOPT_RR 7
+#undef IPOPT_ZSU
#define IPOPT_ZSU 10 /* ZSU */
+#undef IPOPT_MTUP
#define IPOPT_MTUP 11 /* MTUP */
+#undef IPOPT_MTUR
#define IPOPT_MTUR 12 /* MTUR */
+#undef IPOPT_ENCODE
#define IPOPT_ENCODE 15 /* ENCODE */
#undef IPOPT_TS
#define IPOPT_TS 68
+#undef IPOPT_TR
#define IPOPT_TR 82 /* TR */
#undef IPOPT_SECURITY
#define IPOPT_SECURITY 130
#undef IPOPT_LSRR
#define IPOPT_LSRR 131
+#undef IPOPT_E_SEC
#define IPOPT_E_SEC 133 /* E-SEC */
#undef IPOPT_CIPSO
#define IPOPT_CIPSO 134 /* CIPSO */
@@ -1334,15 +1833,25 @@ typedef struct tcpiphdr tcpiphdr_t;
#endif
#undef IPOPT_SSRR
#define IPOPT_SSRR 137
+#undef IPOPT_ADDEXT
#define IPOPT_ADDEXT 147 /* ADDEXT */
+#undef IPOPT_VISA
#define IPOPT_VISA 142 /* VISA */
+#undef IPOPT_IMITD
#define IPOPT_IMITD 144 /* IMITD */
+#undef IPOPT_EIP
#define IPOPT_EIP 145 /* EIP */
+#undef IPOPT_RTRALRT
#define IPOPT_RTRALRT 148 /* RTRALRT */
+#undef IPOPT_SDB
#define IPOPT_SDB 149
+#undef IPOPT_NSAPA
#define IPOPT_NSAPA 150
+#undef IPOPT_DPS
#define IPOPT_DPS 151
+#undef IPOPT_UMP
#define IPOPT_UMP 152
+#undef IPOPT_FINN
#define IPOPT_FINN 205 /* FINN */
#ifndef TCPOPT_EOL
@@ -1888,7 +2397,7 @@ typedef struct tcpiphdr tcpiphdr_t;
/*
* ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
* another IP header and then 64 bits of data, totalling 56. Of course,
- * the last 64 bits is dependant on that being available.
+ * the last 64 bits is dependent on that being available.
*/
#define ICMPERR_ICMPHLEN 8
#define ICMPERR_IPICMPHLEN (20 + 8)
@@ -1897,16 +2406,18 @@ typedef struct tcpiphdr tcpiphdr_t;
#define ICMP6ERR_MINPKTLEN (40 + 8)
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
-#ifdef __GNUC__
-# define INLINE __inline__
+#ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifdef IPF_DEBUG
+# define DPRINT(x) printf x
#else
-# ifndef INLINE
-# define INLINE
-# endif
+# define DPRINT(x)
#endif
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
+#ifdef RESCUE
+# undef IPFILTER_BPF
#endif
#endif /* __IP_COMPAT_H__ */
diff --git a/usr/src/common/ipf/ip_fil.h b/usr/src/uts/common/inet/ipf/netinet/ip_fil.h
index e853b697bd..e7ec154f4f 100644
--- a/usr/src/common/ipf/ip_fil.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_fil.h
@@ -3,7 +3,8 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_fil.h,v 2.146 2003/07/01 18:30:19 darrenr Exp $
+ * @(#)ip_fil.h 1.35 6/5/96
+ * $Id: ip_fil.h,v 2.170.2.22 2005/07/16 05:55:35 darrenr Exp $
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -14,6 +15,8 @@
#ifndef __IP_FIL_H__
#define __IP_FIL_H__
+#include "netinet/ip_compat.h"
+
#ifndef SOLARIS
# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
@@ -26,7 +29,7 @@
# endif
#endif
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCADAFR _IOW('r', 60, struct ipfobj)
# define SIOCRMAFR _IOW('r', 61, struct ipfobj)
# define SIOCSETFF _IOW('r', 62, u_int)
@@ -123,6 +126,7 @@ typedef union i6addr {
lookupfunc_t lptr[2];
} i6addr_t;
#endif
+
#define in4_addr in4.s_addr
#define iplookupnum i6[0]
#define iplookuptype i6[1]
@@ -235,10 +239,11 @@ typedef struct fr_ip {
#define FI_BAD 0x0400
#define FI_OOW 0x0800 /* Out of state window, else match */
#define FI_ICMPERR 0x1000
-#define FI_FRAGTAIL 0x2000
+#define FI_FRAGBODY 0x2000
#define FI_BADSRC 0x4000
#define FI_LOWTTL 0x8000
-#define FI_CMP 0xcff3 /* Not FI_FRAG,FI_FRAGTAIL */
+#define FI_CMP 0xcfe3 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL */
+#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
@@ -276,7 +281,7 @@ typedef struct fr_ip {
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
- struct fr_ip fin_fi; /* IP Packet summary */
+ fr_ip_t fin_fi; /* IP Packet summary */
union {
u_short fid_16[2]; /* TCP/UDP ports, ICMP code/type */
u_32_t fid_32;
@@ -292,8 +297,9 @@ typedef struct fr_info {
void *fin_dp; /* start of data past IP header */
int fin_dlen; /* length of data portion of packet */
int fin_plen;
- int fin_flen; /* length of layer 4 hdr and
+ int fin_flen; /* length of layer 4 hdr and
ipv6 ext hdr after fragment hdr */
+ int fin_ipoff; /* # bytes from buffer start to hdr */
u_32_t fin_id; /* IP packet id field */
u_short fin_off;
int fin_depth; /* Group nesting depth */
@@ -306,7 +312,10 @@ typedef struct fr_info {
mb_t *fin_m; /* pointer to mbuf */
#ifdef MENTAT
mb_t *fin_qfm; /* pointer to mblk where pkt starts */
- void *fin_qif;
+ void *fin_qpi;
+#endif
+#ifdef __sgi
+ void *fin_hbuf;
#endif
} fr_info_t;
@@ -351,12 +360,13 @@ typedef struct ipfunc_resolve {
#define FI_COPYSIZE offsetof(fr_info_t, fin_dp)
/*
- *
+ * Structure for holding IPFilter's tag information
*/
+#define IPFTAG_LEN 16
typedef struct {
union {
u_32_t iptu_num[4];
- char iptu_tag[16];
+ char iptu_tag[IPFTAG_LEN];
} ipt_un;
int ipt_not;
} ipftag_t;
@@ -424,8 +434,8 @@ typedef struct frtuc {
* used to define the result which are in frentry_t and not here.
*/
typedef struct fripf {
- struct fr_ip fri_ip;
- struct fr_ip fri_mip; /* mask structure */
+ fr_ip_t fri_ip;
+ fr_ip_t fri_mip; /* mask structure */
u_short fri_icmpm; /* data for ICMP packets (mask) */
u_short fri_icmp;
@@ -503,11 +513,11 @@ typedef struct frentry {
u_char fr_icode; /* return ICMP code */
char fr_group[FR_GROUPLEN]; /* group to which this rule belongs */
char fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */
- ipftag_t fr_nattag;
+ ipftag_t fr_nattag;
char fr_ifnames[4][LIFNAMSIZ];
char fr_isctag[16];
- struct frdest fr_tifs[2]; /* "to"/"reply-to" interface */
- struct frdest fr_dif; /* duplicate packet interface */
+ frdest_t fr_tifs[2]; /* "to"/"reply-to" interface */
+ frdest_t fr_dif; /* duplicate packet interface */
/*
* This must be last and will change after loaded into the kernel.
*/
@@ -578,7 +588,7 @@ typedef struct frentry {
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#define FR_CMPSIZ (sizeof(struct frentry) - \
- offsetof(struct frentry, fr_dsize))
+ offsetof(struct frentry, fr_func))
/*
* fr_type
@@ -626,6 +636,7 @@ typedef struct frentry {
#define FR_STSTRICT 0x200000 /* strict keep state */
#define FR_NEWISN 0x400000 /* new ISN for outgoing TCP */
#define FR_NOICMPERR 0x800000 /* do not match ICMP errors in state */
+#define FR_STATESYNC 0x1000000 /* synchronize state to slave */
#define FR_NOMATCH 0x8000000 /* no match occured */
/* 0x10000000 FF_LOGPASS */
/* 0x20000000 FF_LOGBLOCK */
@@ -757,15 +768,17 @@ typedef struct filter_kstats {
typedef struct iplog {
u_32_t ipl_magic;
u_int ipl_count;
- struct timeval ipl_tv;
+ struct timeval ipl_time;
size_t ipl_dsize;
struct iplog *ipl_next;
} iplog_t;
-#define ipl_sec ipl_tv.tv_sec
-#define ipl_usec ipl_tv.tv_usec
+#define ipl_sec ipl_time.tv_sec
+#define ipl_usec ipl_time.tv_usec
#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+#define IPL_MAGIC_NAT 0x49504c4e /* 'IPLN' */
+#define IPL_MAGIC_STATE 0x49504c53 /* 'IPLS' */
#define IPLOG_SIZE sizeof(iplog_t)
typedef struct ipflog {
@@ -777,13 +790,14 @@ typedef struct ipflog {
u_32_t fl_rule;
u_32_t fl_flags;
u_32_t fl_lflags;
- u_32_t fl_tag;
+ u_32_t fl_logtag;
+ ipftag_t fl_nattag;
u_short fl_plen; /* extra data after hlen */
u_short fl_loglevel; /* syslog log level */
char fl_group[FR_GROUPLEN];
u_char fl_hlen; /* length of IP headers saved */
u_char fl_dir;
- u_char fl_xxx[6]; /* pad */
+ u_char fl_xxx[2]; /* pad */
char fl_ifname[LIFNAMSIZ];
} ipflog_t;
@@ -798,8 +812,8 @@ typedef struct ipflog {
#ifndef IPFILTER_LOGSIZE
# define IPFILTER_LOGSIZE DEFAULT_IPFLOGSIZE
#else
-# if IPF_LOGSIZE < DEFAULT_IPFLOGSIZE
-# error IPFILTER_LOGSISZE too small. Must be >= DEFAULT_IPFLOGSIZE
+# if IPFILTER_LOGSIZE < DEFAULT_IPFLOGSIZE
+# error IPFILTER_LOGSIZE too small. Must be >= DEFAULT_IPFLOGSIZE
# endif
#endif
@@ -857,9 +871,10 @@ typedef struct friostat {
size_t f_kmutex_sz;
size_t f_krwlock_sz;
int f_defpass; /* default pass - from fr_pass */
- char f_active; /* 1 or 0 - active rule set */
- char f_running; /* 1 if running, else 0 */
- char f_logging; /* 1 if enabled, else 0 */
+ int f_active; /* 1 or 0 - active rule set */
+ int f_running; /* 1 if running, else 0 */
+ int f_logging; /* 1 if enabled, else 0 */
+ int f_features;
char f_version[32]; /* version string */
} friostat_t;
@@ -872,6 +887,15 @@ typedef struct friostat {
#define f_acctout f_acct[1]
#define f_acctout6 f_acct6[1]
+#define IPF_FEAT_LKM 0x001
+#define IPF_FEAT_LOG 0x002
+#define IPF_FEAT_LOOKUP 0x004
+#define IPF_FEAT_BPF 0x008
+#define IPF_FEAT_COMPILED 0x010
+#define IPF_FEAT_CKSUM 0x020
+#define IPF_FEAT_SYNC 0x040
+#define IPF_FEAT_SCAN 0x080
+#define IPF_FEAT_IPV6 0x100
typedef struct optlist {
u_short ol_val;
@@ -930,43 +954,68 @@ typedef struct tcpinfo {
tcpdata_t ts_data[2];
} tcpinfo_t;
-typedef struct greinfo {
- u_short gs_flags;
- u_short gs_ptype;
- u_short gs_call;
-} greinfo_t;
+
+/*
+ * Structures to define a GRE header as seen in a packet.
+ */
+struct grebits {
+ u_32_t grb_C:1;
+ u_32_t grb_R:1;
+ u_32_t grb_K:1;
+ u_32_t grb_S:1;
+ u_32_t grb_s:1;
+ u_32_t grb_recur:1;
+ u_32_t grb_A:1;
+ u_32_t grb_flags:3;
+ u_32_t grb_ver:3;
+ u_short grb_ptype;
+};
typedef struct grehdr {
union {
- struct grebits {
- u_32_t grub_C:1;
- u_32_t grub_R:1;
- u_32_t grub_K:1;
- u_32_t grub_S:1;
- u_32_t grub_s:1;
- u_32_t grub_recur:1;
- u_32_t grub_A:1;
- u_32_t grub_flags:3;
- u_32_t grub_ver:3;
- u_short grub_ptype;
- } gru_bits;
+ struct grebits gru_bits;
u_short gru_flags;
} gr_un;
u_short gr_len;
u_short gr_call;
} grehdr_t;
+#define gr_flags gr_un.gru_flags
#define gr_bits gr_un.gru_bits
-#define gr_ptype gr_un.gru_bits.grub_ptype
-#define gr_C gr_bits.grub_C
-#define gr_R gr_bits.grub_R
-#define gr_K gr_bits.grub_K
-#define gr_S gr_bits.grub_S
-#define gr_s gr_bits.grub_s
-#define gr_recur gr_bits.grub_recur
-#define gr_A gr_bits.grub_A
-#define gr_flags gr_bits.grub_flags
-#define gr_ver gr_bits.grub_ver
+#define gr_ptype gr_bits.grb_ptype
+#define gr_C gr_bits.grb_C
+#define gr_R gr_bits.grb_R
+#define gr_K gr_bits.grb_K
+#define gr_S gr_bits.grb_S
+#define gr_s gr_bits.grb_s
+#define gr_recur gr_bits.grb_recur
+#define gr_A gr_bits.grb_A
+#define gr_ver gr_bits.grb_ver
+
+/*
+ * GRE information tracked by "keep state"
+ */
+typedef struct greinfo {
+ u_short gs_call[2];
+ u_short gs_flags;
+ u_short gs_ptype;
+} greinfo_t;
+
+#define GRE_REV(x) ((ntohs(x) >> 13) & 7)
+
+
+/*
+ * Format of an Authentication header
+ */
+typedef struct authhdr {
+ u_char ah_next;
+ u_char ah_plen;
+ u_short ah_reserved;
+ u_32_t ah_spi;
+ u_32_t ah_seq;
+ /* Following the sequence number field is 0 or more bytes of */
+ /* authentication data, as specified by ah_plen - RFC 2402. */
+} authhdr_t;
/*
@@ -1001,6 +1050,8 @@ typedef struct ipftq {
} ipftq_t;
#define IFQF_USER 0x01 /* User defined aging */
+#define IFQF_DELETE 0x02 /* Marked for deletion */
+#define IFQF_PROXY 0x04 /* Timeout queue in use by a proxy */
#define IPF_HZ_MULT 1
#define IPF_HZ_DIVIDE 2 /* How many times a second ipfilter */
@@ -1060,6 +1111,7 @@ typedef struct ipftuneable {
u_long ipft_max;
int ipft_sz;
int ipft_flags;
+ struct ipftuneable *ipft_next;
} ipftuneable_t;
#define ipft_addr ipft_una.ipftp_void
@@ -1131,63 +1183,54 @@ extern struct ifnet *get_unit __P((char *, int));
extern char *get_ifname __P((struct ifnet *));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-extern int frrequest __P((int, u_long, caddr_t, int, int));
-extern int iplioctl __P((int, u_long, caddr_t, int));
-extern int fr_ipftune __P((u_long, char *));
+extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int));
# else
-extern int frrequest __P((int, int, caddr_t, int, int));
-extern int iplioctl __P((int, int, caddr_t, int));
-extern int fr_ipftune __P((int, char *));
+extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int));
# endif
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
extern void m_freem __P((mb_t *));
#else /* #ifndef _KERNEL */
-extern void *fr_pullup __P((mb_t *, fr_info_t *, int));
# if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern void ipfilterattach __P((int));
# endif
extern int ipl_enable __P((void));
extern int ipl_disable __P((void));
# ifdef MENTAT
-extern int frrequest __P((int, int, caddr_t, int, int));
-extern int fr_check __P((struct ip *, int, void *, int, struct qif *,
+extern int fr_check __P((struct ip *, int, void *, int, void *,
mblk_t **));
# if SOLARIS
# if SOLARIS2 >= 7
extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
-extern int fr_ipftune __P((int, char *));
# else
extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
-extern int fr_ipftune __P((int, char *));
# endif
extern int iplopen __P((dev_t *, int, int, cred_t *));
extern int iplclose __P((dev_t, int, int, cred_t *));
-extern int iplread __P((dev_t, struct uio *, cred_t *));
+extern int iplread __P((dev_t, uio_t *, cred_t *));
+extern int iplwrite __P((dev_t, uio_t *, cred_t *));
# endif
# ifdef __hpux
extern int iplopen __P((dev_t, int, intptr_t, int));
extern int iplclose __P((dev_t, int, int));
extern int iplioctl __P((dev_t, int, caddr_t, int));
-extern int fr_ipftune __P((int, char *));
-extern int iplread __P((dev_t, struct uio *));
+extern int iplread __P((dev_t, uio_t *));
+extern int iplwrite __P((dev_t, uio_t *));
extern int iplselect __P((dev_t, int));
# endif
extern int ipfsync __P((void));
extern int fr_qout __P((queue_t *, mblk_t *));
-extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *));
# else /* MENTAT */
extern int fr_check __P((struct ip *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
extern size_t mbufchainlen __P((mb_t *));
# ifdef __sgi
# include <sys/cred.h>
-extern int frrequest __P((int, int, caddr_t, int, int));
extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *));
-extern int fr_ipftune __P((int, char *));
extern int iplopen __P((dev_t *, int, int, cred_t *));
extern int iplclose __P((dev_t, int, int, cred_t *));
-extern int iplread __P((dev_t, struct uio *, cred_t *));
+extern int iplread __P((dev_t, uio_t *, cred_t *));
+extern int iplwrite __P((dev_t, uio_t *, cred_t *));
extern int ipfsync __P((void));
extern int ipfilter_sgi_attach __P((void));
extern void ipfilter_sgi_detach __P((void));
@@ -1200,37 +1243,52 @@ extern int iplidentify __P((char *));
(NetBSD >= 199511) || defined(__OpenBSD__)
# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \
defined(__OpenBSD__) || (__FreeBSD_version >= 300000)
-extern int frrequest __P((int, u_long, caddr_t, int, int));
# if (__FreeBSD_version >= 500024)
+# if (__FreeBSD_version >= 502116)
+extern int iplioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *));
+# else
extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct thread *));
-extern int fr_ipftune __P((u_long, char *));
+# endif /* __FreeBSD_version >= 502116 */
# else
extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-extern int fr_ipftune __P((u_long, char *));
# endif /* __FreeBSD_version >= 500024 */
# else
-extern int frrequest __P((int, int, caddr_t, int, int));
extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
-extern int fr_ipftune __P((int, char *));
# endif
# if (__FreeBSD_version >= 500024)
+# if (__FreeBSD_version >= 502116)
+extern int iplopen __P((struct cdev*, int, int, struct thread *));
+extern int iplclose __P((struct cdev*, int, int, struct thread *));
+# else
extern int iplopen __P((dev_t, int, int, struct thread *));
extern int iplclose __P((dev_t, int, int, struct thread *));
+# endif /* __FreeBSD_version >= 502116 */
# else
extern int iplopen __P((dev_t, int, int, struct proc *));
extern int iplclose __P((dev_t, int, int, struct proc *));
# endif /* __FreeBSD_version >= 500024 */
# else
+# ifdef linux
+extern int iplioctl __P((struct inode *, struct file *, u_int, u_long));
+# else
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
-extern int frrequest __P((int, int, caddr_t, int, int));
extern int iplioctl __P((dev_t, int, caddr_t, int));
-extern int fr_ipftune __P((int, char *));
+# endif
# endif /* (_BSDI_VERSION >= 199510) */
# if BSD >= 199306
+# if (__FreeBSD_version >= 502116)
+extern int iplread __P((struct cdev*, struct uio *, int));
+extern int iplwrite __P((struct cdev*, struct uio *, int));
+# else
extern int iplread __P((dev_t, struct uio *, int));
+extern int iplwrite __P((dev_t, struct uio *, int));
+# endif /* __FreeBSD_version >= 502116 */
# else
+# ifndef linux
extern int iplread __P((dev_t, struct uio *));
+extern int iplwrite __P((dev_t, struct uio *));
+# endif
# endif /* BSD >= 199306 */
# endif /* __ sgi */
# endif /* MENTAT */
@@ -1238,39 +1296,45 @@ extern int iplread __P((dev_t, struct uio *));
#endif /* #ifndef _KERNEL */
extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
-extern ipfmutex_t ipf_timeoutlock;
-extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw;
+extern ipfmutex_t ipf_timeoutlock, ipf_stinsert, ipf_natio, ipf_nat_new;
+extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag;
extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
+extern ipfrwlock_t ipf_frcache;
extern char *memstr __P((char *, char *, int, int));
extern int count4bits __P((u_32_t));
-#ifdef USE_INET6
extern int count6bits __P((u_32_t *));
-#endif
+extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int));
extern char *getifname __P((struct ifnet *));
extern int iplattach __P((void));
extern int ipldetach __P((void));
-# if defined(__NetBSD__) || defined(__OpenBSD__)
-extern INLINE int fr_ioctlswitch __P((int, void *, u_long, int));
-#else
-extern INLINE int fr_ioctlswitch __P((int, void *, int, int));
-#endif
extern u_short ipf_cksum __P((u_short *, int));
extern int copyinptr __P((void *, void *, size_t));
extern int copyoutptr __P((void *, void *, size_t));
+extern int fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *));
extern int fr_inobj __P((void *, void *, int));
+extern int fr_inobjsz __P((void *, void *, int, int));
+extern int fr_ioctlswitch __P((int, void *, ioctlcmd_t, int));
+extern int fr_ipftune __P((ioctlcmd_t, void *));
extern int fr_outobj __P((void *, void *, int));
-extern int fr_send_reset __P((fr_info_t *));
-extern int fr_send_icmp_err __P((int, fr_info_t *, int));
-extern void fr_resolvdest __P((struct frdest *, int));
+extern int fr_outobjsz __P((void *, void *, int, int));
+extern void *fr_pullup __P((mb_t *, fr_info_t *, int));
+extern void fr_resolvedest __P((struct frdest *, int));
extern int fr_resolvefunc __P((void *));
-extern int fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *));
+extern void *fr_resolvenic __P((char *, int));
+extern int fr_send_icmp_err __P((int, fr_info_t *, int));
+extern int fr_send_reset __P((fr_info_t *));
+#if (__FreeBSD_version < 490000) || !defined(_KERNEL)
extern int ppsratecheck __P((struct timeval *, int *, int));
+#endif
extern ipftq_t *fr_addtimeoutqueue __P((ipftq_t **, u_int));
-extern void fr_deletetimeoutqueue __P((ipftq_t *));
+extern void fr_deletequeueentry __P((ipftqent_t *));
+extern int fr_deletetimeoutqueue __P((ipftq_t *));
+extern void fr_freetimeoutqueue __P((ipftq_t *));
extern void fr_movequeue __P((ipftqent_t *, ipftq_t *, ipftq_t *));
-extern void fr_queuefront __P((ipftqent_t *));
+extern void fr_queueappend __P((ipftqent_t *, ipftq_t *, void *));
extern void fr_queueback __P((ipftqent_t *));
+extern void fr_queuefront __P((ipftqent_t *));
extern void fr_checkv4sum __P((fr_info_t *));
extern int fr_checkl4sum __P((fr_info_t *));
extern int fr_ifpfillv4addr __P((int, struct sockaddr_in *,
@@ -1284,8 +1348,11 @@ extern int fr_ifpfillv6addr __P((int, struct sockaddr_in6 *,
struct in_addr *));
#endif
+extern int fr_addipftune __P((ipftuneable_t *));
+extern int fr_delipftune __P((ipftuneable_t *));
+
extern int frflush __P((minor_t, int, int));
-extern void frsync __P((void));
+extern void frsync __P((void *));
extern frgroup_t *fr_addgroup __P((char *, void *, u_32_t, minor_t, int));
extern int fr_derefrule __P((frentry_t **));
extern void fr_delgroup __P((char *, minor_t, int));
@@ -1293,7 +1360,7 @@ extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***));
extern int fr_loginit __P((void));
extern int ipflog_clear __P((minor_t));
-extern int ipflog_read __P((minor_t, struct uio *));
+extern int ipflog_read __P((minor_t, uio_t *));
extern int ipflog __P((fr_info_t *, u_int));
extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern void fr_logunload __P((void));
@@ -1301,6 +1368,7 @@ extern void fr_logunload __P((void));
extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *));
extern int fr_copytolog __P((int, char *, int));
extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *));
+extern void fr_deinitialise __P((void));
extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *));
extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *));
extern void fr_fixskip __P((frentry_t **, frentry_t *, int));
@@ -1309,20 +1377,21 @@ extern frentry_t *fr_getrulen __P((int, char *, u_32_t));
extern void fr_getstat __P((struct friostat *));
extern int fr_ifpaddr __P((int, int, void *,
struct in_addr *, struct in_addr *));
-extern int fr_lock __P((caddr_t, int *));
+extern int fr_initialise __P((void));
+extern void 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 *,
struct icmp *, int));
extern u_32_t fr_newisn __P((fr_info_t *));
-extern INLINE u_short fr_nextipid __P((fr_info_t *));
+extern u_short fr_nextipid __P((fr_info_t *));
extern int fr_rulen __P((int, frentry_t *));
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_unreach;
extern int fr_running;
extern u_long fr_frouteok[2];
extern int fr_pass;
@@ -1339,6 +1408,7 @@ extern int ipl_suppress;
extern int ipl_buffer_sz;
extern int ipl_logmax;
extern int ipl_logall;
+extern int ipl_logsize;
extern u_long fr_ticks;
extern fr_info_t frcache[2][8];
extern char ipfilter_version[];
@@ -1354,11 +1424,8 @@ extern int icmpreplytype6[ICMP6_MAXTYPE + 1];
extern int icmpreplytype4[ICMP_MAXTYPE + 1];
extern struct frgroup *ipfgroups[IPL_LOGSIZE][2];
extern struct filterstats frstats[];
-extern int icmpreplytype4[ICMP_MAXTYPE + 1];
-extern struct frgroup *ipfgroups[IPL_LOGSIZE][2];
-extern struct filterstats frstats[];
extern frentry_t *ipfrule_match __P((fr_info_t *));
extern u_char ipf_iss_secret[32];
-
+extern ipftuneable_t ipf_tuneables[];
#endif /* __IP_FIL_H__ */
diff --git a/usr/src/common/ipf/ip_frag.h b/usr/src/uts/common/inet/ipf/netinet/ip_frag.h
index a7fa4eed71..7eb7399010 100644
--- a/usr/src/common/ipf/ip_frag.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_frag.h
@@ -4,9 +4,9 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_frag.h 1.5 3/24/96
- * $Id: ip_frag.h,v 2.22 2003/06/24 11:13:53 darrenr Exp $
+ * $Id: ip_frag.h,v 2.23.2.2 2005/06/10 18:02:37 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,8 +38,8 @@ typedef struct ipfr {
frentry_t *ipfr_rule;
} ipfr_t;
-#define ipfr_src ipfr_source.in4
-#define ipfr_dst ipfr_dest.in4
+#define ipfr_src ipfr_source.in4
+#define ipfr_dst ipfr_dest.in4
typedef struct ipfrstat {
u_long ifs_exists; /* add & already exists */
@@ -79,16 +79,18 @@ extern void fr_fragclear __P((void));
extern void fr_fragexpire __P((void));
#if defined(_KERNEL) && ((BSD >= 199306) || SOLARIS || defined(__sgi) \
- || defined(__osf__) || (defined(__sgi) && (IRIX >= 605)))
+ || defined(__osf__) || (defined(__sgi) && (IRIX >= 60500)))
# if defined(SOLARIS2) && (SOLARIS2 < 7)
extern void fr_slowtimer __P((void));
# else
-#ifndef _KERNEL
extern void fr_slowtimer __P((void *));
-#endif
# endif
#else
+# if defined(linux) && defined(_KERNEL)
+extern void fr_slowtimer __P((long));
+# else
extern int fr_slowtimer __P((void));
+# endif
#endif
#endif /* __IP_FRAG_H__ */
diff --git a/usr/src/common/ipf/ip_ftp_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_ftp_pxy.c
index 6428ebf6c0..7d1ed33c96 100644
--- a/usr/src/common/ipf/ip_ftp_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_ftp_pxy.c
@@ -3,21 +3,18 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * $Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp $
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
- *
- */
+*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#ifdef USE_MUTEXES
-extern ipfmutex_t ipf_rw;
-#endif
-#define IPF_FTP_DEBUG
#define IPF_FTP_PROXY
#define IPF_MINPORTLEN 18
@@ -26,7 +23,6 @@ extern ipfmutex_t ipf_rw;
#define IPF_MAX227LEN 51
#define IPF_MIN229LEN 47
#define IPF_MAX229LEN 51
-#define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */
#define FTPXY_GO 0
#define FTPXY_INIT 1
@@ -69,13 +65,36 @@ u_short ippr_ftp_atoi __P((char **));
int ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *,
u_int, char *, char *, u_int));
-static frentry_t ftppxyfr;
int ftp_proxy_init = 0;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0; /* Do not require logins before transfers */
int ippr_ftp_pasvrdr = 0;
int ippr_ftp_forcepasv = 0; /* PASV must be last command prior to 227 */
+#if defined(_KERNEL)
+int ippr_ftp_debug = 0;
+#else
+int ippr_ftp_debug = 2;
+#endif
+/*
+ * 1 - security
+ * 2 - errors
+ * 3 - error debugging
+ * 4 - parsing errors
+ * 5 - parsing info
+ * 6 - parsing debug
+ */
+
+static frentry_t ftppxyfr;
+static ipftuneable_t ftptune = {
+ { &ippr_ftp_debug },
+ "ippr_ftp_debug",
+ 0,
+ 10,
+ sizeof(ippr_ftp_debug),
+ 0,
+ NULL
+};
/*
@@ -88,6 +107,7 @@ int ippr_ftp_init()
ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
MUTEX_INIT(&ftppxyfr.fr_lock, "FTP Proxy Mutex");
ftp_proxy_init = 1;
+ (void) fr_addipftune(&ftptune);
return 0;
}
@@ -95,6 +115,8 @@ int ippr_ftp_init()
void ippr_ftp_fini()
{
+ (void) fr_delipftune(&ftptune);
+
if (ftp_proxy_init == 1) {
MUTEX_DESTROY(&ftppxyfr.fr_lock);
ftp_proxy_init = 0;
@@ -143,8 +165,8 @@ int dlen;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
char newbuf[IPF_FTPBUFSZ], *s;
struct in_addr swip, swip2;
- int inc, off = 0, flags;
u_int a1, a2, a3, a4;
+ int inc, off, flags;
u_short a5, a6, sp;
size_t nlen, olen;
fr_info_t fi;
@@ -153,15 +175,15 @@ int dlen;
m = fin->fin_m;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
+ off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
/*
* Check for client sending out PORT message.
*/
if (dlen < IPF_MINPORTLEN) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", dlen);
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n",
+ dlen);
return 0;
}
/*
@@ -173,18 +195,17 @@ int dlen;
*/
a1 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:ippr_ftp_atoi(1) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 1);
return 0;
}
a2 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:ippr_ftp_atoi(2) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2);
return 0;
}
+
/*
* Check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
@@ -195,17 +216,15 @@ int dlen;
(a1 != ntohl(nat->nat_inip.s_addr))) ||
((nat->nat_dir == NAT_INBOUND) &&
(a1 != ntohl(nat->nat_oip.s_addr)))) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:a1 != nat->nat_inip\n");
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1");
return APR_ERR(1);
}
a5 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:ippr_ftp_atoi(3) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3);
return 0;
}
if (*s == ')')
@@ -220,13 +239,23 @@ int dlen;
s += 2;
a6 = a5 & 0xff;
} else {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:missing cr-lf\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_port:missing %s\n", "cr-lf");
return 0;
}
+
a5 >>= 8;
a5 &= 0xff;
+ sp = a5 << 8 | a6;
+ /*
+ * Don't allow the PORT command to specify a port < 1024 due to
+ * security crap.
+ */
+ if (sp < 1024) {
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_port:sp(%d) < 1024\n", sp);
+ return 0;
+ }
/*
* Calculate new address parts for PORT command
*/
@@ -240,9 +269,9 @@ int dlen;
a1 >>= 24;
olen = s - f->ftps_rptr;
/* DO NOT change this to snprintf! */
-#if defined(__hpux) && defined(_KERNEL)
- (void) sprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
- "PORT", a1, a2, a3, a4, a5, a6);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
+ "PORT", a1, a2, a3, a4, a5, a6);
#else
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
@@ -251,9 +280,9 @@ int dlen;
nlen = strlen(newbuf);
inc = nlen - olen;
if ((inc + ip->ip_len) > 65535) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", inc);
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n",
+ inc);
return 0;
}
@@ -263,16 +292,16 @@ int dlen;
# if defined(MENTAT)
if (inc < 0)
(void)adjmsg(m, inc);
-# else
+# else /* defined(MENTAT) */
+ /*
+ * m_adj takes care of pkthdr.len, if required and treats inc<0 to
+ * mean remove -len bytes from the end of the packet.
+ * The mbuf chain will be extended if necessary by m_copyback().
+ */
if (inc < 0)
m_adj(m, inc);
-# ifdef M_PKTHDR
- if (!(m->m_flags & M_PKTHDR))
- m->m_pkthdr.len += inc;
-# endif
-# endif
-#endif
- /* the mbuf chain will be extended if necessary by m_copyback() */
+# endif /* defined(MENTAT) */
+#endif /* !defined(_KERNEL) */
COPYBACK(m, off, nlen, newbuf);
if (inc != 0) {
@@ -282,29 +311,20 @@ int dlen;
}
/*
- * Add skeleton NAT entry for connection which will come back the
- * other way.
- */
- sp = a5 << 8 | a6;
- /*
- * Don't allow the PORT command to specify a port < 1024 due to
- * security crap.
- */
- if (sp < 1024) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_port:sp(%d) < 1024\n", sp);
-#endif
- return 0;
- }
- /*
* The server may not make the connection back from port 20, but
* it is the most likely so use it here to check for a conflicting
* mapping.
*/
bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_flx |= FI_IGNORE;
fi.fin_data[0] = sp;
fi.fin_data[1] = fin->fin_data[1] - 1;
+ /*
+ * Add skeleton NAT entry for connection which will come back the
+ * other way.
+ */
if (nat->nat_dir == NAT_OUTBOUND)
nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
nat->nat_inip, nat->nat_oip);
@@ -353,6 +373,8 @@ int dlen;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_len = slen;
ip->ip_src = swip;
@@ -365,8 +387,8 @@ int dlen;
is = nat2->nat_state;
if (is != NULL) {
MUTEX_ENTER(&is->is_lock);
- (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
- is->is_flags);
+ (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
+ is->is_flags);
MUTEX_EXIT(&is->is_lock);
}
RWLOCK_EXIT(&ipf_state);
@@ -393,8 +415,8 @@ int dlen;
for (i = 0; (i < 5) && (i < dlen); i++) {
c = rptr[i];
- if (isalpha(c)) {
- cmd[i] = toupper(c);
+ if (ISALPHA(c)) {
+ cmd[i] = TOUPPER(c);
} else {
cmd[i] = c;
}
@@ -455,16 +477,15 @@ int dlen;
{
u_int a1, a2, a3, a4, data_ip;
char newbuf[IPF_FTPBUFSZ];
+ char *s, *brackets[2];
u_short a5, a6;
ftpside_t *f;
- char *s;
if (ippr_ftp_forcepasv != 0 &&
ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
- ftp->ftp_side[0].ftps_cmds);
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
+ ftp->ftp_side[0].ftps_cmds);
return 0;
}
@@ -475,39 +496,44 @@ int dlen;
* Check for PASV reply message.
*/
if (dlen < IPF_MIN227LEN) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", dlen);
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n",
+ dlen);
return 0;
} else if (strncmp(f->ftps_rptr,
"227 Entering Passive Mod", PASV_REPLEN)) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:227 reply wrong\n");
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_pasv:%d reply wrong\n", 227);
return 0;
}
+ brackets[0] = "";
+ brackets[1] = "";
/*
* Skip the PASV reply + space
*/
s = f->ftps_rptr + PASV_REPLEN;
- while (*s && !isdigit(*s))
+ while (*s && !ISDIGIT(*s)) {
+ if (*s == '(') {
+ brackets[0] = "(";
+ brackets[1] = ")";
+ }
s++;
+ }
+
/*
* Pick out the address components, two at a time.
*/
a1 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:ippr_ftp_atoi(1) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1);
return 0;
}
a2 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:ippr_ftp_atoi(2) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2);
return 0;
}
@@ -522,17 +548,15 @@ int dlen;
(a1 != ntohl(nat->nat_inip.s_addr))) ||
((nat->nat_dir == NAT_OUTBOUND) &&
(a1 != ntohl(nat->nat_oip.s_addr)))) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:a1 != nat->nat_oip\n");
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1");
return 0;
}
a5 = ippr_ftp_atoi(&s);
if (s == NULL) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:ippr_ftp_atoi(3) failed\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3);
return 0;
}
@@ -548,9 +572,8 @@ int dlen;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
} else {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:missing cr-lf\n");
-#endif
+ if (ippr_ftp_debug > 1)
+ printf("ippr_ftp_pasv:missing %s", "cr-lf\n");
return 0;
}
@@ -570,12 +593,14 @@ int dlen;
a4 = a1 & 0xff;
a1 >>= 24;
-#if defined(__hpux) && defined(_KERNEL)
- (void) sprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
- "227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(newbuf, sizeof(newbuf), "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
+ "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
+ a5, a6, brackets[1]);
#else
- (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
- "227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
+ (void) sprintf(newbuf, "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
+ "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
+ a5, a6, brackets[1]);
#endif
return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6),
newbuf, s, data_ip);
@@ -602,7 +627,7 @@ u_int data_ip;
m = fin->fin_m;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
+ off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
data_addr.s_addr = data_ip;
tcp2 = &tcph;
@@ -613,22 +638,26 @@ u_int data_ip;
nlen = strlen(newmsg);
inc = nlen - olen;
if ((inc + ip->ip_len) > 65535) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n", inc);
-#endif
+ if (ippr_ftp_debug > 0)
+ printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n",
+ inc);
return 0;
}
#if !defined(_KERNEL)
- bcopy(newmsg, (char *)m + off, nlen);
+ bcopy(newmsg, MTOD(m, char *) + off, nlen);
#else
# if defined(MENTAT)
if (inc < 0)
(void)adjmsg(m, inc);
# else /* defined(MENTAT) */
+ /*
+ * m_adj takes care of pkthdr.len, if required and treats inc<0 to
+ * mean remove -len bytes from the end of the packet.
+ * The mbuf chain will be extended if necessary by m_copyback().
+ */
if (inc < 0)
m_adj(m, inc);
- /* the mbuf chain will be extended if necessary by m_copyback() */
# endif /* defined(MENTAT) */
#endif /* !defined(_KERNEL) */
COPYBACK(m, off, nlen, newmsg);
@@ -644,6 +673,8 @@ u_int data_ip;
* other way.
*/
bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_flx |= FI_IGNORE;
fi.fin_data[0] = 0;
fi.fin_data[1] = port;
@@ -703,6 +734,8 @@ u_int data_ip;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, sflags);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_len = slen;
@@ -716,8 +749,8 @@ u_int data_ip;
is = nat2->nat_state;
if (is != NULL) {
MUTEX_ENTER(&is->is_lock);
- (void) fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
- is->is_flags);
+ (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
+ is->is_flags);
MUTEX_EXIT(&is->is_lock);
}
RWLOCK_EXIT(&ipf_state);
@@ -742,7 +775,9 @@ int dlen;
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
- if (!isdigit(*rptr) || !isdigit(*(rptr + 1)) || !isdigit(*(rptr + 2)))
+ if (*rptr == ' ')
+ goto server_cmd_ok;
+ if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2)))
return 0;
if (ftp->ftp_passok == FTPXY_GO) {
if (!strncmp(rptr, "227 ", 4))
@@ -777,6 +812,7 @@ int dlen;
}
}
}
+server_cmd_ok:
ftp->ftp_incok = 0;
while ((*rptr++ != '\n') && (rptr < wptr))
@@ -795,34 +831,38 @@ ftpside_t *ftps;
char *buf;
size_t len;
{
- register char *s, c;
+ register char *s, c, pc;
register size_t i = len;
char cmd[5];
+ s = buf;
+
+ if (ftps->ftps_junk == 1)
+ return 1;
+
if (i < 5) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i);
-#endif
+ if (ippr_ftp_debug > 3)
+ printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i);
return 2;
}
- s = buf;
- c = *s++;
+
i--;
+ c = *s++;
- if (isalpha(c)) {
- cmd[0] = toupper(c);
+ if (ISALPHA(c)) {
+ cmd[0] = TOUPPER(c);
c = *s++;
i--;
- if (isalpha(c)) {
- cmd[1] = toupper(c);
+ if (ISALPHA(c)) {
+ cmd[1] = TOUPPER(c);
c = *s++;
i--;
- if (isalpha(c)) {
- cmd[2] = toupper(c);
+ if (ISALPHA(c)) {
+ cmd[2] = TOUPPER(c);
c = *s++;
i--;
- if (isalpha(c)) {
- cmd[3] = toupper(c);
+ if (ISALPHA(c)) {
+ cmd[3] = TOUPPER(c);
c = *s++;
i--;
if ((c != ' ') && (c != '\r'))
@@ -835,16 +875,18 @@ size_t len;
goto bad_client_command;
} else {
bad_client_command:
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_client_valid:bad cmd:len %d i %d c 0x%x\n",
- (int)i, (int)len, c);
-#endif
+ if (ippr_ftp_debug > 3)
+ printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
+ "ippr_ftp_client_valid",
+ ftps->ftps_junk, (int)len, (int)i, c,
+ (int)len, buf);
return 1;
}
for (; i; i--) {
+ pc = c;
c = *s++;
- if (c == '\n') {
+ if ((pc == '\r') && (c == '\n')) {
cmd[4] = '\0';
if (!strcmp(cmd, "PASV"))
ftps->ftps_cmds = FTPXY_C_PASV;
@@ -854,7 +896,8 @@ bad_client_command:
}
}
#if !defined(_KERNEL)
- printf("ippr_ftp_client_valid:junk after cmd[%s]\n", buf);
+ printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n",
+ (int)len, (int)len, buf);
#endif
return 2;
}
@@ -865,26 +908,36 @@ ftpside_t *ftps;
char *buf;
size_t len;
{
- register char *s, c;
+ register char *s, c, pc;
register size_t i = len;
int cmd;
- if (i < 5)
- return 2;
s = buf;
- c = *s++;
cmd = 0;
+
+ if (ftps->ftps_junk == 1)
+ return 1;
+
+ if (i < 5) {
+ if (ippr_ftp_debug > 3)
+ printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i);
+ return 2;
+ }
+
+ c = *s++;
i--;
+ if (c == ' ')
+ goto search_eol;
- if (isdigit(c)) {
+ if (ISDIGIT(c)) {
cmd = (c - '0') * 100;
c = *s++;
i--;
- if (isdigit(c)) {
+ if (ISDIGIT(c)) {
cmd += (c - '0') * 10;
c = *s++;
i--;
- if (isdigit(c)) {
+ if (ISDIGIT(c)) {
cmd += (c - '0');
c = *s++;
i--;
@@ -896,23 +949,25 @@ size_t len;
goto bad_server_command;
} else {
bad_server_command:
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_server_valid:bad cmd:len %d i %d c 0x%x\n",
- (int)i, (int)len, c);
-#endif
+ if (ippr_ftp_debug > 3)
+ printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
+ "ippr_ftp_server_valid",
+ ftps->ftps_junk, (int)len, (int)i,
+ c, (int)len, buf);
return 1;
}
-
+search_eol:
for (; i; i--) {
+ pc = c;
c = *s++;
- if (c == '\n') {
+ if ((pc == '\r') && (c == '\n')) {
ftps->ftps_cmds = cmd;
return 0;
}
}
-#if !defined(_KERNEL)
- printf("ippr_ftp_server_valid:junk after cmd[%s]\n", buf);
-#endif
+ if (ippr_ftp_debug > 3)
+ printf("ippr_ftp_server_valid:junk after cmd[%*s]\n",
+ (int)len, buf);
return 2;
}
@@ -951,8 +1006,8 @@ ftpinfo_t *ftp;
int rv;
{
int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff;
+ char *rptr, *wptr, *s;
u_32_t thseq, thack;
- char *rptr, *wptr;
ap_session_t *aps;
ftpside_t *f, *t;
tcphdr_t *tcp;
@@ -962,14 +1017,21 @@ int rv;
m = fin->fin_m;
ip = fin->fin_ip;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
+ off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
f = &ftp->ftp_side[rv];
t = &ftp->ftp_side[1 - rv];
thseq = ntohl(tcp->th_seq);
thack = ntohl(tcp->th_ack);
+#ifdef __sgi
+ mlen = fin->fin_plen - off;
+#else
mlen = MSGDSIZE(m) - off;
+#endif
+ if (ippr_ftp_debug > 4)
+ printf("ippr_ftp_process: mlen %d\n", mlen);
+
if (mlen <= 0) {
if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
f->ftps_seq[0] = thseq + 1;
@@ -989,19 +1051,17 @@ int rv;
if (aps->aps_ackmin[sel2] > ackoff + thack)
ackoff = aps->aps_ackoff[!sel2];
} else {
-#if PROXY_DEBUG
- printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
- aps->aps_ackmin[sel]);
-#endif
seqoff = aps->aps_ackoff[sel];
+ if (ippr_ftp_debug > 2)
+ printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
+ aps->aps_ackmin[sel]);
if (aps->aps_ackmin[sel] > seqoff + thseq)
seqoff = aps->aps_ackoff[!sel];
-#if PROXY_DEBUG
- printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
- aps->aps_seqmin[sel2]);
-#endif
ackoff = aps->aps_seqoff[sel2];
+ if (ippr_ftp_debug > 2)
+ printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
+ aps->aps_seqmin[sel2]);
if (ackoff > 0) {
if (aps->aps_seqmin[sel2] > ackoff + thack)
ackoff = aps->aps_seqoff[!sel2];
@@ -1010,26 +1070,27 @@ int rv;
ackoff = aps->aps_seqoff[!sel2];
}
}
-#if PROXY_DEBUG
- printf("%s: %x seq %x/%d ack %x/%d len %d\n", rv ? "IN" : "OUT",
- tcp->th_flags, thseq, seqoff, thack, ackoff, mlen);
- printf("sel %d seqmin %x/%x offset %d/%d\n", sel,
- aps->aps_seqmin[sel], aps->aps_seqmin[sel2],
- aps->aps_seqoff[sel], aps->aps_seqoff[sel2]);
- printf("sel %d ackmin %x/%x offset %d/%d\n", sel2,
- aps->aps_ackmin[sel], aps->aps_ackmin[sel2],
- aps->aps_ackoff[sel], aps->aps_ackoff[sel2]);
-#endif
+ if (ippr_ftp_debug > 2) {
+ printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n",
+ rv ? "IN" : "OUT", tcp->th_flags, thseq, seqoff,
+ thack, ackoff, mlen, fin->fin_plen, off);
+ printf("sel %d seqmin %x/%x offset %d/%d\n", sel,
+ aps->aps_seqmin[sel], aps->aps_seqmin[sel2],
+ aps->aps_seqoff[sel], aps->aps_seqoff[sel2]);
+ printf("sel %d ackmin %x/%x offset %d/%d\n", sel2,
+ aps->aps_ackmin[sel], aps->aps_ackmin[sel2],
+ aps->aps_ackoff[sel], aps->aps_ackoff[sel2]);
+ }
/*
* XXX - Ideally, this packet should get dropped because we now know
* that it is out of order (and there is no real danger in doing so
* apart from causing packets to go through here ordered).
*/
-#if PROXY_DEBUG
- printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n",
- rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
-#endif
+ if (ippr_ftp_debug > 2) {
+ printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n",
+ rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
+ }
ok = 0;
if (t->ftps_seq[0] == 0) {
@@ -1058,33 +1119,35 @@ int rv;
}
}
-#if PROXY_DEBUG
- if (!ok)
- printf("not ok\n");
-#endif
+ if (ippr_ftp_debug > 2) {
+ if (!ok)
+ printf("%s ok\n", "not");
+ }
if (!mlen) {
if (t->ftps_seq[0] + ackoff != thack) {
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf(
- "ippr_ftp_process:seq[0](%x) + ackoff(%x) != thack(%x)\n",
- t->ftps_seq[0], ackoff, thack);
-#endif
+ if (ippr_ftp_debug > 1) {
+ printf("%s:seq[0](%x) + (%x) != (%x)\n",
+ "ippr_ftp_process", t->ftps_seq[0],
+ ackoff, thack);
+ }
return APR_ERR(1);
}
-#if PROXY_DEBUG
- printf("f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]);
-#endif
+ if (ippr_ftp_debug > 2) {
+ printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n",
+ f->ftps_seq[0], f->ftps_seq[1]);
+ }
+
if (tcp->th_flags & TH_FIN) {
if (thseq == f->ftps_seq[1]) {
f->ftps_seq[0] = f->ftps_seq[1] - seqoff;
f->ftps_seq[1] = thseq + 1 - seqoff;
} else {
-#if PROXY_DEBUG || !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
- thseq, seqoff, f->ftps_seq[0]);
-#endif
+ if (ippr_ftp_debug > 1) {
+ printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
+ thseq, seqoff, f->ftps_seq[0]);
+ }
return APR_ERR(1);
}
}
@@ -1105,15 +1168,15 @@ int rv;
if (ok == 0) {
inc = thseq - f->ftps_seq[0];
-#if PROXY_DEBUG || !defined(_KERNEL)
- printf("inc %d sel %d rv %d\n", inc, sel, rv);
- printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
- f->ftps_seq[1]);
- printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
- aps->aps_ackoff[sel]);
- printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
- aps->aps_seqoff[sel]);
-#endif
+ if (ippr_ftp_debug > 1) {
+ printf("inc %d sel %d rv %d\n", inc, sel, rv);
+ printf("th_seq %x ftps_seq %x/%x\n",
+ thseq, f->ftps_seq[0], f->ftps_seq[1]);
+ printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
+ aps->aps_ackoff[sel]);
+ printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
+ aps->aps_seqoff[sel]);
+ }
return APR_ERR(1);
}
@@ -1126,22 +1189,62 @@ int rv;
f->ftps_len = mlen;
while (mlen > 0) {
- len = MIN(mlen, FTP_BUFSZ / 2);
+ len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr));
COPYDATA(m, off, len, wptr);
mlen -= len;
off += len;
wptr += len;
+
+ if (ippr_ftp_debug > 3)
+ printf("%s:len %d/%d off %d wptr %lx junk %d [%*s]\n",
+ "ippr_ftp_process",
+ len, mlen, off, (u_long)wptr, f->ftps_junk,
+ len, rptr);
+
f->ftps_wptr = wptr;
- if (f->ftps_junk == 2)
+ if (f->ftps_junk != 0) {
+ i = f->ftps_junk;
f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
wptr - rptr);
+ if (ippr_ftp_debug > 5)
+ printf("%s:junk %d -> %d\n",
+ "ippr_ftp_process", i, f->ftps_junk);
+
+ if (f->ftps_junk != 0) {
+ if (wptr - rptr == sizeof(f->ftps_buf)) {
+ if (ippr_ftp_debug > 4)
+ printf("%s:full buffer\n",
+ "ippr_ftp_process");
+ f->ftps_rptr = f->ftps_buf;
+ f->ftps_wptr = f->ftps_buf;
+ rptr = f->ftps_rptr;
+ wptr = f->ftps_wptr;
+ /*
+ * Because we throw away data here that
+ * we would otherwise parse, set the
+ * junk flag to indicate just ignore
+ * any data upto the next CRLF.
+ */
+ f->ftps_junk = 1;
+ continue;
+ }
+ }
+ }
+
while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
- wptr - rptr);
+ len = wptr - rptr;
+ f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len);
+
+ if (ippr_ftp_debug > 3) {
+ printf("%s=%d len %d rv %d ptr %lx/%lx ",
+ "ippr_ftp_valid",
+ f->ftps_junk, len, rv, (u_long)rptr,
+ (u_long)wptr);
+ printf("buf [%*s]\n", len, rptr);
+ }
+
if (f->ftps_junk == 0) {
- f->ftps_cmds++;
- len = wptr - rptr;
f->ftps_rptr = rptr;
if (rv)
inc += ippr_ftp_server(fin, ip, nat,
@@ -1160,57 +1263,56 @@ int rv;
*/
if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) {
/* f->ftps_seq[1] += inc; */
-#if !defined(_KERNEL) || defined(IPF_FTP_DEBUG)
- printf("ippr_ftp_process:cmds == 0 junk == 1\n");
-#endif
+
+ if (ippr_ftp_debug > 1)
+ printf("%s:cmds == 0 junk == 1\n",
+ "ippr_ftp_process");
return APR_ERR(2);
}
- while ((f->ftps_junk == 1) && (rptr < wptr)) {
- while ((rptr < wptr) && (*rptr != '\r'))
- rptr++;
-
- if (*rptr == '\r') {
- if (rptr + 1 < wptr) {
- if (*(rptr + 1) == '\n') {
- rptr += 2;
- f->ftps_junk = 0;
- } else
- rptr++;
- } else
+ if ((f->ftps_junk != 0) && (rptr < wptr)) {
+ for (s = rptr; s < wptr; s++) {
+ if ((*s == '\r') && (s + 1 < wptr) &&
+ (*(s + 1) == '\n')) {
+ rptr = s + 2;
+ f->ftps_junk = 0;
break;
+ }
}
}
- f->ftps_rptr = rptr;
if (rptr == wptr) {
rptr = wptr = f->ftps_buf;
} else {
- if ((wptr > f->ftps_buf + FTP_BUFSZ / 2)) {
- i = wptr - rptr;
- if ((rptr == f->ftps_buf) ||
- (wptr - rptr > FTP_BUFSZ / 2)) {
- f->ftps_junk = 1;
- rptr = wptr = f->ftps_buf;
- } else {
- bcopy(rptr, f->ftps_buf, i);
- wptr = f->ftps_buf + i;
- rptr = f->ftps_buf;
- }
+ /*
+ * Compact the buffer back to the start. The junk
+ * flag should already be set and because we're not
+ * throwing away any data, it is preserved from its
+ * current state.
+ */
+ if (rptr > f->ftps_buf) {
+ bcopy(rptr, f->ftps_buf, len);
+ wptr -= rptr - f->ftps_buf;
+ rptr = f->ftps_buf;
}
- f->ftps_rptr = rptr;
- f->ftps_wptr = wptr;
}
+ f->ftps_rptr = rptr;
+ f->ftps_wptr = wptr;
}
/* f->ftps_seq[1] += inc; */
if (tcp->th_flags & TH_FIN)
f->ftps_seq[1]++;
-#if PROXY_DEBUG
- mlen = MSGDSIZE(m);
- mlen -= off;
- printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen);
+ if (ippr_ftp_debug > 3) {
+#ifdef __sgi
+ mlen = fin->fin_plen;
+#else
+ mlen = MSGDSIZE(m);
#endif
+ mlen -= off;
+ printf("ftps_seq[1] = %x inc %d len %d\n",
+ f->ftps_seq[1], inc, mlen);
+ }
f->ftps_rptr = rptr;
f->ftps_wptr = wptr;
@@ -1270,7 +1372,7 @@ char **ptr;
register char *s = *ptr, c;
register u_char i = 0, j = 0;
- while (((c = *s++) != '\0') && isdigit(c)) {
+ while (((c = *s++) != '\0') && ISDIGIT(c)) {
i *= 10;
i += c - '0';
}
@@ -1278,7 +1380,7 @@ char **ptr;
*ptr = NULL;
return 0;
}
- while (((c = *s++) != '\0') && isdigit(c)) {
+ while (((c = *s++) != '\0') && ISDIGIT(c)) {
j *= 10;
j += c - '0';
}
@@ -1314,14 +1416,14 @@ int dlen;
* Skip the EPSV command + space
*/
s = f->ftps_rptr + 33;
- while (*s && !isdigit(*s))
+ while (*s && !ISDIGIT(*s))
s++;
/*
* As per RFC 2428, there are no addres components in the EPSV
* response. So we'll go straight to getting the port.
*/
- while (*s && isdigit(*s)) {
+ while (*s && ISDIGIT(*s)) {
ap *= 10;
ap += *s++ - '0';
}
@@ -1343,9 +1445,9 @@ int dlen;
} else
return 0;
-#if defined(__hpux) && defined(_KERNEL)
- (void) sprintf(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n",
- "229 Entering Extended Passive Mode", ap);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n",
+ "229 Entering Extended Passive Mode", ap);
#else
(void) sprintf(newbuf, "%s (|||%u|)\r\n",
"229 Entering Extended Passive Mode", ap);
@@ -1354,36 +1456,3 @@ int dlen;
return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s,
ip->ip_src.s_addr);
}
-
-
-#if 0
-ippr_ftp_parse(str, len)
-{
- char *s, c;
-
- if (len < 5)
- return -1;
- s = str;
- if (*s++ != '|')
- return -1;
- c = *s++;
- if (c != '|') {
- if (*s++ != '|')
- return -1;
- } else
- c = '1';
-
- if (c == '1') {
- /*
- * IPv4 dotted quad.
- */
- return 0;
- } else if (c == '2') {
- /*
- * IPv6 hex string
- */
- return 0;
- }
- return -1;
-}
-#endif
diff --git a/usr/src/common/ipf/ip_h323_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_h323_pxy.c
index 2a2e1738f4..7fc62276c5 100644
--- a/usr/src/common/ipf/ip_h323_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_h323_pxy.c
@@ -1,6 +1,6 @@
/*
* Copyright 2001, QNX Software Systems Ltd. All Rights Reserved
- *
+ *
* This source code has been published by QNX Software Systems Ltd. (QSSL).
* However, any use, reproduction, modification, distribution or transfer of
* this software, or any software which includes or is based upon any of this
@@ -14,7 +14,7 @@
/*
* Simple H.323 proxy
- *
+ *
* by xtang@canada.com
* ported to ipfilter 3.4.20 by Michael Grant mg-ipf@grant.org
*/
@@ -23,7 +23,9 @@
# include <sys/fcntl.h>
# include <sys/filio.h>
#else
-# include <sys/ioctl.h>
+# ifndef linux
+# include <sys/ioctl.h>
+# endif
#endif
#define IPF_H323_PROXY
@@ -40,9 +42,6 @@ int ippr_h245_out __P((fr_info_t *, ap_session_t *, nat_t *));
int ippr_h245_in __P((fr_info_t *, ap_session_t *, nat_t *));
static frentry_t h323_fr;
-#ifdef USE_MUTEXES
-extern ipfrwlock_t ipf_nat;
-#endif
int h323_proxy_init = 0;
@@ -126,10 +125,10 @@ ap_session_t *aps;
if (aps->aps_data) {
for (i = 0, ipn = aps->aps_data;
- i < (aps->aps_psiz / sizeof(ipnat_t));
+ i < (aps->aps_psiz / sizeof(ipnat_t));
i++, ipn = (ipnat_t *)((char *)ipn + sizeof(*ipn)))
{
- /*
+ /*
* Check the comment in ippr_h323_in() function,
* just above fr_nat_ioctl() call.
* We are lucky here because this function is not
@@ -186,13 +185,13 @@ nat_t *nat;
ipn->in_inip = nat->nat_inip.s_addr;
ipn->in_inmsk = 0xffffffff;
ipn->in_dport = htons(port);
- /*
+ /*
* we got a problem here. we need to call fr_nat_ioctl() to add
* the h245 proxy rule, but since we already hold (READ locked)
* the nat table rwlock (ipf_nat), if we go into fr_nat_ioctl(),
* it will try to WRITE lock it. This will causing dead lock
* on RTP.
- *
+ *
* The quick & dirty solution here is release the read lock,
* call fr_nat_ioctl() and re-lock it.
* A (maybe better) solution is do a UPGRADE(), and instead
@@ -247,7 +246,7 @@ nat_t *nat;
tcp = (tcphdr_t *)fin->fin_dp;
ipaddr = nat->nat_inip.s_addr;
data = (caddr_t)tcp + (TCP_OFF(tcp) << 2);
- datlen = ip->ip_len - fin->fin_hlen - (TCP_OFF(tcp) << 2);
+ datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
if (find_port(ipaddr, data, datlen, &off, &port) == 0) {
fr_info_t fi;
nat_t *nat2;
diff --git a/usr/src/common/ipf/ip_htable.h b/usr/src/uts/common/inet/ipf/netinet/ip_htable.h
index 269688ce68..082959a9c5 100644
--- a/usr/src/common/ipf/ip_htable.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_htable.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -12,11 +12,7 @@
#ifndef __IP_HTABLE_H__
#define __IP_HTABLE_H__
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#else
#include "netinet/ip_lookup.h"
-#endif
typedef struct iphtent_s {
struct iphtent_s *ipe_next, **ipe_pnext;
diff --git a/usr/src/common/ipf/ip_ipsec_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_ipsec_pxy.c
index dd9298d7f4..aa7e1afd4d 100644
--- a/usr/src/common/ipf/ip_ipsec_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_ipsec_pxy.c
@@ -3,13 +3,13 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_ipsec_pxy.c,v 2.16 2003/06/25 12:08:21 darrenr Exp $
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
* Simple ISAKMP transparent proxy for in-kernel use. For use with the NAT
* code.
+ *
+ * $Id: ip_ipsec_pxy.c,v 2.20.2.7 2005/07/15 21:56:50 darrenr Exp $
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -21,7 +21,7 @@ int ippr_ipsec_init __P((void));
void ippr_ipsec_fini __P((void));
int ippr_ipsec_new __P((fr_info_t *, ap_session_t *, nat_t *));
void ippr_ipsec_del __P((ap_session_t *));
-int ippr_ipsec_out __P((fr_info_t *, ap_session_t *, nat_t *));
+int ippr_ipsec_inout __P((fr_info_t *, ap_session_t *, nat_t *));
int ippr_ipsec_match __P((fr_info_t *, ap_session_t *, nat_t *));
static frentry_t ipsecfr;
@@ -30,6 +30,7 @@ static ipftq_t *ipsecstatetqe;
static char ipsec_buffer[1500];
int ipsec_proxy_init = 0;
+int ipsec_proxy_ttl = 60;
/*
* IPSec application proxy initialization.
@@ -42,28 +43,37 @@ int ippr_ipsec_init()
MUTEX_INIT(&ipsecfr.fr_lock, "IPsec proxy rule lock");
ipsec_proxy_init = 1;
- ipsecnattqe = fr_addtimeoutqueue(&nat_utqe, 60);
+ ipsecnattqe = fr_addtimeoutqueue(&nat_utqe, ipsec_proxy_ttl);
if (ipsecnattqe == NULL)
return -1;
- ipsecstatetqe = fr_addtimeoutqueue(&ips_utqe, 60);
+ ipsecstatetqe = fr_addtimeoutqueue(&ips_utqe, ipsec_proxy_ttl);
if (ipsecstatetqe == NULL) {
- fr_deletetimeoutqueue(ipsecnattqe);
+ if (fr_deletetimeoutqueue(ipsecnattqe) == 0)
+ fr_freetimeoutqueue(ipsecnattqe);
ipsecnattqe = NULL;
return -1;
}
- ipsecfr.fr_age[0] = 60;
- ipsecfr.fr_age[1] = 60;
+
+ ipsecnattqe->ifq_flags |= IFQF_PROXY;
+ ipsecstatetqe->ifq_flags |= IFQF_PROXY;
+
+ ipsecfr.fr_age[0] = ipsec_proxy_ttl;
+ ipsecfr.fr_age[1] = ipsec_proxy_ttl;
return 0;
}
void ippr_ipsec_fini()
{
- if (ipsecnattqe != NULL)
- fr_deletetimeoutqueue(ipsecnattqe);
+ if (ipsecnattqe != NULL) {
+ if (fr_deletetimeoutqueue(ipsecnattqe) == 0)
+ fr_freetimeoutqueue(ipsecnattqe);
+ }
ipsecnattqe = NULL;
- if (ipsecstatetqe != NULL)
- fr_deletetimeoutqueue(ipsecstatetqe);
+ if (ipsecstatetqe != NULL) {
+ if (fr_deletetimeoutqueue(ipsecstatetqe) == 0)
+ fr_freetimeoutqueue(ipsecstatetqe);
+ }
ipsecstatetqe = NULL;
if (ipsec_proxy_init == 1) {
@@ -85,12 +95,12 @@ nat_t *nat;
fr_info_t fi;
ipnat_t *ipn;
char *ptr;
- int p, off, dlen;
+ int p, off, dlen, ttl;
mb_t *m;
ip_t *ip;
+ off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff;
bzero(ipsec_buffer, sizeof(ipsec_buffer));
- off = fin->fin_hlen + sizeof(udphdr_t);
ip = fin->fin_ip;
m = fin->fin_m;
@@ -117,13 +127,14 @@ nat_t *nat;
* describe ESP but UDP instead.
*/
ipn = &ipsec->ipsc_rule;
- ipn->in_tqehead[0] = ipsecnattqe;
- ipn->in_tqehead[1] = ipsecnattqe;
+ ttl = IPF_TTLVAL(ipsecnattqe->ifq_ttl);
+ ipn->in_tqehead[0] = fr_addtimeoutqueue(&nat_utqe, ttl);
+ ipn->in_tqehead[1] = fr_addtimeoutqueue(&nat_utqe, ttl);
ipn->in_ifps[0] = fin->fin_ifp;
ipn->in_apr = NULL;
ipn->in_use = 1;
ipn->in_hits = 1;
- ipn->in_nip = nat->nat_outip.s_addr;
+ ipn->in_nip = ntohl(nat->nat_outip.s_addr);
ipn->in_ippip = 1;
ipn->in_inip = nat->nat_inip.s_addr;
ipn->in_inmsk = 0xffffffff;
@@ -137,13 +148,15 @@ nat_t *nat;
ipn->in_p = IPPROTO_ESP;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_fi.fi_p = IPPROTO_ESP;
fi.fin_fr = &ipsecfr;
fi.fin_data[0] = 0;
fi.fin_data[1] = 0;
p = ip->ip_p;
ip->ip_p = IPPROTO_ESP;
- fi.fin_flx &= ~FI_TCPUDP;
+ fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG);
fi.fin_flx |= FI_IGNORE;
ptr = ipsec_buffer;
@@ -168,6 +181,8 @@ nat_t *nat;
fi.fin_data[1] = 0;
ipsec->ipsc_state = fr_addstate(&fi, &ipsec->ipsc_state,
SI_WILDP);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_p = p & 0xff;
return 0;
@@ -178,7 +193,7 @@ nat_t *nat;
* For outgoing IKE packets. refresh timeouts for NAT & state entries, if
* we can. If they have disappeared, recreate them.
*/
-int ippr_ipsec_out(fin, aps, nat)
+int ippr_ipsec_inout(fin, aps, nat)
fr_info_t *fin;
ap_session_t *aps;
nat_t *nat;
@@ -188,19 +203,31 @@ nat_t *nat;
ip_t *ip;
int p;
- ip = fin->fin_ip;
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
- fi.fin_fi.fi_p = IPPROTO_ESP;
- fi.fin_fr = &ipsecfr;
- fi.fin_data[0] = 0;
- fi.fin_data[1] = 0;
- p = ip->ip_p;
- ip->ip_p = IPPROTO_ESP;
- fi.fin_flx &= ~FI_TCPUDP;
- fi.fin_flx |= FI_IGNORE;
+ if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND))
+ return 0;
+
+ if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND))
+ return 0;
ipsec = aps->aps_data;
+
if (ipsec != NULL) {
+ ip = fin->fin_ip;
+ p = ip->ip_p;
+
+ if ((ipsec->ipsc_nat == NULL) || (ipsec->ipsc_state == NULL)) {
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
+ fi.fin_fi.fi_p = IPPROTO_ESP;
+ fi.fin_fr = &ipsecfr;
+ fi.fin_data[0] = 0;
+ fi.fin_data[1] = 0;
+ ip->ip_p = IPPROTO_ESP;
+ fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG);
+ fi.fin_flx |= FI_IGNORE;
+ }
+
/*
* Update NAT timeout/create NAT if missing.
*/
@@ -210,7 +237,7 @@ nat_t *nat;
ipsec->ipsc_nat = nat_new(&fi, &ipsec->ipsc_rule,
&ipsec->ipsc_nat,
NAT_SLAVE|SI_WILDP,
- NAT_OUTBOUND);
+ nat->nat_dir);
if (ipsec->ipsc_nat != NULL) {
(void) nat_proto(&fi, ipsec->ipsc_nat, 0);
nat_update(&fi, ipsec->ipsc_nat,
@@ -233,9 +260,11 @@ nat_t *nat;
ipsec->ipsc_state = fr_addstate(&fi,
&ipsec->ipsc_state,
SI_WILDP);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
+ ip->ip_p = p;
}
- ip->ip_p = p & 0xff;
return 0;
}
@@ -261,8 +290,8 @@ nat_t *nat;
if ((fin->fin_dlen < sizeof(cookies)) || (fin->fin_flx & FI_FRAG))
return -1;
+ off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff;
ipsec = aps->aps_data;
- off = fin->fin_hlen + sizeof(udphdr_t);
m = fin->fin_m;
COPYDATA(m, off, sizeof(cookies), (char *)cookies);
@@ -299,18 +328,14 @@ ap_session_t *aps;
if (ipsec != NULL) {
/*
- * Don't delete it from here, just schedule it to be
- * deleted ASAP.
+ * Don't bother changing any of the NAT structure details,
+ * *_del() is on a callback from aps_free(), from nat_delete()
*/
- if (ipsec->ipsc_nat != NULL) {
- ipsec->ipsc_nat->nat_age = fr_ticks + 1;
- ipsec->ipsc_nat->nat_ptr = NULL;
- fr_queuefront(&ipsec->ipsc_nat->nat_tqe);
- }
READ_ENTER(&ipf_state);
if (ipsec->ipsc_state != NULL) {
ipsec->ipsc_state->is_die = fr_ticks + 1;
+ ipsec->ipsc_state->is_me = NULL;
fr_queuefront(&ipsec->ipsc_state->is_sti);
}
RWLOCK_EXIT(&ipf_state);
diff --git a/usr/src/common/ipf/ip_irc_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_irc_pxy.c
index 95d3d64fc2..4b7a139048 100644
--- a/usr/src/common/ipf/ip_irc_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_irc_pxy.c
@@ -3,21 +3,14 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_irc_pxy.c,v 2.30 2003/06/28 17:01:57 darrenr Exp $
+ * $Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp $
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- *
- * Simple FTP transparent proxy for in-kernel use. For use with the NAT
- * code.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#ifdef USE_MUTEXES
-extern ipfmutex_t ipf_rw;
-#endif
-
#define IPF_IRC_PROXY
#define IPF_IRCBUFSZ 96 /* This *MUST* be >= 64! */
@@ -105,10 +98,10 @@ size_t len;
s++;
c = *s;
ircp->irc_snick = s;
- if (!isalpha(c))
+ if (!ISALPHA(c))
return 0;
i--;
- for (c = *s; !isspace(c) && (i > 0); i--)
+ for (c = *s; !ISSPACE(c) && (i > 0); i--)
c = *s++;
if (i < 31)
return 0;
@@ -130,9 +123,9 @@ size_t len;
/*
* Loosely check that the destination is a nickname of some sort
*/
- if (!isalpha(c))
+ if (!ISALPHA(c))
return 0;
- for (; !isspace(c) && (i > 0); i--)
+ for (; !ISSPACE(c) && (i > 0); i--)
c = *s++;
if (i < 20)
return 0;
@@ -176,7 +169,7 @@ size_t len;
* Check for the arg
*/
c = *s;
- if (isspace(c))
+ if (ISSPACE(c))
return 0;
ircp->irc_arg = s;
for (; (c != ' ') && (c != '\001') && (i > 0); i--)
@@ -191,13 +184,13 @@ size_t len;
s++;
i--;
c = *s;
- if (!isdigit(c))
+ if (!ISDIGIT(c))
return 0;
ircp->irc_addr = s;
/*
* Get the IP#
*/
- for (l = 0; isdigit(c) && (i > 0); i--) {
+ for (l = 0; ISDIGIT(c) && (i > 0); i--) {
l *= 10;
l += c - '0';
c = *s++;
@@ -213,12 +206,12 @@ size_t len;
s++;
i--;
c = *s;
- if (!isdigit(c))
+ if (!ISDIGIT(c))
return 0;
/*
* Get the port#
*/
- for (l = 0; isdigit(c) && (i > 0); i--) {
+ for (l = 0; ISDIGIT(c) && (i > 0); i--) {
l *= 10;
l += c - '0';
c = *s++;
@@ -276,13 +269,17 @@ nat_t *nat;
mb_t *m1;
#endif
+ m = fin->fin_m;
ip = fin->fin_ip;
tcp = (tcphdr_t *)fin->fin_dp;
bzero(ctcpbuf, sizeof(ctcpbuf));
- m = fin->fin_m;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
+ off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
+#ifdef __sgi
+ dlen = fin->fin_plen - off;
+#else
dlen = MSGDSIZE(m) - off;
+#endif
if (dlen <= 0)
return 0;
COPYDATA(m, off, MIN(sizeof(ctcpbuf), dlen), ctcpbuf);
@@ -314,8 +311,8 @@ nat_t *nat;
i++;
(void) strncpy(newbuf, ctcpbuf, i);
/* DO NOT change these! */
-#if defined(__hpux) && defined(KERNEL)
- (void) sprintf(newbuf, sizeof(newbuf) - i, "%u %u\001\r\n", a1, a5);
+#if defined(SNPRINTF) && defined(KERNEL)
+ (void) SNPRINTF(newbuf, sizeof(newbuf) - i, "%u %u\001\r\n", a1, a5);
#else
(void) sprintf(newbuf, "%u %u\001\r\n", a1, a5);
#endif
@@ -405,6 +402,8 @@ nat_t *nat;
tcp2->th_win = htons(8192);
tcp2->th_sport = sp;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
@@ -420,6 +419,8 @@ nat_t *nat;
nat_update(&fi, nat2, nat2->nat_ptr);
(void) fr_addstate(&fi, NULL, SI_W_DPORT);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_src = swip;
}
diff --git a/usr/src/common/ipf/ip_lookup.h b/usr/src/uts/common/inet/ipf/netinet/ip_lookup.h
index 355658d234..76cdd8fd0a 100644
--- a/usr/src/common/ipf/ip_lookup.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_lookup.h
@@ -1,21 +1,31 @@
+/*
+ * Copyright (C) 1993-2005 by Darren Reed.
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
#ifndef __IP_LOOKUP_H__
#define __IP_LOOKUP_H__
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop)
# define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop)
-# define SIOCLOOKUPSTAT _IOR('r', 64, struct iplookupop)
+# define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop)
+# define SIOCLOOKUPSTATW _IOW('r', 64, struct iplookupop)
# define SIOCLOOKUPFLUSH _IOWR('r', 65, struct iplookupflush)
-# define SIOCLOOKUPADDNODE _IOW('r', 67, struct iplookupop)
-# define SIOCLOOKUPDELNODE _IOW('r', 68, struct iplookupop)
+# define SIOCLOOKUPADDNODE _IOWR('r', 67, struct iplookupop)
+# define SIOCLOOKUPADDNODEW _IOW('r', 67, struct iplookupop)
+# define SIOCLOOKUPDELNODE _IOWR('r', 68, struct iplookupop)
+# define SIOCLOOKUPDELNODEW _IOW('r', 68, struct iplookupop)
#else
# define SIOCLOOKUPADDTABLE _IOWR(r, 60, struct iplookupop)
# define SIOCLOOKUPDELTABLE _IOWR(r, 61, struct iplookupop)
-# define SIOCLOOKUPSTAT _IOR(r, 64, struct iplookupop)
+# define SIOCLOOKUPSTAT _IOWR(r, 64, struct iplookupop)
+# define SIOCLOOKUPSTATW _IOW(r, 64, struct iplookupop)
# define SIOCLOOKUPFLUSH _IOWR(r, 65, struct iplookupflush)
-# define SIOCLOOKUPADDNODE _IOW(r, 67, struct iplookupop)
-# define SIOCLOOKUPDELNODE _IOW(r, 68, struct iplookupop)
+# define SIOCLOOKUPADDNODE _IOWR(r, 67, struct iplookupop)
+# define SIOCLOOKUPADDNODEW _IOW(r, 67, struct iplookupop)
+# define SIOCLOOKUPDELNODE _IOWR(r, 68, struct iplookupop)
+# define SIOCLOOKUPDELNODEW _IOW(r, 68, struct iplookupop)
#endif
typedef struct iplookupop {
@@ -50,12 +60,8 @@ typedef struct iplookuplink {
#define IPLT_ANON 0x80000000
extern int ip_lookup_init __P((void));
+extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int));
extern void ip_lookup_unload __P((void));
extern void ip_lookup_deref __P((int, void *));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-extern int ip_lookup_ioctl __P((caddr_t, u_long, int));
-#else
-extern int ip_lookup_ioctl __P((caddr_t, int, int));
-#endif
#endif /* __IP_LOOKUP_H__ */
diff --git a/usr/src/common/ipf/ip_nat.h b/usr/src/uts/common/inet/ipf/netinet/ip_nat.h
index a27ac35783..930e8aa103 100644
--- a/usr/src/common/ipf/ip_nat.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_nat.h
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 1995-2001 by Darren Reed.
+ * Copyright (C) 1995-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.83 2003/08/14 15:22:58 darrenr Exp $
- *
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * $Id: ip_nat.h,v 2.90.2.11 2005/06/18 02:41:32 darrenr Exp $
+*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -18,18 +18,16 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
#define SIOCADNAT _IOW('r', 60, struct ipfobj)
#define SIOCRMNAT _IOW('r', 61, struct ipfobj)
#define SIOCGNATS _IOWR('r', 62, struct ipfobj)
#define SIOCGNATL _IOWR('r', 63, struct ipfobj)
-#define SIOCPROXY _IOWR('r', 64, struct ap_control)
#else
#define SIOCADNAT _IOW(r, 60, struct ipfobj)
#define SIOCRMNAT _IOW(r, 61, struct ipfobj)
#define SIOCGNATS _IOWR(r, 62, struct ipfobj)
#define SIOCGNATL _IOWR(r, 63, struct ipfobj)
-#define SIOCPROXY _IOWR(r, 64, struct ap_control)
#endif
#undef LARGE_NAT /* define this if you're setting up a system to NAT
@@ -55,16 +53,27 @@
#endif
#ifndef HOSTMAP_SIZE
# ifdef LARGE_NAT
+# define HOSTMAP_SIZE 8191
+# else
# define HOSTMAP_SIZE 2047
+# endif
+#endif
+#ifndef NAT_TABLE_MAX
+/*
+ * This is newly introduced and for the sake of "least surprise", the numbers
+ * present aren't what we'd normally use for creating a proper hash table.
+ */
+# ifdef LARGE_NAT
+# define NAT_TABLE_MAX 180000
# else
-# define HOSTMAP_SIZE 8191
+# define NAT_TABLE_MAX 30000
# endif
#endif
#ifndef NAT_TABLE_SZ
# ifdef LARGE_NAT
-# define NAT_TABLE_SZ 2047
-# else
# define NAT_TABLE_SZ 16383
+# else
+# define NAT_TABLE_SZ 2047
# endif
#endif
#ifndef APR_LABELLEN
@@ -115,6 +124,7 @@ typedef struct nat {
int nat_ref; /* reference count */
int nat_hv[2];
char nat_ifnames[2][LIFNAMSIZ];
+ int nat_rev; /* 0 = forward, 1 = reverse */
} nat_t;
#define nat_inip nat_inip6.in4
@@ -127,7 +137,6 @@ typedef struct nat {
#define nat_seq nat_un.nat_uni.ici_seq
#define nat_id nat_un.nat_uni.ici_id
#define nat_tcpstate nat_tqe.tqe_state
-#define nat_gre nat_un.nat_ugre
/*
* Values for nat_dir
@@ -148,6 +157,7 @@ typedef struct nat {
#define NAT_TCPUDP (NAT_TCP|NAT_UDP)
#define NAT_TCPUDPICMP (NAT_TCP|NAT_UDP|NAT_ICMPERR)
+#define NAT_TCPUDPICMPQ (NAT_TCP|NAT_UDP|NAT_ICMPQUERY)
#define NAT_FROMRULE (NAT_TCP|NAT_UDP)
/* 0x0100 reserved for FI_W_SPORT */
@@ -178,7 +188,8 @@ typedef struct ipnat {
u_int in_hv;
int in_flineno; /* conf. file line number */
u_short in_pnext;
- u_char in_xxx1[2];
+ u_char in_v;
+ u_char in_xxx;
/* From here to the end is covered by IPN_CMPSIZ */
u_32_t in_flags;
u_32_t in_mssclamp; /* if != 0 clamp MSS to this */
@@ -224,6 +235,7 @@ typedef struct ipnat {
#define IPN_ICMPERR 0x00004
#define IPN_TCPUDPICMP (IPN_TCP|IPN_UDP|IPN_ICMPERR)
#define IPN_ICMPQUERY 0x00008
+#define IPN_TCPUDPICMPQ (IPN_TCP|IPN_UDP|IPN_ICMPQUERY)
#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
#define IPN_AUTOPORTMAP 0x00010
#define IPN_IPRANGE 0x00020
@@ -237,10 +249,12 @@ typedef struct ipnat {
#define IPN_DELETE 0x40000
#define IPN_STICKY 0x80000
#define IPN_FRAG 0x100000
+#define IPN_FIXEDDPORT 0x200000
#define IPN_FINDFORWARD 0x400000
+#define IPN_IN 0x800000
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
- IPN_FRAG|IPN_STICKY)
+ IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY)
/*
* Values for in_redir
@@ -283,6 +297,7 @@ typedef struct natget {
} natget_t;
+#undef tr_flags
typedef struct nattrpnt {
struct in_addr tr_dstip; /* real destination IP# */
struct in_addr tr_srcip; /* real source IP# */
@@ -353,6 +368,7 @@ typedef struct natstat {
void *ns_apslist;
u_int ns_wilds;
u_int ns_nattab_sz;
+ u_int ns_nattab_max;
u_int ns_rultab_sz;
u_int ns_rdrtab_sz;
u_int ns_trpntab_sz;
@@ -405,6 +421,7 @@ typedef struct natlog {
extern u_int ipf_nattable_sz;
+extern u_int ipf_nattable_max;
extern u_int ipf_natrules_sz;
extern u_int ipf_rdrrules_sz;
extern u_int ipf_hostmap_sz;
@@ -414,6 +431,7 @@ extern int fr_nat_lock;
extern void fr_natsync __P((void *));
extern u_long fr_defnatage;
extern u_long fr_defnaticmpage;
+extern u_long fr_defnatipage;
/* nat_table[0] -> hashed list sorted by inside (ip, port) */
/* nat_table[1] -> hashed list sorted by outside (ip, port) */
extern nat_t **nat_table[2];
@@ -427,11 +445,7 @@ extern natstat_t nat_stats;
#if defined(__OpenBSD__)
extern void nat_ifdetach __P((void *));
#endif
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-extern int fr_nat_ioctl __P((caddr_t, u_long, int));
-#else
-extern int fr_nat_ioctl __P((caddr_t, int, int));
-#endif
+extern int fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int));
extern int fr_natinit __P((void));
extern nat_t *nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int));
extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
@@ -445,7 +459,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 int nat_insert __P((nat_t *));
+extern int nat_insert __P((nat_t *, int));
extern int fr_checknatout __P((fr_info_t *, u_32_t *));
extern int fr_natout __P((fr_info_t *, nat_t *, int, u_32_t));
diff --git a/usr/src/common/ipf/ip_netbios_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_netbios_pxy.c
index 70d40a2587..8bfa8fac47 100644
--- a/usr/src/common/ipf/ip_netbios_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_netbios_pxy.c
@@ -1,7 +1,7 @@
/*
* Simple netbios-dgm transparent proxy for in-kernel use.
* For use with the NAT code.
- * $Id: ip_netbios_pxy.c,v 2.7 2003/06/25 12:08:21 darrenr Exp $
+ * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/07/15 21:56:51 darrenr Exp $
*/
/*-
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ip_netbios_pxy.c,v 2.7 2003/06/25 12:08:21 darrenr Exp $
+ * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/07/15 21:56:51 darrenr Exp $
*/
#define IPF_NETBIOS_PROXY
@@ -80,25 +80,23 @@ nat_t *nat;
aps = aps; /* LINT */
nat = nat; /* LINT */
- ip = fin->fin_ip;
- m = *(mb_t **)fin->fin_mp;
- off = fin->fin_hlen + sizeof(udphdr_t);
- dlen = M_LEN(m);
- dlen -= off;
-
+ m = fin->fin_m;
+ dlen = fin->fin_dlen - sizeof(*udp);
/*
* no net bios datagram could possibly be shorter than this
*/
- if (dlen < 11)
+ if (dlen < 11)
return 0;
+ ip = fin->fin_ip;
udp = (udphdr_t *)fin->fin_dp;
+ off = (char *)udp - (char *)ip + sizeof(*udp) + fin->fin_ipoff;
- /*
+ /*
* move past the
* ip header;
* udp header;
- * 4 bytes into the net bios dgm header.
+ * 4 bytes into the net bios dgm header.
* According to rfc1002, this should be the exact location of
* the source address/port
*/
diff --git a/usr/src/common/ipf/ip_pool.h b/usr/src/uts/common/inet/ipf/netinet/ip_pool.h
index 1df2ea4675..b40ba2b0fb 100644
--- a/usr/src/common/ipf/ip_pool.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_pool.h
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_pool.h,v 2.19 2003/11/08 23:01:26 darrenr Exp $
+ * $Id: ip_pool.h,v 2.26.2.3 2005/06/12 07:18:27 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -14,17 +14,23 @@
#ifndef __IP_POOL_H__
#define __IP_POOL_H__
-#if defined(_KERNEL) && \
- !(defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \
+ !defined(linux) && !defined(sun) && !defined(AIX)
# include <net/radix.h>
+extern void rn_freehead __P((struct radix_node_head *));
+# define FreeS(p, z) KFREES(p, z)
+extern int max_keylen;
#else
-# include "radix.h"
+# if defined(__osf__) || defined(__hpux)
+# include "radix_ipf_local.h"
+# define radix_mask ipf_radix_mask
+# define radix_node ipf_radix_node
+# define radix_node_head ipf_radix_node_head
+# else
+# include "radix_ipf.h"
+# endif
#endif
-#if SOLARIS2 >= 10
-#include "ip_lookup.h"
-#else
#include "netinet/ip_lookup.h"
-#endif
#define IP_POOL_NOMATCH 0
#define IP_POOL_POSITIVE 1
@@ -57,6 +63,7 @@ typedef struct ip_pool_s {
typedef struct ip_pool_stat {
u_long ipls_pools;
+ u_long ipls_tables;
u_long ipls_nodes;
ip_pool_t *ipls_list[IPL_LOGSIZE];
} ip_pool_stat_t;
@@ -77,7 +84,8 @@ extern void ip_pool_free __P((ip_pool_t *));
extern void ip_pool_deref __P((ip_pool_t *));
extern void *ip_pool_find __P((int, char *));
extern ip_pool_node_t *ip_pool_findeq __P((ip_pool_t *,
- addrfamily_t *, addrfamily_t *));
+ addrfamily_t *, addrfamily_t *));
+extern int ip_pool_flush __P((iplookupflush_t *));
extern int ip_pool_statistics __P((iplookupop_t *));
#endif /* __IP_POOL_H__ */
diff --git a/usr/src/uts/common/inet/ipf/netinet/ip_pptp_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_pptp_pxy.c
new file mode 100644
index 0000000000..480edf1a00
--- /dev/null
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_pptp_pxy.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2002-2003 by Darren Reed
+ *
+ * Simple PPTP transparent proxy for in-kernel use. For use with the NAT
+ * code.
+ *
+ * $Id: ip_pptp_pxy.c,v 2.10.2.10 2005/07/15 21:56:52 darrenr Exp $
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define IPF_PPTP_PROXY
+
+typedef struct pptp_hdr {
+ u_short pptph_len;
+ u_short pptph_type;
+ u_32_t pptph_cookie;
+} pptp_hdr_t;
+
+#define PPTP_MSGTYPE_CTL 1
+#define PPTP_MTCTL_STARTREQ 1
+#define PPTP_MTCTL_STARTREP 2
+#define PPTP_MTCTL_STOPREQ 3
+#define PPTP_MTCTL_STOPREP 4
+#define PPTP_MTCTL_ECHOREQ 5
+#define PPTP_MTCTL_ECHOREP 6
+#define PPTP_MTCTL_OUTREQ 7
+#define PPTP_MTCTL_OUTREP 8
+#define PPTP_MTCTL_INREQ 9
+#define PPTP_MTCTL_INREP 10
+#define PPTP_MTCTL_INCONNECT 11
+#define PPTP_MTCTL_CLEAR 12
+#define PPTP_MTCTL_DISCONNECT 13
+#define PPTP_MTCTL_WANERROR 14
+#define PPTP_MTCTL_LINKINFO 15
+
+
+int ippr_pptp_init __P((void));
+void ippr_pptp_fini __P((void));
+int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *));
+void ippr_pptp_del __P((ap_session_t *));
+int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *));
+void ippr_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *));
+int ippr_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *));
+int ippr_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int));
+int ippr_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *));
+
+static frentry_t pptpfr;
+
+int pptp_proxy_init = 0;
+int ippr_pptp_debug = 0;
+int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */
+
+
+/*
+ * PPTP application proxy initialization.
+ */
+int ippr_pptp_init()
+{
+ bzero((char *)&pptpfr, sizeof(pptpfr));
+ pptpfr.fr_ref = 1;
+ pptpfr.fr_age[0] = ippr_pptp_gretimeout;
+ pptpfr.fr_age[1] = ippr_pptp_gretimeout;
+ pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
+ MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock");
+ pptp_proxy_init = 1;
+
+ return 0;
+}
+
+
+void ippr_pptp_fini()
+{
+ if (pptp_proxy_init == 1) {
+ MUTEX_DESTROY(&pptpfr.fr_lock);
+ pptp_proxy_init = 0;
+ }
+}
+
+
+/*
+ * Setup for a new PPTP proxy.
+ */
+int ippr_pptp_new(fin, aps, nat)
+fr_info_t *fin;
+ap_session_t *aps;
+nat_t *nat;
+{
+ pptp_pxy_t *pptp;
+ ipnat_t *ipn;
+ ip_t *ip;
+
+ ip = fin->fin_ip;
+
+ if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
+ ip->ip_dst) != NULL) {
+ if (ippr_pptp_debug > 0)
+ printf("ippr_pptp_new: GRE session already exists\n");
+ return -1;
+ }
+
+ aps->aps_psiz = sizeof(*pptp);
+ KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
+ if (aps->aps_data == NULL) {
+ if (ippr_pptp_debug > 0)
+ printf("ippr_pptp_new: malloc for aps_data failed\n");
+ return -1;
+ }
+
+ /*
+ * Create NAT rule against which the tunnel/transport mapping is
+ * created. This is required because the current NAT rule does not
+ * describe GRE but TCP instead.
+ */
+ pptp = aps->aps_data;
+ bzero((char *)pptp, sizeof(*pptp));
+ ipn = &pptp->pptp_rule;
+ ipn->in_ifps[0] = fin->fin_ifp;
+ ipn->in_apr = NULL;
+ ipn->in_use = 1;
+ ipn->in_hits = 1;
+ ipn->in_ippip = 1;
+ if (nat->nat_dir == NAT_OUTBOUND) {
+ ipn->in_nip = ntohl(nat->nat_outip.s_addr);
+ ipn->in_outip = fin->fin_saddr;
+ ipn->in_redir = NAT_MAP;
+ } else if (nat->nat_dir == NAT_INBOUND) {
+ ipn->in_nip = 0;
+ ipn->in_outip = nat->nat_outip.s_addr;
+ ipn->in_redir = NAT_REDIRECT;
+ }
+ ipn->in_inip = nat->nat_inip.s_addr;
+ ipn->in_inmsk = 0xffffffff;
+ ipn->in_outmsk = 0xffffffff;
+ ipn->in_srcip = fin->fin_saddr;
+ ipn->in_srcmsk = 0xffffffff;
+ bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0],
+ sizeof(ipn->in_ifnames[0]));
+ ipn->in_p = IPPROTO_GRE;
+
+ pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer;
+ pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer;
+ return 0;
+}
+
+
+void ippr_pptp_donatstate(fin, nat, pptp)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+{
+ fr_info_t fi;
+ grehdr_t gre;
+ nat_t *nat2;
+ u_char p;
+ ip_t *ip;
+
+ ip = fin->fin_ip;
+ p = ip->ip_p;
+
+ nat2 = pptp->pptp_nat;
+ if ((nat2 == NULL) || (pptp->pptp_state == NULL)) {
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ bzero((char *)&gre, sizeof(gre));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
+ fi.fin_fi.fi_p = IPPROTO_GRE;
+ fi.fin_fr = &pptpfr;
+ if ((nat->nat_dir == NAT_OUTBOUND && fin->fin_out) ||
+ (nat->nat_dir == NAT_INBOUND && !fin->fin_out)) {
+ fi.fin_data[0] = pptp->pptp_call[0];
+ fi.fin_data[1] = pptp->pptp_call[1];
+ } else {
+ fi.fin_data[0] = pptp->pptp_call[1];
+ fi.fin_data[1] = pptp->pptp_call[0];
+ }
+ ip = fin->fin_ip;
+ ip->ip_p = IPPROTO_GRE;
+ fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG);
+ fi.fin_flx |= FI_IGNORE;
+ fi.fin_dp = &gre;
+ gre.gr_flags = htons(1 << 13);
+ if (fin->fin_out && nat->nat_dir == NAT_INBOUND) {
+ fi.fin_fi.fi_saddr = fin->fin_fi.fi_daddr;
+ fi.fin_fi.fi_daddr = nat->nat_outip.s_addr;
+ } else if (!fin->fin_out && nat->nat_dir == NAT_OUTBOUND) {
+ fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
+ fi.fin_fi.fi_daddr = fin->fin_fi.fi_saddr;
+ }
+ }
+
+ /*
+ * Update NAT timeout/create NAT if missing.
+ */
+ if (nat2 != NULL)
+ fr_queueback(&nat2->nat_tqe);
+ else {
+ nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat,
+ NAT_SLAVE, nat->nat_dir);
+ pptp->pptp_nat = nat2;
+ if (nat2 != NULL) {
+ (void) nat_proto(&fi, nat2, 0);
+ nat_update(&fi, nat2, nat2->nat_ptr);
+ }
+ }
+
+ READ_ENTER(&ipf_state);
+ if (pptp->pptp_state != NULL) {
+ fr_queueback(&pptp->pptp_state->is_sti);
+ RWLOCK_EXIT(&ipf_state);
+ } else {
+ RWLOCK_EXIT(&ipf_state);
+ if (nat->nat_dir == NAT_INBOUND)
+ fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr;
+ else
+ fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr;
+ fi.fin_ifp = NULL;
+ pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state,
+ 0);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
+ }
+ ip->ip_p = p;
+ return;
+}
+
+
+/*
+ * Try and build up the next PPTP message in the TCP stream and if we can
+ * build it up completely (fits in our buffer) then pass it off to the message
+ * parsing function.
+ */
+int ippr_pptp_nextmessage(fin, nat, pptp, rev)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+int rev;
+{
+ static char *funcname = "ippr_pptp_nextmessage";
+ pptp_side_t *pptps;
+ u_32_t start, end;
+ pptp_hdr_t *hdr;
+ tcphdr_t *tcp;
+ int dlen, off;
+ u_short len;
+ char *msg;
+
+ tcp = fin->fin_dp;
+ dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
+ start = ntohl(tcp->th_seq);
+ pptps = &pptp->pptp_side[rev];
+ off = (char *)tcp - (char *)fin->fin_ip + (TCP_OFF(tcp) << 2) +
+ fin->fin_ipoff;
+
+ if (dlen <= 0)
+ return 0;
+ /*
+ * If the complete data packet is before what we expect to see
+ * "next", just ignore it as the chances are we've already seen it.
+ * The next if statement following this one really just causes packets
+ * ahead of what we've seen to be dropped, implying that something in
+ * the middle went missing and we want to see that first.
+ */
+ end = start + dlen;
+ if (pptps->pptps_next > end && pptps->pptps_next > start)
+ return 0;
+
+ if (pptps->pptps_next != start) {
+ if (ippr_pptp_debug > 5)
+ printf("%s: next (%x) != start (%x)\n", funcname,
+ pptps->pptps_next, start);
+ return -1;
+ }
+
+ msg = (char *)fin->fin_dp + (TCP_OFF(tcp) << 2);
+
+ while (dlen > 0) {
+ off += pptps->pptps_bytes;
+ if (pptps->pptps_gothdr == 0) {
+ /*
+ * PPTP has an 8 byte header that inclues the cookie.
+ * The start of every message should include one and
+ * it should match 1a2b3c4d. Byte order is ignored,
+ * deliberately, when printing out the error.
+ */
+ len = MIN(8 - pptps->pptps_bytes, dlen);
+ COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr);
+ pptps->pptps_bytes += len;
+ pptps->pptps_wptr += len;
+ hdr = (pptp_hdr_t *)pptps->pptps_buffer;
+ if (pptps->pptps_bytes == 8) {
+ pptps->pptps_next += 8;
+ if (ntohl(hdr->pptph_cookie) != 0x1a2b3c4d) {
+ if (ippr_pptp_debug > 1)
+ printf("%s: bad cookie (%x)\n",
+ funcname,
+ hdr->pptph_cookie);
+ return -1;
+ }
+ }
+ dlen -= len;
+ msg += len;
+ off += len;
+
+ pptps->pptps_gothdr = 1;
+ len = ntohs(hdr->pptph_len);
+ pptps->pptps_len = len;
+ pptps->pptps_nexthdr += len;
+
+ /*
+ * If a message is too big for the buffer, just set
+ * the fields for the next message to come along.
+ * The messages defined in RFC 2637 will not exceed
+ * 512 bytes (in total length) so this is likely a
+ * bad data packet, anyway.
+ */
+ if (len > sizeof(pptps->pptps_buffer)) {
+ if (ippr_pptp_debug > 3)
+ printf("%s: message too big (%d)\n",
+ funcname, len);
+ pptps->pptps_next = pptps->pptps_nexthdr;
+ pptps->pptps_wptr = pptps->pptps_buffer;
+ pptps->pptps_gothdr = 0;
+ pptps->pptps_bytes = 0;
+ pptps->pptps_len = 0;
+ break;
+ }
+ }
+
+ len = MIN(pptps->pptps_len - pptps->pptps_bytes, dlen);
+ COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr);
+ pptps->pptps_bytes += len;
+ pptps->pptps_wptr += len;
+ pptps->pptps_next += len;
+
+ if (pptps->pptps_len > pptps->pptps_bytes)
+ break;
+
+ (void) ippr_pptp_message(fin, nat, pptp, pptps);
+ pptps->pptps_wptr = pptps->pptps_buffer;
+ pptps->pptps_gothdr = 0;
+ pptps->pptps_bytes = 0;
+ pptps->pptps_len = 0;
+
+ start += len;
+ msg += len;
+ dlen -= len;
+ }
+
+ return 0;
+}
+
+
+/*
+ * handle a complete PPTP message
+ */
+int ippr_pptp_message(fin, nat, pptp, pptps)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+pptp_side_t *pptps;
+{
+ pptp_hdr_t *hdr = (pptp_hdr_t *)pptps->pptps_buffer;
+
+ switch (ntohs(hdr->pptph_type))
+ {
+ case PPTP_MSGTYPE_CTL :
+ (void) ippr_pptp_mctl(fin, nat, pptp, pptps);
+ break;
+
+ default :
+ break;
+ }
+ return 0;
+}
+
+
+/*
+ * handle a complete PPTP control message
+ */
+int ippr_pptp_mctl(fin, nat, pptp, pptps)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+pptp_side_t *pptps;
+{
+ u_short *buffer = (u_short *)(pptps->pptps_buffer);
+ pptp_side_t *pptpo;
+
+ if (pptps == &pptp->pptp_side[0])
+ pptpo = &pptp->pptp_side[1];
+ else
+ pptpo = &pptp->pptp_side[0];
+
+ /*
+ * Breakout to handle all the various messages. Most are just state
+ * transition.
+ */
+ switch (ntohs(buffer[4]))
+ {
+ case PPTP_MTCTL_STARTREQ :
+ pptps->pptps_state = PPTP_MTCTL_STARTREQ;
+ break;
+ case PPTP_MTCTL_STARTREP :
+ if (pptpo->pptps_state == PPTP_MTCTL_STARTREQ)
+ pptps->pptps_state = PPTP_MTCTL_STARTREP;
+ break;
+ case PPTP_MTCTL_STOPREQ :
+ pptps->pptps_state = PPTP_MTCTL_STOPREQ;
+ break;
+ case PPTP_MTCTL_STOPREP :
+ if (pptpo->pptps_state == PPTP_MTCTL_STOPREQ)
+ pptps->pptps_state = PPTP_MTCTL_STOPREP;
+ break;
+ case PPTP_MTCTL_ECHOREQ :
+ pptps->pptps_state = PPTP_MTCTL_ECHOREQ;
+ break;
+ case PPTP_MTCTL_ECHOREP :
+ if (pptpo->pptps_state == PPTP_MTCTL_ECHOREQ)
+ pptps->pptps_state = PPTP_MTCTL_ECHOREP;
+ break;
+ case PPTP_MTCTL_OUTREQ :
+ pptps->pptps_state = PPTP_MTCTL_OUTREQ;
+ break;
+ case PPTP_MTCTL_OUTREP :
+ if (pptpo->pptps_state == PPTP_MTCTL_OUTREQ) {
+ pptps->pptps_state = PPTP_MTCTL_OUTREP;
+ pptp->pptp_call[0] = buffer[7];
+ pptp->pptp_call[1] = buffer[6];
+ ippr_pptp_donatstate(fin, nat, pptp);
+ }
+ break;
+ case PPTP_MTCTL_INREQ :
+ pptps->pptps_state = PPTP_MTCTL_INREQ;
+ break;
+ case PPTP_MTCTL_INREP :
+ if (pptpo->pptps_state == PPTP_MTCTL_INREQ) {
+ pptps->pptps_state = PPTP_MTCTL_INREP;
+ pptp->pptp_call[0] = buffer[7];
+ pptp->pptp_call[1] = buffer[6];
+ ippr_pptp_donatstate(fin, nat, pptp);
+ }
+ break;
+ case PPTP_MTCTL_INCONNECT :
+ pptps->pptps_state = PPTP_MTCTL_INCONNECT;
+ break;
+ case PPTP_MTCTL_CLEAR :
+ pptps->pptps_state = PPTP_MTCTL_CLEAR;
+ break;
+ case PPTP_MTCTL_DISCONNECT :
+ pptps->pptps_state = PPTP_MTCTL_DISCONNECT;
+ break;
+ case PPTP_MTCTL_WANERROR :
+ pptps->pptps_state = PPTP_MTCTL_WANERROR;
+ break;
+ case PPTP_MTCTL_LINKINFO :
+ pptps->pptps_state = PPTP_MTCTL_LINKINFO;
+ break;
+ }
+
+ return 0;
+}
+
+
+/*
+ * For outgoing PPTP packets. refresh timeouts for NAT & state entries, if
+ * we can. If they have disappeared, recreate them.
+ */
+int ippr_pptp_inout(fin, aps, nat)
+fr_info_t *fin;
+ap_session_t *aps;
+nat_t *nat;
+{
+ pptp_pxy_t *pptp;
+ tcphdr_t *tcp;
+ int rev;
+
+ if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND))
+ rev = 1;
+ else if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND))
+ rev = 1;
+ else
+ rev = 0;
+
+ tcp = (tcphdr_t *)fin->fin_dp;
+ if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
+ pptp = (pptp_pxy_t *)aps->aps_data;
+ pptp->pptp_side[1 - rev].pptps_next = ntohl(tcp->th_ack);
+ pptp->pptp_side[1 - rev].pptps_nexthdr = ntohl(tcp->th_ack);
+ pptp->pptp_side[rev].pptps_next = ntohl(tcp->th_seq) + 1;
+ pptp->pptp_side[rev].pptps_nexthdr = ntohl(tcp->th_seq) + 1;
+ }
+ return ippr_pptp_nextmessage(fin, nat, (pptp_pxy_t *)aps->aps_data,
+ rev);
+}
+
+
+/*
+ * clean up after ourselves.
+ */
+void ippr_pptp_del(aps)
+ap_session_t *aps;
+{
+ pptp_pxy_t *pptp;
+
+ pptp = aps->aps_data;
+
+ if (pptp != NULL) {
+ /*
+ * Don't bother changing any of the NAT structure details,
+ * *_del() is on a callback from aps_free(), from nat_delete()
+ */
+
+ READ_ENTER(&ipf_state);
+ if (pptp->pptp_state != NULL) {
+ pptp->pptp_state->is_die = fr_ticks + 1;
+ pptp->pptp_state->is_me = NULL;
+ fr_queuefront(&pptp->pptp_state->is_sti);
+ }
+ RWLOCK_EXIT(&ipf_state);
+
+ pptp->pptp_state = NULL;
+ pptp->pptp_nat = NULL;
+ }
+}
diff --git a/usr/src/common/ipf/ip_proxy.h b/usr/src/uts/common/inet/ipf/netinet/ip_proxy.h
index 73fa62ed3c..1e0bedef64 100644
--- a/usr/src/common/ipf/ip_proxy.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_proxy.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_proxy.h,v 2.30 2003/07/01 01:01:29 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.31.2.3 2005/06/18 02:41:33 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -13,6 +13,12 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
+#define SIOCPROXY _IOWR('r', 64, struct ap_control)
+#else
+#define SIOCPROXY _IOWR(r, 64, struct ap_control)
+#endif
+
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
#endif
@@ -20,15 +26,16 @@
struct nat;
struct ipnat;
+struct ipstate;
typedef struct ap_tcp {
u_short apt_sport; /* source port */
u_short apt_dport; /* destination port */
short apt_sel[2]; /* {seq,ack}{off,min} set selector */
short apt_seqoff[2]; /* sequence # difference */
- tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
+ u_32_t apt_seqmin[2]; /* don't change seq-off until after this */
short apt_ackoff[2]; /* sequence # difference */
- tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
+ u_32_t apt_ackmin[2]; /* don't change seq-off until after this */
u_char apt_state[2]; /* connection state */
} ap_tcp_t;
@@ -130,9 +137,18 @@ typedef struct aproxy {
#endif
/*
- * For the ftp proxy.
+ * This is the scratch buffer size used to hold strings from the TCP stream
+ * that we may want to parse. It's an arbitrary size, really, but it must
+ * be at least as large as IPF_FTPBUFSZ.
+ */
+#define FTP_BUFSZ 120
+
+/*
+ * This buffer, however, doesn't need to be nearly so big. It just needs to
+ * be able to squeeze in the largest command it needs to rewrite, Which ones
+ * does it rewrite? EPRT, PORT, 227 replies.
*/
-#define FTP_BUFSZ 160
+#define IPF_FTPBUFSZ 80 /* This *MUST* be >= 53! */
typedef struct ftpside {
char *ftps_rptr;
@@ -140,7 +156,7 @@ typedef struct ftpside {
void *ftps_ifp;
u_32_t ftps_seq[2];
u_32_t ftps_len;
- int ftps_junk;
+ int ftps_junk; /* 2 = no cr/lf yet, 1 = cannot parse */
int ftps_cmds;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
@@ -186,7 +202,7 @@ typedef struct raudio_s {
u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have
* been filled
*/
- tcp_seq rap_sseq;
+ u_32_t rap_sseq;
} raudio_t;
#define RA_ID_END 0
@@ -199,6 +215,9 @@ typedef struct raudio_s {
#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
+/*
+ * MSN RPC proxy
+ */
typedef struct msnrpcinfo {
u_int mri_flags;
int mri_cmd[2];
@@ -219,10 +238,33 @@ typedef struct ipsec_pxy {
int ipsc_rckset;
ipnat_t ipsc_rule;
nat_t *ipsc_nat;
- ipstate_t *ipsc_state;
+ struct ipstate *ipsc_state;
} ipsec_pxy_t;
/*
+ * PPTP proxy
+ */
+typedef struct pptp_side {
+ u_32_t pptps_nexthdr;
+ u_32_t pptps_next;
+ int pptps_state;
+ int pptps_gothdr;
+ int pptps_len;
+ int pptps_bytes;
+ char *pptps_wptr;
+ char pptps_buffer[512];
+} pptp_side_t;
+
+typedef struct pptp_pxy {
+ ipnat_t pptp_rule;
+ nat_t *pptp_nat;
+ struct ipstate *pptp_state;
+ u_short pptp_call[2];
+ pptp_side_t pptp_side[2];
+} pptp_pxy_t;
+
+
+/*
* Sun RPCBIND proxy
*/
#define RPCB_MAXMSG 888
@@ -411,10 +453,6 @@ extern void aps_free __P((ap_session_t *));
extern int appr_check __P((fr_info_t *, struct nat *));
extern aproxy_t *appr_lookup __P((u_int, char *));
extern int appr_new __P((fr_info_t *, struct nat *));
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-extern int appr_ioctl __P((caddr_t, u_long, int));
-#else
-extern int appr_ioctl __P((caddr_t, int, int));
-#endif
+extern int appr_ioctl __P((caddr_t, ioctlcmd_t, int));
#endif /* __IP_PROXY_H__ */
diff --git a/usr/src/common/ipf/ip_raudio_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_raudio_pxy.c
index 70254575b8..a9abc5809b 100644
--- a/usr/src/common/ipf/ip_raudio_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_raudio_pxy.c
@@ -3,18 +3,14 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_raudio_pxy.c,v 1.35 2003/06/28 17:01:58 darrenr Exp $
+ * $Id: ip_raudio_pxy.c,v 1.40.2.3 2005/02/04 10:22:55 darrenr Exp $
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#ifdef USE_MUTEXES
-extern ipfmutex_t ipf_rw;
-#endif
-
#define IPF_RAUDIO_PROXY
@@ -103,16 +99,21 @@ nat_t *nat;
m = fin->fin_m;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
- bzero((char *)membuf, sizeof(membuf));
+ off = (char *)tcp - (char *)fin->fin_ip;
+ off += (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
+#ifdef __sgi
+ dlen = fin->fin_plen - off;
+#else
dlen = MSGDSIZE(m) - off;
+#endif
if (dlen <= 0)
return 0;
if (dlen > sizeof(membuf))
dlen = sizeof(membuf);
+ bzero((char *)membuf, sizeof(membuf));
COPYDATA(m, off, dlen, (char *)membuf);
/*
* In all the startup parsing, ensure that we don't go outside
@@ -188,8 +189,8 @@ nat_t *nat;
unsigned char membuf[IPF_MAXPORTLEN + 1], *s;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
- int off, dlen, slen, clen;
struct in_addr swa, swb;
+ int off, dlen, slen;
int a1, a2, a3, a4;
u_short sp, dp;
fr_info_t fi;
@@ -208,11 +209,15 @@ nat_t *nat;
return 0;
m = fin->fin_m;
- ip = fin->fin_ip;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
+ off = (char *)tcp - (char *)fin->fin_ip;
+ off += (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
+#ifdef __sgi
+ dlen = fin->fin_plen - off;
+#else
dlen = MSGDSIZE(m) - off;
+#endif
if (dlen <= 0)
return 0;
@@ -220,8 +225,7 @@ nat_t *nat;
dlen = sizeof(membuf);
bzero((char *)membuf, sizeof(membuf));
- clen = MIN(sizeof(membuf), dlen);
- COPYDATA(m, off, clen, (char *)membuf);
+ COPYDATA(m, off, dlen, (char *)membuf);
seq = ntohl(tcp->th_seq);
/*
@@ -229,7 +233,7 @@ nat_t *nat;
* We only care for the first 19 bytes coming back from the server.
*/
if (rap->rap_sseq == 0) {
- s = (u_char *)memstr("PNA", (char *)membuf, 3, clen);
+ s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
if (s == NULL)
return 0;
a1 = s - membuf;
@@ -264,6 +268,7 @@ nat_t *nat;
rap->rap_srport = (*s << 8) | *(s + 1);
}
+ ip = fin->fin_ip;
swp = ip->ip_p;
swa = ip->ip_src;
swb = ip->ip_dst;
@@ -275,6 +280,8 @@ nat_t *nat;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
TCP_OFF_A(tcp2, 5);
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_flx |= FI_IGNORE;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &raudiofr;
@@ -301,6 +308,8 @@ nat_t *nat;
nat_update(&fi, nat2, nat2->nat_ptr);
(void) fr_addstate(&fi, NULL, (sp ? 0 : SI_W_SPORT));
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
}
@@ -319,6 +328,8 @@ nat_t *nat;
nat_update(&fi, nat2, nat2->nat_ptr);
(void) fr_addstate(&fi, NULL, SI_W_DPORT);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
}
diff --git a/usr/src/common/ipf/ip_rcmd_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_rcmd_pxy.c
index f6a52f8e43..919c47cb90 100644
--- a/usr/src/common/ipf/ip_rcmd_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_rcmd_pxy.c
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_rcmd_pxy.c,v 1.32 2003/06/28 17:01:58 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.41.2.4 2005/02/04 10:22:55 darrenr Exp $
*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -14,24 +14,14 @@
#pragma ident "%Z%%M% %I% %E% SMI"
-#if 0
-#if SOLARIS && defined(_KERNEL)
-extern kmutex_t ipf_rw;
-#endif
-#else
-# ifdef USE_MUTEXES
-extern ipfmutex_t ipf_rw;
-# endif
-#endif
-
#define IPF_RCMD_PROXY
int ippr_rcmd_init __P((void));
void ippr_rcmd_fini __P((void));
int ippr_rcmd_new __P((fr_info_t *, ap_session_t *, nat_t *));
-int ippr_rcmd_in __P((fr_info_t *, ap_session_t *, nat_t *));
int ippr_rcmd_out __P((fr_info_t *, ap_session_t *, nat_t *));
+int ippr_rcmd_in __P((fr_info_t *, ap_session_t *, nat_t *));
u_short ipf_rcmd_atoi __P((char *));
int ippr_rcmd_portmsg __P((fr_info_t *, ap_session_t *, nat_t *));
@@ -101,7 +91,7 @@ char *ptr;
register char *s = ptr, c;
register u_short i = 0;
- while (((c = *s++) != '\0') && isdigit(c)) {
+ while (((c = *s++) != '\0') && ISDIGIT(c)) {
i *= 10;
i += c - '0';
}
@@ -137,9 +127,13 @@ nat_t *nat;
m = fin->fin_m;
ip = fin->fin_ip;
- off = (char *)tcp - MTOD(m, char *) + (TCP_OFF(tcp) << 2);
-
+ off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
+
+#ifdef __sgi
+ dlen = fin->fin_plen - off;
+#else
dlen = MSGDSIZE(m) - off;
+#endif
if (dlen <= 0)
return 0;
@@ -164,7 +158,7 @@ nat_t *nat;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
fi.fin_flx |= FI_IGNORE;
fi.fin_data[0] = sp;
- fi.fin_data[1] = fin->fin_data[1];
+ fi.fin_data[1] = 0;
if (nat->nat_dir == NAT_OUTBOUND)
nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
nat->nat_inip, nat->nat_oip);
@@ -182,7 +176,6 @@ nat_t *nat;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
TCP_OFF_A(tcp2, 5);
tcp2->th_flags = TH_SYN;
- fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &rcmdfr;
fi.fin_dlen = sizeof(*tcp2);
@@ -213,6 +206,8 @@ nat_t *nat;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_len = slen;
ip->ip_src = swip;
diff --git a/usr/src/common/ipf/ip_rpcb_pxy.c b/usr/src/uts/common/inet/ipf/netinet/ip_rpcb_pxy.c
index fa1a230721..f67c01a232 100644
--- a/usr/src/common/ipf/ip_rpcb_pxy.c
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_rpcb_pxy.c
@@ -37,7 +37,7 @@
* o The enclosed hack of STREAMS support is pretty sick and most likely
* broken.
*
- * $Id: ip_rpcb_pxy.c,v 2.17 2003/07/01 18:30:21 darrenr Exp $
+ * $Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp $
*/
#define IPF_RPCB_PROXY
@@ -75,7 +75,7 @@ static int ippr_rpcb_modv3 __P((fr_info_t *, nat_t *, rpc_msg_t *,
static int ippr_rpcb_modv4 __P((fr_info_t *, nat_t *, rpc_msg_t *,
mb_t *, u_int));
static void ippr_rpcb_fixlen __P((fr_info_t *, int));
-
+
/*
* Global variables
*/
@@ -220,7 +220,8 @@ ippr_rpcb_in(fin, aps, nat)
rs = (rpcb_session_t *)aps->aps_data;
m = fin->fin_m;
- off = (char *)fin->fin_dp - MTOD(m, char *) + sizeof(udphdr_t);
+ off = (char *)fin->fin_dp - (char *)fin->fin_ip;
+ off += sizeof(udphdr_t) + fin->fin_ipoff;
dlen = fin->fin_dlen - sizeof(udphdr_t);
/* Disallow packets outside legal range for supported requests. */
@@ -289,7 +290,8 @@ ippr_rpcb_out(fin, aps, nat)
rs = (rpcb_session_t *)aps->aps_data;
m = fin->fin_m;
- off = (char *)fin->fin_dp - MTOD(m, char *) + sizeof(udphdr_t);
+ off = (char *)fin->fin_dp - (char *)fin->fin_ip;
+ off += sizeof(udphdr_t) + fin->fin_ipoff;
dlen = fin->fin_dlen - sizeof(udphdr_t);
diff = 0;
@@ -676,11 +678,11 @@ ippr_rpcb_getuaddr(rm, xu, p)
* Expected format: a.b.c.d.e.f where [a-d] correspond to bytes of
* an IP address and [ef] are the bytes of a L4 port.
*/
- if (!(isdigit(uastr[0]) && isdigit(uastr[l-1])))
+ if (!(ISDIGIT(uastr[0]) && ISDIGIT(uastr[l-1])))
return(-1);
b = uastr;
for (c = &uastr[1], d = 0, dd = 0; c < &uastr[l-1]; c++) {
- if (isdigit(*c)) {
+ if (ISDIGIT(*c)) {
dd = 0;
continue;
}
@@ -734,7 +736,7 @@ ippr_rpcb_atoi(ptr)
register char *s = ptr, c;
register u_int i = 0;
- while (((c = *s++) != '\0') && isdigit(c)) {
+ while (((c = *s++) != '\0') && ISDIGIT(c)) {
i *= 10;
i += c - '0';
}
@@ -775,8 +777,13 @@ ippr_rpcb_modreq(fin, nat, rm, m, off)
/* Form new string. */
bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */
- (void) sprintf(uaddr, "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff,
- i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(uaddr, sizeof(uaddr),
+#else
+ (void) sprintf(uaddr,
+#endif
+ "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff,
+ i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff);
len = strlen(uaddr);
xlen = XDRALIGN(len);
@@ -996,7 +1003,7 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp)
for(rl->rl_cnt = 0; rl->rl_cnt < cnt; rl->rl_cnt++) {
re = &rl->rl_entries[rl->rl_cnt];
rv = ippr_rpcb_getnat(fin, nat,
- re->re_proto.xp_proto,
+ re->re_proto.xp_proto,
(u_int)re->re_maddr.xu_port);
if (rv != 0)
return(-1);
@@ -1169,7 +1176,7 @@ ippr_rpcb_getnat(fin, nat, proto, port)
fi.fin_dp = &tcp;
fi.fin_plen = fi.fin_hlen + fi.fin_dlen;
- /*
+ /*
* Search for existing NAT & state entries. Pay close attention to
* mutexes / locks grabbed from lookup routines, as not doing so could
* lead to bad things.
@@ -1257,6 +1264,8 @@ ippr_rpcb_getnat(fin, nat, proto, port)
*/
return(-1);
}
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
return(0);
@@ -1294,8 +1303,13 @@ ippr_rpcb_modv3(fin, nat, rm, m, off)
/* Form new string. */
bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */
- (void) sprintf(uaddr, "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff,
- i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(uaddr, sizeof(uaddr),
+#else
+ (void) sprintf(uaddr,
+#endif
+ "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff,
+ i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff);
len = strlen(uaddr);
xlen = XDRALIGN(len);
@@ -1369,8 +1383,14 @@ ippr_rpcb_modv4(fin, nat, rm, m, off)
/* Form new string. */
bzero(uaddr, sizeof(uaddr)); /* Just in case we need
padding. */
- (void) sprintf(uaddr, "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff,
- i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff);
+#if defined(SNPRINTF) && defined(_KERNEL)
+ (void) SNPRINTF(uaddr, sizeof(uaddr),
+#else
+ (void) sprintf(uaddr,
+#endif
+ "%u.%u.%u.%u.%u.%u", i[0] & 0xff,
+ i[1] & 0xff, i[2] & 0xff, i[3] & 0xff,
+ p[0] & 0xff, p[1] & 0xff);
len = strlen(uaddr);
xlen = XDRALIGN(len);
diff --git a/usr/src/common/ipf/ip_state.h b/usr/src/uts/common/inet/ipf/netinet/ip_state.h
index ce293cd350..7b5891d86d 100644
--- a/usr/src/common/ipf/ip_state.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_state.h
@@ -4,9 +4,9 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
- * $Id: ip_state.h,v 2.63 2003/06/28 17:02:00 darrenr Exp $
+ * $Id: ip_state.h,v 2.68.2.5 2005/08/11 19:58:04 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -15,7 +15,7 @@
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCDELST _IOW('r', 61, struct ipfobj)
#else
# define SIOCDELST _IOW(r, 61, struct ipfobj)
@@ -48,8 +48,10 @@ typedef struct ipstate {
struct nat *is_nat[2];
frentry_t *is_rule;
struct ipftq *is_tqehead[2];
+ struct ipscan *is_isc;
U_QUAD_T is_pkts[4];
U_QUAD_T is_bytes[4];
+ U_QUAD_T is_icmppkts[4];
struct ipftqent is_sti;
u_int is_frage[2];
int is_ref; /* reference count */
@@ -81,7 +83,6 @@ typedef struct ipstate {
u_32_t is_rulen; /* rule number when created */
u_32_t is_s0[2];
u_short is_smsk[2];
- struct ipscan *is_isc;
char is_group[FR_GROUPLEN];
char is_sbuf[2][16];
char is_ifname[4][LIFNAMSIZ];
@@ -112,6 +113,7 @@ typedef struct ipstate {
#define is_ifpin is_ifp[0]
#define is_ifpout is_ifp[2]
#define is_gre is_ps.is_ug
+#define is_call is_gre.gs_call
#define IS_WSPORT SI_W_SPORT /* 0x00100 */
#define IS_WDPORT SI_W_DPORT /* 0x00200 */
@@ -124,6 +126,7 @@ typedef struct ipstate {
#define IS_STRICT 0x20000
#define IS_ISNSYN 0x40000
#define IS_ISNACK 0x80000
+#define IS_STATESYNC 0x100000
/*
* IS_SC flags are for scan-operations that need to be recognised in state.
*/
@@ -231,6 +234,7 @@ extern u_long fr_udptimeout;
extern u_long fr_udpacktimeout;
extern u_long fr_icmptimeout;
extern u_long fr_icmpacktimeout;
+extern u_long fr_iptimeout;
extern int fr_statemax;
extern int fr_statesize;
extern int fr_state_lock;
@@ -249,18 +253,15 @@ extern void fr_timeoutstate __P((void));
extern int fr_tcp_age __P((struct ipftqent *, struct fr_info *,
struct ipftq *, int));
extern int fr_tcpinwindow __P((struct fr_info *, struct tcpdata *,
- struct tcpdata *, struct tcphdr *, int));
+ struct tcpdata *, tcphdr_t *, int));
extern void fr_stateunload __P((void));
extern void ipstate_log __P((struct ipstate *, u_int));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-extern int fr_state_ioctl __P((caddr_t, u_long, int));
-#else
-extern int fr_state_ioctl __P((caddr_t, int, int));
-#endif
-extern void fr_stinsert __P((struct ipstate *));
+extern int fr_state_ioctl __P((caddr_t, ioctlcmd_t, int));
+extern void fr_stinsert __P((struct ipstate *, int));
extern void fr_sttab_init __P((struct ipftq *));
extern void fr_sttab_destroy __P((struct ipftq *));
extern void fr_updatestate __P((fr_info_t *, ipstate_t *, ipftq_t *));
extern void fr_statederef __P((fr_info_t *, ipstate_t **));
+extern void fr_setstatequeue __P((ipstate_t *, int));
#endif /* __IP_STATE_H__ */
diff --git a/usr/src/uts/common/inet/ipf/netinet/ipl.h b/usr/src/uts/common/inet/ipf/netinet/ipl.h
new file mode 100644
index 0000000000..df2c0b4f3b
--- /dev/null
+++ b/usr/src/uts/common/inet/ipf/netinet/ipl.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * @(#)ipl.h 1.21 6/5/96
+ * $Id: ipl.h,v 2.52.2.10 2005/08/13 05:42:49 darrenr Exp $
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#ifndef __IPL_H__
+#define __IPL_H__
+
+#define IPL_VERSION "IP Filter: v4.1.9"
+
+#define IPFILTER_VERSION 4010900
+
+#endif
diff --git a/usr/src/common/ipf/opts.h b/usr/src/uts/common/inet/ipf/opts.h
index 6850e6b52f..d944df6242 100644
--- a/usr/src/common/ipf/opts.h
+++ b/usr/src/uts/common/inet/ipf/opts.h
@@ -3,9 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: opts.h,v 2.11 2003/06/14 02:05:21 darrenr Exp $
+ * $Id: opts.h,v 2.12 2003/08/14 14:24:27 darrenr Exp $
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,7 +44,8 @@
#define OPT_CLEAR 0x1000000
#define OPT_HEX 0x2000000
#define OPT_ASCII 0x4000000
-#define OPT_UNDEF 0x8000000
+#define OPT_NORESOLVE 0x8000000
+#define OPT_UNDEF 0x10000000
#define OPT_STAT OPT_FRSTATES
#define OPT_LIST OPT_SHOWLIST
diff --git a/usr/src/uts/common/inet/ipf/pfil.conf b/usr/src/uts/common/inet/ipf/pfil.conf
deleted file mode 100644
index 018946143b..0000000000
--- a/usr/src/uts/common/inet/ipf/pfil.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-name="pfil" parent="pseudo" instance=0;
-
diff --git a/usr/src/common/ipf/radix.c b/usr/src/uts/common/inet/ipf/radix.c
index f3dd0a6170..69b50c062a 100644
--- a/usr/src/common/ipf/radix.c
+++ b/usr/src/uts/common/inet/ipf/radix.c
@@ -29,8 +29,15 @@
/*
* Routines to build and maintain radix trees for routing lookups.
*/
-
-#if !defined(__svr4__) && !defined(__SVR4) && !defined(__osf__)
+#if defined(KERNEL) || defined(_KERNEL)
+# undef KERNEL
+# undef _KERNEL
+# define KERNEL 1
+# define _KERNEL 1
+#endif
+#define __SYS_ATOMIC_OPS_H__
+#if !defined(__svr4__) && !defined(__SVR4) && !defined(__osf__) && \
+ !defined(__hpux) && !defined(__sgi)
#include <sys/cdefs.h>
#endif
#ifndef __P
@@ -40,31 +47,47 @@
# define __P(x) ()
# endif
#endif
+#ifdef __osf__
+# define CONST
+# define _IPV6_SWTAB_H
+# define _PROTO_NET_H_
+# define _PROTO_IPV6_H
+# include <sys/malloc.h>
+#endif
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
-void panic(char *str);
+void panic __P((char *str));
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#endif
+#ifdef __hpux
+#include <syslog.h>
+#else
#include <sys/syslog.h>
+#endif
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <net/if.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "radix.h"
-#define min MIN
-#define max MAX
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+/* END OF INCLUDES */
+#include "radix_ipf.h"
+#ifndef min
+# define min MIN
+#endif
+#ifndef max
+# define max MAX
+#endif
int max_keylen = 16;
-struct radix_mask *rn_mkfreelist;
-struct radix_node_head *mask_rnhead;
+static struct radix_mask *rn_mkfreelist;
+static struct radix_node_head *mask_rnhead;
static char *addmask_key;
static u_char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
static char *rn_zeros = NULL, *rn_ones = NULL;
@@ -75,9 +98,15 @@ static char *rn_zeros = NULL, *rn_ones = NULL;
static int rn_satisfies_leaf __P((char *, struct radix_node *, int));
static int rn_lexobetter __P((void *, void *));
-static int rn_freenode __P((struct radix_node *, void *));
static struct radix_mask *rn_new_radix_mask __P((struct radix_node *,
struct radix_mask *));
+static int rn_freenode __P((struct radix_node *, void *));
+#if defined(AIX) && !defined(_KERNEL)
+struct radix_node *rn_match __P((void *, struct radix_node_head *));
+struct radix_node *rn_addmask __P((int, int, void *));
+#define FreeS(x, y) KFREES(x, y)
+#define Bcopy(x, y, z) bcopy(x, y, z)
+#endif
/*
* The data structure for the keys is a radix tree with one way
@@ -94,18 +123,18 @@ static struct radix_mask *rn_new_radix_mask __P((struct radix_node *,
* We define the index of a route to associated with the mask to be
* the first bit number in the mask where 0 occurs (with bit number 0
* representing the highest order bit).
- *
+ *
* We say a mask is normal if every bit is 0, past the index of the mask.
* If a node n has a descendant (k, m) with index(m) == index(n) == rn_b,
* and m is a normal mask, then the route applies to every descendant of n.
* If the index(m) < rn_b, this implies the trailing last few bits of k
* before bit b are all 0, (and hence consequently true of every descendant
* of n), so the route applies to all descendants of the node as well.
- *
+ *
* Similar logic shows that a non-normal mask m such that
* index(m) <= index(n) could potentially apply to many children of n.
* Thus, for each non-host route, we attach its mask to a list at an internal
- * node as high in the tree as we can go.
+ * node as high in the tree as we can go.
*
* The present version of the code makes use of normal routes in short-
* circuiting an explict mask and compare operation when testing whether
@@ -159,7 +188,7 @@ rn_refines(m_arg, n_arg)
if (longer > 0)
lim -= longer;
- while (n < lim) {
+ while (n < lim) {
if (*n & ~(*m))
return 0;
if (*n++ != *m++)
@@ -210,7 +239,9 @@ rn_satisfies_leaf(trial, leaf, skip)
cp3 = rn_ones;
else
length = min(length, *(u_char *)cp3);
- cplim = cp + length; cp3 += skip; cp2 += skip;
+ cplim = cp + length;
+ cp3 += skip;
+ cp2 += skip;
for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
if ((*cp ^ *cp2) & *cp3)
return 0;
@@ -253,7 +284,9 @@ rn_match(v_arg, head)
*/
if (t->rn_mask)
vlen = *(u_char *)t->rn_mask;
- cp += off; cp2 = t->rn_key + off; cplim = v + vlen;
+ cp += off;
+ cp2 = t->rn_key + off;
+ cplim = v + vlen;
for (; cp < cplim; cp++, cp2++)
if (*cp != *cp2)
goto on1;
@@ -318,7 +351,7 @@ on1:
} while (t != top);
return 0;
}
-
+
#ifdef RN_DEBUG
int rn_nodenum;
struct radix_node *rn_clist;
@@ -333,13 +366,20 @@ rn_newpair(v, b, nodes)
struct radix_node nodes[2];
{
struct radix_node *tt = nodes, *t = tt + 1;
- t->rn_b = b; t->rn_bmask = 0x80 >> (b & 7);
- t->rn_l = tt; t->rn_off = b >> 3;
- tt->rn_b = -1; tt->rn_key = (caddr_t)v; tt->rn_p = t;
+ t->rn_b = b;
+ t->rn_bmask = 0x80 >> (b & 7);
+ t->rn_l = tt;
+ t->rn_off = b >> 3;
+ tt->rn_b = -1;
+ tt->rn_key = (caddr_t)v;
+ tt->rn_p = t;
tt->rn_flags = t->rn_flags = RNF_ACTIVE;
#ifdef RN_DEBUG
- tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
- tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
+ tt->rn_info = rn_nodenum++;
+ t->rn_info = rn_nodenum++;
+ tt->rn_twin = t;
+ tt->rn_ybro = rn_clist;
+ rn_clist = tt;
#endif
return t;
}
@@ -387,24 +427,28 @@ on1:
cp = v;
do {
p = x;
- if (cp[x->rn_off] & x->rn_bmask)
+ if (cp[x->rn_off] & x->rn_bmask)
x = x->rn_r;
- else x = x->rn_l;
+ else
+ x = x->rn_l;
} while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */
#ifdef RN_DEBUG
if (rn_debug)
log(LOG_DEBUG, "rn_insert: Going In:\n"); // traverse(p);
#endif
- t = rn_newpair(v_arg, b, nodes); tt = t->rn_l;
+ t = rn_newpair(v_arg, b, nodes);
+ tt = t->rn_l;
if ((cp[p->rn_off] & p->rn_bmask) == 0)
p->rn_l = t;
else
p->rn_r = t;
- x->rn_p = t; t->rn_p = p; /* frees x, p as temp vars below */
+ x->rn_p = t;
+ t->rn_p = p; /* frees x, p as temp vars below */
if ((cp[t->rn_off] & t->rn_bmask) == 0) {
t->rn_r = x;
} else {
- t->rn_r = tt; t->rn_l = x;
+ t->rn_r = tt;
+ t->rn_l = x;
}
#ifdef RN_DEBUG
if (rn_debug)
@@ -478,11 +522,12 @@ rn_addmask(n_arg, search, skip)
/*
* Calculate index of mask, and check for normalcy.
*/
- cplim = netmask + mlen; isnormal = 1;
+ cplim = netmask + mlen;
+ isnormal = 1;
for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
cp++;
if (cp != cplim) {
- for (j = 0x80; (j & *cp) != 0; j >>= 1)
+ for (j = 0x80; (j & *cp) != 0; j >>= 1)
b++;
if (*cp != normal_chars[b] || cp != (cplim - 1))
isnormal = 0;
@@ -502,7 +547,7 @@ rn_lexobetter(m_arg, n_arg)
if (*mp > *np)
return 1; /* not really, but need to check longer one first */
- if (*mp == *np)
+ if (*mp == *np)
for (lim = mp + *mp; mp < lim;)
if (*mp++ > *np++)
return 1;
@@ -542,7 +587,7 @@ rn_addroute(v_arg, n_arg, head, treenodes)
struct radix_node treenodes[2];
{
caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
- struct radix_node *t, *x = 0, *tt;
+ struct radix_node *t, *x = NULL, *tt;
struct radix_node *saved_tt, *top = head->rnh_treetop;
short b = 0, b_leaf = 0;
int keyduplicated;
@@ -560,7 +605,7 @@ rn_addroute(v_arg, n_arg, head, treenodes)
* the mask to speed avoiding duplicate references at
* nodes and possibly save time in calculating indices.
*/
- if (netmask) {
+ if (netmask) {
if ((x = rn_addmask(netmask, 0, top->rn_off)) == 0)
return (0);
b_leaf = x->rn_b;
@@ -602,8 +647,12 @@ rn_addroute(v_arg, n_arg, head, treenodes)
tt->rn_flags = t->rn_flags;
tt->rn_p = x = t->rn_p;
t->rn_p = tt;
- if (x->rn_l == t) x->rn_l = tt; else x->rn_r = tt;
- saved_tt = tt; x = xx;
+ if (x->rn_l == t)
+ x->rn_l = tt;
+ else
+ x->rn_r = tt;
+ saved_tt = tt;
+ x = xx;
} else {
(tt = treenodes)->rn_dupedkey = t->rn_dupedkey;
t->rn_dupedkey = tt;
@@ -612,8 +661,12 @@ rn_addroute(v_arg, n_arg, head, treenodes)
tt->rn_dupedkey->rn_p = tt;
}
#ifdef RN_DEBUG
- t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
- tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
+ t=tt+1;
+ tt->rn_info = rn_nodenum++;
+ t->rn_info = rn_nodenum++;
+ tt->rn_twin = t;
+ tt->rn_ybro = rn_clist;
+ rn_clist = tt;
#endif
tt->rn_key = (caddr_t) v;
tt->rn_b = -1;
@@ -631,9 +684,12 @@ rn_addroute(v_arg, n_arg, head, treenodes)
if (keyduplicated)
goto on2;
b_leaf = -1 - t->rn_b;
- if (t->rn_r == saved_tt) x = t->rn_l; else x = t->rn_r;
+ if (t->rn_r == saved_tt)
+ x = t->rn_l;
+ else
+ x = t->rn_r;
/* Promote general routes from below */
- if (x->rn_b < 0) {
+ if (x->rn_b < 0) {
for (mp = &t->rn_mklist; x; x = x->rn_dupedkey)
if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) {
*mp = m = rn_new_radix_mask(x, 0);
@@ -644,10 +700,11 @@ rn_addroute(v_arg, n_arg, head, treenodes)
/*
* Skip over masks whose index is > that of new node
*/
- for (mp = &x->rn_mklist; ((m = *mp) != NULL); mp = &m->rm_mklist)
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
if (m->rm_b >= b_leaf)
break;
- t->rn_mklist = m; *mp = 0;
+ t->rn_mklist = m;
+ *mp = 0;
}
on2:
/* Add new route to highest possible ancestor's list */
@@ -664,7 +721,7 @@ on2:
* Need same criteria as when sorting dupedkeys to avoid
* double loop on deletion.
*/
- for (mp = &x->rn_mklist; ((m = *mp) != NULL); mp = &m->rm_mklist) {
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) {
if (m->rm_b < b_leaf)
continue;
if (m->rm_b > b_leaf)
@@ -685,7 +742,8 @@ on2:
tt->rn_mklist = m;
return tt;
}
- if (rn_refines(netmask, mmask) || rn_lexobetter(netmask, mmask))
+ if (rn_refines(netmask, mmask)
+ || rn_lexobetter(netmask, mmask))
break;
}
*mp = rn_new_radix_mask(tt, *mp);
@@ -734,7 +792,7 @@ rn_delete(v_arg, netmask_arg, head)
#endif
return 0; /* dangling ref could cause disaster */
}
- } else {
+ } else {
if (m->rm_mask != tt->rn_mask) {
#if 0
log(LOG_ERR, "rn_delete: inconsistent annotation\n");
@@ -752,7 +810,7 @@ rn_delete(v_arg, netmask_arg, head)
x = t;
t = t->rn_p;
} while (b <= t->rn_b && x != top);
- for (mp = &x->rn_mklist; ((m = *mp) != NULL); mp = &m->rm_mklist)
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
if (m == saved_m) {
*mp = m->rm_mklist;
MKFree(m);
@@ -773,19 +831,24 @@ on1:
return (0);
#ifdef RN_DEBUG
/* Get us out of the creation list */
- for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {}
+ for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro)
+ ;
if (t) t->rn_ybro = tt->rn_ybro;
#endif
t = tt->rn_p;
dupedkey = saved_tt->rn_dupedkey;
if (dupedkey) {
/*
- * Here, tt is the deletion target, and
+ * Here, tt is the deletion target and
* saved_tt is the head of the dupedkey chain.
*/
if (tt == saved_tt) {
- x = dupedkey; x->rn_p = t;
- if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x;
+ x = dupedkey;
+ x->rn_p = t;
+ if (t->rn_l == tt)
+ t->rn_l = x;
+ else
+ t->rn_r = x;
} else {
/* find node in front of tt on the chain */
for (x = p = saved_tt; p && p->rn_dupedkey != tt;)
@@ -803,25 +866,39 @@ on1:
t = tt + 1;
if (t->rn_flags & RNF_ACTIVE) {
#ifndef RN_DEBUG
- *++x = *t; p = t->rn_p;
+ *++x = *t;
+ p = t->rn_p;
#else
- b = t->rn_info; *++x = *t; t->rn_info = b; p = t->rn_p;
+ b = t->rn_info;
+ *++x = *t;
+ t->rn_info = b;
+ p = t->rn_p;
#endif
- if (p->rn_l == t) p->rn_l = x; else p->rn_r = x;
- x->rn_l->rn_p = x; x->rn_r->rn_p = x;
+ if (p->rn_l == t)
+ p->rn_l = x;
+ else
+ p->rn_r = x;
+ x->rn_l->rn_p = x;
+ x->rn_r->rn_p = x;
}
goto out;
}
- if (t->rn_l == tt) x = t->rn_r; else x = t->rn_l;
+ if (t->rn_l == tt)
+ x = t->rn_r;
+ else
+ x = t->rn_l;
p = t->rn_p;
- if (p->rn_r == t) p->rn_r = x; else p->rn_l = x;
+ if (p->rn_r == t)
+ p->rn_r = x;
+ else
+ p->rn_l = x;
x->rn_p = p;
/*
* Demote routes attached to us.
*/
if (t->rn_mklist) {
if (x->rn_b >= 0) {
- for (mp = &x->rn_mklist; ((m = *mp) != NULL);)
+ for (mp = &x->rn_mklist; (m = *mp) != NULL;)
mp = &m->rm_mklist;
*mp = t->rn_mklist;
} else {
@@ -851,11 +928,17 @@ on1:
#ifndef RN_DEBUG
*t = *x;
#else
- b = t->rn_info; *t = *x; t->rn_info = b;
+ b = t->rn_info;
+ *t = *x;
+ t->rn_info = b;
#endif
- t->rn_l->rn_p = t; t->rn_r->rn_p = t;
+ t->rn_l->rn_p = t;
+ t->rn_r->rn_p = t;
p = x->rn_p;
- if (p->rn_l == x) p->rn_l = t; else p->rn_r = t;
+ if (p->rn_l == x)
+ p->rn_l = t;
+ else
+ p->rn_r = t;
}
out:
tt->rn_flags &= ~RNF_ACTIVE;
@@ -892,7 +975,8 @@ rn_walktree(h, f, w)
/* Process leaves */
while ((rn = base) != NULL) {
base = rn->rn_dupedkey;
- if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w)))
+ if (!(rn->rn_flags & RNF_ROOT)
+ && (error = (*f)(rn, w)))
return (error);
}
rn = next;
@@ -902,7 +986,6 @@ rn_walktree(h, f, w)
/* NOTREACHED */
}
-
int
rn_inithead(head, off)
void **head;
@@ -967,7 +1050,7 @@ rn_init()
addmask_key = cplim = rn_ones + max_keylen;
while (cp < cplim)
*cp++ = -1;
- if (rn_inithead((void **)&mask_rnhead, 0) == 0)
+ if (rn_inithead((void *)&mask_rnhead, 0) == 0)
panic("rn_init 2");
}
@@ -988,7 +1071,7 @@ rn_freenode(struct radix_node *n, void *p)
void
rn_freehead(rnh)
- struct radix_node_head *rnh;
+ struct radix_node_head *rnh;
{
(void)rn_walktree(rnh, rn_freenode, rnh);
@@ -1013,7 +1096,6 @@ rn_fini()
rn_zeros = NULL;
}
-
if (mask_rnhead != NULL) {
rn_freehead(mask_rnhead);
mask_rnhead = NULL;
@@ -1039,7 +1121,7 @@ main(int argc, char *argv[])
{
struct radix_node_head *rnh;
struct radix_node *rn;
- addrfamily_t af;
+ addrfamily_t af, mf;
myst_t st1, st2, *stp;
memset(&st1, 0, sizeof(st1));
@@ -1069,7 +1151,18 @@ main(int argc, char *argv[])
af.adf_addr.in4.s_addr = inet_addr("127.0.1.0");
rn = rnh->rnh_matchaddr(&af, rnh);
if (rn != NULL) {
- printf("lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
+ printf("1.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
+ stp = rn->rn_key;
+ printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
+ stp = rn->rn_mask;
+ printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4));
+ }
+
+ mf.adf_len = sizeof(mf);
+ mf.adf_addr.in4.s_addr = inet_addr("255.255.255.0");
+ rn = rnh->rnh_lookup(&af, &mf, rnh);
+ if (rn != NULL) {
+ printf("2.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
stp = rn->rn_key;
printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
stp = rn->rn_mask;
@@ -1080,7 +1173,7 @@ main(int argc, char *argv[])
af.adf_addr.in4.s_addr = inet_addr("126.0.0.1");
rn = rnh->rnh_matchaddr(&af, rnh);
if (rn != NULL) {
- printf("lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
+ printf("3.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
stp = rn->rn_key;
printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
stp = rn->rn_mask;
diff --git a/usr/src/common/ipf/radix.h b/usr/src/uts/common/inet/ipf/radix.h
index 0b55412605..0b55412605 100644
--- a/usr/src/common/ipf/radix.h
+++ b/usr/src/uts/common/inet/ipf/radix.h
diff --git a/usr/src/uts/common/inet/ipf/radix_ipf.h b/usr/src/uts/common/inet/ipf/radix_ipf.h
new file mode 100644
index 0000000000..357b9c40dc
--- /dev/null
+++ b/usr/src/uts/common/inet/ipf/radix_ipf.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 1988, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)radix.h 8.2 (Berkeley) 10/31/94
+ */
+
+#if !defined(_NET_RADIX_H_) && !defined(_RADIX_H_)
+#define _NET_RADIX_H_
+#ifndef _RADIX_H_
+#define _RADIX_H_
+#endif /* _RADIX_H_ */
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+#if defined(__sgi)
+# define radix_mask ipf_radix_mask
+# define radix_node ipf_radix_node
+# define radix_node_head ipf_radix_node_head
+#endif
+
+/*
+ * Radix search tree node layout.
+ */
+
+struct radix_node {
+ struct radix_mask *rn_mklist; /* list of masks contained in subtree */
+ struct radix_node *rn_p; /* parent */
+ short rn_b; /* bit offset; -1-index(netmask) */
+ char rn_bmask; /* node: mask for bit test*/
+ u_char rn_flags; /* enumerated next */
+#define RNF_NORMAL 1 /* leaf contains normal route */
+#define RNF_ROOT 2 /* leaf is root leaf for tree */
+#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */
+ union {
+ struct { /* leaf only data: */
+ caddr_t rn_Key; /* object of search */
+ caddr_t rn_Mask; /* netmask, if present */
+ struct radix_node *rn_Dupedkey;
+ } rn_leaf;
+ struct { /* node only data: */
+ int rn_Off; /* where to start compare */
+ struct radix_node *rn_L;/* progeny */
+ struct radix_node *rn_R;/* progeny */
+ } rn_node;
+ } rn_u;
+#ifdef RN_DEBUG
+ int rn_info;
+ struct radix_node *rn_twin;
+ struct radix_node *rn_ybro;
+#endif
+};
+
+#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
+#define rn_key rn_u.rn_leaf.rn_Key
+#define rn_mask rn_u.rn_leaf.rn_Mask
+#define rn_off rn_u.rn_node.rn_Off
+#define rn_l rn_u.rn_node.rn_L
+#define rn_r rn_u.rn_node.rn_R
+
+/*
+ * Annotations to tree concerning potential routes applying to subtrees.
+ */
+
+struct radix_mask {
+ short rm_b; /* bit offset; -1-index(netmask) */
+ char rm_unused; /* cf. rn_bmask */
+ u_char rm_flags; /* cf. rn_flags */
+ struct radix_mask *rm_mklist; /* more masks to try */
+ union {
+ caddr_t rmu_mask; /* the mask */
+ struct radix_node *rmu_leaf; /* for normal routes */
+ } rm_rmu;
+ int rm_refs; /* # of references to this struct */
+};
+
+#define rm_mask rm_rmu.rmu_mask
+#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */
+
+#define MKGet(m) {\
+ if (rn_mkfreelist) {\
+ m = rn_mkfreelist; \
+ rn_mkfreelist = (m)->rm_mklist; \
+ } else \
+ R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\
+
+#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
+
+struct radix_node_head {
+ struct radix_node *rnh_treetop;
+ struct radix_node *rnh_leaflist;
+ u_long rnh_hits;
+ u_int rnh_number;
+ u_int rnh_ref;
+ int rnh_addrsize; /* permit, but not require fixed keys */
+ int rnh_pktsize; /* permit, but not require fixed keys */
+ struct radix_node *(*rnh_addaddr) /* add based on sockaddr */
+ __P((void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]));
+ struct radix_node *(*rnh_addpkt) /* add based on packet hdr */
+ __P((void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]));
+ struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */
+ __P((void *v, struct radix_node_head *head));
+ struct radix_node *(*rnh_lookup) /* locate based on sockaddr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */
+ __P((void *v, struct radix_node_head *head));
+ int (*rnh_walktree) /* traverse tree */
+ __P((struct radix_node_head *,
+ int (*)(struct radix_node *, void *), void *));
+ struct radix_node rnh_nodes[3]; /* empty tree for common case */
+};
+
+
+#if defined(AIX)
+# undef Bcmp
+# undef Bzero
+# undef R_Malloc
+# undef Free
+#endif
+#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#if defined(linux) && defined(_KERNEL)
+# define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
+#else
+# define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#endif
+#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n));
+#define R_Malloc(p, t, n) KMALLOCS(p, t, n)
+#define FreeS(p, z) KFREES(p, z)
+#define Free(p) KFREE(p)
+
+#if (defined(__osf__) || defined(AIX) || (IRIX >= 60516)) && defined(_KERNEL)
+# define rn_init ipf_rn_init
+# define rn_fini ipf_rn_fini
+# define rn_inithead ipf_rn_inithead
+# define rn_freehead ipf_rn_freehead
+# define rn_inithead0 ipf_rn_inithead0
+# define rn_refines ipf_rn_refines
+# define rn_walktree ipf_rn_walktree
+# define rn_addmask ipf_rn_addmask
+# define rn_addroute ipf_rn_addroute
+# define rn_delete ipf_rn_delete
+# define rn_insert ipf_rn_insert
+# define rn_lookup ipf_rn_lookup
+# define rn_match ipf_rn_match
+# define rn_newpair ipf_rn_newpair
+# define rn_search ipf_rn_search
+# define rn_search_m ipf_rn_search_m
+# define max_keylen ipf_maxkeylen
+# define rn_mkfreelist ipf_rn_mkfreelist
+# define rn_zeros ipf_rn_zeros
+# define rn_ones ipf_rn_ones
+# define rn_satisfies_leaf ipf_rn_satisfies_leaf
+# define rn_lexobetter ipf_rn_lexobetter
+# define rn_new_radix_mask ipf_rn_new_radix_mask
+# define rn_freenode ipf_rn_freenode
+#endif
+
+void rn_init __P((void));
+void rn_fini __P((void));
+int rn_inithead __P((void **, int));
+void rn_freehead __P((struct radix_node_head *));
+int rn_inithead0 __P((struct radix_node_head *, int));
+int rn_refines __P((void *, void *));
+int rn_walktree __P((struct radix_node_head *,
+ int (*)(struct radix_node *, void *), void *));
+struct radix_node
+ *rn_addmask __P((void *, int, int)),
+ *rn_addroute __P((void *, void *, struct radix_node_head *,
+ struct radix_node [2])),
+ *rn_delete __P((void *, void *, struct radix_node_head *)),
+ *rn_insert __P((void *, struct radix_node_head *, int *,
+ struct radix_node [2])),
+ *rn_lookup __P((void *, void *, struct radix_node_head *)),
+ *rn_match __P((void *, struct radix_node_head *)),
+ *rn_newpair __P((void *, int, struct radix_node[2])),
+ *rn_search __P((void *, struct radix_node *)),
+ *rn_search_m __P((void *, struct radix_node *, void *));
+
+#endif /* _NET_RADIX_H_ */
diff --git a/usr/src/uts/common/inet/ipf/solaris.c b/usr/src/uts/common/inet/ipf/solaris.c
new file mode 100644
index 0000000000..0c21d1f15f
--- /dev/null
+++ b/usr/src/uts/common/inet/ipf/solaris.c
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 1993-2001, 2003 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/
+#pragma ident "@(#)$Id: solaris.c,v 2.73.2.6 2005/07/13 21:40:47 darrenr Exp $"
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/modctl.h>
+#include <sys/open.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/cred.h>
+#include <sys/dditypes.h>
+#include <sys/stream.h>
+#include <sys/poll.h>
+#include <sys/autoconf.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/dlpi.h>
+#include <sys/stropts.h>
+#include <sys/kstat.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#if SOLARIS2 >= 6
+# include <net/if_types.h>
+#endif
+#include <net/af.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/tcpip.h>
+#include <netinet/ip_icmp.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include "netinet/ip_compat.h"
+#include "netinet/ipl.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_auth.h"
+#include "netinet/ip_state.h"
+
+
+extern struct filterstats frstats[];
+extern int fr_running;
+extern int fr_flags;
+extern int iplwrite __P((dev_t, struct uio *, cred_t *));
+
+extern ipnat_t *nat_list;
+
+static int ipf_getinfo __P((dev_info_t *, ddi_info_cmd_t,
+ void *, void **));
+#if SOLARIS2 < 10
+static int ipf_identify __P((dev_info_t *));
+#endif
+static int ipf_attach __P((dev_info_t *, ddi_attach_cmd_t));
+static int ipf_detach __P((dev_info_t *, ddi_detach_cmd_t));
+static int fr_qifsync __P((ip_t *, int, void *, int, void *, mblk_t **));
+static int ipf_property_update __P((dev_info_t *));
+static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
+ IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
+ IPLOOKUP_NAME, NULL };
+
+
+#if SOLARIS2 >= 7
+extern timeout_id_t fr_timer_id;
+#else
+extern int fr_timer_id;
+#endif
+
+static struct cb_ops ipf_cb_ops = {
+ iplopen,
+ iplclose,
+ nodev, /* strategy */
+ nodev, /* print */
+ nodev, /* dump */
+ iplread,
+ iplwrite, /* write */
+ iplioctl, /* ioctl */
+ nodev, /* devmap */
+ nodev, /* mmap */
+ nodev, /* segmap */
+ nochpoll, /* poll */
+ ddi_prop_op,
+ NULL,
+ D_MTSAFE,
+#if SOLARIS2 > 4
+ CB_REV,
+ nodev, /* aread */
+ nodev, /* awrite */
+#endif
+};
+
+static struct dev_ops ipf_ops = {
+ DEVO_REV,
+ 0,
+ ipf_getinfo,
+#if SOLARIS2 >= 10
+ nulldev,
+#else
+ ipf_identify,
+#endif
+ nulldev,
+ ipf_attach,
+ ipf_detach,
+ nodev, /* reset */
+ &ipf_cb_ops,
+ (struct bus_ops *)0
+};
+
+extern struct mod_ops mod_driverops;
+static struct modldrv iplmod = {
+ &mod_driverops, IPL_VERSION, &ipf_ops };
+static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL };
+
+#if SOLARIS2 >= 6
+static size_t hdrsizes[57][2] = {
+ { 0, 0 },
+ { IFT_OTHER, 0 },
+ { IFT_1822, 0 },
+ { IFT_HDH1822, 0 },
+ { IFT_X25DDN, 0 },
+ { IFT_X25, 0 },
+ { IFT_ETHER, 14 },
+ { IFT_ISO88023, 0 },
+ { IFT_ISO88024, 0 },
+ { IFT_ISO88025, 0 },
+ { IFT_ISO88026, 0 },
+ { IFT_STARLAN, 0 },
+ { IFT_P10, 0 },
+ { IFT_P80, 0 },
+ { IFT_HY, 0 },
+ { IFT_FDDI, 24 },
+ { IFT_LAPB, 0 },
+ { IFT_SDLC, 0 },
+ { IFT_T1, 0 },
+ { IFT_CEPT, 0 },
+ { IFT_ISDNBASIC, 0 },
+ { IFT_ISDNPRIMARY, 0 },
+ { IFT_PTPSERIAL, 0 },
+ { IFT_PPP, 0 },
+ { IFT_LOOP, 0 },
+ { IFT_EON, 0 },
+ { IFT_XETHER, 0 },
+ { IFT_NSIP, 0 },
+ { IFT_SLIP, 0 },
+ { IFT_ULTRA, 0 },
+ { IFT_DS3, 0 },
+ { IFT_SIP, 0 },
+ { IFT_FRELAY, 0 },
+ { IFT_RS232, 0 },
+ { IFT_PARA, 0 },
+ { IFT_ARCNET, 0 },
+ { IFT_ARCNETPLUS, 0 },
+ { IFT_ATM, 0 },
+ { IFT_MIOX25, 0 },
+ { IFT_SONET, 0 },
+ { IFT_X25PLE, 0 },
+ { IFT_ISO88022LLC, 0 },
+ { IFT_LOCALTALK, 0 },
+ { IFT_SMDSDXI, 0 },
+ { IFT_FRELAYDCE, 0 },
+ { IFT_V35, 0 },
+ { IFT_HSSI, 0 },
+ { IFT_HIPPI, 0 },
+ { IFT_MODEM, 0 },
+ { IFT_AAL5, 0 },
+ { IFT_SONETPATH, 0 },
+ { IFT_SONETVT, 0 },
+ { IFT_SMDSICIP, 0 },
+ { IFT_PROPVIRTUAL, 0 },
+ { IFT_PROPMUX, 0 },
+};
+#endif /* SOLARIS2 >= 6 */
+
+static dev_info_t *ipf_dev_info = NULL;
+
+static const filter_kstats_t ipf_kstat_tmp = {
+ { "pass", KSTAT_DATA_ULONG },
+ { "block", KSTAT_DATA_ULONG },
+ { "nomatch", KSTAT_DATA_ULONG },
+ { "short", KSTAT_DATA_ULONG },
+ { "pass, logged", KSTAT_DATA_ULONG },
+ { "block, logged", KSTAT_DATA_ULONG },
+ { "nomatch, logged", KSTAT_DATA_ULONG },
+ { "logged", KSTAT_DATA_ULONG },
+ { "skip", KSTAT_DATA_ULONG },
+ { "return sent", KSTAT_DATA_ULONG },
+ { "acct", KSTAT_DATA_ULONG },
+ { "bad frag state alloc", KSTAT_DATA_ULONG },
+ { "new frag state kept", KSTAT_DATA_ULONG },
+ { "new frag state compl. pkt", KSTAT_DATA_ULONG },
+ { "bad pkt state alloc", KSTAT_DATA_ULONG },
+ { "new pkt kept state", KSTAT_DATA_ULONG },
+ { "cachehit", KSTAT_DATA_ULONG },
+ { "tcp cksum bad", KSTAT_DATA_ULONG },
+ {{ "pullup ok", KSTAT_DATA_ULONG },
+ { "pullup nok", KSTAT_DATA_ULONG }},
+ { "src != route", KSTAT_DATA_ULONG },
+ { "ttl invalid", KSTAT_DATA_ULONG },
+ { "bad ip pkt", KSTAT_DATA_ULONG },
+ { "ipv6 pkt", KSTAT_DATA_ULONG },
+ { "dropped:pps ceiling", KSTAT_DATA_ULONG },
+ { "ip upd. fail", KSTAT_DATA_ULONG }
+};
+
+kstat_t *ipf_kstatp[2] = {NULL, NULL};
+static int ipf_kstat_update(kstat_t *ksp, int rwflag);
+
+static void
+ipf_kstat_init(void)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ ipf_kstatp[i] = kstat_create("ipf", 0,
+ (i==0)?"inbound":"outbound",
+ "net",
+ KSTAT_TYPE_NAMED,
+ sizeof (filter_kstats_t) / sizeof (kstat_named_t),
+ 0);
+ if (ipf_kstatp[i] != NULL) {
+ bcopy(&ipf_kstat_tmp, ipf_kstatp[i]->ks_data,
+ sizeof (filter_kstats_t));
+ ipf_kstatp[i]->ks_update = ipf_kstat_update;
+ ipf_kstatp[i]->ks_private = &frstats[i];
+ kstat_install(ipf_kstatp[i]);
+ }
+ }
+
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: ipf_kstat_init() installed 0x%x, 0x%x",
+ ipf_kstatp[0], ipf_kstatp[1]);
+#endif
+}
+
+static void
+ipf_kstat_fini(void)
+{
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (ipf_kstatp[i] != NULL) {
+ kstat_delete(ipf_kstatp[i]);
+ ipf_kstatp[i] = NULL;
+ }
+ }
+}
+
+static int
+ipf_kstat_update(kstat_t *ksp, int rwflag)
+{
+ filter_kstats_t *fkp;
+ filterstats_t *fsp;
+
+ if (rwflag == KSTAT_WRITE)
+ return (EACCES);
+
+ fkp = ksp->ks_data;
+ fsp = ksp->ks_private;
+
+ fkp->fks_pass.value.ul = fsp->fr_pass;
+ fkp->fks_block.value.ul = fsp->fr_block;
+ fkp->fks_nom.value.ul = fsp->fr_nom;
+ fkp->fks_short.value.ul = fsp->fr_short;
+ fkp->fks_ppkl.value.ul = fsp->fr_ppkl;
+ fkp->fks_bpkl.value.ul = fsp->fr_bpkl;
+ fkp->fks_npkl.value.ul = fsp->fr_npkl;
+ fkp->fks_pkl.value.ul = fsp->fr_pkl;
+ fkp->fks_skip.value.ul = fsp->fr_skip;
+ fkp->fks_ret.value.ul = fsp->fr_ret;
+ fkp->fks_acct.value.ul = fsp->fr_acct;
+ fkp->fks_bnfr.value.ul = fsp->fr_bnfr;
+ fkp->fks_nfr.value.ul = fsp->fr_nfr;
+ fkp->fks_cfr.value.ul = fsp->fr_cfr;
+ fkp->fks_bads.value.ul = fsp->fr_bads;
+ fkp->fks_ads.value.ul = fsp->fr_ads;
+ fkp->fks_chit.value.ul = fsp->fr_chit;
+ fkp->fks_tcpbad.value.ul = fsp->fr_tcpbad;
+ fkp->fks_pull[0].value.ul = fsp->fr_pull[0];
+ fkp->fks_pull[1].value.ul = fsp->fr_pull[1];
+ fkp->fks_badsrc.value.ul = fsp->fr_badsrc;
+ fkp->fks_badttl.value.ul = fsp->fr_badttl;
+ fkp->fks_bad.value.ul = fsp->fr_bad;
+ fkp->fks_ipv6.value.ul = fsp->fr_ipv6;
+ fkp->fks_ppshit.value.ul = fsp->fr_ppshit;
+ fkp->fks_ipud.value.ul = fsp->fr_ipud;
+
+ return (0);
+}
+
+int _init()
+{
+ int ipfinst;
+
+ ipf_kstat_init();
+ ipfinst = mod_install(&modlink1);
+ if (ipfinst != 0)
+ ipf_kstat_fini();
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
+#endif
+ return ipfinst;
+}
+
+
+int _fini(void)
+{
+ int ipfinst;
+
+ ipfinst = mod_remove(&modlink1);
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
+#endif
+ if (ipfinst == 0)
+ ipf_kstat_fini();
+ return ipfinst;
+}
+
+
+int _info(modinfop)
+struct modinfo *modinfop;
+{
+ int ipfinst;
+
+ ipfinst = mod_info(&modlink1, modinfop);
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x", modinfop, ipfinst);
+#endif
+ return ipfinst;
+}
+
+
+#if SOLARIS2 < 10
+static int ipf_identify(dip)
+dev_info_t *dip;
+{
+# ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
+# endif
+ if (strcmp(ddi_get_name(dip), "ipf") == 0)
+ return (DDI_IDENTIFIED);
+ return (DDI_NOT_IDENTIFIED);
+}
+#endif
+
+
+static int ipf_attach(dip, cmd)
+dev_info_t *dip;
+ddi_attach_cmd_t cmd;
+{
+ char *s;
+ int i;
+ int instance;
+
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
+#endif
+
+ if ((pfilinterface != PFIL_INTERFACE) || (PFIL_INTERFACE < 2000000)) {
+ cmn_err(CE_NOTE, "pfilinterface(%d) != %d\n", pfilinterface,
+ PFIL_INTERFACE);
+ return EINVAL;
+ }
+
+ switch (cmd)
+ {
+ case DDI_ATTACH:
+ instance = ddi_get_instance(dip);
+ /* Only one instance of ipf (instance 0) can be attached. */
+ if (instance > 0)
+ return DDI_FAILURE;
+ if (fr_running != 0)
+ return DDI_FAILURE;
+
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: attach ipf instance %d", instance);
+#endif
+
+ (void) ipf_property_update(dip);
+
+ for (i = 0; ((s = ipf_devfiles[i]) != NULL); i++) {
+ s = strrchr(s, '/');
+ if (s == NULL)
+ continue;
+ s++;
+ if (ddi_create_minor_node(dip, s, S_IFCHR, i,
+ DDI_PSEUDO, 0) ==
+ DDI_FAILURE) {
+ ddi_remove_minor_node(dip, NULL);
+ goto attach_failed;
+ }
+ }
+
+ ipf_dev_info = dip;
+ /*
+ * Initialize mutex's
+ */
+ RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
+ RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
+ RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
+
+ /*
+ * Lock people out while we set things up.
+ */
+ WRITE_ENTER(&ipf_global);
+ if ((fr_running != 0) || (iplattach() == -1)) {
+ RWLOCK_EXIT(&ipf_global);
+ goto attach_failed;
+ }
+
+ if (pfil_add_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet4))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_inet4) failed",
+ "pfil_add_hook");
+#ifdef USE_INET6
+ if (pfil_add_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet6))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_inet6) failed",
+ "pfil_add_hook");
+#endif
+ if (pfil_add_hook(fr_qifsync, PFIL_IN|PFIL_OUT, &pfh_sync))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_sync) failed",
+ "pfil_add_hook");
+
+ fr_timer_id = timeout(fr_slowtimer, NULL,
+ drv_usectohz(500000));
+
+ fr_running = 1;
+
+ RWLOCK_EXIT(&ipf_global);
+
+ cmn_err(CE_CONT, "!%s, running.\n", ipfilter_version);
+
+ return DDI_SUCCESS;
+ /* NOTREACHED */
+ default:
+ break;
+ }
+
+attach_failed:
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: failed to attach\n");
+#endif
+ /*
+ * Use our own detach routine to toss
+ * away any stuff we allocated above.
+ */
+ (void) ipf_detach(dip, DDI_DETACH);
+ return DDI_FAILURE;
+}
+
+
+static int ipf_detach(dip, cmd)
+dev_info_t *dip;
+ddi_detach_cmd_t cmd;
+{
+ int i;
+
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
+#endif
+ switch (cmd) {
+ case DDI_DETACH:
+ if (fr_refcnt != 0)
+ return DDI_FAILURE;
+
+ if (fr_running == -2 || fr_running == 0)
+ break;
+ /*
+ * Make sure we're the only one's modifying things. With
+ * this lock others should just fall out of the loop.
+ */
+ WRITE_ENTER(&ipf_global);
+ if (fr_running <= 0) {
+ RWLOCK_EXIT(&ipf_global);
+ return DDI_FAILURE;
+ }
+ fr_running = -2;
+
+ if (pfil_remove_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet4))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_inet4) failed",
+ "pfil_remove_hook");
+#ifdef USE_INET6
+ if (pfil_remove_hook(fr_check, PFIL_IN|PFIL_OUT, &pfh_inet6))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_inet6) failed",
+ "pfil_add_hook");
+#endif
+ if (pfil_remove_hook(fr_qifsync, PFIL_IN|PFIL_OUT, &pfh_sync))
+ cmn_err(CE_WARN, "IP Filter: %s(pfh_sync) failed",
+ "pfil_remove_hook");
+
+ RWLOCK_EXIT(&ipf_global);
+
+ if (fr_timer_id != 0) {
+ (void) untimeout(fr_timer_id);
+ fr_timer_id = 0;
+ }
+
+ /*
+ * Undo what we did in ipf_attach, freeing resources
+ * and removing things we installed. The system
+ * framework guarantees we are not active with this devinfo
+ * node in any other entry points at this time.
+ */
+ ddi_prop_remove_all(dip);
+ i = ddi_get_instance(dip);
+ ddi_remove_minor_node(dip, NULL);
+ if (i > 0) {
+ cmn_err(CE_CONT, "IP Filter: still attached (%d)\n", i);
+ return DDI_FAILURE;
+ }
+
+ WRITE_ENTER(&ipf_global);
+ if (!ipldetach()) {
+ RWLOCK_EXIT(&ipf_global);
+ RW_DESTROY(&ipf_mutex);
+ RW_DESTROY(&ipf_frcache);
+ RW_DESTROY(&ipf_global);
+ cmn_err(CE_CONT, "!%s detached.\n", ipfilter_version);
+ return (DDI_SUCCESS);
+ }
+ RWLOCK_EXIT(&ipf_global);
+ break;
+ default:
+ break;
+ }
+ cmn_err(CE_NOTE, "IP Filter: failed to detach\n");
+ return DDI_FAILURE;
+}
+
+
+/*ARGSUSED*/
+static int ipf_getinfo(dip, infocmd, arg, result)
+dev_info_t *dip;
+ddi_info_cmd_t infocmd;
+void *arg, **result;
+{
+ int error;
+
+ if (fr_running <= 0)
+ return DDI_FAILURE;
+ error = DDI_FAILURE;
+#ifdef IPFDEBUG
+ cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)", dip, infocmd, arg);
+#endif
+ switch (infocmd) {
+ case DDI_INFO_DEVT2DEVINFO:
+ *result = ipf_dev_info;
+ error = DDI_SUCCESS;
+ break;
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = (void *)0;
+ error = DDI_SUCCESS;
+ break;
+ default:
+ break;
+ }
+ return (error);
+}
+
+
+/*
+ * look for bad consistancies between the list of interfaces the filter knows
+ * about and those which are currently configured.
+ */
+/*ARGSUSED*/
+static int fr_qifsync(ip, hlen, il, out, qif, mp)
+ip_t *ip;
+int hlen;
+void *il;
+int out;
+void *qif;
+mblk_t **mp;
+{
+
+ frsync(qif);
+ /*
+ * Resync. any NAT `connections' using this interface and its IP #.
+ */
+ fr_natsync(qif);
+ fr_statesync(qif);
+ return 0;
+}
+
+
+/*
+ * look for bad consistancies between the list of interfaces the filter knows
+ * about and those which are currently configured.
+ */
+int ipfsync()
+{
+ frsync(NULL);
+ return 0;
+}
+
+
+/*
+ * Fetch configuration file values that have been entered into the ipf.conf
+ * driver file.
+ */
+static int ipf_property_update(dip)
+dev_info_t *dip;
+{
+ ipftuneable_t *ipft;
+ int64_t *i64p;
+ char *name;
+ u_int one;
+ int *i32p;
+ int err;
+
+#ifdef DDI_NO_AUTODETACH
+ if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
+ DDI_NO_AUTODETACH, 1) != DDI_PROP_SUCCESS) {
+ cmn_err(CE_WARN, "!updating DDI_NO_AUTODETACH failed");
+ return DDI_FAILURE;
+ }
+#else
+ if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
+ "ddi-no-autodetach", 1) != DDI_PROP_SUCCESS) {
+ cmn_err(CE_WARN, "!updating ddi-no-autodetach failed");
+ return DDI_FAILURE;
+ }
+#endif
+
+ err = DDI_SUCCESS;
+ ipft = ipf_tuneables;
+ for (ipft = ipf_tuneables; (name = ipft->ipft_name) != NULL; ipft++) {
+ one = 1;
+ switch (ipft->ipft_sz)
+ {
+ case 4 :
+ i32p = NULL;
+ err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
+ 0, name, &i32p, &one);
+ if (err == DDI_PROP_NOT_FOUND)
+ continue;
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "IP Filter: lookup_int(%s) = %d\n",
+ name, err);
+#endif
+ if (err != DDI_PROP_SUCCESS)
+ return err;
+ if (*i32p >= ipft->ipft_min && *i32p <= ipft->ipft_max)
+ *ipft->ipft_pint = *i32p;
+ else
+ err = DDI_PROP_CANNOT_DECODE;
+ ddi_prop_free(i32p);
+ break;
+
+#if SOLARIS2 > 8
+ case 8 :
+ i64p = NULL;
+ err = ddi_prop_lookup_int64_array(DDI_DEV_T_ANY, dip,
+ 0, name, &i64p, &one);
+ if (err == DDI_PROP_NOT_FOUND)
+ continue;
+# ifdef IPFDEBUG
+ cmn_err(CE_CONT, "IP Filter: lookup_int64(%s) = %d\n",
+ name, err);
+# endif
+ if (err != DDI_PROP_SUCCESS)
+ return err;
+ if (*i64p >= ipft->ipft_min && *i64p <= ipft->ipft_max)
+ *ipft->ipft_pint = *i64p;
+ else
+ err = DDI_PROP_CANNOT_DECODE;
+ ddi_prop_free(i64p);
+ break;
+#endif
+
+ default :
+ break;
+ }
+ if (err != DDI_SUCCESS)
+ break;
+ }
+
+ return err;
+}
diff --git a/usr/src/uts/common/inet/ipf/compat.h b/usr/src/uts/common/inet/pfil/compat.h
index 776dd8d0c6..ddaa3354e2 100644
--- a/usr/src/uts/common/inet/ipf/compat.h
+++ b/usr/src/uts/common/inet/pfil/compat.h
@@ -3,7 +3,6 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-
#ifdef DEBUG
# define PFILDEBUG
#endif
@@ -42,3 +41,38 @@
# define ASSERT(x)
#endif
+/*
+ * The list of SAPs below all come from Sun's <atm/iftypes.h> file. It's not
+ * yet clear whether pfil should deal with any of these or not.
+ */
+#ifndef IFMP_SAP
+# define IFMP_SAP 0x0065
+#endif
+
+#ifndef LANER_SAP
+# define LANER_SAP 0x9999
+#endif
+
+#ifndef SNMP_SAP
+# define SNMP_SAP 0x999a
+#endif
+
+#ifndef ILMI_SAP
+# define ILMI_SAP 0x999b
+#endif
+
+#ifndef SIG_SAP
+# define SIG_SAP 0x999c
+#endif
+
+#ifndef Q93B_MGMT_SAP
+# define Q93B_MGMT_SAP 0x999d
+#endif
+
+#ifndef UTIL_SAP
+# define UTIL_SAP 0x999e
+#endif
+
+#ifndef ERROR_SAP
+# define ERROR_SAP 0x999f
+#endif
diff --git a/usr/src/uts/common/inet/ipf/misc.c b/usr/src/uts/common/inet/pfil/misc.c
index b65ca63837..2a8c84dd4c 100644
--- a/usr/src/uts/common/inet/ipf/misc.c
+++ b/usr/src/uts/common/inet/pfil/misc.c
@@ -1,8 +1,10 @@
/*
- * Copyright (C) 2000 by Darren Reed.
+ * Copyright (C) 2003 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
#ifndef __hpux
-#pragma ident "@(#)$Id: misc.c,v 1.9 2003/07/20 15:36:27 darrenr Exp $"
+#pragma ident "@(#)$Id: misc.c,v 1.12 2003/11/29 07:11:03 darrenr Exp $"
#else
struct uio;
#endif
diff --git a/usr/src/uts/common/inet/ipf/ndd.c b/usr/src/uts/common/inet/pfil/ndd.c
index c733a1d162..ce85cc0091 100644
--- a/usr/src/uts/common/inet/ipf/ndd.c
+++ b/usr/src/uts/common/inet/pfil/ndd.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,13 +30,15 @@ static int qif_report(queue_t *, mblk_t *, caddr_t);
static int sill_report(queue_t *, mblk_t *, caddr_t);
static int qif_ipmp_report(queue_t *, mblk_t *, caddr_t);
static int qif_ipmp_set(queue_t *, mblk_t *, char *, caddr_t);
+static int pfil_hl_set(queue_t *, mblk_t *, char *, caddr_t);
extern int pfil_report(queue_t *, mblk_t *, caddr_t);
#else
static int qif_report(queue_t *, mblk_t *, caddr_t, cred_t *);
static int sill_report(queue_t *, mblk_t *, caddr_t, cred_t *);
static int qif_ipmp_report(queue_t *, mblk_t *, caddr_t, cred_t *);
-static int qif_ipmp_set(queue_t *, mblk_t *, char *, caddr_t, cred_t *);
+static int qif_ipmp_set(queue_t *, mblk_t *, char *, caddr_t , cred_t *);
+static int pfil_hl_set(queue_t *, mblk_t *, char *, caddr_t , cred_t *);
extern int pfil_report(queue_t *, mblk_t *, caddr_t, cred_t *);
#endif
@@ -101,16 +103,24 @@ int pfil_nd_set(queue_t *q, mblk_t *mp, char *str, caddr_t ptr, cred_t *cred)
(void *)q, (void *)mp, str, (void *)str,
(void *)ptr));
+#if (SOLARIS2 >= 10)
if (ddi_strtol(str, &end, 10, &i) != 0)
return (EINVAL);
-
+#else
+ i = mi_strtol(str, &end, 10);
+#endif
+
if (ptr == (caddr_t)&pfildebug) {
#ifdef PFILDEBUG
+#if (SOLARIS2 >= 10)
if ((end == str) || (i < 0) || (i > 100))
+#else
+ if (i < 0 || i > 1)
+#endif
#endif
return EINVAL;
} else if (ptr == (caddr_t)&qif_verbose) {
- if (i < 0 || i > 1)
+ if ((end == str) || (i < 0) || (i > 1))
return EINVAL;
}
*((int *)ptr) = i;
@@ -122,7 +132,7 @@ int pfil_nd_set(queue_t *q, mblk_t *mp, char *str, caddr_t ptr, cred_t *cred)
/* ------------------------------------------------------------------------ */
/* Function: pfil_ioctl_nd */
-/* Returns: int - B_TRUE == success, B_FALSE == getset error */
+/* Returns: int - B_TRUE == success, B_FALSE == getset error */
/* Parameters: q(I) - pointer to queue */
/* mp(I) - pointer to mblk */
/* */
@@ -146,11 +156,13 @@ int pfil_ioctl_nd(queue_t *q, mblk_t *mp)
int pfil_nd_init()
{
+#ifdef PFILDEBUG
if (!nd_load(&pfil_nd, "pfildebug", pfil_nd_get, pfil_nd_set,
(caddr_t)&pfildebug)) {
nd_free(&pfil_nd);
return -1;
}
+#endif
if (!nd_load(&pfil_nd, "pfil_delayed_copy", pfil_nd_get, pfil_nd_set,
(caddr_t)&pfil_delayed_copy)) {
@@ -209,6 +221,11 @@ int pfil_nd_init()
return -1;
}
+ if (!nd_load(&pfil_nd, "pfil_hl", NULL, pfil_hl_set, NULL)) {
+ nd_free(&pfil_nd);
+ return -1;
+ }
+
return 0;
}
@@ -267,6 +284,7 @@ static int qif_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *cred)
}
+
/* ------------------------------------------------------------------------ */
/* Function: sill_report */
/* Returns: int */
@@ -303,6 +321,7 @@ static int sill_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *cred)
return 0;
}
+
/* ------------------------------------------------------------------------ */
/* Function: qif_ipmp_report */
/* Returns: int */
@@ -378,3 +397,46 @@ static int qif_ipmp_set(queue_t *q, mblk_t *mp, char *str, caddr_t ptr,
return 0;
}
+
+/* ------------------------------------------------------------------------ */
+/* Function: pfil_hl_set */
+/* Returns: int - 0 == success, > 0 error occurred */
+/* Parameters: q(I) - pointer to queue */
+/* mp(I) - pointer to mblk */
+/* str(I) - pointer to new value as a string */
+/* ptr(I) - pointer to value to be stored */
+/* cred(I) - pointer to credential information */
+/* */
+/* Explicitly set the header length (hl) field of the qif structure. This */
+/* is used in situations where pfil cannot, for some reason, automatically */
+/* determine it via either ioctl snooping or looking at passing messages. */
+/* ndd -set /dev/pfil pfil_hl ipmp0=14 or v4:ipmp0=14 */
+/* ------------------------------------------------------------------------ */
+#if !defined(sun) || SOLARIS2 <= 8
+/*ARGSUSED*/
+static int pfil_hl_set(queue_t *q, mblk_t *mp, char *str, caddr_t ptr)
+#else
+/*ARGSUSED*/
+static int pfil_hl_set(queue_t *q, mblk_t *mp, char *str, caddr_t ptr,
+ cred_t *cred)
+#endif
+{
+ char *s, *t;
+
+ /* LINTED: E_CONSTANT_CONDITION */
+ PRINT(2, (CE_CONT, "pfil_hl_set(0x%lx,0x%lx,0x%lx[%s],0x%lx)\n",
+ (u_long)q, (u_long)mp, (u_long)str, str, (u_long)ptr));
+
+ t = NULL;
+ s = str;
+ do {
+ if (t != NULL)
+ s = t + 1;
+ t = strchr(s, ';');
+ if (t != NULL)
+ *t = '\0';
+ qif_hl_set(s);
+ } while (t != NULL);
+
+ return 0;
+}
diff --git a/usr/src/uts/common/inet/ipf/os.h b/usr/src/uts/common/inet/pfil/os.h
index f0c8e7502a..b7a77e130e 100644
--- a/usr/src/uts/common/inet/ipf/os.h
+++ b/usr/src/uts/common/inet/pfil/os.h
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 2003 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
#include <sys/sunddi.h>
#include <sys/ddi.h>
#if SOLARIS2 >= 6
@@ -28,3 +33,8 @@
#define KMFREE(v, z) kmem_free(v, z)
extern caddr_t pfil_nd;
+
+#if defined(atomic_add_long) && (SOLARIS2 < 7)
+# undef atomic_add_long
+# define atomic_add_long(x,y) atomic_add_32((uint32_t *)x, y)
+#endif
diff --git a/usr/src/uts/common/inet/ipf/pfil.c b/usr/src/uts/common/inet/pfil/pfil.c
index a42055d693..d44f1ac5bc 100644
--- a/usr/src/uts/common/inet/ipf/pfil.c
+++ b/usr/src/uts/common/inet/pfil/pfil.c
@@ -3,12 +3,11 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * ident "@(#)$Id: pfil.c,v 1.22 2003/08/18 22:13:59 darrenr Exp $"
+ * ident "@(#)$Id: pfil.c,v 1.27 2003/11/30 09:45:57 darrenr Exp $"
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#ifndef __hpux
#pragma ident "%Z%%M% %I% %E% SMI"
#else
@@ -80,11 +79,11 @@ struct pfil_head pfh_sync;
static int pfil_list_add(pfil_list_t *,
int (*) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **)),
+ void *, mblk_t **)),
int);
static int pfil_list_remove(pfil_list_t *,
int (*) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **)));
+ void *, mblk_t **)));
/* ------------------------------------------------------------------------ */
@@ -116,14 +115,14 @@ int pfil_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *cred)
(void) mi_mpprintf(mp, "in");
(void) mi_mpprintf(mp, "function\tflags");
for (p = ph->ph_in.pfl_top; p; p = p->pfil_next)
- (void)mi_mpprintf(mp,"%p\t%x",
- (void *)p->pfil_func, p->pfil_flags);
+ (void) mi_mpprintf(mp,"%p\t%x",
+ (void *)p->pfil_func, p->pfil_flags);
(void) mi_mpprintf(mp, "out");
(void) mi_mpprintf(mp, "function\tflags");
for (p = ph->ph_out.pfl_top; p; p = p->pfil_next)
- (void)mi_mpprintf(mp,"%p\t%x",
- (void *)p->pfil_func, p->pfil_flags);
+ (void) mi_mpprintf(mp,"%p\t%x",
+ (void *)p->pfil_func, p->pfil_flags);
RW_EXIT(&ph->ph_lock);
@@ -176,7 +175,7 @@ pfil_init(ph)
int
pfil_add_hook(func, flags, ph)
int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **));
+ void *, mblk_t **));
int flags;
struct pfil_head *ph;
{
@@ -216,7 +215,7 @@ static int
pfil_list_add(list, func, flags)
pfil_list_t *list;
int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **));
+ void *, mblk_t **));
int flags;
{
struct packet_filter_hook *pfh;
@@ -270,7 +269,7 @@ pfil_list_add(list, func, flags)
int
pfil_remove_hook(func, flags, ph)
int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **));
+ void *, mblk_t **));
int flags;
struct pfil_head *ph;
{
@@ -309,7 +308,7 @@ static int
pfil_list_remove(list, func)
pfil_list_t *list;
int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **));
+ void *, mblk_t **));
{
struct packet_filter_hook *pfh;
diff --git a/usr/src/uts/common/inet/pfil/pfil.conf b/usr/src/uts/common/inet/pfil/pfil.conf
new file mode 100644
index 0000000000..1cf479a0d6
--- /dev/null
+++ b/usr/src/uts/common/inet/pfil/pfil.conf
@@ -0,0 +1,28 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+name="pfil" parent="pseudo" instance=0;
+
diff --git a/usr/src/uts/common/inet/ipf/pfil.h b/usr/src/uts/common/inet/pfil/pfil.h
index 9c3da19714..97f926da8b 100644
--- a/usr/src/uts/common/inet/ipf/pfil.h
+++ b/usr/src/uts/common/inet/pfil/pfil.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -12,8 +12,8 @@
#ifndef _NET_PFIL_H_
#define _NET_PFIL_H_
-#define PFIL_RELEASE "2.1.4"
-#define PFIL_VERSION 2010400
+#define PFIL_RELEASE "2.1.6"
+#define PFIL_VERSION 2010600
#define PFIL_INTERFACE 2000000
#ifndef __P
@@ -24,6 +24,7 @@
# endif
#endif
+#ifdef sun
# include <inet/ip.h>
# if SOLARIS2 < 9
# include <netinet/in_systm.h>
@@ -34,15 +35,19 @@
# undef IPOPT_SSRR
# include <netinet/ip.h>
# endif
+#endif
+#ifdef __hpux
+# include <netinet/in_systm.h>
+# include <netinet/in.h>
+# include <netinet/ip.h>
+#endif
-struct qif;
-struct ip;
typedef struct packet_filter_hook {
struct packet_filter_hook *pfil_next;
struct packet_filter_hook **pfil_pnext;
- int (*pfil_func) __P((struct ip *, int, void *, int, struct qif *,
- mblk_t **));
+ int (*pfil_func) __P((struct ip *, int, void *, int,
+ void *, mblk_t **));
int pfil_flags;
} packet_filter_hook_t;
@@ -82,12 +87,12 @@ typedef struct pfil_head {
void pfil_init __P((struct pfil_head *));
struct packet_filter_hook *pfil_hook_get __P((int, struct pfil_head *));
int pfil_add_hook __P((int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **)), int,
+ void *, mblk_t **)), int,
struct pfil_head *));
int pfil_remove_hook __P((int (*func) __P((struct ip *, int, void *, int,
- struct qif *, mblk_t **)), int,
+ void *, mblk_t **)), int,
struct pfil_head *));
-int pfil_sendbuf __P((mblk_t *));
+int pfil_sendbuf(mblk_t *);
mblk_t *pfil_make_dl_packet __P((mblk_t *, struct ip *, void *,
char *, queue_t **));
void pfil_send_dl_packet __P((queue_t *, mblk_t *));
@@ -103,8 +108,6 @@ extern struct pfil_head pfh_sync; /* Notification of interface */
extern krwlock_t qif_rwlock;
extern krwlock_t pfil_rw;
-extern u_int pfil_ip_csum_hdr __P((u_char *));
-
/*
* NOTE: On Solaris, even though pfilwput(), etc, are prototyped as returning
* an int, the return value is never checked and much code ignores it, anyway,
diff --git a/usr/src/common/ipf/pfild.h b/usr/src/uts/common/inet/pfil/pfild.h
index e866e514ae..e866e514ae 100644
--- a/usr/src/common/ipf/pfild.h
+++ b/usr/src/uts/common/inet/pfil/pfild.h
diff --git a/usr/src/uts/common/inet/ipf/pfildrv.c b/usr/src/uts/common/inet/pfil/pfildrv.c
index e787b5338e..45d694d304 100644
--- a/usr/src/uts/common/inet/ipf/pfildrv.c
+++ b/usr/src/uts/common/inet/pfil/pfildrv.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -11,6 +11,7 @@
#include <sys/conf.h>
#include <sys/debug.h>
+#include <sys/atomic.h>
#include <sys/ethernet.h>
#include <sys/stream.h>
#include <sys/errno.h>
@@ -97,6 +98,9 @@ struct streamtab pfil_dev_strtab = {
&pfil_rinit, &pfil_winit
};
+extern int nulldev();
+extern int nodev();
+
void pfil_donotip(int, qif_t *, queue_t *, mblk_t *, mblk_t *, struct ip *, size_t);
static int pfil_info(dev_info_t *, ddi_info_cmd_t , void *, void **);
static int pfil_attach(dev_info_t *, ddi_attach_cmd_t);
@@ -105,9 +109,48 @@ static int pfil_identify(dev_info_t *);
#endif
static int pfil_detach(dev_info_t *, ddi_detach_cmd_t);
+#ifdef DDI_DEFINE_STREAM_OPS
DDI_DEFINE_STREAM_OPS(pfil_devops, nulldev, nulldev, pfil_attach, pfil_detach,
nulldev, pfil_info, D_MP, &pfil_dev_strtab);
+#else
+static struct cb_ops pfil_ops = {
+ nodev, /* cb_open */
+ nodev, /* cb_close */
+ nodev, /* cb_strategy */
+ nodev, /* cb_print */
+ nodev, /* cb_dump */
+ nodev, /* cb_read */
+ nodev, /* cb_write */
+ nodev, /* cb_ioctl */
+ nodev, /* cb_devmap */
+ nodev, /* cb_mmap */
+ nodev, /* cb_segmap */
+ nochpoll, /* cb_chpoll */
+ ddi_prop_op, /* cb_prop_op */
+ &pfilinfo, /* cb_stream */
+ D_MP /* cb_flag */
+};
+
+static struct dev_ops pfil_devops =
+{
+ DEVO_REV, /* devo_rev */
+ 0, /* devo_refcnt */
+ pfil_info, /* devo_getinfo */
+#if SOLARIS2 >= 10
+ nulldev,
+#else
+ pfil_identify, /* devo_identify */
+#endif
+ nulldev, /* devo_probe */
+ pfil_attach, /* devo_attach */
+ pfil_detach, /* devo_detach */
+ nodev, /* devo_reset */
+ &pfil_ops, /* devo_cb_ops */
+ NULL /* devo_bus_ops */
+};
+#endif
+
static struct modldrv modldrv = {
&mod_driverops, "pfil Streams driver "/**/PFIL_RELEASE, &pfil_devops
};
@@ -115,9 +158,8 @@ static struct modldrv modldrv = {
/************************************************************************
* STREAMS module information
*/
-static int pfilmodopen(queue_t *q, dev_t *devp, int flag, int sflag,
- cred_t *crp);
-static int pfilmodclose(queue_t *q, int flag, cred_t *crp);
+static int pfilmodopen(queue_t *, dev_t *, int, int, cred_t *);
+static int pfilmodclose(queue_t *, int, cred_t *);
static struct qinit pfilmod_rinit = {
(pfi_t)pfilmodrput, NULL, pfilmodopen, pfilmodclose,
@@ -174,7 +216,11 @@ static int pfil_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
pfil_dev_info = devi;
+#if SOLARIS2 >= 8
return (ddi_create_minor_node(devi, "pfil", S_IFCHR, 0, DDI_PSEUDO, 0));
+#else
+ return (ddi_create_minor_node(devi, "pfil", S_IFCHR, 0, NULL, 0));
+#endif
}
@@ -324,7 +370,6 @@ static int pfildevclose(queue_t *q, int flag, cred_t *crp)
return 0;
}
-
/************************************************************************
* STREAMS module functions
*/
@@ -394,8 +439,11 @@ static int pfilmodclose(queue_t *q, int flag, cred_t *crp)
/* ------------------------------------------------------------------------ */
/* Function: pfil_precheck */
-/* Returns: int - < 0 is error in this function, 0 == pass packet, else */
-/* (> 0) indicates passing prohibited */
+/* Returns: int - < 0 pass packet because it's not a type subject to */
+/* firewall rules (i.e. internal STREAMS messages), */
+/* 0 == pass packet, else > 0 indicates passing */
+/* prohibited (possibly due to an error occuring in */
+/* this function.) */
/* Parameters: q(I) - pointer to STREAMS queue */
/* mp(I) - pointer to STREAMS message */
/* qif(I) - pointer to per-queue interface information */
@@ -413,23 +461,32 @@ int pfil_precheck(queue_t *q, mblk_t **mp, int flags, qif_t *qif)
{
register struct ip *ip;
size_t hlen, len, off, mlen, iphlen, plen;
- int err, out, sap, realigned = 0;
packet_filter_hook_t *pfh;
+ qpktinfo_t qpkt, *qpi;
struct pfil_head *ph;
mblk_t *m, *mt = *mp;
- u_char *bp, *s;
- qif_t qf, *qp;
+ int err, out, sap;
+ u_char *bp;
#if SOLARIS2 >= 8
ip6_t *ip6;
#endif
#ifndef sparc
u_short __ipoff, __iplen;
#endif
- qf = *qif;
- qp = qif;
- qif = &qf;
- qif->qf_next = NULL;
- qif->qf_flags = 0;
+
+ qpi = &qpkt;
+ qpi->qpi_q = q;
+ qpi->qpi_off = 0;
+ qpi->qpi_name = qif->qf_name;
+ qpi->qpi_real = qif;
+ qpi->qpi_ill = qif->qf_ill;
+ qpi->qpi_hl = qif->qf_hl;
+ qpi->qpi_ppa = qif->qf_ppa;
+ qpi->qpi_num = qif->qf_num;
+ qpi->qpi_flags = qif->qf_flags;
+ qpi->qpi_max_frag = qif->qf_max_frag;
+ if ((flags & PFIL_GROUP) != 0)
+ qpi->qpi_flags |= QF_GROUP;
/*
* If there is only M_DATA for a packet going out, then any header
@@ -437,10 +494,9 @@ int pfil_precheck(queue_t *q, mblk_t **mp, int flags, qif_t *qif)
* the M_DATA) is prepended before the IP header. We need to set the
* offset to account for this.
*/
- qif->qf_off = 0;
out = (flags & PFIL_OUT) ? 1 : 0;
- off = (out) ? qif->qf_hl : 0;
-tryagain:
+ off = (out) ? qpi->qpi_hl : 0;
+
ip = NULL;
m = NULL;
#if SOLARIS2 >= 8
@@ -468,13 +524,13 @@ tryagain:
off = 0;
m = mt;
} else {
- atomic_add_long(&qp->qf_notdata, 1);
+ atomic_add_long(&qif->qf_notdata, 1);
return -1;
}
} else {
m = mt->b_cont;
if (m == NULL) {
- atomic_add_long(&qp->qf_nodata, 1);
+ atomic_add_long(&qif->qf_nodata, 1);
return -3; /* No data blocks */
}
}
@@ -484,7 +540,7 @@ tryagain:
m = mt;
break;
default :
- atomic_add_long(&qp->qf_notdata, 1);
+ atomic_add_long(&qif->qf_notdata, 1);
return -2;
}
@@ -497,7 +553,7 @@ tryagain:
off = 0; /* Any non-M_DATA cancels the offset */
if (m == NULL) {
- atomic_add_long(&qp->qf_nodata, 1);
+ atomic_add_long(&qif->qf_nodata, 1);
return -3; /* No data blocks */
}
@@ -510,7 +566,7 @@ tryagain:
if ((dl->dl_primitive == DL_UNITDATA_IND) &&
(dl->dl_group_address == 1)) {
- qif->qf_flags |= QF_GROUP;
+ qpi->qpi_flags |= QF_GROUP;
if (((*((u_char *)m->b_rptr) == 0x0) &&
((*((u_char *)m->b_rptr + 2) == 0x45))))
off += 2;
@@ -519,52 +575,21 @@ tryagain:
}
/*
- * If there is more than one copy of this message traversing the
- * STREAMS stack (ie packet is being used for snoop data) then make a
- * copy of it for our use so we become the sole owner of the new
- * message and do a freemsg() on the one passed in as we're no longer
- * using it or passing it up.
- */
- if ((pfil_delayed_copy == 0) && (m->b_datap->db_ref > 1)) {
- mblk_t *new;
-
-forced_copy:
- new = copymsg(m);
- if (new == NULL) {
- atomic_add_long(&qp->qf_copyfail, 1);
- return -3;
- }
- atomic_add_long(&qp->qf_copy, 1);
-
- if (mt != m)
- mt->b_cont = new;
- else {
- *mp = new;
- mt = new;
- }
- freemsg(m);
- m = new;
- }
-
- ip = (struct ip *)(m->b_rptr + off);
-
- /*
* We might have a 1st data block which is really M_PROTO, i.e. it is
* only big enough for the link layer header
*/
- while ((u_char *)ip >= m->b_wptr) {
- len = (u_char *)ip - m->b_wptr;
+ while ((len = m->b_wptr - m->b_rptr) <= off) {
+ off -= len;
m = m->b_cont;
if (m == NULL) {
- atomic_add_long(&qp->qf_nodata, 1);
+ atomic_add_long(&qif->qf_nodata, 1);
return -4; /* not enough data for IP */
}
- ip = (struct ip *)(m->b_rptr + len);
}
- off = (u_char *)ip - m->b_rptr;
- mlen = msgdsize(m) - off;
- if (mlen == 0)
- mlen = mt->b_wptr - mt->b_rptr;
+
+ ip = (struct ip *)(m->b_rptr + off);
+ len = m->b_wptr - m->b_rptr - off;
+ mlen = msgdsize(m);
#ifdef IRE_ILL_CN
sap = ((s_ill_t *)qif->qf_ill)->ill_sap;
@@ -572,7 +597,105 @@ forced_copy:
sap = ((ill_t *)qif->qf_ill)->ill_sap;
#endif
- if (sap == ETHERTYPE_IP) {
+ if (mlen == 0)
+ mlen = m->b_wptr - m->b_rptr;
+ mlen -= off;
+
+#ifdef PFILDEBUG
+ /*LINTED: E_CONSTANT_CONDITION*/
+ PRINT(10,(CE_CONT,
+ "!IP Filter[%s]: out %d len %ld/%ld sap %d ip %p b_rptr %p off %ld m %p/%d/%d/%p mt %p/%d/%d/%p\n",
+ qif->qf_name, out, len, mlen, sap,
+ (void *)ip, (void *)m->b_rptr, off,
+ (void *)m, MTYPE(m), (int)MLEN(m), (void *)m->b_cont,
+ (void *)mt, MTYPE(mt), (int)MLEN(mt), (void *)mt->b_cont));
+#endif
+
+ /*
+ * If there is more than one copy of this message traversing the
+ * STREAMS stack (ie the packet is being used for snoop data), the
+ * IP header isn't on a 32bit aligned address, or the IP header
+ * isn't contain within a single block, then make a copy which
+ * meets our requirements and do a freemsg on the one passed in
+ * since we're no longer using it or passing it up.
+ */
+
+ if ((pfil_delayed_copy == 0 && m->b_datap->db_ref > 1)
+ || ((uintptr_t)ip & 0x3) || len < sizeof(*ip)
+ || (sap != IP_DL_SAP
+#if SOLARIS2 >= 8
+ && sap != IP6_DL_SAP
+#endif
+ )) {
+ mblk_t *b;
+ mblk_t *nm;
+ mblk_t *nmt;
+ mblk_t *previous_nm;
+
+forced_copy:
+ nmt = NULL;
+ previous_nm = NULL;
+
+ /*
+ * Duplicate the message block descriptors up to (and
+ * including if the offset is non-zero) the block where
+ * IP begins.
+ */
+ for (b = mt; b != m || off; b = b->b_cont) {
+ nm = dupb(b);
+ if (nm == NULL) {
+ atomic_add_long(&qif->qf_copyfail, 1);
+ if (nmt)
+ freemsg(nmt);
+ return ENOBUFS;
+ }
+
+ nm->b_cont = NULL;
+ if (nmt)
+ linkb(previous_nm, nm);
+ else
+ nmt = nm;
+ previous_nm = nm;
+
+ /*
+ * Set the length so the block only contains what
+ * appears before IP.
+ */
+ if (b == m) {
+ nm->b_wptr = nm->b_rptr + off;
+ break;
+ }
+ }
+
+ m->b_rptr += off;
+ nm = msgpullup(m, -1);
+ m->b_rptr -= off;
+
+ if (nm == NULL) {
+ atomic_add_long(&qif->qf_copyfail, 1);
+ if (nmt)
+ freemsg(nmt);
+ return ENOBUFS;
+ }
+
+ if (nmt)
+ linkb(previous_nm, nm);
+ else
+ nmt = nm;
+
+ freemsg(mt);
+
+ *mp = nmt;
+ mt = nmt;
+ m = nm;
+
+ ip = (struct ip *)m->b_rptr;
+ len = m->b_wptr - m->b_rptr;
+ mlen = len;
+ off = 0;
+ }
+
+ if (sap == IP_DL_SAP) {
u_short tlen;
hlen = sizeof(*ip);
@@ -582,7 +705,6 @@ forced_copy:
((char *)&tlen)[1] = ((char *)&ip->ip_len)[1];
plen = ntohs(tlen);
- sap = 0;
ph = &pfh_inet4;
}
#if SOLARIS2 >= 8
@@ -599,165 +721,43 @@ forced_copy:
if (plen == 0)
return EMSGSIZE; /* Jumbo gram */
- sap = IP6_DL_SAP;
ph = &pfh_inet6;
}
#endif
else {
- hlen = 0;
sap = -1;
}
-
- len = m->b_wptr - m->b_rptr - off;
-#ifdef PFILDEBUG
- /*LINTED: E_CONSTANT_CONDITION*/
- PRINT(10,(CE_CONT,
- "!IP Filter[%s]: out %d len %ld/%ld sap %d ip %p b_rptr %p off %ld m %p/%d/%d/%p mt %p/%d/%d/%p\n",
- qif->qf_name, out, len, mlen, sap,
- (void *)ip, (void *)m->b_rptr, off,
- (void *)m, MTYPE(m), (int)MLEN(m), (void *)m->b_cont,
- (void *)mt, MTYPE(mt), (int)MLEN(mt), (void *)mt->b_cont));
-#endif
-
- /*
- * Ok, the IP header isn't on a 32bit aligned address so fix this.
- */
- if (((uintptr_t)ip & 0x3) || (len < sizeof(*ip)) || (sap == -1)) {
- mblk_t *m2, *m1;
- int off2;
-
- if (m->b_datap->db_ref > 1)
- goto forced_copy;
- /*
- * If we have already tried to realign the IP header and we
- * are back here, then the attempt has failed, so stop now
- * rather than try again (could keep on retrying with no
- * benefit.)
- */
- if (realigned) {
- atomic_add_long(&qp->qf_drop, 1);
- return EINVAL;
- }
- realigned = 1;
-
- len = msgdsize(m);
- if (len < sizeof(*ip)) {
- atomic_add_long(&qp->qf_bad, 1);
- return EINVAL;
- }
-
- /*
- * XXX - Now I understand how pullupmsg() & STREAMS messages
- * work better, this can possibly be junked in favour of using
- * pullupmsg() which will preserve all the dblk bits correctly,
- * as is done in fr_pullup in the ipf code.
- */
-
- /*
- * Junk using pullupmsg()
- */
- off2 = (uintptr_t)ip & 0x3;
- if (off2)
- off2 = 4 - off2;
- m2 = allocb(len + off2, BPRI_HI);
- if (m2 == NULL) {
- atomic_add_long(&qp->qf_drop, 1);
- return ENOBUFS;
- }
-
- MTYPE(m2) = M_DATA;
- if (m->b_rptr != (u_char *)ip)
- m2->b_rptr += off2;
- m2->b_wptr = m2->b_rptr + len;
- m1 = m;
- s = (u_char *)m->b_rptr;
- for (bp = m2->b_rptr; m1 && (bp < m2->b_wptr); bp += len) {
- len = MIN(m1->b_wptr - s, m2->b_wptr - bp);
- bcopy(s, bp, len);
- m1 = m1->b_cont;
- if (m1 != NULL)
- s = m1->b_rptr;
- }
-
- if ((mt != m) && (mt->b_cont == m) && (off == 0)) {
- /*
- * check if the buffer we're changing is chained in-
- * between other buffers and unlink/relink as required.
- */
- (void) unlinkb(mt); /* should return 'm' */
- m1 = unlinkb(m);
- if (m1 != NULL)
- linkb(m2, m1);
- freemsg(m);
- linkb(mt, m2);
- } else {
- if (m == mt) {
- m1 = unlinkb(mt);
- if (m1)
- linkb(m2, m1);
- }
- freemsg(mt);
- *mp = m2;
- mt = m2;
- }
-
- off = 0;
- goto tryagain;
- }
-
- if (((sap == 0) && (ip->ip_v != IPVERSION))
+ if (((sap == IP_DL_SAP) && (ip->ip_v != IPVERSION))
#if SOLARIS2 >= 8
|| ((sap == IP6_DL_SAP) && (((ip6->ip6_vfc) & 0xf0) != 0x60))
#endif
+ || sap == -1
) {
- atomic_add_long(&qp->qf_notip, 1);
+ atomic_add_long(&qif->qf_notip, 1);
#ifdef PFILDEBUG
pfil_donotip(out, qif, q, m, mt, ip, off);
#endif
return EINVAL;
}
- /*
- * The code in IPFilter assumes that both the ip_off and ip_len
- * fields are in host byte order, so convert them here to fulfill
- * that expectation.
- *
- * If the target compile host is non-SPARC, assume it is a little
- * endian machine, requiring the conversion of offset/length fields
- * to both be host byte ordered.
- */
-#ifndef sparc
- if (sap == 0) {
- __ipoff = (u_short)ip->ip_off;
- ip->ip_len = plen;
- ip->ip_off = ntohs(__ipoff);
- }
-#endif
- if (sap == 0)
+ if (sap == IP_DL_SAP)
iphlen = ip->ip_hl << 2;
#if SOLARIS2 >= 8
else if (sap == IP6_DL_SAP)
iphlen = sizeof(ip6_t);
#endif
+
if ((
#if SOLARIS2 >= 8
- (sap == IP6_DL_SAP) && (mlen < iphlen + plen)) ||
- ((sap == 0) &&
+ (sap == IP6_DL_SAP) && (mlen < plen)) ||
+ ((sap == IP_DL_SAP) &&
#endif
((iphlen < hlen) || (iphlen > plen) || (mlen < plen)))) {
/*
* Bad IP packet or not enough data/data length mismatches
*/
-#ifndef sparc
- if (sap == 0) {
- __ipoff = (u_short)ip->ip_off;
-
- ip->ip_len = htons(plen);
- ip->ip_off = htons(__ipoff);
- }
-#endif
- atomic_add_long(&qp->qf_bad, 1);
+ atomic_add_long(&qif->qf_bad, 1);
return EINVAL;
}
@@ -769,28 +769,43 @@ forced_copy:
if (m->b_datap->db_ref > 1)
goto forced_copy;
if (!pullupmsg(m, (int)iphlen + off)) {
- atomic_add_long(&qp->qf_nodata, 1);
- return -5;
+ atomic_add_long(&qif->qf_nodata, 1);
+ return ENOBUFS;
}
ip = (struct ip *)ALIGN32(m->b_rptr + off);
}
- if (sap == IP6_DL_SAP) {
- if ((len > iphlen + plen) && (off == 0))
- m->b_wptr -= len - (iphlen + plen);
- } else {
- if ((len > plen) && (off == 0))
- m->b_wptr -= len - plen;
+ /*
+ * Discard any excess data.
+ */
+ if (sap == IP6_DL_SAP && len > iphlen + plen)
+ m->b_wptr = m->b_rptr + off + plen + iphlen;
+ else if (sap == IP_DL_SAP && len > plen)
+ m->b_wptr = m->b_rptr + off + plen;
+
+ /*
+ * The code in IPFilter assumes that both the ip_off and ip_len
+ * fields are in host byte order, so convert them here to fulfill
+ * that expectation.
+ *
+ * If the target compile host is non-SPARC, assume it is a little
+ * endian machine, requiring the conversion of offset/length fields
+ * to both be host byte ordered.
+ */
+#ifndef sparc
+ if (sap == IP_DL_SAP) {
+ __ipoff = (u_short)ip->ip_off;
+ ip->ip_len = plen;
+ ip->ip_off = ntohs(__ipoff);
}
+#endif
- qif->qf_m = m;
- qif->qf_q = q;
- qif->qf_data = ip;
- qif->qf_oq = OTHERQ(q);
- qif->qf_off = off;
+ qpi->qpi_m = m;
+ qpi->qpi_off = off;
+ qpi->qpi_data = ip;
- if (qp->qf_ipmp != NULL)
- qp = qp->qf_ipmp;
+ if (qif->qf_ipmp != NULL)
+ qif = qif->qf_ipmp;
READ_ENTER(&ph->ph_lock);
@@ -802,15 +817,24 @@ forced_copy:
flags, (void *)ph, (void *)pfh));
for (; pfh; pfh = pfh->pfil_next)
if (pfh->pfil_func) {
- err = (*pfh->pfil_func)(ip, iphlen, qif->qf_ill, out,
- qif, mp);
+ err = (*pfh->pfil_func)(ip, iphlen, qif, out, qpi, mp);
if (err || !*mp)
break;
- ip = qif->qf_data;
+ /*
+ * fr_pullup may have allocated a new buffer.
+ */
+ ip = qpi->qpi_data;
}
RW_EXIT(&ph->ph_lock);
/*
+ * Functions called via pfil_func should only return values >= 0, so
+ * convert any that are < 0 to be > 0 and preserve the absolute value.
+ */
+ if (err < 0)
+ err = -err;
+
+ /*
* If we still have a STREAMS message after calling the filtering
* hooks, return the byte order of the fields changed above on
* platforms where this is required. They are refetched from the
@@ -818,8 +842,8 @@ forced_copy:
* them in some way.
*/
#ifndef sparc
- if (*mp != NULL) {
- if (sap == 0) {
+ if ((err == 0) && (*mp != NULL)) {
+ if (sap == IP_DL_SAP) {
__iplen = (u_short)ip->ip_len;
__ipoff = (u_short)ip->ip_off;
ip->ip_len = htons(__iplen);
@@ -827,7 +851,6 @@ forced_copy:
}
}
#endif
-
return err;
}
@@ -1015,6 +1038,9 @@ static void pfil_remif(queue_t *rq)
#endif /* IRE_ILL_CN */
+/************************************************************************
+ *
+ */
#ifdef PFILDEBUG
/* ------------------------------------------------------------------------ */
/* Function: pfil_donotip */
@@ -1090,6 +1116,51 @@ void pfil_donotip(int out, qif_t *qif, queue_t *q, mblk_t *m, mblk_t *mt, struct
#endif
+/* ------------------------------------------------------------------------ */
+/* Function: pfil_property_update */
+/* Returns: int - DDI_SUCCESS == success, else failure */
+/* Parameters: modinfop(I) - pointer to module informatio buffer */
+/* */
+/* Fetch configuration file values that have been entered into the */
+/* pfil.conf driver file. */
+/* ------------------------------------------------------------------------ */
+static int pfil_property_update(dev_info_t *dip)
+{
+ char *list, *s, *t;
+ int err;
+
+ if (ddi_prop_update_int(DDI_DEV_T_ANY, dip,
+ "ddi-no-autodetach", 1) == -1) {
+ cmn_err(CE_WARN, "!updating ddi-no-authdetach failed");
+ return DDI_FAILURE;
+ }
+
+ list = NULL;
+ err = ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
+ 0, "qif_ipmp_set", &list);
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "IP Filter: lookup_string(pfil_ipmp_list) = %d\n",
+ err);
+#endif
+ if (err == DDI_SUCCESS) {
+ t = NULL;
+ s = list;
+ do {
+ if (t != NULL)
+ s = t + 1;
+ t = strchr(s, ';');
+ if (t != NULL)
+ *t = '\0';
+ qif_ipmp_update(s);
+ } while (t != NULL);
+
+ ddi_prop_free(list);
+ }
+
+ return DDI_SUCCESS;
+}
+
+
#if SOLARIS2 == 8
int miocpullup(mblk_t *m, size_t len)
{
@@ -1098,4 +1169,3 @@ int miocpullup(mblk_t *m, size_t len)
return pullupmsg(m->b_cont, len);
}
#endif
-
diff --git a/usr/src/uts/common/inet/ipf/pfilstream.c b/usr/src/uts/common/inet/pfil/pfilstream.c
index 580f60d95a..51d1b30d5a 100644
--- a/usr/src/uts/common/inet/ipf/pfilstream.c
+++ b/usr/src/uts/common/inet/pfil/pfilstream.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -20,6 +20,7 @@ struct uio;
#include <sys/dlpi.h>
#include <sys/cmn_err.h>
#ifdef sun
+# include <sys/atomic.h>
# include <sys/sockio.h>
# include <sys/ksynch.h>
# include <sys/strsubr.h>
@@ -27,6 +28,7 @@ struct uio;
#endif
#ifdef __hpux
# include <sys/dlpi_ext.h>
+# include <net/mtcp.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -37,6 +39,8 @@ struct uio;
# include <inet/common.h>
# if SOLARIS2 >= 8
# include <netinet/ip6.h>
+# else
+# include <net/if_dl.h>
# endif
# if SOLARIS2 >= 10
# include <sys/policy.h>
@@ -50,17 +54,10 @@ struct uio;
# include <inet/ip_if.h>
#endif
-#ifdef sun
-# include <inet/ipf/compat.h>
-# include <inet/ipf/pfil.h>
-# include <inet/ipf/qif.h>
-# include <pfild.h>
-#else
-# include "compat.h"
-# include "pfil.h"
-# include "qif.h"
-# include "pfild.h"
-#endif
+#include "compat.h"
+#include "qif.h"
+#include "pfil.h"
+#include "pfild.h"
#if SOLARIS2 >= 10
extern queue_t *pfildq;
@@ -85,6 +82,7 @@ extern queue_t *pfildq;
static int pfil_drv_priv __P((cred_t *));
+
#ifdef PFILDEBUG
/* ------------------------------------------------------------------------ */
/* Function: pfil_printmchain */
@@ -209,6 +207,7 @@ static void pfil_printioctl(mblk_t *mp)
}
#endif /* PFILDEBUG */
+
/* ------------------------------------------------------------------------ */
/* Function: pfilbind */
/* Returns: int - 0 == success, else error */
@@ -234,7 +233,7 @@ int pfilbind(queue_t *q)
/* ------------------------------------------------------------------------ */
/* Function: pfilwput_ioctl */
-/* Returns: void */
+/* Returns: void */
/* Parameters: q(I) - pointer to queue */
/* mp(I) - pointer to STREAMS message */
/* */
@@ -318,7 +317,21 @@ void pfilwput_ioctl(queue_t *q, mblk_t *mp)
break;
#endif
#endif /* pre-S10 */
- default:
+#ifdef __hpux
+ case ND_SET :
+ case ND_GET :
+ if (pfil_ioctl_nd(q, mp)) {
+ if (iocp->ioc_error)
+ iocp->ioc_count = 0;
+ mp->b_datap->db_type = M_IOCACK;
+ qreply(q, mp);
+ } else {
+ miocnak(q, mp, 0, EINVAL);
+ }
+ return;
+ break;
+#endif
+ default :
break;
}
@@ -408,7 +421,7 @@ static void pfil_update_ifaddrset(mblk_t *mp)
*/
/* ------------------------------------------------------------------------ */
/* Function: pfilwput */
-/* Returns: void */
+/* Returns: void */
/* Parameters: q(I) - pointer to queue */
/* mp(I) - pointer to STREAMS message */
/* */
@@ -416,19 +429,21 @@ static void pfil_update_ifaddrset(mblk_t *mp)
/* /dev/pfil, not the STREAMS module pushed on another queue. As it does */
/* not do any IO, this should never be called except to handle ioctl's and */
/* so all other messages are free'd and no reply sent back. */
-/* The only ioctls handled by the driver are ND_GET/ND_SET. */
-/* pfilwput also handles PFILCMD_IFADDRS and PFILCMD_IFADDRSET messages */
+/* The only ioctls handled by the driver are ND_GET/ND_SET. */
+/* pfilwput also handles PFILCMD_IFADDRS and PFILCMD_IFADDRSET messages. */
+/* NOTE: HP-UX does not need or have pfil implemented as a STREAMS device. */
/* ------------------------------------------------------------------------ */
+#ifdef sun
void pfilwput(queue_t *q, mblk_t *mp)
{
struct iocblk *iocp;
uint32_t cmd;
-#ifdef PFILDEBUG
+# ifdef PFILDEBUG
/* LINTED: E_CONSTANT_CONDITION */
PRINT(9,(CE_CONT, "!pfilwput(%p,%p) [%s] qif %p\n",
(void *)q, (void *)mp, QTONM(q), (void *)q->q_ptr));
-#endif
+# endif
switch (MTYPE(mp))
{
@@ -463,7 +478,8 @@ void pfilwput(queue_t *q, mblk_t *mp)
#endif
case M_IOCTL:
iocp = (struct iocblk *)mp->b_rptr;
- switch (iocp->ioc_cmd) {
+ switch (iocp->ioc_cmd)
+ {
case ND_SET :
case ND_GET :
if (pfil_ioctl_nd(q, mp)) {
@@ -475,17 +491,20 @@ void pfilwput(queue_t *q, mblk_t *mp)
miocnak(q, mp, 0, EINVAL);
}
break;
- default:
+
+ default :
miocnak(q, mp, 0, EINVAL);
break;
}
return;
- default:
+ default :
break;
}
+
freemsg(mp);
}
+#endif
/************************************************************************
@@ -493,7 +512,7 @@ void pfilwput(queue_t *q, mblk_t *mp)
*/
/* ------------------------------------------------------------------------ */
/* Function: pfilmodwput */
-/* Returns: Void. */
+/* Returns: void */
/* Parameters: q(I) - pointer to queue */
/* mp(I) - pointer to STREAMS message */
/* */
@@ -527,7 +546,7 @@ void pfilmodwput(queue_t *q, mblk_t *mp)
break;
}
- /*FALLTHROUGH*/
+ /*FALLTHROUGH*/
case M_DATA :
atomic_add_long(&qif->qf_nw, 1);
@@ -535,6 +554,7 @@ void pfilmodwput(queue_t *q, mblk_t *mp)
int i;
i = pfil_precheck(q, &mp, PFIL_OUT, qif);
+
/* LINTED: E_CONSTANT_CONDITION */
PRINT(9, (CE_CONT, "!%s: pfil_precheck=%d mp %p\n",
"pfilmodwput", i, (void *)mp));
@@ -547,9 +567,10 @@ void pfilmodwput(queue_t *q, mblk_t *mp)
}
break;
- case M_IOCTL:
+ case M_IOCTL :
pfilwput_ioctl(q, mp);
return;
+
default :
break;
}
@@ -572,9 +593,10 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
{
union DL_primitives *dl;
dl_bind_ack_t *b;
- int i;
+ int i, flags;
qif_t *qif;
+ flags = 0;
qif = q->q_ptr;
/* LINTED: E_CONSTANT_CONDITION */
@@ -582,7 +604,9 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
(void *)q, (void *)mp, mp->b_datap->db_type, QTONM(q),
QTONM(OTHERQ(q)), (void *)qif,
(void *)qif->qf_ill));
- switch (MTYPE(mp)) {
+
+ switch (MTYPE(mp))
+ {
#ifdef DL_IOC_HDR_INFO
case M_IOCACK :
{
@@ -602,6 +626,7 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
pfil_printioctl(mp);
#endif
break;
+
case M_PROTO :
case M_PCPROTO :
@@ -616,7 +641,7 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
case DL_UNITDATA_IND :
if ((MLEN(mp) >= sizeof(dl_unitdata_ind_t)) &&
(dl->unitdata_ind.dl_group_address))
- qif->qf_flags |= QF_GROUP;
+ flags |= PFIL_GROUP;
break;
case DL_SUBS_BIND_ACK :
@@ -625,7 +650,6 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
c = (dl_subs_bind_ack_t *)dl;
if (qif->qf_sap == 0) {
-/* XXX: What is this message? */
#if 0
qif->qf_sap = c->dl_sap;
if (qif->qf_sap < 0)
@@ -655,7 +679,9 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
qif->qf_waitack++;
break;
}
- if (!b->dl_sap || b->dl_sap == IP_DL_SAP || b->dl_sap == IP6_DL_SAP)
+
+ if (!b->dl_sap || b->dl_sap == IP_DL_SAP ||
+ b->dl_sap == IP6_DL_SAP)
(void) pfilbind(q);
break;
@@ -672,7 +698,8 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
atomic_add_long(&qif->qf_nr, 1);
if (qif->qf_ill != NULL) {
- i = pfil_precheck(q, &mp, PFIL_IN, qif);
+ flags |= PFIL_IN;
+ i = pfil_precheck(q, &mp, flags, qif);
/* LINTED: E_CONSTANT_CONDITION */
PRINT(9, (CE_CONT,
@@ -686,9 +713,11 @@ void pfilmodrput(queue_t *q, mblk_t *mp)
}
}
break;
+
default :
break;
}
+
putnext(q, mp);
}
@@ -730,4 +759,3 @@ void pfil_startup()
pfil_init(&pfh_inet6);
pfil_init(&pfh_sync);
}
-
diff --git a/usr/src/uts/common/inet/ipf/pkt.c b/usr/src/uts/common/inet/pfil/pkt.c
index 0b4653b5d4..6a9c74b139 100644
--- a/usr/src/uts/common/inet/ipf/pkt.c
+++ b/usr/src/uts/common/inet/pfil/pkt.c
@@ -3,8 +3,6 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * ident "@(#)$Id: pkt.c,v 1.8 2003/07/28 05:13:58 darrenr Exp $"
- *
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -25,7 +23,9 @@
#include <netinet/in.h>
#include <netinet/ip.h>
#if SOLARIS2 >= 8
-#include <netinet/ip6.h>
+# include <netinet/ip6.h>
+#else
+# include <net/if_dl.h>
#endif
#undef IPOPT_EOL
@@ -253,7 +253,6 @@ mblk_t *mb;
/* Function: pfil_sendbuf */
/* Returns: int - 0 == success, 1 == failure */
/* Parameters: m(I) - pointer to streams message */
-/* v - indicated v4 or v6 */
/* */
/* Output an IPv4 packet to whichever interface has the correct route. */
/* ------------------------------------------------------------------------ */
diff --git a/usr/src/uts/common/inet/ipf/qif.c b/usr/src/uts/common/inet/pfil/qif.c
index 7715098c0f..fc74ca00fc 100644
--- a/usr/src/uts/common/inet/ipf/qif.c
+++ b/usr/src/uts/common/inet/pfil/qif.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,10 +42,10 @@
# endif
# include <net/if_dl.h>
#endif
-#include <inet/common.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <inet/common.h>
#undef IPOPT_EOL
#undef IPOPT_NOP
#undef IPOPT_LSRR
@@ -326,7 +326,7 @@ qif_attach(rq)
(hdrsizes[ill->ill_type][0] == ill->ill_type))
qif->qf_hl = hdrsizes[ill->ill_type][1];
- if (qif->qf_hl == 0) {
+ if (qif->qf_hl == 0 && ill->ill_type != IFT_OTHER) {
cmn_err(CE_WARN,
"!Unknown layer 2 header size for %s type %d sap %x\n",
qif->qf_name, ill->ill_type, ill->ill_sap);
@@ -364,7 +364,7 @@ qif_attach(rq)
pfh = pfil_hook_get(PFIL_IN, &pfh_sync);
for (; pfh; pfh = pfh->pfil_next)
if (pfh->pfil_func)
- (void) (*pfh->pfil_func)(NULL, 0, ill, 0, qif, NULL);
+ (void) (*pfh->pfil_func)(NULL, 0, qif, 0, qif, NULL);
RW_EXIT(&pfh_sync.ph_lock);
@@ -420,6 +420,7 @@ qif_new(q, mflags)
return qif;
}
+
/* ------------------------------------------------------------------------ */
/* Function: qif_delete */
/* Returns: void */
@@ -470,7 +471,7 @@ queue_t *q;
pfh = pfil_hook_get(PFIL_OUT, &pfh_sync);
for (; pfh; pfh = pfh->pfil_next)
if (pfh->pfil_func)
- (void) (*pfh->pfil_func)(NULL, 0, qif->qf_ill,
+ (void) (*pfh->pfil_func)(NULL, 0, qif,
1, qif, NULL);
RW_EXIT(&pfh_sync.ph_lock);
}
@@ -480,9 +481,10 @@ queue_t *q;
freeb(qif->qf_addrset);
mutex_destroy(&qif->qf_ptl.pt_lock);
cv_destroy(&qif->qf_ptl.pt_cv);
- if (qif->qf_qifsz == sizeof(*qif)) {
+
+ if (qif->qf_qifsz == sizeof(*qif))
kmem_cache_free(qif_cache, qif);
- } else {
+ else {
KMFREE(qif, qif->qf_qifsz);
}
}
@@ -604,6 +606,7 @@ qif_t *qif_walk(qif_t **qfp)
return *qfp;
}
+
/* ------------------------------------------------------------------------ */
/* Function: qif_ipmp_update */
/* Returns: void */
@@ -710,7 +713,7 @@ void qif_ipmp_delete(char *qifname)
pfh = pfil_hook_get(PFIL_OUT, &pfh_sync);
for (; pfh; pfh = pfh->pfil_next)
if (pfh->pfil_func)
- (void) (*pfh->pfil_func)(NULL, 0, qif->qf_ill, 1,
+ (void) (*pfh->pfil_func)(NULL, 0, qif, 1,
qif, NULL);
KMFREE(qif, qif->qf_qifsz);
@@ -796,3 +799,59 @@ void qif_ipmp_syncslave(qif_t *target, const int sap)
}
}
+
+/* ------------------------------------------------------------------------ */
+/* Function: qif_hl_set */
+/* Returns: void */
+/* Parameters: ipmpconf(I) - string with header length setting for NIC */
+/* */
+/* For NICs that we cannot automatically determine the MAC header length of */
+/* we provide a manual crook to achieve that with. The input syntax for */
+/* the string is "[v4:|v6:]<ifname>=<length>" */
+/* ------------------------------------------------------------------------ */
+void qif_hl_set(char *ipmpconf)
+{
+ qif_t *qf;
+ char *s;
+
+ if (!strncmp(ipmpconf, "v4:", 3)) {
+ ipmpconf += 3;
+ } else if (!strncmp(ipmpconf, "v6:", 3)) {
+#if SOLARIS2 >= 8
+ ipmpconf += 3;
+#else
+ return;
+#endif
+ }
+
+ s = strchr(ipmpconf, '=');
+ if (s != NULL) {
+ if (*(s + 1) == '\0')
+ *s = '\0';
+ else
+ *s++ = '\0';
+ }
+ if (s == NULL || *s == NULL)
+ return;
+
+ READ_ENTER(&pfil_rw);
+ for (qf = qif_head; qf; qf = qf->qf_next)
+ if (strcmp(qf->qf_name, ipmpconf) == 0)
+ break;
+
+ if (qf != NULL) {
+ int hl = 0;
+
+ for (; *s != '\0'; s++) {
+ char c = *s;
+
+ if (c < '0' || c > '9')
+ return;
+ hl *= 10;
+ hl += c - '0';
+ }
+ qf->qf_hl = hl;
+ }
+
+ RW_EXIT(&pfil_rw);
+}
diff --git a/usr/src/uts/common/inet/ipf/qif.h b/usr/src/uts/common/inet/pfil/qif.h
index 2e3c7cc886..7371ab420a 100644
--- a/usr/src/uts/common/inet/ipf/qif.h
+++ b/usr/src/uts/common/inet/pfil/qif.h
@@ -3,14 +3,17 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include "pfil.h"
-#include <sys/ptms.h>
+#ifdef sun
+# include <sys/dditypes.h>
+# include <sys/ptms.h>
+#endif
+
#ifdef IRE_ILL_CN
typedef union {
@@ -63,7 +66,6 @@ typedef struct s_ill_s {
uint_t mtu;
} s_ill_t;
-
typedef struct qif {
/* for alignment reasons, the lock is first. */
kmutex_t qf_lock;
@@ -103,7 +105,7 @@ typedef struct qif {
char qf_name[LIFNAMSIZ];
char *qf_members;
- /* ON10 specific */
+ /* ON(10, NV) specific */
mblk_t *qf_addrset;
size_t qf_off;
mblk_t *qf_m;
@@ -155,7 +157,15 @@ typedef struct qpktinfo {
#endif
#ifdef __hpux
-# define QF_V4_ADDR(x) ((ifinfot_t *)(x)->qf_ill)->ifi_addr[0]
+# define QF_V4_ADDR(x) ((ifinfo_t *)(x)->qf_ill)->ifi_addr[0]
+# define QF_V4_BROADCAST(x) 0
+# define QF_V4_NETMASK(x) 0xffffffff
+# define QF_V4_PEERADDR(x) 0
+# ifdef USE_INET6
+# define QF_V6_BROADCAST(x) 0
+# define QF_V6_NETMASK(x) 0
+# define QF_V6_PEERADDR(x) 0
+# endif
#endif
@@ -170,14 +180,16 @@ extern int qif_startup(void);
extern void qif_stop(void);
extern void *qif_iflookup(char *, int);
+#ifdef __hpux
struct irinfo_s;
extern void *ir_to_ill(struct irinfo_s *ir);
-
+#endif
extern struct qif *qif_walk(struct qif **);
extern struct qif *qif_head;
extern int qif_verbose;
extern void qif_update(struct qif *, mblk_t *);
extern void qif_nd_init(void);
+extern void qif_hl_set(char *);
extern void qif_ipmp_delete(char *);
extern void qif_ipmp_update(char *);
extern void qif_ipmp_syncmaster(struct qif *, const int);
diff --git a/usr/src/uts/intel/ipf/Makefile b/usr/src/uts/intel/ipf/Makefile
index 79067cfbce..84d447a2cc 100644
--- a/usr/src/uts/intel/ipf/Makefile
+++ b/usr/src/uts/intel/ipf/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -43,6 +43,8 @@ CPPFLAGS += -DIPFILTER_LKM -DIPFILTER_LOG -DIPFILTER_LOOKUP -DUSE_INET6
CPPFLAGS += -DSUNDDI -DSOLARIS2=$(MINOR:sh) -DIRE_ILL_CN
LDFLAGS += -dy -Ndrv/ip -Ndrv/pfil -Nmisc/md5
+INC_PATH += -I$(UTSBASE)/common/inet/ipf
+
#
# Default build targets.
#
diff --git a/usr/src/uts/intel/pfil/Makefile b/usr/src/uts/intel/pfil/Makefile
index c88648e53f..14556577bf 100644
--- a/usr/src/uts/intel/pfil/Makefile
+++ b/usr/src/uts/intel/pfil/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -46,7 +45,7 @@ OBJECTS = $(PFIL_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PFIL_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/common/inet/ipf
+CONF_SRCDIR = $(UTSBASE)/common/inet/pfil
#
# Include common rules.
diff --git a/usr/src/uts/req.flg b/usr/src/uts/req.flg
index 36f48f01be..64495a7f73 100644
--- a/usr/src/uts/req.flg
+++ b/usr/src/uts/req.flg
@@ -45,7 +45,6 @@ find_files "s.*" usr/src/common/avl
# For full builds (open and closed), we want both etc/certs and
# etc/keys. For an open source build, there's no etc/keys directory.
find_files "s.*" usr/src/cmd/cmd-crypto/etc
-find_files "s.*" usr/src/common/ipf
find_files "s.*" usr/src/common/mdesc
find_files "s.*" usr/src/common/fs
find_files "s.*" usr/src/common/acl
diff --git a/usr/src/uts/sparc/ipf/Makefile b/usr/src/uts/sparc/ipf/Makefile
index 22756183a1..c0400bb4c4 100644
--- a/usr/src/uts/sparc/ipf/Makefile
+++ b/usr/src/uts/sparc/ipf/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -48,6 +48,8 @@ CPPFLAGS += -DIPFILTER_LKM -DIPFILTER_LOG -DIPFILTER_LOOKUP
CPPFLAGS += -DSUNDDI -DSOLARIS2=$(MINOR:sh) -DIRE_ILL_CN -DUSE_INET6
LDFLAGS += -dy -Ndrv/ip -Ndrv/pfil -Nmisc/md5
+INC_PATH += -I$(UTSBASE)/common/inet/ipf
+
#
# Default build targets.
#
diff --git a/usr/src/uts/sparc/pfil/Makefile b/usr/src/uts/sparc/pfil/Makefile
index 2de916bb35..fae0500ce1 100644
--- a/usr/src/uts/sparc/pfil/Makefile
+++ b/usr/src/uts/sparc/pfil/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -46,7 +45,7 @@ OBJECTS = $(PFIL_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PFIL_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/common/inet/ipf
+CONF_SRCDIR = $(UTSBASE)/common/inet/pfil
#
# Include common rules.