aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2002-03-19 11:45:20 +0000
committerDarren Reed <darrenr@FreeBSD.org>2002-03-19 11:45:20 +0000
commitd564cc784ffa00509dbff15d4784ce85dfce1026 (patch)
treee420b9c485fbd878875892eef69b8b6121924075
parentdba82da1c8912a1a3a6328593dc75b9f15f19fcf (diff)
downloadsrc-d564cc784ffa00509dbff15d4784ce85dfce1026.tar.gz
src-d564cc784ffa00509dbff15d4784ce85dfce1026.zip
Import IPFilter 3.4.25
Notes
Notes: svn path=/vendor/ipfilter/dist/; revision=92686
-rw-r--r--contrib/ipfilter/BNF13
-rw-r--r--contrib/ipfilter/BSD/Makefile61
-rw-r--r--contrib/ipfilter/BSD/kupgrade10
-rwxr-xr-xcontrib/ipfilter/FreeBSD-2.2/kinstall8
-rwxr-xr-xcontrib/ipfilter/FreeBSD-3/kinstall8
-rwxr-xr-xcontrib/ipfilter/FreeBSD-4.0/kinstall23
-rwxr-xr-xcontrib/ipfilter/FreeBSD/kinstall8
-rw-r--r--contrib/ipfilter/HISTORY213
-rw-r--r--contrib/ipfilter/INSTALL.FreeBSD50
-rw-r--r--contrib/ipfilter/IPFILTER.LICENCE2
-rw-r--r--contrib/ipfilter/Makefile16
-rw-r--r--contrib/ipfilter/common.c56
-rw-r--r--contrib/ipfilter/etc/protocols10
-rw-r--r--contrib/ipfilter/fil.c202
-rw-r--r--contrib/ipfilter/fils.c688
-rw-r--r--contrib/ipfilter/inet_addr.c5
-rw-r--r--contrib/ipfilter/ip_auth.c18
-rw-r--r--contrib/ipfilter/ip_auth.h5
-rw-r--r--contrib/ipfilter/ip_compat.h448
-rw-r--r--contrib/ipfilter/ip_fil.c582
-rw-r--r--contrib/ipfilter/ip_fil.h89
-rw-r--r--contrib/ipfilter/ip_frag.c21
-rw-r--r--contrib/ipfilter/ip_frag.h18
-rw-r--r--contrib/ipfilter/ip_ftp_pxy.c150
-rw-r--r--contrib/ipfilter/ip_lfil.c5
-rw-r--r--contrib/ipfilter/ip_log.c76
-rw-r--r--contrib/ipfilter/ip_nat.c468
-rw-r--r--contrib/ipfilter/ip_nat.h22
-rw-r--r--contrib/ipfilter/ip_proxy.c143
-rw-r--r--contrib/ipfilter/ip_proxy.h24
-rw-r--r--contrib/ipfilter/ip_raudio_pxy.c17
-rw-r--r--contrib/ipfilter/ip_rcmd_pxy.c24
-rw-r--r--contrib/ipfilter/ip_sfil.c28
-rw-r--r--contrib/ipfilter/ip_state.c609
-rw-r--r--contrib/ipfilter/ip_state.h18
-rw-r--r--contrib/ipfilter/ipf.c9
-rw-r--r--contrib/ipfilter/ipf.h12
-rw-r--r--contrib/ipfilter/ipfs.c12
-rw-r--r--contrib/ipfilter/ipft_ef.c5
-rw-r--r--contrib/ipfilter/ipft_hx.c31
-rw-r--r--contrib/ipfilter/ipft_pc.c5
-rw-r--r--contrib/ipfilter/ipft_sn.c5
-rw-r--r--contrib/ipfilter/ipft_td.c5
-rw-r--r--contrib/ipfilter/ipft_tx.c7
-rw-r--r--contrib/ipfilter/ipl.h6
-rw-r--r--contrib/ipfilter/iplang/iplang_y.y5
-rw-r--r--contrib/ipfilter/ipmon.c447
-rw-r--r--contrib/ipfilter/ipnat.c409
-rw-r--r--contrib/ipfilter/ipsend/44arp.c3
-rw-r--r--contrib/ipfilter/ipsend/arp.c5
-rw-r--r--contrib/ipfilter/ipsend/ip.c5
-rw-r--r--contrib/ipfilter/ipsend/ipresend.c6
-rw-r--r--contrib/ipfilter/ipsend/ipsend.c5
-rw-r--r--contrib/ipfilter/ipsend/ipsopt.c6
-rw-r--r--contrib/ipfilter/ipsend/iptest.c5
-rw-r--r--contrib/ipfilter/ipsend/iptests.c22
-rw-r--r--contrib/ipfilter/ipsend/lsock.c5
-rw-r--r--contrib/ipfilter/ipsend/resend.c5
-rw-r--r--contrib/ipfilter/ipsend/sbpf.c4
-rw-r--r--contrib/ipfilter/ipsend/sirix.c3
-rw-r--r--contrib/ipfilter/ipsend/sock.c7
-rw-r--r--contrib/ipfilter/ipt.c380
-rw-r--r--contrib/ipfilter/kmem.c187
-rw-r--r--contrib/ipfilter/kmem.h5
-rw-r--r--contrib/ipfilter/man/Makefile2
-rw-r--r--contrib/ipfilter/man/ipf.46
-rw-r--r--contrib/ipfilter/man/ipfilter.54
-rw-r--r--contrib/ipfilter/man/ipfs.88
-rw-r--r--contrib/ipfilter/man/ipl.42
-rw-r--r--contrib/ipfilter/man/ipmon.86
-rw-r--r--contrib/ipfilter/man/ipnat.54
-rw-r--r--contrib/ipfilter/misc.c80
-rw-r--r--contrib/ipfilter/mlf_ipl.c4
-rw-r--r--contrib/ipfilter/mlfk_ipl.c6
-rw-r--r--contrib/ipfilter/mli_ipl.c21
-rw-r--r--contrib/ipfilter/mln_ipl.c2
-rw-r--r--contrib/ipfilter/natparse.c490
-rw-r--r--contrib/ipfilter/opt.c5
-rw-r--r--contrib/ipfilter/parse.c270
-rw-r--r--contrib/ipfilter/samples/Makefile18
-rw-r--r--contrib/ipfilter/samples/proxy.c195
-rw-r--r--contrib/ipfilter/solaris.c262
-rw-r--r--contrib/ipfilter/test/Makefile22
-rw-r--r--contrib/ipfilter/todo1
84 files changed, 4894 insertions, 2263 deletions
diff --git a/contrib/ipfilter/BNF b/contrib/ipfilter/BNF
index ac2381b6d4de..cf30ab6f1064 100644
--- a/contrib/ipfilter/BNF
+++ b/contrib/ipfilter/BNF
@@ -2,27 +2,29 @@ filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
[ proto ] [ ip ] [ group ].
insert = "@" decnumber .
-action = block | "pass" | log | "count" | skip | auth | call .
+action = block | "no-match" | "pass" | log | "count" | skip | auth | call .
in-out = "in" | "out" .
-options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
+options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ]
+ [ via ] ] .
tos = "tos" decnumber | "tos" hexnumber .
ttl = "ttl" decnumber .
proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
group = [ "head" decnumber ] [ "group" decnumber ] .
-block = "block" [ reutrn-icmp[return-code] | "return-rst" ] .
+block = "block" [ return-icmp[return-code] | "return-rst" ] .
auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
call = "call" [ "now" ] function-name .
skip = "skip" decnumber .
dup = "dup-to" interface-name[":"ipaddr] .
+via = "in-via" interface-name | "out-via" interface-name .
froute = "fastroute" | "to" interface-name [ ":" ipaddr ] .
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
-reutrn-icmp = "return-icmp" | "return-icmp-as-dest" .
+return-icmp = "return-icmp" | "return-icmp-as-dest" .
loglevel = facility"."priority | priority .
object = addr [ port-comp | port-range ] .
addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
@@ -32,7 +34,8 @@ flags = "flags" flag { flag } [ "/" flag { flag } ] .
with = "with" | "and" .
icmp = "icmp-type" icmp-type [ "code" decnumber ] .
return-code = "("icmp-code")" .
-keep = "keep" "state" | "keep" "frags" .
+keep = "keep" "state" | "keep" "frags" | "keep" "state-age" state-age .
+state-age = decnmber [ "/" decnumber ] .
nummask = host-name [ "/" decnumber ] .
host-name = ipaddr | hostname | "any" .
diff --git a/contrib/ipfilter/BSD/Makefile b/contrib/ipfilter/BSD/Makefile
index 5f1cbc02c2ec..8d2b28d5f78f 100644
--- a/contrib/ipfilter/BSD/Makefile
+++ b/contrib/ipfilter/BSD/Makefile
@@ -8,7 +8,7 @@
BINDEST=/usr/sbin
SBINDEST=/sbin
MANDIR=/usr/share/man
-CC=cc -Wall -Wuninitialized -Wstrict-prototypes -Werror -O
+CC=cc -Wall -Wstrict-prototypes -Wuninitialized -O
CFLAGS=-g -I$(TOP)
#
# For NetBSD/FreeBSD
@@ -39,22 +39,23 @@ INSTALL=install
#
MODOBJS=ip_fil.o fil_k.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \
ip_auth.o ip_log.o
-DFLAGS=$(IPFLKM) $(IPFLOG) $(DEF) $(DLKM)
+DFLAGS=$(IPFLKM) $(DEF) $(DLKM)
IPF=ipf.o parse.o common.o opt.o facpri.o
IPT=ipt.o parse.o common.o fil.o ipft_sn.o ipft_ef.o ipft_td.o ipft_pc.o \
opt.o ipft_tx.o misc.o ip_frag_u.o ip_state_u.o ip_nat_u.o ip_proxy_u.o \
- ip_auth_u.o ipft_hx.o ip_fil_u.o natparse.o facpri.o
-IPNAT=ipnat.o kmem.o natparse.o common.o
-FILS=fils.o parse.o kmem.o opt.o facpri.o common.o
+ ip_auth_u.o ipft_hx.o ip_fil_u.o ip_log_u.o natparse.o facpri.o \
+ printnat.o printstate.o
+IPNAT=ipnat.o kmem.o natparse.o common.o printnat.o
+FILS=fils.o parse.o kmem.o opt.o facpri.o common.o printstate.o
build all: ipf ipfs ipfstat ipftest ipmon ipnat $(LKM)
ipfstat: $(FILS)
- $(CC) $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) $(FILS) \
- -o $@ $(LIBS) $(STATETOP_LIB)
+ $(CC) -static $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
+ $(FILS) -o $@ $(LIBS) $(STATETOP_LIB) -lkvm
ipf: $(IPF)
- $(CC) $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
+ $(CC) -static $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
/bin/rm -f $(TOP)/ipf
ln -s `pwd`/ipf $(TOP)
@@ -64,10 +65,10 @@ ipftest: $(IPT)
ln -s `pwd`/ipftest $(TOP)
ipnat: $(IPNAT)
- $(CC) $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS)
+ $(CC) -static $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS) -lkvm
ipfs: ipfs.o
- $(CC) $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
+ $(CC) -static $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
tests:
(cd test; make )
@@ -107,6 +108,14 @@ natparse.o: $(TOP)/natparse.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
$(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/natparse.c -o $@
+printnat.o: $(TOP)/printnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
+ $(TOP)/ip_compat.h $(TOP)/ip_proxy.h
+ $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printnat.c -o $@
+
+printstate.o: $(TOP)/printstate.c $(TOP)/ip_fil.h $(TOP)/ipf.h \
+ $(TOP)/ip_state.h $(TOP)/ip_compat.h
+ $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printstate.c -o $@
+
ipft_sn.o: $(TOP)/ipft_sn.c $(TOP)/ipt.h $(TOP)/ipf.h $(TOP)/ip_fil.h \
$(TOP)/snoop.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_sn.c -o $@
@@ -130,7 +139,8 @@ ip_nat_u.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_nat.c -o $@
ip_proxy_u.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
- $(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_nat.h
+ $(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_rcmd_pxy.c \
+ $(TOP)/ip_raudio_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_proxy.c -o $@
ip_frag_u.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h \
@@ -148,6 +158,9 @@ ip_auth_u.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
ip_fil_u.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/$(IPFILC) -o $@
+ip_log_u.o: $(TOP)/ip_log.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h
+ $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_log.c -o $@
+
if_ipl.o: $(MODOBJS)
ld -r $(MODOBJS) -o $(LKM)
${RM} -f if_ipl
@@ -170,7 +183,7 @@ ip_state.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
ip_proxy.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_raudio_pxy.c \
- $(TOP)/ip_nat.h
+ $(TOP)/ip_rcmd_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_proxy.c -o $@
ip_auth.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
@@ -207,6 +220,8 @@ facpri.o: $(TOP)/facpri.c $(TOP)/facpri.h
ipmon: $(TOP)/ipmon.c
$(CC) $(DEBUG) $(CFLAGS) $(LOGFAC) $(TOP)/ipmon.c -o $@ $(LIBS)
+ /bin/rm -f $(TOP)/ipmon
+ ln -s `pwd`/ipmon $(TOP)
clean:
${RM} -f *.core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipnat \
@@ -231,10 +246,20 @@ install:
-if [ -d /modules -a -f ipf.ko ] ; then \
cp ipf.ko /modules; \
fi
- -$(INSTALL) -cs -g wheel -m 755 -o root ipf $(SBINDEST)
- -$(INSTALL) -cs -g wheel -m 755 -o root ipfs $(SBINDEST)
- -$(INSTALL) -cs -g wheel -m 755 -o root ipnat $(SBINDEST)
- -$(INSTALL) -cs -g wheel -m 755 -o root ipfstat $(SBINDEST)
- -$(INSTALL) -cs -g wheel -m 755 -o root ipmon $(BINDEST)
- -$(INSTALL) -cs -g wheel -m 755 -o root ipftest $(BINDEST)
+ @for i in ipf:$(SBINDEST) ipfs:$(SBINDEST) ipnat:$(SBINDEST) \
+ ipfstat:$(SBINDEST) ipftest:$(SBINDEST) ipmon:$(BINDEST); do \
+ def="`expr $$i : '[^:]*:\(.*\)'`"; \
+ p="`expr $$i : '\([^:]*\):.*'`"; \
+ for d in $(BINDEST) $(SBINDEST); do \
+ if [ -f $$d/$$i ] ; then \
+ echo "$(INSTALL) -cs -g wheel -m 755 -o root $$p $$d"; \
+ $(INSTALL) -cs -g wheel -m 755 -o root $$p $$d; \
+ dd=$$d; \
+ fi; \
+ done; \
+ if [ -z "$$dd" ] ; then \
+ echo $(INSTALL) -cs -g wheel -m 755 -o root $$p $$def; \
+ $(INSTALL) -cs -g wheel -m 755 -o root $$p $$def; \
+ fi \
+ done
(cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP))
diff --git a/contrib/ipfilter/BSD/kupgrade b/contrib/ipfilter/BSD/kupgrade
index 2159a29dc091..092f3ab05a85 100644
--- a/contrib/ipfilter/BSD/kupgrade
+++ b/contrib/ipfilter/BSD/kupgrade
@@ -9,13 +9,17 @@ argv0=`basename $0`
dir=`pwd`
karch=`uname -m`
archdir="/sys/arch/$karch"
+ipfdir=/sys/netinet
+if [ -d /sys/contrib/ipfilter ] ; then
+ ipfdir=/sys/contrib/ipfilter/netinet
+fi
confdir="$archdir/conf"
echo -n "Installing "
-for i in ip_fil.[ch] fil.c ip_nat.[ch] ip_frag.[ch] ip_state.[ch] ip_proxy.[ch] ip_auth.[ch] ip_log.c ip_compat.h ipl.h ip_ftp_pxy.c ip_rcmd_pxy.c ip_raudio_pxy.c ; do
+for i in ip_fil.[ch] fil.c ip_nat.[ch] ip_frag.[ch] ip_state.[ch] ip_proxy.[ch] ip_auth.[ch] ip_log.c ip_compat.h ipl.h ip_*_pxy.c ; do
echo -n "$i "
- cp $i /sys/netinet/
- chmod 644 /sys/netinet/$i
+ cp $i $ipfdir
+ chmod 644 $ipfdir/$i
done
echo ""
if [ -f /sys/netinet/ip_fil_compat.h ] ; then
diff --git a/contrib/ipfilter/FreeBSD-2.2/kinstall b/contrib/ipfilter/FreeBSD-2.2/kinstall
index 94b5009cb236..9ecadc4ce2c2 100755
--- a/contrib/ipfilter/FreeBSD-2.2/kinstall
+++ b/contrib/ipfilter/FreeBSD-2.2/kinstall
@@ -9,11 +9,17 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
- ip_proxy.[ch] ip_{ftp,rcmd}_pxy.c mlf_ipl.c ipl.h ip_compat.h \
+ ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c ipl.h ip_compat.h \
ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
+ switch ( $i )
+ case *.h:
+ /bin/cp $i /usr/include/netinet/$i
+ chmod 644 /usr/include/netinet/$i
+ breaksw
+ endsw
end
echo ""
echo "Copying /usr/include/osreldate.h to /sys/sys"
diff --git a/contrib/ipfilter/FreeBSD-3/kinstall b/contrib/ipfilter/FreeBSD-3/kinstall
index c77f446ea444..8282de731d21 100755
--- a/contrib/ipfilter/FreeBSD-3/kinstall
+++ b/contrib/ipfilter/FreeBSD-3/kinstall
@@ -9,11 +9,17 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
- ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c ipl.h \
+ ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c ipl.h \
ip_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
+ switch ( $i )
+ case *.h:
+ /bin/cp $i /usr/include/netinet/$i
+ chmod 644 /usr/include/netinet/$i
+ breaksw
+ endsw
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
diff --git a/contrib/ipfilter/FreeBSD-4.0/kinstall b/contrib/ipfilter/FreeBSD-4.0/kinstall
index b3ed4542e30e..9e34e33328bc 100755
--- a/contrib/ipfilter/FreeBSD-4.0/kinstall
+++ b/contrib/ipfilter/FreeBSD-4.0/kinstall
@@ -2,27 +2,38 @@
#
set dir=`pwd`
set karch=`uname -m`
+set ipfdir=/sys/netinet
set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
+if ( -d /sys/contrib/ipfilter ) set ipfdir=/sys/contrib/ipfilter/netinet
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
- ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c mlfk_ipl.c \
+ ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c mlfk_ipl.c \
ipl.h ip_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
- cp $i /sys/netinet
- chmod 644 /sys/netinet/$i
+ cp $i $ipfdir
+ chmod 644 $ipfdir/$i
+ switch ( $i )
+ case *.h:
+ /bin/cp $i /usr/include/netinet/$i
+ chmod 644 /usr/include/netinet/$i
+ breaksw
+ endsw
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
ln -s /usr/include/osreldate.h /sys/sys/osreldate.h
-echo ""
-echo "Patching ip6_input.c and ip6_output.c"
-cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch)
+patchfile=FreeBSd-4.0/ipv6-patch-$krev
+if ( -f $patchfile ) then
+ echo ""
+ echo "Patching ip6_input.c and ip6_output.c"
+ cat $patchfile | (cd /sys/netinet6; patch)
+endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
diff --git a/contrib/ipfilter/FreeBSD/kinstall b/contrib/ipfilter/FreeBSD/kinstall
index bb5aef50da4d..ef2db54b27cb 100755
--- a/contrib/ipfilter/FreeBSD/kinstall
+++ b/contrib/ipfilter/FreeBSD/kinstall
@@ -9,10 +9,16 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
- ip_proxy.[ch] ip_auth.[ch] ip_{ftp,rcmd}_pxy.c ip_compat.h ip_log.c)
+ ip_proxy.[ch] ip_auth.[ch] ip_*_pxy.c ip_compat.h ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
+ switch ( $i )
+ case *.h:
+ /bin/cp $i /usr/include/netinet/$i
+ chmod 644 /usr/include/netinet/$i
+ breaksw
+ endsw
end
echo ""
grep iplopen $archdir/$karch/conf.c >& /dev/null
diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY
index 584f4f20347d..80632b498e83 100644
--- a/contrib/ipfilter/HISTORY
+++ b/contrib/ipfilter/HISTORY
@@ -22,6 +22,219 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
+3.4.25 13/03/2002 - Released
+
+retain rule # in state information
+
+log the direction of a packet so ipmon gets it right rather than incorrectly
+deriving it from the rule flags
+
+add #ifdef for IPFILTER_LOGSIZE (put options IPFILTER_LOGSIZE=16384 in BSD
+kernel config files to increase that buffer size)
+
+recognise return-* rules differently to block in ipftest
+
+fix bug in ipmon output for solaris
+
+add regression testing for skip rules, logging and using head/group
+
+fix output of ipmon: was displaying large unsigned ints rather than -1
+when no rules matched.
+
+make logging code compile into ipftest and add -l command line option to
+dump binary log file (read with ipmon -f) when it finishes.
+
+protect rule # and group # from interference when checking accounting rules
+
+add regression testing for log output (text) from ipmon.
+
+document -b command line option for ipmon
+
+fix double-quick in Solaris startup script
+
+3.4.24 01/03/2002 - Released
+
+fix how files are installed on SunOS5
+
+fix some minor problems in SunOS5 ipfboot script
+
+by default, compile all OpenBSD tools in 3.0 for IPv6
+
+fix NULL-pointer dereference in NAT code
+
+make a better attempt at replacing the appropriate binaries on BSD systems
+
+always print IPv6 icmp-types as a number
+
+impose some rules about what "skip" can be used with
+
+fix parsing problems with "keep state" and "keep state-age"
+
+Try to read as much data as is in the log device in ipmon
+
+remove some redundant checks when searching for rdr/nat rules
+
+fix bug in handling of ACCT with FTP proxy
+
+increase array size for interface names, using LIFNAMSIZ
+
+include H.323 proxy from QNX
+
+3.4.23 16/01/2002 - Released
+
+Include patches to install IPFilter into OpenBSD 3.0, both for just kernel
+compiles and complete system builds.
+
+Fix bug in automatic flushing of state table which would cause it to hang
+in an infinite loop bug introduced in 3.4.20.
+
+Modify the sample proxy (samples/proxy.c) so that it ads a NAT mapping for
+the outgoing connection to make it look like it comes from the real source.
+
+Only support ICMPv6 with IPv6.
+
+Move ipnat.1 to ipnat.8
+
+Enhance ipmon to print textual ICMP[v6] types and subtypes where possible.
+
+Make it possible to do IPv6 regression testing with ipftest.
+
+Use kvm library for kmem access, rather than trying to do it manually with
+open/lseek/read.
+
+Fix diffs for ip_input.c on BSDOS so it doesn't crash with fastroute.
+
+Remove Berkeley advertising licence clause. Reference:
+ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
+
+Add more regression tests: ICMPv6 neighbour discovery, ICMP time exceeded
+and fragmentation required.
+
+Fix ipfboot script on Solaris to deal with no nameservers or no route to
+them in a clean manner.
+
+Support per-rule set timeouts for non-TCP NAT and state
+
+Add netbios proxy
+
+Add ICMPv6 stateful checking, including handling multicast destination
+addresses for neighbour discovery.
+
+Fix problems with internals of ICMP messages for MTU discovery and
+unreachables not being correctly adjust on little endian boxes.
+
+Add "in-via" and "out-via" to filtering rules grammar. It is now possible
+to bind a rule to both incoming and outgoing interfaces, in both forward
+and reverse directions (4 directions in total). allows for asymetric flows
+through a firewall.
+
+Fix ipfstat and ipnat for working on crash dumps.
+
+Don't let USE_INET6 stay defined for SunOS4
+
+Count things we see for each interface on solaris.
+
+Include <netinet/icmp6.h> when compiling with USE_INET6 defined and
+also include a whole bunch of #define's to make sure the symbols expected
+can be used.
+
+Fix up fastroute on BSD systems.
+
+Make fastrouting work for IPv6 just a bit better. doesn't split up big
+packets into fragments like the IPv4 one does. You can now do a
+"to <if>:<ipv6_addr>"
+
+Remove some of the differences between user-space and kernel-space code
+that is internal to ipfilter.
+
+Call ipfr_slowtimer() after each packet is processed in ipftest to artificially
+create the illusion of passing time and include the expire functions in the
+code compiled for user-space.
+
+Fix issues with the IPSec proxy not working or leading to a system crash.
+
+Junk all processing of SPIs and special handling for ESP.
+
+Add "no-match" as a filter rule action (resets _LAST_ match)
+
+Add hack to workaround problems with Cassini interface cards on
+Solaris and VLANs
+
+Add some protocols to etc/protocols
+
+3.4.22 03/12/2001 - Released
+
+various openbsd changes
+
+sorting based on IP numbers for ipfstat top output
+
+fix various IPv6 code & compile problems
+
+modify ip_fil.c to be more netbsd friendly
+
+fix fastroute bug where it modified a packet post-sending
+
+fix get_unit() - don't understand why it was broken.
+
+add FI_IGNOREPKT and don't count so marked packets when doing stats or
+state/nat.
+
+extend the interface name saved to log output
+
+make proxies capable of extending the matching done on a packet with a
+particular nat session
+
+change interfaces inside NAT & state code to accomodate redesign to allow
+IPsec proxy to work.
+
+fix bug when free'ing loaded rules that results in a memory leak
+(only an issue with "ipf -rf -", not flush)
+
+make ipftest capable of loading > 1 file or rules, making it now possible
+to load both NAT & filter rules
+
+fix hex input for ipftest to allow interface name & direction to work
+
+show ipsec proxy details in ipnat output
+
+if OPT_HEX is set in opts, print a packet out as hex
+
+don't modify b_next or preseve it or preserve b_prev for solaris
+
+fix up kinstall scripts to install all the files everywhere they need to
+
+fix overflowing of bits in ip_off inside iptest
+
+make userauth and proxy in samples directory compile
+
+fix minimum size when doing a pullup for ESP & ICMPv6
+
+3.4.21 24/10/2001 - Released
+
+include ipsec proxy
+
+make state work for non-tcp/udp/icmp in a very simple way
+
+include diffs for ipv6 firewall on openbsd-2.9
+
+add compatibility filter wrapper for NetBSD-current
+
+fix command line option problems with ipfs
+
+if we fill the state table and a automated flush doesn't purge any
+expiring entries, remove all entries idle for more than half a day
+
+fix bug with sending resets/icmp errors where the pointer to the data
+section of the packet was not being set (BSD only)
+
+split out validating ftp commands and responses into different halves,
+one for each of server & client.
+
+do not compile in STATETOP support for specific architectures
+
+fix INSTALL.FreeBSD to no longer provide directions and properly direct
+people to the right file for the right version of FreeBSD.
+
3.4.20 24/07/2001 - Released
adjust NAT hashing to give a better spread across the table
diff --git a/contrib/ipfilter/INSTALL.FreeBSD b/contrib/ipfilter/INSTALL.FreeBSD
index 66ad297bf9ca..c732bacfaa29 100644
--- a/contrib/ipfilter/INSTALL.FreeBSD
+++ b/contrib/ipfilter/INSTALL.FreeBSD
@@ -1,51 +1,7 @@
-*** IF you are using FreeBSD 2.2.x, see the file "INST.FreeBSD-2.2" ***
-*** IF you are using FreeBSD 3 or later, see the file "INST.FreeBSD-3" ***
-*** in the "FreeBSD-3" directory ***
-
-
-To build a kernel for use with the loadable kernel module, follow these
-steps:
- 1. do "make freebsd"
-
- 2. do "make install-bsd"
- (probably has to be done as root)
-
- 3. run "FreeBSD/minstall" as root
-
- 4. build a new kernel
-
- 5. install and reboot with the new kernel
-
- 6. use modload(8) to load the packet filter with:
- modload if_ipl.o
-
- 7. do "modstat" to confirm that it has been loaded successfully.
-
-There is no need to use mknod to create the device in /dev;
-- upon loading the module, it will create itself with the correct values,
- under the name (IPL_NAME) from the Makefile. It will also remove itself
- from /dev when it is modunload'd.
-
-To build a kernel with the IP filter, follow these steps:
-
- 1. do "make freebsd"
-
- 2. do "make install-bsd"
- (probably has to be done as root)
-
- 3. run "FreeBSD/kinstall" as root
-
- 4. build a new kernel
-
- 5. create devices for IP Filter as follows (assuming it was
- installed into the device table as char dev 20):
- mknod /dev/ipl c 20 0
- mknod /dev/ipnat c 20 1
- mknod /dev/ipstate c 20 2
- mknod /dev/ipauth c 20 3
-
- 6. install and reboot with the new kernel
+*** IF you are using FreeBSD 2.2.x, see the file "INST.FreeBSD-2.2" ***
+*** IF you are using FreeBSD 3.x, see the file "FreeBSD-3/INST.FreeBSD-3" ***
+*** IF you are using FreeBSD 4.x, see the file "FreeBSD-4.0/INST.FreeBSD-4" ***
Darren Reed
darrenr@pobox.com
diff --git a/contrib/ipfilter/IPFILTER.LICENCE b/contrib/ipfilter/IPFILTER.LICENCE
index a8f6abb121c9..2b4b67e86fd9 100644
--- a/contrib/ipfilter/IPFILTER.LICENCE
+++ b/contrib/ipfilter/IPFILTER.LICENCE
@@ -1,4 +1,4 @@
-Copyright (C) 1993-2001 by Darren Reed.
+Copyright (C) 1993-2002 by Darren Reed.
The author accepts no responsibility for the use of this software and
provides it on an ``as is'' basis without express or implied warranty.
diff --git a/contrib/ipfilter/Makefile b/contrib/ipfilter/Makefile
index 09b5db60b50a..9cc636ba7c39 100644
--- a/contrib/ipfilter/Makefile
+++ b/contrib/ipfilter/Makefile
@@ -3,7 +3,7 @@
#
# See the IPFILTER.LICENCE file for details on licencing.
#
-# $Id: Makefile,v 2.11.2.8 2001/06/26 10:43:10 darrenr Exp $
+# $Id: Makefile,v 2.11.2.13 2002/03/06 09:43:15 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@@ -34,7 +34,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
# Uncomment the next 3 lines if you want to view the state table a la top(1)
# (requires that you have installed ncurses).
-#STATETOP_CFLAGS=-DSTATETOP
+STATETOP_CFLAGS=-DSTATETOP
#
# Where to find the ncurses include files (if not in default path),
#
@@ -43,7 +43,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
# How to link the ncurses library
#
-#STATETOP_LIB=-lncurses
+STATETOP_LIB=-lcurses
#STATETOP_LIB=-L/usr/local/lib -lncurses
#
@@ -59,7 +59,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
-MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6)' \
+MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6) $(IPFLOG)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \
@@ -100,7 +100,7 @@ tests:
include:
if [ ! -f netinet/done ] ; then \
- (cd netinet; ln -s ../*.h .; ln -s ../ip_ftp_pxy.c .; ln -s ../ip_rcmd_pxy.c .; ln -s ../ip_raudio_pxy.c .); \
+ (cd netinet; ln -s ../*.h .; ln -s ../ip_*_pxy.c .; ); \
(cd netinet; ln -s ../ipsend/tcpip.h tcpip.h); \
touch netinet/done; \
fi
@@ -168,8 +168,8 @@ bsdi bsdos: include
irix IRIX: include
make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
- -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.std build TOP=../.. $(DEST) $(MFLAGS); else smake build TOP=../.. $(DEST) $(MFLAGS); fi;)
- -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.ipsend.std TOP=../.. $(DEST) $(MFLAGS); else smake -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); fi)
+ -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.std build TOP=../.. $(DEST) SGI=`../getrev` $(MFLAGS); else smake build SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi;)
+ -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.ipsend.std SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); else smake -f Makefile.ipsend SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi)
linux: include
make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
@@ -258,7 +258,7 @@ install-bsd:
(cd BSD/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
install-sunos4: solaris
- (cd SunOS4; $(MAKE) "CPU=$(CPU) TOP=.." install)
+ (cd SunOS4; $(MAKE) "CPU=$(CPU)" "TOP=.." install)
install-sunos5: solaris
(cd SunOS5; $(MAKE) "CPUDIR=`uname -p`-`uname -r`" "CPU=$(CPU) TOP=.." install)
diff --git a/contrib/ipfilter/common.c b/contrib/ipfilter/common.c
index e46e63ec20d8..b3319c53aba9 100644
--- a/contrib/ipfilter/common.c
+++ b/contrib/ipfilter/common.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
@@ -44,9 +47,7 @@ static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 da
extern struct ipopt_names ionames[], secclass[];
extern int opts;
-#ifdef USE_INET6
extern int use_inet6;
-#endif
char *proto = NULL;
@@ -54,10 +55,8 @@ char flagset[] = "FSRPAUEC";
u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
TH_ECN, TH_CWR };
-#ifdef USE_INET6
void fill6bits __P((int, u_32_t *));
int count6bits __P((u_32_t *));
-#endif
static char thishost[MAXHOSTNAMELEN];
@@ -95,30 +94,24 @@ u_32_t *mskp;
* set x most significant bits
*/
bits = (int)strtol(msk, &endptr, 0);
-#ifdef USE_INET6
if ((*endptr != '\0') ||
((bits > 32) && !use_inet6) || (bits < 0) ||
((bits > 128) && use_inet6))
-#else
- if (*endptr != '\0' || bits > 32 || bits < 0)
-#endif
return -1;
-#ifdef USE_INET6
if (use_inet6)
fill6bits(bits, mskp);
- else
-#endif
- if (bits == 0)
- *mskp = 0;
- else
- *mskp = htonl(0xffffffff << (32 - bits));
+ else {
+ if (bits == 0)
+ *mskp = 0;
+ else
+ *mskp = htonl(0xffffffff << (32 - bits));
+ }
}
return 0;
}
-#ifdef USE_INET6
void fill6bits(bits, msk)
int bits;
u_32_t *msk;
@@ -134,7 +127,6 @@ u_32_t *msk;
while (i < 4)
msk[i++] = 0;
}
-#endif
/*
@@ -197,7 +189,6 @@ int linenum;
return -1;
}
(*seg)++;
-#ifdef USE_INET6
if (use_inet6) {
u_32_t k = 0;
if (sa[0] || sa[1] || sa[2] || sa[3])
@@ -205,8 +196,7 @@ int linenum;
msk[0] = msk[1] = msk[2] = msk[3] = k;
}
else
-#endif
- *msk = *sa ? 0xffffffff : 0;
+ *msk = *sa ? 0xffffffff : 0;
return ports(seg, pp, cp, tp, linenum);
}
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
@@ -448,7 +438,6 @@ u_32_t ip;
}
-#ifdef USE_INET6
int count6bits(msk)
u_32_t *msk;
{
@@ -465,7 +454,6 @@ u_32_t *msk;
}
return i;
}
-#endif
char *portname(pr, port)
@@ -596,3 +584,27 @@ int len, zend;
break;
}
}
+
+
+
+char *hostname(v, ip)
+int v;
+void *ip;
+{
+#ifdef USE_INET6
+ static char hostbuf[MAXHOSTNAMELEN+1];
+#endif
+ struct in_addr ipa;
+
+ if (v == 4) {
+ ipa.s_addr = *(u_32_t *)ip;
+ return inet_ntoa(ipa);
+ }
+#ifdef USE_INET6
+ (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
+ hostbuf[MAXHOSTNAMELEN] = '\0';
+ return hostbuf;
+#else
+ return "IPv6";
+#endif
+}
diff --git a/contrib/ipfilter/etc/protocols b/contrib/ipfilter/etc/protocols
index b41aa1df4372..fd7a1d246be1 100644
--- a/contrib/ipfilter/etc/protocols
+++ b/contrib/ipfilter/etc/protocols
@@ -47,11 +47,15 @@ rsvp 46 RSVP # Reservation Protocol
gre 47 GRE # General Routing Encapsulation
mhrp 48 MHRP # Mobile Host Routing Protocol
bna 49 BNA # BNA
-sipp-esp 50 SIPP-ESP # SIPP Encap Security Payload
-sipp-ah 51 SIPP-AH # SIPP Authentication Header
+esp 50 esp # Encap Security Payload
+ah 51 AH # Authentication Header
i-nlsp 52 I-NLSP # Integrated Net Layer Security TUBA
swipe 53 SWIPE # IP with Encryption
nhrp 54 NHRP # NBMA Next Hop Resolution Protocol
+mobile 55 MOBILE # IP Mobility (IP tunneling)
+ipv6-icmp 58 icmpv6 IPv6-ICMP ICMPv6 # ICMP version 6
+ipv6-nonxt 59 IPv6-Nonxt # No Next Header for IPv6
+ipv6-opts 60 IPv6-Opts # Destination Options for IPv6
any 61 any # host internal protocol
cftp 62 CFTP # CFTP
any 63 any # local network
@@ -92,4 +96,6 @@ etherip 97 ETHERIP # Ethernet-within-IP Encapsulation
encap 98 ENCAP # Encapsulation Header
any 99 any # private encryption scheme
gmtp 100 GMTP # GMTP
+pim 103 PIM # Protocol Independant Multicast
+ipcomp 108 IPCOMP # IP Payload Compression Protocol
reserved 255 Reserved #
diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c
index c4cd2e041168..06623c357ebb 100644
--- a/contrib/ipfilter/fil.c
+++ b/contrib/ipfilter/fil.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -34,7 +37,6 @@
# include <string.h>
# include <stdlib.h>
#endif
-#include <sys/uio.h>
#if !defined(__SVR4) && !defined(__svr4__)
# ifndef linux
# include <sys/mbuf.h>
@@ -77,10 +79,10 @@
#endif
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.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"
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@@ -95,7 +97,7 @@
#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.35.2.39 2001/07/18 13:30:32 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $";
#endif
#ifndef _KERNEL
@@ -105,7 +107,7 @@ extern int opts;
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
-# define IPLLOG(a, c, d, e) ipllog()
+# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
#else /* #ifndef _KERNEL */
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
@@ -260,7 +262,7 @@ fr_info_t *fin;
fin->fin_off = off;
fin->fin_plen = plen;
- fin->fin_dp = (void *)tcp;
+ fin->fin_dp = (char *)tcp;
off <<= 3;
switch (p)
@@ -280,7 +282,7 @@ fr_info_t *fin;
{
case ICMP6_ECHO_REPLY :
case ICMP6_ECHO_REQUEST :
- minicmpsz = ICMP6ERR_MINPKTLEN;
+ minicmpsz = ICMP6_MINLEN;
break;
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
@@ -380,6 +382,19 @@ getports:
fin->fin_data[1] = ntohs(tcp->th_dport);
}
break;
+ case IPPROTO_ESP :
+#ifdef USE_INET6
+ if (v == 6) {
+ if (plen < 8)
+ fi->fi_fl |= FI_SHORT;
+ } else
+#endif
+ if (v == 4) {
+ if (((ip->ip_len < hlen + 8) && !off) ||
+ (off && off < 8))
+ fi->fi_fl |= FI_SHORT;
+ }
+ break;
default :
break;
}
@@ -545,8 +560,8 @@ fr_info_t *fin;
* Could be per interface, but this gets real nasty when you don't have
* kernel sauce.
*/
-int fr_scanlist(pass, ip, fin, m)
-u_32_t pass;
+int fr_scanlist(passin, ip, fin, m)
+u_32_t passin;
ip_t *ip;
register fr_info_t *fin;
void *m;
@@ -554,20 +569,21 @@ void *m;
register struct frentry *fr;
register fr_ip_t *fi = &fin->fin_fi;
int rulen, portcmp = 0, off, skip = 0, logged = 0;
- u_32_t passt;
+ u_32_t pass, passt, passl;
+ frentry_t *frl;
+ frl = NULL;
+ pass = passin;
fr = fin->fin_fr;
fin->fin_fr = NULL;
- fin->fin_rule = 0;
- fin->fin_group = 0;
off = fin->fin_off;
- pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
portcmp = 1;
for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
if (skip) {
+ FR_VERBOSE(("%d (%#x)\n", skip, fr->fr_flags));
skip--;
continue;
}
@@ -578,25 +594,28 @@ void *m;
* check that we are working for the right interface
*/
#ifdef _KERNEL
-# if BSD >= 199306
+# if (BSD >= 199306)
if (fin->fin_out != 0) {
if ((fr->fr_oifa &&
- fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif) ||
- (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp))
+ (fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif)))
continue;
- } else
+ }
# endif
- if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
- continue;
#else
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
- FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
- (pass & FR_AUTH) ? 'a' : 'b'));
+#endif
+
+ FR_VERBOSE(("%c", fr->fr_skip ? 's' :
+ (pass & FR_PASS) ? 'p' :
+ (pass & FR_AUTH) ? 'a' :
+ (pass & FR_ACCOUNT) ? 'A' :
+ (pass & FR_NOMATCH) ? 'n' : 'b'));
+
if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
continue;
+
FR_VERBOSE((":i"));
-#endif
{
register u_32_t *ld, *lm, *lip;
register int i;
@@ -618,22 +637,19 @@ void *m;
/*
* Unrolled loops (4 each, for 32 bits).
*/
- i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
} else {
lip += 3;
lm += 3;
@@ -642,23 +658,19 @@ void *m;
i ^= (fr->fr_flags & FR_NOTSRCIP);
if (i)
continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
} else {
lip += 3;
lm += 3;
@@ -667,14 +679,12 @@ void *m;
i ^= (fr->fr_flags & FR_NOTDSTIP);
if (i)
continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
FR_DEBUG(("3. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
+ i |= ((*lip++ & *lm++) != *ld++);
FR_DEBUG(("4. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip & *lm) != *ld);
if (i)
continue;
}
@@ -701,17 +711,30 @@ void *m;
}
}
FR_VERBOSE(("*"));
- /*
- * Just log this packet...
- */
+
+ if (fr->fr_flags & FR_NOMATCH) {
+ passt = passl;
+ passl = passin;
+ fin->fin_fr = frl;
+ frl = NULL;
+ if (fr->fr_flags & FR_QUICK)
+ break;
+ continue;
+ }
+
+ passl = passt;
passt = fr->fr_flags;
+ frl = fin->fin_fr;
+ fin->fin_fr = fr;
#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
if (securelevel <= 0)
#endif
if ((passt & FR_CALLNOW) && fr->fr_func)
passt = (*fr->fr_func)(passt, ip, fin);
- fin->fin_fr = fr;
#ifdef IPFILTER_LOG
+ /*
+ * Just log this packet...
+ */
if ((passt & FR_LOGMASK) == FR_LOG) {
if (!IPLLOG(passt, ip, fin, m)) {
if (passt & FR_LOGORBLOCK)
@@ -722,32 +745,33 @@ void *m;
logged = 1;
}
#endif /* IPFILTER_LOG */
- if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
- pass = passt;
- FR_DEBUG(("pass %#x\n", pass));
ATOMIC_INCL(fr->fr_hits);
- if (pass & FR_ACCOUNT)
+ if (passt & FR_ACCOUNT)
fr->fr_bytes += (U_QUAD_T)ip->ip_len;
else
fin->fin_icode = fr->fr_icode;
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
- if (fr->fr_grp) {
+ if (fr->fr_grp != NULL) {
fin->fin_fr = fr->fr_grp;
- pass = fr_scanlist(pass, ip, fin, m);
+ passt = fr_scanlist(passt, ip, fin, m);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
fin->fin_fr = fr;
}
- if (pass & FR_DONTCACHE)
+ if (passt & FR_DONTCACHE)
logged = 1;
}
- if (pass & FR_QUICK)
+ if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
+ pass = passt;
+ FR_DEBUG(("pass %#x\n", pass));
+ if (passt & FR_QUICK)
break;
}
if (logged)
pass |= FR_DONTCACHE;
+ pass |= (fi->fi_fl << 24);
return pass;
}
@@ -803,7 +827,7 @@ int out;
/*
* disable delayed checksums.
*/
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if ((out != 0) && (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
@@ -844,6 +868,9 @@ int out;
case IPPROTO_ICMP:
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
+ case IPPROTO_ESP:
+ plen = 8;
+ break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
@@ -906,20 +933,26 @@ int out;
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
- logit = -2;
+ if (fr_minttllog & 1)
+ logit = -3;
+ if (fr_minttllog & 2)
+ drop = 1;
}
} else
# endif
if (!out) {
if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
- if (fr_chksrc == 2)
+ if (fr_chksrc & 1)
+ drop = 1;
+ if (fr_chksrc & 2)
logit = -2;
} else if (ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
+ if (fr_minttllog & 1)
logit = -3;
+ if (fr_minttllog & 2)
+ drop = 1;
}
}
if (drop) {
@@ -1010,6 +1043,7 @@ int out;
FI_COPYSIZE);
if (pass & FR_NOMATCH) {
ATOMIC_INCL(frstats[out].fr_nom);
+ fin->fin_fr = NULL;
}
}
} else
@@ -1023,11 +1057,7 @@ int out;
*/
if ((pass & FR_AUTH)) {
if (fr_newauth((mb_t *)m, fin, ip) != 0) {
-#ifdef _KERNEL
m = *mp = NULL;
-#else
- ;
-#endif
error = 0;
} else
error = ENOSPC;
@@ -1057,7 +1087,7 @@ int out;
}
}
if (pass & FR_KEEPSTATE) {
- if (fr_addstate(ip, fin, 0) == NULL) {
+ if (fr_addstate(ip, fin, NULL, 0) == NULL) {
ATOMIC_INCL(frstats[out].fr_bads);
} else {
ATOMIC_INCL(frstats[out].fr_ads);
@@ -1086,11 +1116,19 @@ int out;
else
#endif
list = ipacct[1][fr_active];
- if ((fin->fin_fr = list) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[1].fr_acct);
+ if (list != NULL) {
+ u_32_t sg, sr;
+
+ fin->fin_fr = list;
+ sg = fin->fin_group;
+ sr = fin->fin_rule;
+ if (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT) {
+ ATOMIC_INCL(frstats[1].fr_acct);
+ }
+ fin->fin_group = sg;
+ fin->fin_rule = sr;
+ fin->fin_fr = fr;
}
- fin->fin_fr = fr;
changed = ip_natout(ip, fin);
} else
fin->fin_fr = fr;
@@ -1134,10 +1172,10 @@ logit:
# if SOLARIS
mc = dupmsg(m);
# else
-# ifndef linux
- mc = m_copy(m, 0, M_COPYALL);
+# if defined(__OpenBSD__) && (OpenBSD >= 199905)
+ mc = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
# else
- ;
+ mc = m_copy(m, 0, M_COPYALL);
# endif
# endif
#endif
@@ -1154,7 +1192,6 @@ logit:
* some operating systems.
*/
if (!out) {
-#ifdef _KERNEL
if (pass & FR_RETICMP) {
int dst;
@@ -1170,19 +1207,6 @@ logit:
ATOMIC_INCL(frstats[1].fr_ret);
}
}
-#else
- if ((pass & FR_RETMASK) == FR_RETICMP) {
- verbose("- ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if ((pass & FR_RETMASK) == FR_FAKEICMP) {
- verbose("- forged ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fl & FI_SHORT)) {
- verbose("- TCP RST sent\n");
- ATOMIC_INCL(frstats[1].fr_ret);
- }
-#endif
} else {
if (pass & FR_RETRST)
error = ECONNRESET;
@@ -1207,8 +1231,10 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
(void) ipfr_fastroute(m, mp, fin, fdp);
+ m = *mp;
+ }
if (mc != NULL)
(void) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
@@ -1243,6 +1269,12 @@ logit:
return 0;
if (pass & FR_AUTH)
return -2;
+ if ((pass & FR_RETMASK) == FR_RETRST)
+ return -3;
+ if ((pass & FR_RETMASK) == FR_RETICMP)
+ return -4;
+ if ((pass & FR_RETMASK) == FR_FAKEICMP)
+ return -5;
return -1;
#endif /* _KERNEL */
}
@@ -1464,7 +1496,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c
index 3ed698abb34f..b3bfae2758c6 100644
--- a/contrib/ipfilter/fils.c
+++ b/contrib/ipfilter/fils.c
@@ -12,6 +12,9 @@
# endif
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__svr4__)
@@ -21,8 +24,24 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/file.h>
-#if defined(STATETOP) && defined(sun) && !defined(__svr4__) && !defined(__SVR4)
-#include <sys/select.h>
+#if defined(STATETOP)
+# if defined(_BSDI_VERSION)
+# undef STATETOP)
+# endif
+# if defined(__FreeBSD__) && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000))
+# undef STATETOP
+# endif
+# if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000)
+# undef STATETOP
+# endif
+# if defined(sun)
+# if defined(__svr4__) || defined(__SVR4)
+# include <sys/select.h>
+# else
+# undef STATETOP /* NOT supported on SunOS4 */
+# endif
+# endif
#endif
#include <stdlib.h>
#include <unistd.h>
@@ -50,15 +69,16 @@
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "ipf.h"
-#include "netinet/ip_proxy.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"
#ifdef STATETOP
# include "netinet/ipl.h"
# include <ctype.h>
-# if SOLARIS
+# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \
+ defined(__sgi)
# ifdef ERR
# undef ERR
# endif
@@ -74,7 +94,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: fils.c,v 2.21.2.17 2001/07/19 12:24:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.34 2002/02/22 15:32:45 darrenr Exp $";
#endif
extern char *optarg;
@@ -89,9 +109,8 @@ static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
"ipacct(in)", "ipacct(out)" };
int opts = 0;
-#ifdef USE_INET6
int use_inet6 = 0;
-#endif
+int live_kernel = 1;
#ifdef STATETOP
#define STSTRSIZE 80
@@ -102,7 +121,9 @@ int use_inet6 = 0;
#define STSORT_PKTS 1
#define STSORT_BYTES 2
#define STSORT_TTL 3
-#define STSORT_MAX STSORT_TTL
+#define STSORT_SRCIP 4
+#define STSORT_DSTIP 5
+#define STSORT_MAX STSORT_DSTIP
#define STSORT_DEFAULT STSORT_BYTES
@@ -120,51 +141,33 @@ typedef struct statetop {
#endif
extern int main __P((int, char *[]));
-static void showstats __P((int, friostat_t *));
-static void showfrstates __P((int, ipfrstat_t *));
+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((int, ips_stat_t *));
-static void showauthstates __P((int, fr_authstat_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 printlist __P((frentry_t *));
-static char *get_ifname __P((void *));
-static char *hostname __P((int, void *));
static void parse_ipportstr __P((const char *, struct in_addr *, int *));
+static int 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((int, struct in_addr, struct in_addr, int, int, int, int, int));
+static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int));
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_dstip __P((const void *, const void *));
#endif
#if SOLARIS
void showqiflist __P((char *));
#endif
-static char *hostname(v, ip)
-int v;
-void *ip;
-{
-#ifdef USE_INET6
- static char hostbuf[MAXHOSTNAMELEN+1];
-#endif
- struct in_addr ipa;
-
- if (v == 4) {
- ipa.s_addr = *(u_32_t *)ip;
- return inet_ntoa(ipa);
- }
-#ifdef USE_INET6
- (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
- hostbuf[MAXHOSTNAMELEN] = '\0';
- return hostbuf;
-#else
- return "IPv6";
-#endif
-}
-
static void Usage(name)
char *name;
@@ -174,11 +177,8 @@ char *name;
#else
fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
#endif
- fprintf(stderr, "\t\t[-M corefile]");
-#if SOLARIS
- fprintf(stderr, " [-N symbol-list]");
-#endif
- fprintf(stderr, "\n %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
+ 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);
exit(1);
}
@@ -190,15 +190,13 @@ char *argv[];
fr_authstat_t frauthst;
fr_authstat_t *frauthstp = &frauthst;
friostat_t fio;
- friostat_t *fiop=&fio;
+ friostat_t *fiop = &fio;
ips_stat_t ipsst;
ips_stat_t *ipsstp = &ipsst;
ipfrstat_t ifrst;
ipfrstat_t *ifrstp = &ifrst;
- char *name = NULL, *device = IPL_NAME, *memf = NULL;
-#if SOLARIS
+ char *device = IPL_NAME, *memf = NULL;
char *kern = NULL;
-#endif
int c, fd, myoptind;
struct protoent *proto;
@@ -208,6 +206,8 @@ char *argv[];
int dport = -1; /* -1 = wild card for any dest port */
int topclosed = 0; /* do not show closed tcp sessions */
struct in_addr saddr, daddr;
+ u_32_t frf;
+
saddr.s_addr = INADDR_ANY; /* default any source addr */
daddr.s_addr = INADDR_ANY; /* default any dest addr */
@@ -216,45 +216,33 @@ char *argv[];
* in the parsing of the rest.
*/
myoptind = optind;
-#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
-#else
- while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:P:S:T:")) != -1)
-#endif
switch (c)
{
case 'M' :
memf = optarg;
+ live_kernel = 0;
break;
-#if SOLARIS
case 'N' :
kern = optarg;
+ live_kernel = 0;
break;
-#endif
}
optind = myoptind;
-#if SOLARIS
if (kern != NULL || memf != NULL)
-#else
- if (memf != NULL)
-#endif
{
(void)setuid(getuid());
(void)setgid(getgid());
}
- if (openkmem(memf) == -1)
+ if (openkmem(kern, memf) == -1)
exit(-1);
(void)setuid(getuid());
(void)setgid(getgid());
-#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
-#else
- while ((c = getopt(argc, argv, "6aACfghIilnostvd:D:M:P:S:T:")) != -1)
-#endif
{
switch (c)
{
@@ -265,7 +253,8 @@ char *argv[];
#endif
case 'a' :
opts |= OPT_ACCNT|OPT_SHOWLIST;
- break; case 'A' :
+ break;
+ case 'A' :
device = IPAUTH_NAME;
opts |= OPT_AUTHSTATS;
break;
@@ -316,11 +305,15 @@ char *argv[];
exit(-2);
}
break;
-#if SOLARIS
case 'q' :
+#if SOLARIS
showqiflist(kern);
exit(0);
break;
+#else
+ fprintf(stderr, "-q only availble on Solaris\n");
+ exit(1);
+ break;
#endif
case 's' :
opts |= OPT_IPSTATES;
@@ -356,19 +349,67 @@ char *argv[];
}
}
+ if (live_kernel == 1) {
+ bzero((char *)&fio, sizeof(fio));
+ bzero((char *)&ipsst, sizeof(ipsst));
+ bzero((char *)&ifrst, sizeof(ifrst));
+
+ fd = ipfstate_live(device, &fiop, &ipsstp, &ifrstp,
+ &frauthstp, &frf);
+ } else
+ ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf);
+
+ if (opts & OPT_IPSTATES) {
+ showipstates(ipsstp);
+ } else if (opts & OPT_SHOWLIST) {
+ showlist(fiop);
+ if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
+ opts &= ~OPT_OUTQUE;
+ showlist(fiop);
+ }
+ } else {
+ if (opts & OPT_FRSTATES)
+ showfrstates(ifrstp);
+#ifdef STATETOP
+ else if (opts & OPT_STATETOP)
+ topipstates(saddr, daddr, sport, dport,
+ protocol, refreshtime, topclosed);
+#endif
+ else if (opts & OPT_AUTHSTATS)
+ showauthstates(frauthstp);
+ else if (opts & OPT_GROUPS)
+ showgroups(fiop);
+ else
+ showstats(fiop, frf);
+ }
+ return 0;
+}
+
+
+/*
+ * Fill in the stats structures from the live kernel, using a combination
+ * of ioctl's and copying directly from kernel memory.
+ */
+int ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
+char *device;
+friostat_t **fiopp;
+ips_stat_t **ipsstpp;
+ipfrstat_t **ifrstpp;
+fr_authstat_t **frauthstpp;
+u_32_t *frfp;
+{
+ int fd;
+
if ((fd = open(device, O_RDONLY)) < 0) {
perror("open");
exit(-1);
}
- bzero((char *)&fio, sizeof(fio));
- bzero((char *)&ipsst, sizeof(ipsst));
- bzero((char *)&ifrst, sizeof(ifrst));
-
- if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) {
+ if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, fiopp) == -1) {
perror("ioctl(ipf:SIOCGETFS)");
exit(-1);
}
+
if ((opts & OPT_IPSTATES)) {
int sfd = open(IPL_STATE, O_RDONLY);
@@ -376,64 +417,237 @@ char *argv[];
perror("open");
exit(-1);
}
- if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
+ if ((ioctl(sfd, SIOCGETFS, ipsstpp) == -1)) {
perror("ioctl(state:SIOCGETFS)");
exit(-1);
}
close(sfd);
}
- if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrstp) == -1)) {
+ if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, ifrstpp) == -1)) {
perror("ioctl(SIOCGFRST)");
exit(-1);
}
if (opts & OPT_VERBOSE)
- PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
+ PRINTF("opts %#x name %s\n", opts, device);
if ((opts & OPT_AUTHSTATS) &&
- (ioctl(fd, SIOCATHST, &frauthstp) == -1)) {
+ (ioctl(fd, SIOCATHST, frauthstpp) == -1)) {
perror("ioctl(SIOCATHST)");
exit(-1);
}
- if (opts & OPT_IPSTATES) {
- showipstates(fd, ipsstp);
- } else if (opts & OPT_SHOWLIST) {
- showlist(&fio);
- if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
- opts &= ~OPT_OUTQUE;
- showlist(&fio);
- }
- } else {
- if (opts & OPT_FRSTATES)
- showfrstates(fd, ifrstp);
-#ifdef STATETOP
- else if (opts & OPT_STATETOP)
- topipstates(fd, saddr, daddr, sport, dport,
- protocol, refreshtime, topclosed);
-#endif
- else if (opts & OPT_AUTHSTATS)
- showauthstates(fd, frauthstp);
- else if (opts & OPT_GROUPS)
- showgroups(&fio);
- else
- showstats(fd, &fio);
+ if (ioctl(fd, SIOCGETFF, frfp) == -1)
+ perror("ioctl(SIOCGETFF)");
+
+ return fd;
+}
+
+
+/*
+ * Build up the stats structures from data held in the "core" memory.
+ * This is mainly useful when looking at data in crash dumps and ioctl's
+ * just won't work any more.
+ */
+void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
+char *kernel;
+friostat_t **fiopp;
+ips_stat_t **ipsstpp;
+ipfrstat_t **ifrstpp;
+fr_authstat_t **frauthstpp;
+u_32_t *frfp;
+{
+ static fr_authstat_t frauthst, *frauthstp;
+ static ips_stat_t ipsst, *ipsstp;
+ static ipfrstat_t ifrst, *ifrstp;
+ static friostat_t fio, *fiop;
+
+ void *rules[2][2];
+ struct nlist deadlist[42] = {
+ { "fr_authstats" }, /* 0 */
+ { "fae_list" },
+ { "ipauth" },
+ { "fr_authlist" },
+ { "fr_authstart" },
+ { "fr_authend" }, /* 5 */
+ { "fr_authnext" },
+ { "fr_auth" },
+ { "fr_authused" },
+ { "fr_authsize" },
+ { "fr_defaultauthage" }, /* 10 */
+ { "fr_authpkts" },
+ { "fr_auth_lock" },
+ { "frstats" },
+ { "ips_stats" },
+ { "ips_num" }, /* 15 */
+ { "ips_wild" },
+ { "ips_list" },
+ { "ips_table" },
+ { "fr_statemax" },
+ { "fr_statesize" }, /* 20 */
+ { "fr_state_doflush" },
+ { "fr_state_lock" },
+ { "ipfr_heads" },
+ { "ipfr_nattab" },
+ { "ipfr_stats" }, /* 25 */
+ { "ipfr_inuse" },
+ { "fr_ipfrttl" },
+ { "fr_frag_lock" },
+ { "ipfr_timer_id" },
+ { "fr_nat_lock" }, /* 30 */
+ { "ipfilter" },
+ { "ipfilter6" },
+ { "ipacct" },
+ { "ipacct6" },
+ { "ipl_frouteok" }, /* 35 */
+ { "fr_running" },
+ { "ipfgroups" },
+ { "fr_active" },
+ { "fr_pass" },
+ { "fr_flags" }, /* 40 */
+ { NULL }
+ };
+
+
+ frauthstp = &frauthst;
+ ipsstp = &ipsst;
+ ifrstp = &ifrst;
+ fiop = &fio;
+
+ *frfp = 0;
+ *fiopp = fiop;
+ *ipsstpp = ipsstp;
+ *ifrstpp = ifrstp;
+ *frauthstpp = frauthstp;
+
+ bzero((char *)fiop, sizeof(*fiop));
+ bzero((char *)ipsstp, sizeof(*ipsstp));
+ bzero((char *)ifrstp, sizeof(*ifrstp));
+ bzero((char *)frauthstp, sizeof(*frauthstp));
+
+ if (nlist(kernel, deadlist) == -1) {
+ fprintf(stderr, "nlist error\n");
+ return;
}
- return 0;
+
+ /*
+ * This is for SIOCGETFF.
+ */
+ kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp));
+
+ /*
+ * f_locks is a combination of the lock variable from each part of
+ * ipfilter (state, auth, nat, fragments).
+ */
+ kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop));
+ kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value,
+ sizeof(fiop->f_locks[0]));
+ kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value,
+ sizeof(fiop->f_locks[1]));
+ kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value,
+ sizeof(fiop->f_locks[2]));
+ kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value,
+ sizeof(fiop->f_locks[3]));
+
+ /*
+ * Get pointers to each list of rules (active, inactive, in, out)
+ */
+ kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules));
+ fiop->f_fin[0] = rules[0][0];
+ fiop->f_fin[1] = rules[0][1];
+ fiop->f_fout[0] = rules[1][0];
+ fiop->f_fout[1] = rules[1][1];
+
+ /*
+ * Same for IPv6, except make them null if support for it is not
+ * being compiled in.
+ */
+#ifdef USE_INET6
+ kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules));
+ fiop->f_fin6[0] = rules[0][0];
+ fiop->f_fin6[1] = rules[0][1];
+ fiop->f_fout6[0] = rules[1][0];
+ fiop->f_fout6[1] = rules[1][1];
+#else
+ fiop->f_fin6[0] = NULL;
+ fiop->f_fin6[1] = NULL;
+ fiop->f_fout6[0] = NULL;
+ fiop->f_fout6[1] = NULL;
+#endif
+
+ /*
+ * Now get accounting rules pointers.
+ */
+ kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules));
+ fiop->f_acctin[0] = rules[0][0];
+ fiop->f_acctin[1] = rules[0][1];
+ fiop->f_acctout[0] = rules[1][0];
+ fiop->f_acctout[1] = rules[1][1];
+
+#ifdef USE_INET6
+ kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules));
+ fiop->f_acctin6[0] = rules[0][0];
+ fiop->f_acctin6[1] = rules[0][1];
+ fiop->f_acctout6[0] = rules[1][0];
+ fiop->f_acctout6[1] = rules[1][1];
+#else
+ fiop->f_acctin6[0] = NULL;
+ fiop->f_acctin6[1] = NULL;
+ fiop->f_acctout6[0] = NULL;
+ fiop->f_acctout6[1] = NULL;
+#endif
+
+ /*
+ * A collection of "global" variables used inside the kernel which
+ * are all collected in friostat_t via ioctl.
+ */
+ kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value,
+ sizeof(fiop->f_froute));
+ kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value,
+ sizeof(fiop->f_running));
+ kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value,
+ sizeof(fiop->f_groups));
+ kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value,
+ sizeof(fiop->f_active));
+ kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value,
+ sizeof(fiop->f_defpass));
+
+ /*
+ * Build up the state information stats structure.
+ */
+ kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp));
+ kmemcpy((char *)&ipsstp->iss_active, (u_long)deadlist[15].n_value,
+ sizeof(ipsstp->iss_active));
+ ipsstp->iss_table = (void *)deadlist[18].n_value;
+ ipsstp->iss_list = (void *)deadlist[17].n_value;
+
+ /*
+ * Build up the authentiation information stats structure.
+ */
+ kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value,
+ sizeof(*frauthstp));
+ frauthstp->fas_faelist = (void *)deadlist[1].n_value;
+
+ /*
+ * Build up the fragment information stats structure.
+ */
+ kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value,
+ sizeof(*ifrstp));
+ ifrstp->ifs_table = (void *)deadlist[23].n_value;
+ ifrstp->ifs_nattab = (void *)deadlist[24].n_value;
+ kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value,
+ sizeof(ifrstp->ifs_inuse));
}
/*
- * read the kernel stats for packets blocked and passed
+ * Display the kernel stats for packets blocked and passed and other
+ * associated running totals which are kept.
*/
-static void showstats(fd, fp)
-int fd;
+static void showstats(fp, frf)
struct friostat *fp;
+u_32_t frf;
{
- u_32_t frf = 0;
-
- if (ioctl(fd, SIOCGETFF, &frf) == -1)
- perror("ioctl(SIOCGETFF)");
#if SOLARIS
PRINTF("dropped packets:\tin %lu\tout %lu\n",
@@ -505,6 +719,9 @@ struct friostat *fp;
}
+/*
+ * Print out a list of rules from the kernel, starting at the one passed.
+ */
static void printlist(fp)
frentry_t *fp;
{
@@ -543,7 +760,8 @@ frentry_t *fp;
}
/*
- * print out filter rule list
+ * print out all of the asked for rule sets, using the stats struct as
+ * the base from which to get the pointers.
*/
static void showlist(fiop)
struct friostat *fiop;
@@ -598,12 +816,17 @@ struct friostat *fiop;
}
-static void showipstates(fd, ipsp)
-int fd;
+/*
+ * Display ipfilter stateful filtering information
+ */
+static void showipstates(ipsp)
ips_stat_t *ipsp;
{
- ipstate_t *istab[IPSTATE_SIZE], ips;
+ ipstate_t *istab[IPSTATE_SIZE];
+ /*
+ * If a list of states hasn't been asked for, only print out stats
+ */
if (!(opts & OPT_SHOWLIST)) {
PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n",
ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp);
@@ -619,116 +842,20 @@ ips_stat_t *ipsp;
if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
return;
- while (ipsp->iss_list) {
- if (kmemcpy((char *)&ips, (u_long)ipsp->iss_list, sizeof(ips)))
- break;
- ipsp->iss_list = ips.is_next;
- PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4));
- PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n",
- hostname(ips.is_v, &ips.is_dst.in4),
- ips.is_age, ips.is_pass, ips.is_p,
- ips.is_state[0], ips.is_state[1]);
-#ifdef USE_QUAD_T
- PRINTF("\tpkts %qu bytes %qu",
- (unsigned long long) ips.is_pkts,
- (unsigned long long) ips.is_bytes);
-#else
- PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes);
-#endif
- if (ips.is_p == IPPROTO_TCP)
-#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- (__FreeBSD_version >= 220000) || defined(__OpenBSD__)
- PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
- ntohs(ips.is_sport), ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
-#else
- PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
- ntohs(ips.is_sport), ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
-#endif
- else if (ips.is_p == IPPROTO_UDP)
- PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
- ntohs(ips.is_dport));
- else if (ips.is_p == IPPROTO_ICMP
-#ifdef USE_INET6
- || ips.is_p == IPPROTO_ICMPV6
-#endif
- )
- PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
- ips.is_icmp.ics_seq, ips.is_icmp.ics_type);
-
- PRINTF("\n\t");
-
- if (ips.is_pass & FR_PASS) {
- PRINTF("pass");
- } else if (ips.is_pass & FR_BLOCK) {
- PRINTF("block");
- switch (ips.is_pass & FR_RETMASK)
- {
- case FR_RETICMP :
- PRINTF(" return-icmp");
- break;
- case FR_FAKEICMP :
- PRINTF(" return-icmp-as-dest");
- break;
- case FR_RETRST :
- PRINTF(" return-rst");
- break;
- default :
- break;
- }
- } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
- PRINTF("log");
- if (ips.is_pass & FR_LOGBODY)
- PRINTF(" body");
- if (ips.is_pass & FR_LOGFIRST)
- PRINTF(" first");
- } else if (ips.is_pass & FR_ACCOUNT)
- PRINTF("count");
-
- if (ips.is_pass & FR_OUTQUE)
- PRINTF(" out");
- else
- PRINTF(" in");
-
- if ((ips.is_pass & FR_LOG) != 0) {
- PRINTF(" log");
- if (ips.is_pass & FR_LOGBODY)
- PRINTF(" body");
- if (ips.is_pass & FR_LOGFIRST)
- PRINTF(" first");
- if (ips.is_pass & FR_LOGORBLOCK)
- PRINTF(" or-block");
- }
- if (ips.is_pass & FR_QUICK)
- PRINTF(" quick");
- if (ips.is_pass & FR_KEEPFRAG)
- PRINTF(" keep frags");
- /* a given; no? */
- if (ips.is_pass & FR_KEEPSTATE)
- PRINTF(" keep state");
- 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_security & %x = %x, pkt_auth & %x = %x\n",
- ips.is_secmsk, ips.is_sec, ips.is_authmsk,
- ips.is_auth);
- PRINTF("\tinterfaces: in %s[%p] ",
- get_ifname(ips.is_ifpin), ips.is_ifpin);
- PRINTF("out %s[%p]\n",
- get_ifname(ips.is_ifpout), ips.is_ifpout);
+ /*
+ * Print out all the state information currently held in the kernel.
+ */
+ while (ipsp->iss_list != NULL) {
+ ipsp->iss_list = printstate(ipsp->iss_list, opts);
}
}
#if SOLARIS
+/*
+ * Displays the list of interfaces of which IPFilter has taken control in
+ * Solaris.
+ */
void showqiflist(kern)
char *kern;
{
@@ -737,6 +864,7 @@ char *kern;
{ NULL }
};
qif_t qif, *qf;
+ ill_t ill;
if (kern == NULL)
kern = "/dev/ksyms";
@@ -752,24 +880,27 @@ char *kern;
while (qf) {
if (kmemcpy((char *)&qif, (u_long)qf, sizeof(qif)))
break;
- printf("\tName: %-8s Header Length: %2d SAP: %s (%04x)\n",
+ if (kmemcpy((char *)&ill, (u_long)qif.qf_ill, sizeof(ill)))
+ ill.ill_ppa = -1;
+ printf("Name: %-8s Header Length: %2d SAP: %s (%04x) PPA %d",
qif.qf_name, qif.qf_hl,
#ifdef IP6_DL_SAP
(qif.qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
- , qif.qf_sap);
+ , qif.qf_sap, ill.ill_ppa);
+ printf(" %ld %ld", qif.qf_incnt, qif.qf_outcnt);
qf = qif.qf_next;
+ putchar('\n');
}
}
#endif
#ifdef STATETOP
-static void topipstates(fd, saddr, daddr, sport, dport, protocol,
+static void topipstates(saddr, daddr, sport, dport, protocol,
refreshtime, topclosed)
-int fd;
struct in_addr saddr;
struct in_addr daddr;
int sport;
@@ -841,8 +972,8 @@ int topclosed;
((dport < 0) ||
(htons(dport) == ips.is_dport)))) &&
(topclosed || (ips.is_p != IPPROTO_TCP) ||
- (ips.is_state[0] < TCPS_CLOSE_WAIT) ||
- (ips.is_state[1] < TCPS_CLOSE_WAIT))) {
+ (ips.is_state[0] < TCPS_LAST_ACK) ||
+ (ips.is_state[1] < TCPS_LAST_ACK))) {
/*
* if necessary make room for this state
* entry
@@ -899,6 +1030,14 @@ int topclosed;
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_ttl);
break;
+ case STSORT_SRCIP:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_srcip);
+ break;
+ case STSORT_DSTIP:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_dstip);
+ break;
default:
break;
}
@@ -957,6 +1096,12 @@ int topclosed;
case STSORT_TTL:
sprintf(str4, "ttl");
break;
+ case STSORT_SRCIP:
+ sprintf(str4, "srcip");
+ break;
+ case STSORT_DSTIP:
+ sprintf(str4, "dstip");
+ break;
default:
sprintf(str4, "unknown");
break;
@@ -1079,14 +1224,20 @@ int topclosed;
}
#endif
-static void showfrstates(fd, ifsp)
-int fd;
+
+/*
+ * Show fragment cache information that's held in the kernel.
+ */
+static void showfrstates(ifsp)
ipfrstat_t *ifsp;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
frentry_t fr;
int i;
+ /*
+ * print out the numeric statistics
+ */
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 no memory\n\t%lu already exist\n",
@@ -1094,6 +1245,10 @@ ipfrstat_t *ifsp;
PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab)))
return;
+
+ /*
+ * Print out the contents (if any) of the fragment cache table.
+ */
for (i = 0; i < IPFT_SIZE; i++)
while (ipfrtab[i]) {
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
@@ -1129,8 +1284,10 @@ ipfrstat_t *ifsp;
}
-static void showauthstates(fd, asp)
-int fd;
+/*
+ * Show stats on how auth within IPFilter has been used
+ */
+static void showauthstates(asp)
fr_authstat_t *asp;
{
frauthent_t *frap, fra;
@@ -1161,63 +1318,10 @@ fr_authstat_t *asp;
}
-static char *get_ifname(ptr)
-void *ptr;
-{
-#if SOLARIS
- char *ifname;
- ill_t ill;
-
- if (ptr == (void *)-1)
- return "!";
- if (ptr == NULL)
- return "-";
-
- if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
- return "X";
- ifname = malloc(ill.ill_name_length + 1);
- if (kmemcpy(ifname, (u_long)ill.ill_name,
- ill.ill_name_length) == -1)
- return "X";
- return ifname;
-#else
-# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
-#else
- char buf[32];
- int len;
-# endif
- struct ifnet netif;
-
- if (ptr == (void *)-1)
- return "!";
- if (ptr == NULL)
- return "-";
-
- if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
- return "X";
-# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
- return strdup(netif.if_xname);
-# else
- if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
- return "X";
- if (netif.if_unit < 10)
- len = 2;
- else if (netif.if_unit < 1000)
- len = 3;
- else if (netif.if_unit < 10000)
- len = 4;
- else
- len = 5;
- buf[sizeof(buf) - len] = '\0';
- sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
- return strdup(buf);
-# endif
-#endif
-}
-
-
+/*
+ * Display groups used for each of filter rules, accounting rules and
+ * authentication, separately.
+ */
static void showgroups(fiop)
struct friostat *fiop;
{
@@ -1370,4 +1474,32 @@ const void *b;
return 1;
return -1;
}
+
+static int sort_srcip(a, b)
+const void *a;
+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))
+ 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_dstip(a, b)
+const void *a;
+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))
+ return 0;
+ else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr))
+ return 1;
+ return -1;
+}
#endif
diff --git a/contrib/ipfilter/inet_addr.c b/contrib/ipfilter/inet_addr.c
index 03bcf2319698..e940280a280a 100644
--- a/contrib/ipfilter/inet_addr.c
+++ b/contrib/ipfilter/inet_addr.c
@@ -65,7 +65,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 2.1.4.1 2001/07/15 22:06:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.1.4.2 2002/02/22 15:32:46 darrenr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -182,7 +182,8 @@ inet_aton(cp, addr)
* Ascii internet address interpretation routine.
* The value returned is in network order.
*/
-#if defined(SOLARIS2) && (SOLARIS2 > 5)
+#if (defined(SOLARIS2) && (SOLARIS2 > 5)) || \
+ (defined(IRIX) && (IRIX >= 605))
in_addr_t
#else
u_long
diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c
index b22d470b6095..e4ad347280c7 100644
--- a/contrib/ipfilter/ip_auth.c
+++ b/contrib/ipfilter/ip_auth.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -19,7 +22,6 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -102,7 +104,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#endif
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.12 2001/07/18 14:57:08 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.17 2002/03/06 09:44:10 darrenr Exp $";
#endif
@@ -305,7 +307,7 @@ ip_t *ip;
int fr_auth_ioctl(data, mode, cmd, fr, frptr)
caddr_t data;
int mode;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
u_long cmd;
#else
int cmd;
@@ -377,9 +379,7 @@ frentry_t *fr, **frptr;
error = EINVAL;
break;
case SIOCATHST:
- READ_ENTER(&ipf_auth);
fr_authstats.fas_faelist = fae_list;
- RWLOCK_EXIT(&ipf_auth);
error = IWCOPYPTR((char *)&fr_authstats, data,
sizeof(fr_authstats));
break;
@@ -453,7 +453,7 @@ fr_authioctlloop:
bzero((char *)&ro, sizeof(ro));
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
- defined(__OpenBSD__)
+ defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605))
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
# else
@@ -478,7 +478,9 @@ fr_authioctlloop:
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
+# if IRIX < 605
schednetisr(NETISR_IP);
+# endif
}
# endif /* SOLARIS */
if (error)
@@ -526,7 +528,6 @@ fr_authioctlloop:
}
-#ifdef _KERNEL
/*
* Free all network buffer memory used to keep saved packets.
*/
@@ -587,7 +588,7 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
-#if !SOLARIS
+#if !SOLARIS && defined(_KERNEL)
int s;
#endif
@@ -626,4 +627,3 @@ void fr_authexpire()
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
-#endif
diff --git a/contrib/ipfilter/ip_auth.h b/contrib/ipfilter/ip_auth.h
index 7d3e46316d10..cb168c4ca959 100644
--- a/contrib/ipfilter/ip_auth.h
+++ b/contrib/ipfilter/ip_auth.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_auth.h,v 2.3.2.4 2001/07/18 14:57:08 darrenr Exp $
+ * $Id: ip_auth.h,v 2.3.2.5 2001/11/04 13:15:51 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@@ -52,7 +52,8 @@ extern void fr_authexpire __P((void));
extern void fr_authunload __P((void));
extern mb_t *fr_authpkts[];
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || \
+ (__FreeBSD_version >= 300003)
extern int fr_auth_ioctl __P((caddr_t, int, u_long, frentry_t *, frentry_t **));
#else
extern int fr_auth_ioctl __P((caddr_t, int, int, frentry_t *, frentry_t **));
diff --git a/contrib/ipfilter/ip_compat.h b/contrib/ipfilter/ip_compat.h
index a7d0db4f07a8..4eab541231a6 100644
--- a/contrib/ipfilter/ip_compat.h
+++ b/contrib/ipfilter/ip_compat.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.26.2.17 2001/07/23 04:22:48 darrenr Exp $
+ * $Id: ip_compat.h,v 2.26.2.39 2002/03/13 03:54:34 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -25,14 +25,21 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#if SOLARIS && !defined(SOLARIS2)
-# define SOLARIS2 4 /* Pick an old version */
-#endif
-#if SOLARIS2 >= 8
-# ifndef USE_INET6
-# define USE_INET6
+#if SOLARIS
+# if !defined(SOLARIS2)
+# define SOLARIS2 3 /* Pick an old version */
+# endif
+# if SOLARIS2 >= 8
+# ifndef USE_INET6
+# define USE_INET6
+# endif
+# else
+# undef USE_INET6
# endif
#endif
+#if defined(sun) && !(defined(__svr4__) || defined(__SVR4))
+# undef USE_INET6
+#endif
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
@@ -62,6 +69,18 @@ struct ether_addr {
};
#endif
+#ifndef LIFNAMSIZ
+# ifdef IF_NAMESIZE
+# define LIFNAMSIZ IF_NAMESIZE
+# else
+# ifdef IFNAMSIZ
+# define LIFNAMSIZ IFNAMSIZ
+# else
+# define LIFNAMSIZ 16
+# endif
+# endif
+#endif
+
#if defined(__sgi) && !defined(IPFILTER_LKM)
# ifdef __STDC__
# define IPL_EXTERN(ep) ipfilter##ep
@@ -76,12 +95,37 @@ struct ether_addr {
# endif
#endif
+#ifdef __sgi
+# include <sys/debug.h>
+#endif
+
#ifdef linux
# include <sys/sysmacros.h>
#endif
+
+
+/*
+ * 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__
+struct file;
+#endif
+#include <sys/uio.h>
+#ifdef ADD_KERNEL
+# undef _KERNEL
+# undef KERNEL
+#endif
+
#if SOLARIS
# define MTYPE(m) ((m)->b_datap->db_type)
-# include <sys/isa_defs.h>
+# if SOLARIS2 >= 4
+# include <sys/isa_defs.h>
+# endif
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
# include <sys/kmem.h>
@@ -137,12 +181,14 @@ typedef struct qif {
queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
size_t qf_off;
size_t qf_len; /* this field is used for in ipfr_fastroute */
- char qf_name[8];
+ char qf_name[LIFNAMSIZ];
/*
* in case the ILL has disappeared...
*/
size_t qf_hl; /* header length */
int qf_sap;
+ size_t qf_incnt;
+ size_t qf_outcnt;
} qif_t;
#else /* SOLARIS */
# if !defined(__sgi)
@@ -210,6 +256,7 @@ typedef unsigned int u_32_t;
# endif
typedef struct ip6_hdr ip6_t;
# endif
+# include <netinet/icmp6.h>
union i6addr {
u_32_t i6[4];
struct in_addr in4;
@@ -225,6 +272,14 @@ union i6addr {
#define IP6CMP(a,b) bcmp((char *)&(a), (char *)&(b), sizeof(a))
#define IP6EQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) == 0)
#define IP6NEQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) != 0)
+#define IP6_ISZERO(a) ((((union i6addr *)(a))->i6[0] | \
+ ((union i6addr *)(a))->i6[1] | \
+ ((union i6addr *)(a))->i6[2] | \
+ ((union i6addr *)(a))->i6[3]) == 0)
+#define IP6_NOTZERO(a) ((((union i6addr *)(a))->i6[0] | \
+ ((union i6addr *)(a))->i6[1] | \
+ ((union i6addr *)(a))->i6[2] | \
+ ((union i6addr *)(a))->i6[3]) != 0)
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -325,6 +380,21 @@ union i6addr {
* Build some macros and #defines to enable the same code to compile anywhere
* Well, that's the idea, anyway :-)
*/
+#if SOLARIS
+typedef mblk_t mb_t;
+# if SOLARIS2 >= 7
+# ifdef lint
+# define ALIGN32(ptr) (ptr ? 0L : 0L)
+# define ALIGN16(ptr) (ptr ? 0L : 0L)
+# else
+# define ALIGN32(ptr) (ptr)
+# define ALIGN16(ptr) (ptr)
+# endif
+# endif
+#else
+typedef struct mbuf mb_t;
+#endif /* SOLARIS */
+
#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
# define ATOMIC_INCL ATOMIC_INC
# define ATOMIC_INC64 ATOMIC_INC
@@ -506,11 +576,19 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# define GET_MINOR(x) minor(x)
# endif
# if (BSD >= 199306) || defined(__FreeBSD__)
-# include <vm/vm.h>
+# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \
+ defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_BSDI_VERSION)
+# include <vm/vm.h>
+# endif
# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
-# include <vm/vm_extern.h>
-# include <sys/proc.h>
+# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \
+ (defined(OpenBSD) && (OpenBSD >= 200111))
+# include <uvm/uvm_extern.h>
+# else
+# include <vm/vm_extern.h>
extern vm_map_t kmem_map;
+# endif
+# include <sys/proc.h>
# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# include <vm/vm_kern.h>
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
@@ -542,7 +620,7 @@ extern vm_map_t kmem_map;
# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
# define PANIC(x,y) if (x) panic y
#else /* KERNEL */
-# define SLEEP(x,y) ;
+# define SLEEP(x,y) 1
# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define ATOMIC_INC(x) (x)++
@@ -564,40 +642,18 @@ extern vm_map_t kmem_map;
# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
+# define FREE_MB_T(x) ;
# define GETUNIT(x, v) get_unit(x,v)
# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
+# define IFNAME(x) get_ifname((struct ifnet *)x)
+# 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 *));
#endif /* KERNEL */
-#if SOLARIS
-typedef mblk_t mb_t;
-# if SOLARIS2 >= 7
-# ifdef lint
-# define ALIGN32(ptr) (ptr ? 0L : 0L)
-# define ALIGN16(ptr) (ptr ? 0L : 0L)
-# else
-# define ALIGN32(ptr) (ptr)
-# define ALIGN16(ptr) (ptr)
-# endif
-# endif
-#else
-# ifdef linux
-# ifndef kernel
-typedef struct mb {
- struct mb *next;
- u_int len;
- u_char *data;
-} mb_t;
-# else
-typedef struct sk_buff mb_t;
-# endif
-# else
-typedef struct mbuf mb_t;
-# endif
-#endif /* SOLARIS */
-
/*
* These #ifdef's are here mainly for linux, but who knows, they may
* not be in other places or maybe one day linux will grow up and some
@@ -606,38 +662,152 @@ typedef struct mbuf mb_t;
#ifndef ICMP_MINLEN
# define ICMP_MINLEN 8
#endif
+#ifndef ICMP_ECHOREPLY
+# define ICMP_ECHOREPLY 0
+#endif
#ifndef ICMP_UNREACH
-# define ICMP_UNREACH ICMP_DEST_UNREACH
+# define ICMP_UNREACH 3
+#endif
+#ifndef ICMP_UNREACH_NET
+# define ICMP_UNREACH_NET 0
+#endif
+#ifndef ICMP_UNREACH_HOST
+# define ICMP_UNREACH_HOST 1
+#endif
+#ifndef ICMP_UNREACH_PROTOCOL
+# define ICMP_UNREACH_PROTOCOL 2
+#endif
+#ifndef ICMP_UNREACH_PORT
+# define ICMP_UNREACH_PORT 3
+#endif
+#ifndef ICMP_UNREACH_NEEDFRAG
+# define ICMP_UNREACH_NEEDFRAG 4
+#endif
+#ifndef ICMP_UNREACH_SRCFAIL
+# define ICMP_UNREACH_SRCFAIL 5
+#endif
+#ifndef ICMP_UNREACH_NET_UNKNOWN
+# define ICMP_UNREACH_NET_UNKNOWN 6
+#endif
+#ifndef ICMP_UNREACH_HOST_UNKNOWN
+# define ICMP_UNREACH_HOST_UNKNOWN 7
+#endif
+#ifndef ICMP_UNREACH_ISOLATED
+# define ICMP_UNREACH_ISOLATED 8
+#endif
+#ifndef ICMP_UNREACH_NET_PROHIB
+# define ICMP_UNREACH_NET_PROHIB 9
+#endif
+#ifndef ICMP_UNREACH_HOST_PROHIB
+# define ICMP_UNREACH_HOST_PROHIB 10
+#endif
+#ifndef ICMP_UNREACH_TOSNET
+# define ICMP_UNREACH_TOSNET 11
+#endif
+#ifndef ICMP_UNREACH_TOSHOST
+# define ICMP_UNREACH_TOSHOST 12
+#endif
+#ifndef ICMP_UNREACH_ADMIN_PROHIBIT
+# define ICMP_UNREACH_ADMIN_PROHIBIT 13
+#endif
+#ifndef ICMP_UNREACH_HOST_PRECEDENCE
+# define ICMP_UNREACH_HOST_PRECEDENCE 14
+#endif
+#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
+# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
#endif
#ifndef ICMP_SOURCEQUENCH
-# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+# define ICMP_SOURCEQUENCH 4
+#endif
+#ifndef ICMP_REDIRECT_NET
+# define ICMP_REDIRECT_NET 0
+#endif
+#ifndef ICMP_REDIRECT_HOST
+# define ICMP_REDIRECT_HOST 1
+#endif
+#ifndef ICMP_REDIRECT_TOSNET
+# define ICMP_REDIRECT_TOSNET 2
+#endif
+#ifndef ICMP_REDIRECT_TOSHOST
+# define ICMP_REDIRECT_TOSHOST 3
+#endif
+#ifndef ICMP_ALTHOSTADDR
+# define ICMP_ALTHOSTADDR 6
#endif
#ifndef ICMP_TIMXCEED
-# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+# define ICMP_TIMXCEED 11
+#endif
+#ifndef ICMP_TIMXCEED_INTRANS
+# define ICMP_TIMXCEED_INTRANS 0
+#endif
+#ifndef ICMP_TIMXCEED_REASS
+# define ICMP_TIMXCEED_REASS 1
#endif
#ifndef ICMP_PARAMPROB
-# define ICMP_PARAMPROB ICMP_PARAMETERPROB
+# define ICMP_PARAMPROB 12
+#endif
+#ifndef ICMP_PARAMPROB_ERRATPTR
+# define ICMP_PARAMPROB_ERRATPTR 0
+#endif
+#ifndef ICMP_PARAMPROB_OPTABSENT
+# define ICMP_PARAMPROB_OPTABSENT 1
+#endif
+#ifndef ICMP_PARAMPROB_LENGTH
+# define ICMP_PARAMPROB_LENGTH 2
#endif
#ifndef ICMP_TSTAMP
-# define ICMP_TSTAMP ICMP_TIMESTAMP
+# define ICMP_TSTAMP 13
#endif
#ifndef ICMP_TSTAMPREPLY
-# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
+# define ICMP_TSTAMPREPLY 14
#endif
#ifndef ICMP_IREQ
-# define ICMP_IREQ ICMP_INFO_REQUEST
+# define ICMP_IREQ 15
#endif
#ifndef ICMP_IREQREPLY
-# define ICMP_IREQREPLY ICMP_INFO_REPLY
+# define ICMP_IREQREPLY 16
#endif
#ifndef ICMP_MASKREQ
-# define ICMP_MASKREQ ICMP_ADDRESS
+# define ICMP_MASKREQ 17
#endif
#ifndef ICMP_MASKREPLY
-# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
+# define ICMP_MASKREPLY 18
#endif
-#ifndef ICMP_PARAMPROB_OPTABSENT
-# define ICMP_PARAMPROB_OPTABSENT 1
+#ifndef ICMP_TRACEROUTE
+# define ICMP_TRACEROUTE 30
+#endif
+#ifndef ICMP_DATACONVERR
+# define ICMP_DATACONVERR 31
+#endif
+#ifndef ICMP_MOBILE_REDIRECT
+# define ICMP_MOBILE_REDIRECT 32
+#endif
+#ifndef ICMP_IPV6_WHEREAREYOU
+# define ICMP_IPV6_WHEREAREYOU 33
+#endif
+#ifndef ICMP_IPV6_IAMHERE
+# define ICMP_IPV6_IAMHERE 34
+#endif
+#ifndef ICMP_MOBILE_REGREQUEST
+# define ICMP_MOBILE_REGREQUEST 35
+#endif
+#ifndef ICMP_MOBILE_REGREPLY
+# define ICMP_MOBILE_REGREPLY 36
+#endif
+#ifndef ICMP_SKIP
+# define ICMP_SKIP 39
+#endif
+#ifndef ICMP_PHOTURIS
+# define ICMP_PHOTURIS 40
+#endif
+#ifndef ICMP_PHOTURIS_UNKNOWN_INDEX
+# define ICMP_PHOTURIS_UNKNOWN_INDEX 1
+#endif
+#ifndef ICMP_PHOTURIS_AUTH_FAILED
+# define ICMP_PHOTURIS_AUTH_FAILED 2
+#endif
+#ifndef ICMP_PHOTURIS_DECRYPT_FAILED
+# define ICMP_PHOTURIS_DECRYPT_FAILED 3
#endif
#ifndef IPVERSION
# define IPVERSION 4
@@ -726,6 +896,15 @@ typedef struct mbuf mb_t;
#ifndef IPOPT_OLEN
# define IPOPT_OLEN 1
#endif
+#ifndef IPPROTO_GRE
+# define IPPROTO_GRE 47 /* GRE encaps RFC 1701 */
+#endif
+#ifndef IPPROTO_ESP
+# define IPPROTO_ESP 50
+#endif
+#ifndef IPPROTO_ICMPV6
+# define IPPROTO_ICMPV6 58
+#endif
#ifdef linux
#include <linux/in_systm.h>
@@ -997,6 +1176,10 @@ struct ether_addr {
#define A_A &
#endif
+#if (BSD >= 199306) && !defined(m_act)
+# define m_act m_nextpkt
+#endif
+
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
@@ -1016,9 +1199,170 @@ struct ether_addr {
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
+#define ICMP6_MINLEN 8
#define ICMP6ERR_MINPKTLEN (40 + 8)
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
+#ifndef ICMP6_DST_UNREACH
+# define ICMP6_DST_UNREACH 1
+#endif
+#ifndef ICMP6_PACKET_TOO_BIG
+# define ICMP6_PACKET_TOO_BIG 2
+#endif
+#ifndef ICMP6_TIME_EXCEEDED
+# define ICMP6_TIME_EXCEEDED 3
+#endif
+#ifndef ICMP6_PARAM_PROB
+# define ICMP6_PARAM_PROB 4
+#endif
+
+#ifndef ICMP6_ECHO_REQUEST
+# define ICMP6_ECHO_REQUEST 128
+#endif
+#ifndef ICMP6_ECHO_REPLY
+# define ICMP6_ECHO_REPLY 129
+#endif
+#ifndef ICMP6_MEMBERSHIP_QUERY
+# define ICMP6_MEMBERSHIP_QUERY 130
+#endif
+#ifndef MLD6_LISTENER_QUERY
+# define MLD6_LISTENER_QUERY 130
+#endif
+#ifndef ICMP6_MEMBERSHIP_REPORT
+# define ICMP6_MEMBERSHIP_REPORT 131
+#endif
+#ifndef MLD6_LISTENER_REPORT
+# define MLD6_LISTENER_REPORT 131
+#endif
+#ifndef ICMP6_MEMBERSHIP_REDUCTION
+# define ICMP6_MEMBERSHIP_REDUCTION 132
+#endif
+#ifndef MLD6_LISTENER_DONE
+# define MLD6_LISTENER_DONE 132
+#endif
+#ifndef ND_ROUTER_SOLICIT
+# define ND_ROUTER_SOLICIT 133
+#endif
+#ifndef ND_ROUTER_ADVERT
+# define ND_ROUTER_ADVERT 134
+#endif
+#ifndef ND_NEIGHBOR_SOLICIT
+# define ND_NEIGHBOR_SOLICIT 135
+#endif
+#ifndef ND_NEIGHBOR_ADVERT
+# define ND_NEIGHBOR_ADVERT 136
+#endif
+#ifndef ND_REDIRECT
+# define ND_REDIRECT 137
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING
+# define ICMP6_ROUTER_RENUMBERING 138
+#endif
+#ifndef ICMP6_WRUREQUEST
+# define ICMP6_WRUREQUEST 139
+#endif
+#ifndef ICMP6_WRUREPLY
+# define ICMP6_WRUREPLY 140
+#endif
+#ifndef ICMP6_FQDN_QUERY
+# define ICMP6_FQDN_QUERY 139
+#endif
+#ifndef ICMP6_FQDN_REPLY
+# define ICMP6_FQDN_REPLY 140
+#endif
+#ifndef ICMP6_NI_QUERY
+# define ICMP6_NI_QUERY 139
+#endif
+#ifndef ICMP6_NI_REPLY
+# define ICMP6_NI_REPLY 140
+#endif
+#ifndef MLD6_MTRACE_RESP
+# define MLD6_MTRACE_RESP 200
+#endif
+#ifndef MLD6_MTRACE
+# define MLD6_MTRACE 201
+#endif
+#ifndef ICMP6_HADISCOV_REQUEST
+# define ICMP6_HADISCOV_REQUEST 202
+#endif
+#ifndef ICMP6_HADISCOV_REPLY
+# define ICMP6_HADISCOV_REPLY 203
+#endif
+#ifndef ICMP6_MOBILEPREFIX_SOLICIT
+# define ICMP6_MOBILEPREFIX_SOLICIT 204
+#endif
+#ifndef ICMP6_MOBILEPREFIX_ADVERT
+# define ICMP6_MOBILEPREFIX_ADVERT 205
+#endif
+#ifndef ICMP6_MAXTYPE
+# define ICMP6_MAXTYPE 205
+#endif
+
+#ifndef ICMP6_DST_UNREACH_NOROUTE
+# define ICMP6_DST_UNREACH_NOROUTE 0
+#endif
+#ifndef ICMP6_DST_UNREACH_ADMIN
+# define ICMP6_DST_UNREACH_ADMIN 1
+#endif
+#ifndef ICMP6_DST_UNREACH_NOTNEIGHBOR
+# define ICMP6_DST_UNREACH_NOTNEIGHBOR 2
+#endif
+#ifndef ICMP6_DST_UNREACH_BEYONDSCOPE
+# define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#endif
+#ifndef ICMP6_DST_UNREACH_ADDR
+# define ICMP6_DST_UNREACH_ADDR 3
+#endif
+#ifndef ICMP6_DST_UNREACH_NOPORT
+# define ICMP6_DST_UNREACH_NOPORT 4
+#endif
+#ifndef ICMP6_TIME_EXCEED_TRANSIT
+# define ICMP6_TIME_EXCEED_TRANSIT 0
+#endif
+#ifndef ICMP6_TIME_EXCEED_REASSEMBLY
+# define ICMP6_TIME_EXCEED_REASSEMBLY 1
+#endif
+
+#ifndef ICMP6_NI_SUCCESS
+# define ICMP6_NI_SUCCESS 0
+#endif
+#ifndef ICMP6_NI_REFUSED
+# define ICMP6_NI_REFUSED 1
+#endif
+#ifndef ICMP6_NI_UNKNOWN
+# define ICMP6_NI_UNKNOWN 2
+#endif
+
+#ifndef ICMP6_ROUTER_RENUMBERING_COMMAND
+# define ICMP6_ROUTER_RENUMBERING_COMMAND 0
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING_RESULT
+# define ICMP6_ROUTER_RENUMBERING_RESULT 1
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET
+# define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255
+#endif
+
+#ifndef ICMP6_PARAMPROB_HEADER
+# define ICMP6_PARAMPROB_HEADER 0
+#endif
+#ifndef ICMP6_PARAMPROB_NEXTHEADER
+# define ICMP6_PARAMPROB_NEXTHEADER 1
+#endif
+#ifndef ICMP6_PARAMPROB_OPTION
+# define ICMP6_PARAMPROB_OPTION 2
+#endif
+
+#ifndef ICMP6_NI_SUBJ_IPV6
+# define ICMP6_NI_SUBJ_IPV6 0
+#endif
+#ifndef ICMP6_NI_SUBJ_FQDN
+# define ICMP6_NI_SUBJ_FQDN 1
+#endif
+#ifndef ICMP6_NI_SUBJ_IPV4
+# define ICMP6_NI_SUBJ_IPV4 2
+#endif
+
/*
* ECN is a new addition to TCP - RFC 2481
*/
diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c
index e15ff67b6534..1cac072015e6 100644
--- a/contrib/ipfilter/ip_fil.c
+++ b/contrib/ipfilter/ip_fil.c
@@ -16,7 +16,7 @@
#endif
#include <sys/param.h>
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
+ defined(_KERNEL) && !defined(_LKM)
# include "opt_ipfilter_log.h"
#endif
#if defined(__FreeBSD__) && !defined(__FreeBSD_version)
@@ -24,6 +24,9 @@
# include <osreldate.h>
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#ifndef _KERNEL
# include <stdio.h>
# include <string.h>
@@ -44,7 +47,6 @@
#ifdef _KERNEL
# include <sys/systm.h>
#endif
-#include <sys/uio.h>
#if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@@ -93,12 +95,16 @@
#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
+# if !SOLARIS
+# include <netinet6/ip6protosw.h>
+# include <netinet6/nd6.h>
+# endif
#endif
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.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"
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@@ -113,7 +119,7 @@ extern int ip_optcopy __P((struct ip *, struct ip *));
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.34 2001/07/23 13:49:57 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.53 2002/03/13 02:29:08 darrenr Exp $";
#endif
@@ -144,15 +150,18 @@ static int frrequest __P((int, int, caddr_t, int));
#endif
#ifdef _KERNEL
static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
-static int send_ip __P((ip_t *, fr_info_t *, struct mbuf *));
+static int send_ip __P((ip_t *, fr_info_t *, struct mbuf **));
+# ifdef USE_INET6
+static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **,
+ fr_info_t *, frdest_t *));
+# endif
# ifdef __sgi
extern kmutex_t ipf_rw;
extern KRWLOCK_T ipf_mutex;
# endif
#else
-int ipllog __P((void));
void init_ifp __P((void));
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *));
static int write_output __P((struct ifnet *, struct mbuf *,
@@ -208,6 +217,77 @@ int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
# endif /* NETBSD_PF */
#endif /* __NetBSD__ */
+
+#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000) && \
+ defined(_KERNEL)
+# include <net/pfil.h>
+
+static int fr_check_wrapper(void *, struct mbuf **, struct ifnet *, int );
+
+static int fr_check_wrapper(arg, mp, ifp, dir)
+void *arg;
+struct mbuf **mp;
+struct ifnet *ifp;
+int dir;
+{
+ struct ip *ip = mtod(*mp, struct ip *);
+ int rv, hlen = ip->ip_hl << 2;
+
+#if defined(M_CSUM_TCPv4)
+ /*
+ * If the packet is out-bound, we can't delay checksums
+ * here. For in-bound, the checksum has already been
+ * validated.
+ */
+ if (dir == PFIL_OUT) {
+ if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
+ in_delayed_cksum(*mp);
+ (*mp)->m_pkthdr.csum_flags &=
+ ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
+ }
+ }
+#endif /* M_CSUM_TCPv4 */
+
+ /*
+ * We get the packet with all fields in network byte
+ * order. We expect ip_len and ip_off to be in host
+ * order. We frob them, call the filter, then frob
+ * them back.
+ *
+ * Note, we don't need to update the checksum, because
+ * it has already been verified.
+ */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+
+ rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
+
+ if (rv == 0 && *mp != NULL) {
+ ip = mtod(*mp, struct ip *);
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ }
+
+ return (rv);
+}
+
+# ifdef USE_INET6
+# include <netinet/ip6.h>
+
+static int fr_check_wrapper6(void *, struct mbuf **, struct ifnet *, int );
+
+static int fr_check_wrapper6(arg, mp, ifp, dir)
+void *arg;
+struct mbuf **mp;
+struct ifnet *ifp;
+int dir;
+{
+
+ return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
+ ifp, (dir == PFIL_OUT), mp));
+}
+# endif
+#endif /* __NetBSD_Version >= 105110000 && _KERNEL */
#ifdef _KERNEL
# if defined(IPFILTER_LKM) && !defined(__sgi)
int iplidentify(s)
@@ -228,19 +308,32 @@ void
ipfilterattach(count)
int count;
{
- if (iplattach() != 0)
- printf("IP Filter failed to attach\n");
+
+ /*
+ * Do nothing here, really. The filter will be enabled
+ * by the SIOCFRENB ioctl.
+ */
}
# endif
+# if defined(__NetBSD__)
+int ipl_enable()
+# else
int iplattach()
+# endif
{
char *defpass;
int s;
# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000))
int error = 0;
# endif
+#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000)
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+#endif
SPL_NET(s);
if (fr_running || (fr_checkp == fr_check)) {
@@ -267,8 +360,24 @@ int iplattach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
+# if __NetBSD_Version__ >= 105110000
+ if (
+ !(ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET))
+# ifdef USE_INET6
+ && !(ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6))
+# endif
+ )
+ return ENODEV;
+
+ if (ph_inet != NULL)
+ error = pfil_add_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet);
+ else
+ error = 0;
+# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
if (error) {
# ifdef USE_INET6
goto pfil_error;
@@ -284,11 +393,22 @@ int iplattach()
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet6 != NULL)
+ error = pfil_add_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+ else
+ error = 0;
+ if (error) {
+ pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
if (error) {
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
pfil_error:
SPL_X(s);
appr_unload();
@@ -355,11 +475,21 @@ pfil_error:
* Disable the filter by removing the hooks from the IP input/output
* stream.
*/
+# if defined(__NetBSD__)
+int ipl_disable()
+# else
int ipldetach()
+# endif
{
int s, i = FR_INQUE|FR_OUTQUE;
#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
int error = 0;
+# if __NetBSD_Version__ >= 105150000
+ struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+# endif
+# endif
#endif
#ifdef _KERNEL
@@ -397,8 +527,16 @@ int ipldetach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet != NULL)
+ error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet);
+ else
+ error = 0;
+# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
if (error) {
SPL_X(s);
return error;
@@ -407,8 +545,16 @@ int ipldetach()
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet6 != NULL)
+ error = pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+ else
+ error = 0;
+# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
if (error) {
SPL_X(s);
return error;
@@ -530,7 +676,7 @@ int mode;
sizeof(iplused[IPL_LOGIPF]));
#endif
break;
-#if !defined(IPFILTER_LKM) && defined(_KERNEL)
+#if (!defined(IPFILTER_LKM) || defined(__NetBSD__)) && defined(_KERNEL)
case SIOCFRENB :
{
u_int enable;
@@ -542,9 +688,17 @@ int mode;
if (error)
break;
if (enable)
+# if defined(__NetBSD__)
+ error = ipl_enable();
+# else
error = iplattach();
+# endif
else
+# if defined(__NetBSD__)
+ error = ipl_disable();
+# else
error = ipldetach();
+# endif
}
break;
}
@@ -711,11 +865,11 @@ caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
- frentry_t frd;
- frdest_t *fdp;
frgroup_t *fg = NULL;
+ int error = 0, in, i;
u_int *p, *pp;
- int error = 0, in;
+ frentry_t frd;
+ frdest_t *fdp;
u_int group;
fp = &frd;
@@ -764,18 +918,17 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
- if (*fp->fr_ifname) {
- fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_v);
- if (!fp->fr_ifa)
- fp->fr_ifa = (void *)-1;
- }
-#if BSD >= 199306
- if (*fp->fr_oifname) {
- fp->fr_oifa = GETUNIT(fp->fr_oifname, fp->fr_v);
- if (!fp->fr_oifa)
- fp->fr_oifa = (void *)-1;
+ for (i = 0; i < 4; i++) {
+ if ((fp->fr_ifnames[i][1] == '\0') &&
+ ((fp->fr_ifnames[i][0] == '-') ||
+ (fp->fr_ifnames[i][0] == '*'))) {
+ fp->fr_ifas[i] = NULL;
+ } else if (*fp->fr_ifnames[i]) {
+ fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v);
+ if (!fp->fr_ifas[i])
+ fp->fr_ifas[i] = (void *)-1;
+ }
}
-#endif
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
@@ -854,6 +1007,7 @@ caddr_t data;
fixskip(fprev, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
+ f->fr_ref--;
if (f->fr_ref == 0)
KFREE(f);
}
@@ -1002,7 +1156,7 @@ fr_info_t *fin;
if (m == NULL)
return -1;
- tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
+ tlen = fin->fin_dlen - (tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
@@ -1044,7 +1198,7 @@ fr_info_t *fin;
ip6->ip6_dst = oip6->ip6_src;
tcp2->th_sum = in6_cksum(m, IPPROTO_TCP,
sizeof(*ip6), sizeof(*tcp2));
- return send_ip(oip, fin, m);
+ return send_ip(oip, fin, &m);
}
# endif
ip->ip_p = IPPROTO_TCP;
@@ -1053,17 +1207,25 @@ fr_info_t *fin;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2));
ip->ip_len = hlen + sizeof(*tcp2);
- return send_ip(oip, fin, m);
+ return send_ip(oip, fin, &m);
}
-static int send_ip(oip, fin, m)
+/*
+ * Send an IP(v4/v6) datagram out into the network
+ */
+static int send_ip(oip, fin, mp)
ip_t *oip;
fr_info_t *fin;
-struct mbuf *m;
+struct mbuf **mp;
{
+ struct mbuf *m = *mp;
+ char *dpsave;
+ int error;
ip_t *ip;
+ dpsave = fin->fin_dp;
+
ip = mtod(m, ip_t *);
ip->ip_v = fin->fin_v;
@@ -1079,20 +1241,22 @@ struct mbuf *m;
ip->ip_ttl = ip_defttl;
# endif
ip->ip_sum = 0;
+ fin->fin_dp = (char *)(ip + 1);
}
# ifdef USE_INET6
else if (ip->ip_v == 6) {
ip6_t *ip6 = (ip6_t *)ip;
ip6->ip6_hlim = 127;
-
- return ip6_output(m, NULL, NULL, 0, NULL, NULL);
+ fin->fin_dp = (char *)(ip6 + 1);
}
# endif
# ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
# endif
- return ipfr_fastroute(m, fin->fin_mp, fin, NULL);
+ error = ipfr_fastroute(m, mp, fin, NULL);
+ fin->fin_dp = dpsave;
+ return error;
}
@@ -1266,7 +1430,7 @@ int dst;
shlen = fin->fin_hlen;
fin->fin_hlen = hlen;
- err = send_ip(oip, fin, m);
+ err = send_ip(oip, fin, &m);
fin->fin_hlen = shlen;
#ifdef USE_INET6
if (fin->fin_v == 4)
@@ -1279,7 +1443,8 @@ int dst;
}
-# if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
+# if !defined(IPFILTER_LKM) && !defined(__sgi) && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 300000))
# if (BSD < 199306)
int iplinit __P((void));
@@ -1291,21 +1456,35 @@ void
# endif
iplinit()
{
+
+# if defined(__NetBSD__)
+ if (ipl_enable() != 0)
+# else
if (iplattach() != 0)
+# endif
+ {
printf("IP Filter failed to attach\n");
+ }
ip_init();
}
# endif /* ! __NetBSD__ */
+/*
+ * Return the length of the entire mbuf.
+ */
size_t mbufchainlen(m0)
register struct mbuf *m0;
{
+#if BSD >= 199306
+ return m0->m_pkthdr.len;
+#else
register size_t len = 0;
for (; m0; m0 = m0->m_next)
len += m0->m_len;
return len;
+#endif
}
@@ -1323,6 +1502,24 @@ frdest_t *fdp;
struct route iproute;
frentry_t *fr;
+ ip = NULL;
+ ro = NULL;
+ ifp = NULL;
+ ro = &iproute;
+ ro->ro_rt = NULL;
+
+#ifdef USE_INET6
+ if (fin->fin_v == 6) {
+ error = ipfr_fastroute6(m0, mpp, fin, fdp);
+ if (error != 0)
+ goto bad;
+ goto done;
+ }
+#else
+ if (fin->fin_v == 6)
+ goto bad;
+#endif
+
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@@ -1336,13 +1533,14 @@ frdest_t *fdp;
* problem.
*/
if (M_WRITABLE(m) == 0) {
- if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
- m_freem(m);
+ if ((m0 = m_dup(m, M_DONTWAIT)) != NULL) {
+ m_freem(*mpp);
+ *mpp = m0;
m = m0;
} else {
error = ENOBUFS;
- m_freem(m);
- ipl_frouteok[1]++;
+ m_freem(*mpp);
+ goto done;
}
}
#endif
@@ -1354,35 +1552,26 @@ frdest_t *fdp;
/*
* Clear any in-bound checksum flags for this packet.
*/
+# if (__NetBSD_Version__ > 105009999)
+ m0->m_pkthdr.csum_flags = 0;
+# else
m0->m_pkthdr.csuminfo = 0;
+# endif
#endif /* __NetBSD__ && M_CSUM_IPv4 */
-#ifdef USE_INET6
- if (ip->ip_v == 6) {
- /*
- * currently "to <if>" and "to <if>:ip#" are not supported
- * for IPv6
- */
- error = ip6_output(m0, NULL, NULL, 0, NULL, NULL);
- *mpp = NULL;
- return error;
- }
-#endif
/*
* Route packet.
*/
- ro = &iproute;
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
+ dst->sin_addr = ip->ip_dst;
fr = fin->fin_fr;
- if (fdp)
+ if (fdp != NULL)
ifp = fdp->fd_ifp;
- else {
+ else
ifp = fin->fin_ifp;
- dst->sin_addr = ip->ip_dst;
- }
/*
* In case we're here due to "to <if>" being used with "keep state",
@@ -1391,13 +1580,9 @@ frdest_t *fdp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return 0;
- dst->sin_addr = ip->ip_dst;
- } else if (fdp) {
- if (fdp->fd_ip.s_addr) {
+ } else if (fdp != NULL) {
+ if (fdp->fd_ip.s_addr != 0)
dst->sin_addr = fdp->fd_ip;
- ip->ip_dst = fdp->fd_ip;
- } else
- dst->sin_addr = ip->ip_dst;
}
# if BSD >= 199306
@@ -1418,26 +1603,36 @@ frdest_t *fdp;
error = -2;
goto bad;
}
- if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
- if (in_localaddr(ip->ip_dst))
- error = EHOSTUNREACH;
- else
- error = ENETUNREACH;
- goto bad;
- }
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
}
- if (ro->ro_rt)
- ro->ro_rt->rt_use++;
+
+ if ((ifp == NULL) && (ro->ro_rt != NULL))
+ ifp = ro->ro_rt->rt_ifp;
+
+ if ((ro->ro_rt == NULL) || (ifp == NULL)) {
+ if (in_localaddr(ip->ip_dst))
+ error = EHOSTUNREACH;
+ else
+ error = ENETUNREACH;
+ goto bad;
+ }
+
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
+#if BSD >= 199306
+ dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
+#else
+ dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
+#endif
+ }
+ ro->ro_rt->rt_use++;
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
* NAT'd and counted.
*/
- fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
+ sifp = fin->fin_ifp;
+ fin->fin_ifp = ifp;
fin->fin_out = 1;
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
@@ -1447,44 +1642,39 @@ frdest_t *fdp;
if (!fr || !(fr->fr_flags & FR_RETMASK))
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
+ fin->fin_ifp = sifp;
} else
ip->ip_sum = 0;
/*
* If small enough for interface, can just send directly.
*/
if (ip->ip_len <= ifp->if_mtu) {
-# if defined(MCLISREFERENCED) && !defined(sparc)
- int i = 0;
-
- if ((m->m_flags & M_EXT) && MCLISREFERENCED(m))
- i = 1;
-# endif
# ifndef sparc
-# if !(_BSDI_VERSION >= 199510)
+# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510))
ip->ip_id = htons(ip->ip_id);
# endif
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
# endif
# if defined(__NetBSD__) && defined(M_CSUM_IPv4)
+# if (__NetBSD_Version__ > 105009999)
+ if (ifp->if_csum_flags_tx & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+ else if (ip->ip_sum == 0)
+ ip->ip_sum = in_cksum(m, hlen);
+# else
if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
else if (ip->ip_sum == 0)
ip->ip_sum = in_cksum(m, hlen);
+# endif
# else
if (!ip->ip_sum)
ip->ip_sum = in_cksum(m, hlen);
# endif /* __NetBSD__ && M_CSUM_IPv4 */
-# if BSD >= 199306
+# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
ro->ro_rt);
-# if defined(MCLISREFERENCED) && !defined(sparc)
- if (i) {
- ip->ip_id = ntohs(ip->ip_id);
- ip->ip_len = ntohs(ip->ip_len);
- ip->ip_off = ntohs(ip->ip_off);
- }
-# endif
# else
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
# endif
@@ -1554,9 +1744,7 @@ frdest_t *fdp;
m->m_pkthdr.len = mhlen + len;
m->m_pkthdr.rcvif = NULL;
# endif
-# ifndef sparc
mhip->ip_off = htons((u_short)mhip->ip_off);
-# endif
mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen);
*mnext = m;
@@ -1576,7 +1764,7 @@ sendorfree:
m0 = m->m_act;
m->m_act = 0;
if (error == 0)
-# if BSD >= 199306
+# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
# else
@@ -1593,13 +1781,13 @@ done:
else
ipl_frouteok[1]++;
- if (ro->ro_rt) {
+ if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
}
*mpp = NULL;
return error;
bad:
- if (error == EMSGSIZE) {
+ if ((error == EMSGSIZE) && (fin->fin_v == 4)) {
sifp = fin->fin_ifp;
code = fin->fin_icode;
fin->fin_icode = ICMP_UNREACH_NEEDFRAG;
@@ -1613,6 +1801,10 @@ bad:
}
+/*
+ * Return true or false depending on whether the route to the
+ * given IP address uses the same interface as the one passed.
+ */
int fr_verifysrc(ipa, ifp)
struct in_addr ipa;
void *ifp;
@@ -1622,6 +1814,9 @@ void *ifp;
bzero((char *)&iproute, sizeof(iproute));
dst = (struct sockaddr_in *)&iproute.ro_dst;
+# if (BSD >= 199306)
+ dst->sin_len = sizeof(*dst);
+# endif
dst->sin_family = AF_INET;
dst->sin_addr = ipa;
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
@@ -1651,10 +1846,78 @@ struct ifnet *ifp;
return workbuf;
}
# endif
+
+
+# if defined(USE_INET6)
+/*
+ * This is the IPv6 specific fastroute code. It doesn't clean up the mbuf's
+ * or ensure that it is an IPv6 packet that is being forwarded, those are
+ * expected to be done by the called (ipfr_fastroute).
+ */
+static int ipfr_fastroute6(m0, mpp, fin, fdp)
+struct mbuf *m0, **mpp;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+ struct route_in6 ip6route;
+ struct sockaddr_in6 *dst6;
+ struct route_in6 *ro;
+ struct ifnet *ifp;
+ frentry_t *fr;
+ int error;
+
+ ifp = NULL;
+ ro = &ip6route;
+ fr = fin->fin_fr;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(struct sockaddr_in6);
+ dst6->sin6_addr = fin->fin_fi.fi_src.in6;
+
+ if (fdp != NULL)
+ ifp = fdp->fd_ifp;
+
+ if ((fr != NULL) && (fin->fin_rev != 0)) {
+ if ((ifp != NULL) && (fdp == &fr->fr_tif))
+ return 0;
+ } else if (fdp != NULL) {
+ if (IP6_NOTZERO(&fdp->fd_ip6))
+ dst6->sin6_addr = fdp->fd_ip6.in6;
+ }
+ if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
+ return -2;
+
+ rtalloc((struct route *)ro);
+
+ if ((ifp == NULL) && (ro->ro_rt != NULL))
+ ifp = ro->ro_rt->rt_ifp;
+
+ if ((ro->ro_rt == NULL) || (ifp == NULL) ||
+ (ifp != ro->ro_rt->rt_ifp)) {
+ error = EHOSTUNREACH;
+ } else {
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst6 = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
+ ro->ro_rt->rt_use++;
+
+ if (m0->m_pkthdr.len <= nd_ifinfo[ifp->if_index].linkmtu)
+ error = nd6_output(ifp, fin->fin_ifp, m0, dst6,
+ ro->ro_rt);
+ else
+ error = EMSGSIZE;
+ }
+
+ if (ro->ro_rt != NULL) {
+ RTFREE(ro->ro_rt);
+ }
+ return error;
+}
+# endif
#else /* #ifdef _KERNEL */
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@@ -1667,7 +1930,7 @@ static int no_output __P((struct ifnet *ifp, struct mbuf *m,
# ifdef __STDC__
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@@ -1702,26 +1965,39 @@ ip_t *ip;
}
-struct ifnet *get_unit(name, v)
-char *name;
+char *get_ifname(ifp)
+struct ifnet *ifp;
+{
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ return ifp->if_xname;
+# else
+ static char fullifname[LIFNAMSIZ];
+
+ sprintf(fullifname, "%s%d", ifp->if_name, ifp->if_unit);
+ return fullifname;
+# endif
+}
+
+
+struct ifnet *get_unit(ifname, v)
+char *ifname;
int v;
{
struct ifnet *ifp, **ifa, **old_ifneta;
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- if (!strcmp(name, ifp->if_xname))
- return ifp;
- }
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ if (!strncmp(ifname, ifp->if_xname, sizeof(ifp->if_xname)))
# else
- char ifname[32], *s;
+ char fullname[LIFNAMSIZ];
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- (void) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
- if (!strcmp(name, ifname))
+ sprintf(fullname, "%s%d", ifp->if_name, ifp->if_unit);
+ if (!strcmp(ifname, fullname))
+# endif
return ifp;
}
-# endif
if (!ifneta) {
ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
@@ -1754,20 +2030,19 @@ 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))
+ strncpy(ifp->if_xname, ifname, sizeof(ifp->if_xname));
# else
- for (s = name; *s && !isdigit(*s); s++)
- ;
- if (*s && isdigit(*s)) {
- ifp->if_unit = atoi(s);
- ifp->if_name = (char *)malloc(s - name + 1);
- strncpy(ifp->if_name, name, s - name);
- ifp->if_name[s - name] = '\0';
- } else {
- ifp->if_name = strdup(name);
+ ifp->if_name = strdup(ifname);
+
+ ifname = ifp->if_name;
+ while (*ifname && !isdigit(*ifname))
+ ifname++;
+ if (*ifname && isdigit(*ifname)) {
+ ifp->if_unit = atoi(ifname);
+ *ifname = '\0';
+ } else
ifp->if_unit = -1;
- }
# endif
ifp->if_output = no_output;
return ifp;
@@ -1807,27 +2082,22 @@ void init_ifp()
}
-int ipllog __P((void))
-{
- verbose("l");
- return 0;
-}
-
-
-int send_reset(ip, ifp)
+int send_reset(ip, fin)
ip_t *ip;
-struct ifnet *ifp;
+fr_info_t *fin;
{
verbose("- TCP RST sent\n");
return 0;
}
-int icmp_error(ip, ifp)
+int send_icmp_err(ip, code, fin, dst)
ip_t *ip;
-struct ifnet *ifp;
+int code;
+fr_info_t *fin;
+int dst;
{
- verbose("- TCP RST sent\n");
+ verbose("- ICMP UNREACHABLE RST sent\n");
return 0;
}
@@ -1836,4 +2106,52 @@ void frsync()
{
return;
}
+
+void m_copydata(m, off, len, cp)
+mb_t *m;
+int off, len;
+caddr_t cp;
+{
+ bcopy((char *)m + off, cp, len);
+}
+
+
+int ipfuiomove(buf, len, rwflag, uio)
+caddr_t buf;
+int len, rwflag;
+struct uio *uio;
+{
+ int left, ioc, num, offset;
+ struct iovec *io;
+ char *start;
+
+ if (rwflag == UIO_READ) {
+ left = len;
+ ioc = 0;
+
+ offset = uio->uio_offset;
+
+ while ((left > 0) && (ioc < uio->uio_iovcnt)) {
+ io = uio->uio_iov + ioc;
+ num = io->iov_len;
+ if (num > left)
+ num = left;
+ start = io->iov_base + offset;
+ if (start > io->iov_base + io->iov_len) {
+ offset -= io->iov_len;
+ ioc++;
+ continue;
+ }
+ bcopy(buf, start, num);
+ uio->uio_resid -= num;
+ uio->uio_offset += num;
+ left -= num;
+ if (left > 0)
+ ioc++;
+ }
+ if (left > 0)
+ return EFAULT;
+ }
+ return 0;
+}
#endif /* _KERNEL */
diff --git a/contrib/ipfilter/ip_fil.h b/contrib/ipfilter/ip_fil.h
index 6d51ced5e0ae..96a8f4bb8c6e 100644
--- a/contrib/ipfilter/ip_fil.h
+++ b/contrib/ipfilter/ip_fil.h
@@ -1,10 +1,10 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ip_fil.h,v 2.29.2.10 2001/07/15 13:51:42 darrenr Exp $
+ * $Id: ip_fil.h,v 2.29.2.29 2002/03/13 03:56:46 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -34,6 +34,10 @@
# endif
#endif
+#ifndef offsetof
+# define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+
#if defined(__STDC__) || defined(__GNUC__)
# define SIOCADAFR _IOW('r', 60, struct frentry *)
# define SIOCRMAFR _IOW('r', 61, struct frentry *)
@@ -51,8 +55,8 @@
# define SIOCFRSYN _IOW('r', 73, u_int)
# define SIOCFRZST _IOWR('r', 74, struct friostat *)
# define SIOCZRLST _IOWR('r', 75, struct frentry *)
-# define SIOCAUTHW _IOWR('r', 76, struct fr_info *)
-# define SIOCAUTHR _IOWR('r', 77, struct fr_info *)
+# define SIOCAUTHW _IOWR('r', 76, struct frauth_t *)
+# define SIOCAUTHR _IOWR('r', 77, struct frauth_t *)
# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR('r', 79, u_int)
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
@@ -76,8 +80,8 @@
# define SIOCFRSYN _IOW(r, 73, u_int)
# define SIOCFRZST _IOWR(r, 74, struct friostat *)
# define SIOCZRLST _IOWR(r, 75, struct frentry *)
-# define SIOCAUTHW _IOWR(r, 76, struct fr_info *)
-# define SIOCAUTHR _IOWR(r, 77, struct fr_info *)
+# define SIOCAUTHW _IOWR(r, 76, struct frauth_t *)
+# define SIOCAUTHR _IOWR(r, 77, struct frauth_t *)
# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR(r, 79, u_int)
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
@@ -123,7 +127,9 @@ typedef struct fr_ip {
#define FI_W_SADDR 0x00000400
#define FI_W_DADDR 0x00000800
#define FI_WILDA (FI_W_SADDR|FI_W_DADDR)
-#define FI_NEWFR 0x00001000
+#define FI_NEWFR 0x00001000 /* Create a filter rule */
+#define FI_IGNOREPKT 0x00002000 /* Do not treat as a real packet */
+#define FI_NORULE 0x00004000 /* Not direct a result of a rule */
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
@@ -135,10 +141,12 @@ typedef struct fr_info {
u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
/* From here on is packet specific */
u_char fin_icode; /* ICMP error to return */
- u_short fin_rule; /* rule # last matched */
+ u_32_t fin_rule; /* rule # last matched */
u_32_t fin_group; /* group number, -1 for none */
struct frentry *fin_fr; /* last matching rule */
char *fin_dp; /* start of data past IP header */
+ u_short fin_plen;
+ u_short fin_off;
u_short fin_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
void *fin_mp; /* pointer to pointer to mbuf */
@@ -146,19 +154,21 @@ typedef struct fr_info {
void *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qif;
#endif
- u_short fin_plen;
- u_short fin_off;
} fr_info_t;
#define fin_v fin_fi.fi_v
+#define fin_p fin_fi.fi_p
#define fin_saddr fin_fi.fi_saddr
+#define fin_src fin_fi.fi_src.in4
#define fin_daddr fin_fi.fi_daddr
+#define fin_dst fin_fi.fi_dst.in4
#define fin_fl fin_fi.fi_fl
/*
* Size for compares on fr_info structures
*/
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
+#define FI_LCSIZE offsetof(fr_info_t, fin_dp)
/*
* Size for copying cache fr_info structure
@@ -167,13 +177,16 @@ typedef struct fr_info {
typedef struct frdest {
void *fd_ifp;
- struct in_addr fd_ip;
- char fd_ifname[IFNAMSIZ];
+ union i6addr fd_ip6;
+ char fd_ifname[LIFNAMSIZ];
#if SOLARIS
mb_t *fd_mp; /* cache resolver for to/dup-to */
#endif
} frdest_t;
+#define fd_ip fd_ip6.in4
+
+
typedef struct frpcmp {
int frp_cmp; /* data for port comparisons */
u_short frp_port; /* top port for <> and >< */
@@ -198,10 +211,7 @@ typedef struct frentry {
struct frentry *fr_next;
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
- void *fr_ifa;
-#if BSD >= 199306
- void *fr_oifa;
-#endif
+ void *fr_ifas[4];
/*
* These are only incremented when a packet matches this rule and
* it is the last match
@@ -218,6 +228,7 @@ typedef struct frentry {
u_short fr_icmpm; /* data for ICMP packets (mask) */
u_short fr_icmp;
+ u_int fr_age[2]; /* aging for state */
frtuc_t fr_tuc;
u_32_t fr_group; /* group to which this rule belongs */
u_32_t fr_grhead; /* group # which this rule starts */
@@ -227,10 +238,7 @@ typedef struct frentry {
int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
int fr_sap; /* For solaris only */
u_char fr_icode; /* return ICMP code */
- char fr_ifname[IFNAMSIZ];
-#if BSD >= 199306
- char fr_oifname[IFNAMSIZ];
-#endif
+ char fr_ifnames[4][LIFNAMSIZ];
struct frdest fr_tif; /* "to" interface */
struct frdest fr_dif; /* duplicate packet interfaces */
u_int fr_cksum; /* checksum on filter rules for performance */
@@ -252,10 +260,11 @@ typedef struct frentry {
#define fr_src fr_ip.fi_src.in4
#define fr_dmsk fr_mip.fi_dst.in4
#define fr_smsk fr_mip.fi_src.in4
+#define fr_ifname fr_ifnames[0]
+#define fr_oifname fr_ifnames[2]
+#define fr_ifa fr_ifas[0]
+#define fr_oifa fr_ifas[2]
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
-#endif
#define FR_CMPSIZ (sizeof(struct frentry) - offsetof(frentry_t, fr_ip))
/*
@@ -268,8 +277,8 @@ typedef struct frentry {
#define FR_LOG 0x00010 /* Log */
#define FR_LOGB 0x00011 /* Log-fail */
#define FR_LOGP 0x00012 /* Log-pass */
-#define FR_LOGBODY 0x00020 /* Log the body */
-#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
+#define FR_NOTSRCIP 0x00020 /* not the src IP# */
+#define FR_NOTDSTIP 0x00040 /* not the dst IP# */
#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
#define FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
@@ -283,8 +292,8 @@ typedef struct frentry {
#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
#define FR_DUP 0x20000 /* duplicate packet */
#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
-#define FR_NOTSRCIP 0x80000 /* not the src IP# */
-#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
+#define FR_LOGBODY 0x80000 /* Log the body */
+#define FR_LOGFIRST 0x100000 /* Log the first byte if state held */
#define FR_AUTH 0x200000 /* use authentication */
#define FR_PREAUTH 0x400000 /* require preauthentication */
#define FR_DONTCACHE 0x800000 /* don't cache the result */
@@ -406,15 +415,16 @@ typedef struct iplog {
struct iplog *ipl_next;
} iplog_t;
-#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+#define IPLOG_SIZE sizeof(iplog_t)
typedef struct ipflog {
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
- u_char fl_ifname[IFNAMSIZ];
+ u_char fl_ifname[LIFNAMSIZ];
#else
u_int fl_unit;
- u_char fl_ifname[4];
+ u_char fl_ifname[LIFNAMSIZ];
#endif
u_char fl_plen; /* extra data after hlen */
u_char fl_hlen; /* length of IP headers saved */
@@ -422,7 +432,8 @@ typedef struct ipflog {
u_32_t fl_rule;
u_32_t fl_group;
u_32_t fl_flags;
- u_32_t fl_lflags;
+ u_char fl_dir;
+ u_char fl_pad[3];
} ipflog_t;
@@ -485,10 +496,11 @@ typedef struct ipflog {
#ifndef _KERNEL
+extern char *get_ifname __P((struct ifnet *));
extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-extern int send_reset __P((ip_t *, struct ifnet *));
-extern int icmp_error __P((ip_t *, struct ifnet *));
+extern int send_reset __P((ip_t *, fr_info_t *));
+extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int ipf_log __P((void));
extern struct ifnet *get_unit __P((char *, int));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
@@ -506,11 +518,6 @@ extern void ipfilterattach __P((int));
extern int iplattach __P((void));
extern int ipl_enable __P((void));
extern int ipl_disable __P((void));
-extern void ipflog_init __P((void));
-extern int ipflog_clear __P((minor_t));
-extern int ipflog_read __P((minor_t, struct uio *));
-extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
-extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int send_reset __P((ip_t *, fr_info_t *));
# if SOLARIS
@@ -593,6 +600,12 @@ extern u_short ipf_cksum __P((u_short *, int));
extern int ircopyptr __P((void *, void *, size_t));
extern int iwcopyptr __P((void *, void *, size_t));
+extern void ipflog_init __P((void));
+extern int ipflog_clear __P((minor_t));
+extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
+extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
+extern int ipflog_read __P((minor_t, struct uio *));
+
extern int frflush __P((minor_t, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
diff --git a/contrib/ipfilter/ip_frag.c b/contrib/ipfilter/ip_frag.c
index b0e63a9f7551..abc0faa8d72a 100644
--- a/contrib/ipfilter/ip_frag.c
+++ b/contrib/ipfilter/ip_frag.c
@@ -7,6 +7,9 @@
# define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -23,7 +26,6 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -63,7 +65,6 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
@@ -89,7 +90,7 @@ extern struct timeout ipfr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.14 2001/07/15 22:06:15 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.20 2002/03/06 09:44:11 darrenr Exp $";
#endif
@@ -494,7 +495,6 @@ void ipfr_unload()
}
-#ifdef _KERNEL
void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
@@ -565,6 +565,7 @@ void ipfr_fragexpire()
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
+#ifdef _KERNEL
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
@@ -574,6 +575,9 @@ void ipfr_slowtimer __P((void *ptr))
# else
int ipfr_slowtimer()
# endif
+#else
+void ipfr_slowtimer()
+#endif
{
#if defined(_KERNEL) && SOLARIS
extern int fr_running;
@@ -583,7 +587,7 @@ int ipfr_slowtimer()
#endif
READ_ENTER(&ipf_solaris);
-#ifdef __sgi
+#if defined(__sgi) && defined(_KERNEL)
ipfilter_sgi_intfsync();
#endif
@@ -591,6 +595,7 @@ int ipfr_slowtimer()
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
+#if defined(_KERNEL)
# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
RWLOCK_EXIT(&ipf_solaris);
@@ -601,8 +606,8 @@ int ipfr_slowtimer()
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
-# if defined(__OpenBSD_)
- timeout_add(&ipfr_slowtimer_ch, hz/2, ipfr_slowtimer, NULL);
+# if defined(__OpenBSD__)
+ timeout_add(&ipfr_slowtimer_ch, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
@@ -612,5 +617,5 @@ int ipfr_slowtimer()
# endif /* FreeBSD */
# endif /* NetBSD */
# endif /* SOLARIS */
-}
#endif /* defined(_KERNEL) */
+}
diff --git a/contrib/ipfilter/ip_frag.h b/contrib/ipfilter/ip_frag.h
index 446510f0e965..03f41f8d04cd 100644
--- a/contrib/ipfilter/ip_frag.h
+++ b/contrib/ipfilter/ip_frag.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_frag.h 1.5 3/24/96
- * $Id: ip_frag.h,v 2.4.2.5 2001/06/26 10:43:13 darrenr Exp $
+ * $Id: ip_frag.h,v 2.4.2.6 2002/01/01 15:09:38 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -56,14 +56,18 @@ extern void ipfr_forget __P((void *));
extern void ipfr_unload __P((void));
extern void ipfr_fragexpire __P((void));
-#if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
+#ifdef _KERNEL
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
+# if defined(SOLARIS2) && (SOLARIS2 < 7)
extern void ipfr_slowtimer __P((void));
-# else
+# else
extern void ipfr_slowtimer __P((void *));
-# endif
-#else
+# endif
+# else
extern int ipfr_slowtimer __P((void));
-#endif /* (BSD >= 199306) || SOLARIS */
+# endif /* (BSD >= 199306) || SOLARIS */
+#else
+extern void ipfr_slowtimer __P((void));
+#endif /* _KERNEL */
#endif /* __IP_FIL_H__ */
diff --git a/contrib/ipfilter/ip_ftp_pxy.c b/contrib/ipfilter/ip_ftp_pxy.c
index 830a4f66c9ec..0968b1055dc9 100644
--- a/contrib/ipfilter/ip_ftp_pxy.c
+++ b/contrib/ipfilter/ip_ftp_pxy.c
@@ -2,7 +2,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * $Id: ip_ftp_pxy.c,v 2.7.2.26 2001/07/15 13:50:54 darrenr Exp $
+ * $Id: ip_ftp_pxy.c,v 2.7.2.33 2002/02/15 14:48:38 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -49,10 +49,12 @@ int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_valid __P((char *, size_t));
+int ippr_ftp_valid __P((int, char *, size_t));
+int ippr_ftp_server_valid __P((char *, size_t));
+int ippr_ftp_client_valid __P((char *, size_t));
u_short ippr_ftp_atoi __P((char **));
-static frentry_t natfr;
+static frentry_t ftppxyfr;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0;
@@ -62,9 +64,9 @@ int ippr_ftp_insecure = 0;
*/
int ippr_ftp_init()
{
- bzero((char *)&natfr, sizeof(natfr));
- natfr.fr_ref = 1;
- natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
+ bzero((char *)&ftppxyfr, sizeof(ftppxyfr));
+ ftppxyfr.fr_ref = 1;
+ ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
@@ -105,9 +107,9 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
char newbuf[IPF_FTPBUFSZ], *s;
- u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
struct in_addr swip;
+ u_short a5, a6, sp;
size_t nlen, olen;
fr_info_t fi;
int inc, off;
@@ -173,7 +175,7 @@ int dlen;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - f->ftps_rptr;
- /* DO NOT change this to sprintf! */
+ /* DO NOT change this to snprintf! */
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
@@ -241,46 +243,47 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = htons(a5 << 8 | a6);
+ sp = (a5 << 8 | a6);
/*
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
- if (ntohs(sp) < 1024)
+ if (sp < 1024)
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.
*/
- dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = sp;
+ fi.fin_data[1] = fin->fin_data[1] - 1;
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
+ tcp2->th_sport = htons(sp);
tcp2->th_off = 5;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
- fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dlen = sizeof(*tcp2);
fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
+ fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@@ -340,7 +343,8 @@ int dlen;
!strncmp(cmd, "ADAT ", 5)) {
ftp->ftp_passok = FTPXY_ADAT_1;
ftp->ftp_incok = 1;
- } else if ((ftp->ftp_passok == FTPXY_PAOK_2) &&
+ } else if ((ftp->ftp_passok == FTPXY_PAOK_1 ||
+ ftp->ftp_passok == FTPXY_PAOK_2) &&
!strncmp(cmd, "ACCT ", 5)) {
ftp->ftp_passok = FTPXY_ACCT_1;
ftp->ftp_incok = 1;
@@ -368,8 +372,8 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
struct in_addr swip, swip2;
- u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
+ u_short a5, a6, dp;
fr_info_t fi;
nat_t *ipn;
int inc;
@@ -501,26 +505,27 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = 0;
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = 0;
dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ fi.fin_data[1] = ntohs(dp);
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = 0; /* XXX - fake it for nat_new */
tcp2->th_off = 5;
- fi.fin_data[0] = a5 << 8 | a6;
+ fi.fin_data[1] = a5 << 8 | a6;
fi.fin_dlen = sizeof(*tcp2);
- tcp2->th_dport = htons(fi.fin_data[0]);
- fi.fin_data[1] = 0;
+ tcp2->th_dport = htons(fi.fin_data[1]);
+ fi.fin_data[0] = 0;
fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
+ fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
swip2 = ip->ip_dst;
@@ -528,11 +533,12 @@ int dlen;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_dst = ip->ip_src;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_SPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_SPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_SPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_SPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@@ -601,7 +607,7 @@ int dlen;
* Look to see if the buffer starts with something which we recognise as
* being the correct syntax for the FTP protocol.
*/
-int ippr_ftp_valid(buf, len)
+int ippr_ftp_client_valid(buf, len)
char *buf;
size_t len;
{
@@ -614,36 +620,60 @@ size_t len;
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if ((c != '-') && (c != ' '))
+ if (isalpha(c)) {
+ c = *s++;
+ i--;
+ if ((c != ' ') && (c != '\r'))
+ return 1;
+ } else if ((c != ' ') && (c != '\r'))
return 1;
} else
return 1;
} else
return 1;
- } else if (isalpha(c)) {
+ } else
+ return 1;
+ for (; i; i--) {
+ c = *s++;
+ if (c == '\n')
+ return 0;
+ }
+ return 2;
+}
+
+
+int ippr_ftp_server_valid(buf, len)
+char *buf;
+size_t len;
+{
+ register char *s, c;
+ register size_t i = len;
+
+ if (i < 5)
+ return 2;
+ s = buf;
+ c = *s++;
+ i--;
+
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
- c = *s++;
- i--;
- if ((c != ' ') && (c != '\r'))
- return 1;
- } else if ((c != ' ') && (c != '\r'))
+ if ((c != '-') && (c != ' '))
return 1;
} else
return 1;
@@ -660,6 +690,21 @@ size_t len;
}
+int ippr_ftp_valid(side, buf, len)
+int side;
+char *buf;
+size_t len;
+{
+ int ret;
+
+ if (side == 0)
+ ret = ippr_ftp_client_valid(buf, len);
+ else
+ ret = ippr_ftp_server_valid(buf, len);
+ return ret;
+}
+
+
int ippr_ftp_process(fin, ip, nat, ftp, rv)
fr_info_t *fin;
ip_t *ip;
@@ -715,7 +760,7 @@ int rv;
if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq))
f->ftps_seq = ntohl(tcp->th_seq);
else if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
- return APR_ERR(-1);
+ return APR_ERR(1);
}
f->ftps_len = mlen;
@@ -732,11 +777,12 @@ int rv;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
if (f->ftps_junk == 0) {
+ f->ftps_cmds++;
len = wptr - rptr;
f->ftps_rptr = rptr;
if (rv)
@@ -746,9 +792,17 @@ int rv;
inc += ippr_ftp_client(fin, ip, nat,
ftp, len);
rptr = f->ftps_rptr;
+ wptr = f->ftps_wptr;
}
}
+ /*
+ * Off to a bad start so lets just forget about using the
+ * ftp proxy for this connection.
+ */
+ if ((f->ftps_cmds == 0) && (f->ftps_junk == 1))
+ return APR_ERR(2);
+
while ((f->ftps_junk == 1) && (rptr < wptr)) {
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;
diff --git a/contrib/ipfilter/ip_lfil.c b/contrib/ipfilter/ip_lfil.c
index 14e6b42102b7..4393c3ba9634 100644
--- a/contrib/ipfilter/ip_lfil.c
+++ b/contrib/ipfilter/ip_lfil.c
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*/
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.4 2002/03/06 09:44:11 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@@ -16,7 +16,6 @@ static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 da
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/time.h>
-#include <sys/uio.h>
#include <sys/dir.h>
#include <sys/socket.h>
#ifndef _KERNEL
@@ -42,8 +41,8 @@ static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 da
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
+#include "netinet/ip_proxy.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_auth.h"
diff --git a/contrib/ipfilter/ip_log.c b/contrib/ipfilter/ip_log.c
index 5968f46ad4b0..e56c60262460 100644
--- a/contrib/ipfilter/ip_log.c
+++ b/contrib/ipfilter/ip_log.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_log.c,v 2.5.2.5 2001/06/26 10:43:14 darrenr Exp $
+ * $Id: ip_log.c,v 2.5.2.17 2002/03/13 03:57:05 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@@ -52,7 +52,6 @@
# if defined(_KERNEL)
# include <sys/systm.h>
# endif
-# include <sys/uio.h>
# if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@@ -63,13 +62,14 @@
# else
# 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>
+# ifdef _KERNEL
+# include <sys/ddi.h>
+# include <sys/sunddi.h>
+# include <sys/ksynch.h>
+# include <sys/dditypes.h>
+# include <sys/cmn_err.h>
+# endif
# endif
# include <sys/protosw.h>
# include <sys/socket.h>
@@ -104,11 +104,6 @@
# include "netinet/ip_compat.h"
# include <netinet/tcpip.h>
# include "netinet/ip_fil.h"
-# include "netinet/ip_proxy.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)
# include <sys/malloc.h>
# endif
@@ -116,6 +111,10 @@
# ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
# endif
+# ifdef IPFILTER_LOGSIZE
+# undef IPLLOGSIZE
+# define IPLLOGSIZE IPFILTER_LOGSIZE
+# endif
# if SOLARIS || defined(__sgi)
@@ -168,7 +167,7 @@ mb_t *m;
void *ptrs[2];
int types[2];
u_char p;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
ill_t *ifp = fin->fin_ifp;
# else
struct ifnet *ifp = fin->fin_ifp;
@@ -215,9 +214,11 @@ mb_t *m;
* Get the interface number and name to which this packet is
* currently associated.
*/
-# if SOLARIS
+ bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
+# if SOLARIS && defined(_KERNEL)
ipfl.fl_unit = (u_char)ifp->ill_ppa;
- bcopy(ifp->ill_name, ipfl.fl_ifname, MIN(ifp->ill_name_length, 4));
+ bcopy(ifp->ill_name, ipfl.fl_ifname,
+ MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
# else
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
@@ -225,10 +226,8 @@ mb_t *m;
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
# else
ipfl.fl_unit = (u_char)ifp->if_unit;
- 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];
+ strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
+ sizeof(ifp->if_name)));
# endif
mlen = (flags & FR_LOGBODY) ? MIN(fin->fin_plen - hlen, 128) : 0;
# endif
@@ -241,10 +240,11 @@ mb_t *m;
else
ipfl.fl_loglevel = 0xffff;
ipfl.fl_flags = flags;
+ ipfl.fl_dir = fin->fin_out;
ptrs[0] = (void *)&ipfl;
sizes[0] = sizeof(ipfl);
types[0] = 0;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
/*
* Are we copied from the mblk or an aligned array ?
*/
@@ -289,20 +289,20 @@ int *types, cnt;
MUTEX_ENTER(&ipl_mutex);
if (fin != NULL) {
if ((ipll[dev] != NULL) &&
- bcmp((char *)fin, (char *)&iplcrc[dev], FI_CSIZE) == 0) {
+ bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
ipll[dev]->ipl_count++;
MUTEX_EXIT(&ipl_mutex);
return 1;
}
- bcopy((char *)fin, (char *)&iplcrc[dev], FI_CSIZE);
+ bcopy((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE);
} else
- bzero((char *)&iplcrc[dev], FI_CSIZE);
+ bzero((char *)&iplcrc[dev], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
/*
* Get the total amount of data to be logged.
*/
- for (i = 0, len = sizeof(iplog_t); i < cnt; i++)
+ for (i = 0, len = IPLOG_SIZE; i < cnt; i++)
len += itemsz[i];
/*
@@ -330,23 +330,28 @@ int *types, cnt;
ipl->ipl_count = 1;
ipl->ipl_next = NULL;
ipl->ipl_dsize = len;
-# if SOLARIS || defined(sun)
+# ifdef _KERNEL
+# if SOLARIS || defined(sun)
uniqtime((struct timeval *)&ipl->ipl_sec);
-# else
-# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
+# else
+# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
microtime((struct timeval *)&ipl->ipl_sec);
+# endif
# endif
+# else
+ ipl->ipl_sec = 0;
+ ipl->ipl_usec = 0;
# endif
/*
* 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, s = buf + IPLOG_SIZE; i < cnt; i++) {
if (types[i] == 0)
bcopy(items[i], s, itemsz[i]);
else if (types[i] == 1) {
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
copyout_mblk(items[i], 0, itemsz[i], s);
# else
m_copydata(items[i], 0, itemsz[i], s);
@@ -358,12 +363,12 @@ int *types, cnt;
ipll[dev] = ipl;
*iplh[dev] = ipl;
iplh[dev] = &ipl->ipl_next;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait);
mutex_exit(&ipl_mutex);
# else
MUTEX_EXIT(&ipl_mutex);
- wakeup(&iplh[dev]);
+ WAKEUP(&iplh[dev]);
# endif
return 1;
}
@@ -388,7 +393,7 @@ struct uio *uio;
return ENXIO;
if (!uio->uio_resid)
return 0;
- if (uio->uio_resid < sizeof(iplog_t))
+ if (uio->uio_resid < IPLOG_SIZE)
return EINVAL;
/*
@@ -430,15 +435,14 @@ struct uio *uio;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
+ MUTEX_ENTER(&ipl_mutex);
if (error) {
- MUTEX_ENTER(&ipl_mutex);
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
iplused[unit] += dlen;
break;
}
KFREES((caddr_t)ipl, dlen);
- MUTEX_ENTER(&ipl_mutex);
}
if (!iplt[unit]) {
iplused[unit] = 0;
@@ -467,7 +471,7 @@ minor_t unit;
ipll[unit] = NULL;
used = iplused[unit];
iplused[unit] = 0;
- bzero((char *)&iplcrc[unit], FI_CSIZE);
+ bzero((char *)&iplcrc[unit], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
return used;
}
diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c
index eb6e133bfc0f..5c10bc4ba3f3 100644
--- a/contrib/ipfilter/ip_nat.c
+++ b/contrib/ipfilter/ip_nat.c
@@ -9,6 +9,9 @@
#define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -30,7 +33,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -92,10 +94,10 @@ extern struct ifnet vpnif;
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
@@ -107,7 +109,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.44 2001/07/21 07:17:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.63 2002/03/06 09:44:11 darrenr Exp $";
#endif
nat_t **nat_table[2] = { NULL, NULL },
@@ -133,7 +135,6 @@ extern KRWLOCK_T ipf_nat;
#endif
static int nat_flushtable __P((void));
-static int nat_clearlist __P((void));
static void nat_addnat __P((struct ipnat *));
static void nat_addrdr __P((struct ipnat *));
static void nat_delete __P((struct nat *));
@@ -142,7 +143,7 @@ static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t));
-static void nat_tabmove __P((nat_t *, u_32_t));
+static void nat_tabmove __P((fr_info_t *, nat_t *));
static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr));
@@ -501,7 +502,7 @@ int mode;
if (!n->in_ifp)
n->in_ifp = (void *)-1;
if (n->in_plabel[0] != '\0') {
- n->in_apr = appr_match(n->in_p, n->in_plabel);
+ n->in_apr = appr_lookup(n->in_p, n->in_plabel);
if (!n->in_apr) {
error = ENOENT;
break;
@@ -900,7 +901,9 @@ caddr_t data;
nat->nat_aps = NULL;
in = nat->nat_ptr;
nat->nat_ptr = NULL;
+ nat->nat_hm = NULL;
nat->nat_data = NULL;
+ nat->nat_ifp = GETUNIT(nat->nat_ifname, 4);
/*
* Restore the rule associated with this nat session
@@ -922,7 +925,7 @@ caddr_t data;
in->in_pmnext = NULL;
in->in_ifp = GETUNIT(in->in_ifname, 4);
if (in->in_plabel[0] != '\0') {
- in->in_apr = appr_match(in->in_p, in->in_plabel);
+ in->in_apr = appr_lookup(in->in_p, in->in_plabel);
}
}
@@ -1015,6 +1018,8 @@ struct nat *natd;
if (natd->nat_hnext[1])
natd->nat_hnext[1]->nat_phnext[1] = natd->nat_phnext[1];
*natd->nat_phnext[1] = natd->nat_hnext[1];
+ if (natd->nat_me != NULL)
+ *natd->nat_me = NULL;
if (natd->nat_fr != NULL) {
ATOMIC_DEC32(natd->nat_fr->fr_ref);
@@ -1054,6 +1059,7 @@ struct nat *natd;
/*
* nat_flushtable - clear the NAT table of all mapping entries.
+ * (this is for the dynamic mappings)
*/
static int nat_flushtable()
{
@@ -1086,8 +1092,9 @@ static int nat_flushtable()
/*
* nat_clearlist - delete all rules in the active NAT mapping list.
+ * (this is for NAT/RDR rules)
*/
-static int nat_clearlist()
+int nat_clearlist()
{
register ipnat_t *n, **np = &nat_list;
int i = 0;
@@ -1118,22 +1125,25 @@ static int nat_clearlist()
/*
* Create a new NAT table entry.
- * NOTE: assumes write lock on ipf_nat has been obtained already.
+ * NOTE: Assumes write lock on ipf_nat has been obtained already.
+ * If you intend on changing this, beware: appr_new() may call nat_new()
+ * recursively!
*/
-nat_t *nat_new(np, ip, fin, flags, direction)
-ipnat_t *np;
-ip_t *ip;
+nat_t *nat_new(fin, ip, np, natsave, flags, direction)
fr_info_t *fin;
+ip_t *ip;
+ipnat_t *np;
+nat_t **natsave;
u_int flags;
int direction;
{
register u_32_t sum1, sum2, sumd, l;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in, inb;
+ u_short nflags, sp, dp;
tcphdr_t *tcp = NULL;
hostmap_t *hm = NULL;
nat_t *nat, *natl;
- u_short nflags;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
qif_t *qf = fin->fin_qif;
#endif
@@ -1141,8 +1151,8 @@ int direction;
nflags = flags & np->in_flags;
if (flags & IPN_TCPUDP) {
tcp = (tcphdr_t *)fin->fin_dp;
- sport = tcp->th_sport;
- dport = tcp->th_dport;
+ sport = htons(fin->fin_data[0]);
+ dport = htons(fin->fin_data[1]);
}
/* Give me a new nat */
@@ -1182,7 +1192,7 @@ int direction;
* Check to see if there is an existing NAT
* setup for this IP address pair.
*/
- hm = nat_hostmap(np, ip->ip_src, in);
+ hm = nat_hostmap(np, fin->fin_src, in);
if (hm != NULL)
in.s_addr = hm->hm_mapip.s_addr;
} else if ((l == 1) && (hm != NULL)) {
@@ -1206,7 +1216,7 @@ int direction;
/*
* map-block - Calculate destination address.
*/
- in.s_addr = ntohl(ip->ip_src.s_addr);
+ in.s_addr = ntohl(fin->fin_saddr);
in.s_addr &= ntohl(~np->in_inmsk);
inb.s_addr = in.s_addr;
in.s_addr /= np->in_ippip;
@@ -1239,7 +1249,7 @@ int direction;
*/
if (l > 0)
goto badnat;
- in.s_addr = ntohl(ip->ip_src.s_addr);
+ in.s_addr = ntohl(fin->fin_saddr);
} else if ((np->in_outmsk != 0xffffffff) &&
(np->in_pnext == 0) &&
((l > 0) || (hm == NULL)))
@@ -1261,7 +1271,7 @@ int direction;
port += (l % np->in_ppip);
port %= np->in_ppip;
port += np->in_ppip *
- (ntohl(ip->ip_src.s_addr) %
+ (ntohl(fin->fin_saddr) %
np->in_ippip);
port += MAPBLK_MINPORT;
port = htons(port);
@@ -1301,9 +1311,15 @@ int direction;
* this is appropriate.
*/
inb.s_addr = htonl(in.s_addr);
- natl = nat_inlookup(fin->fin_ifp, flags & ~FI_WILDP,
- (u_int)ip->ip_p, ip->ip_dst, inb,
- (port << 16) | dport, 1);
+ sp = fin->fin_data[0];
+ dp = fin->fin_data[1];
+ fin->fin_data[0] = fin->fin_data[1];
+ fin->fin_data[1] = htons(port);
+ natl = nat_inlookup(fin, flags & ~FI_WILDP,
+ (u_int)fin->fin_p, fin->fin_dst,
+ inb, 1);
+ fin->fin_data[0] = sp;
+ fin->fin_data[1] = dp;
/*
* Has the search wrapped around and come back to the
@@ -1320,14 +1336,14 @@ int direction;
np->in_space--;
/* Setup the NAT table */
- nat->nat_inip = ip->ip_src;
+ nat->nat_inip = fin->fin_src;
nat->nat_outip.s_addr = htonl(in.s_addr);
- nat->nat_oip = ip->ip_dst;
+ nat->nat_oip = fin->fin_dst;
if (nat->nat_hm == NULL)
- nat->nat_hm = nat_hostmap(np, ip->ip_src,
+ nat->nat_hm = nat_hostmap(np, fin->fin_src,
nat->nat_outip);
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr)) + ntohs(sport);
+ sum1 = LONG_SUM(ntohl(fin->fin_saddr)) + ntohs(sport);
sum2 = LONG_SUM(in.s_addr) + ntohs(port);
if (flags & IPN_TCPUDP) {
@@ -1367,27 +1383,26 @@ int direction;
* Whilst not optimized for the case where
* pmin == pmax, the gain is not significant.
*/
- nport = ntohs(dport) - ntohs(np->in_pmin) +
- ntohs(np->in_pnext);
- nport = htons(nport);
+ if (np->in_pmin != np->in_pmax) {
+ nport = ntohs(dport) - ntohs(np->in_pmin) +
+ ntohs(np->in_pnext);
+ nport = ntohs(nport);
+ } else
+ nport = np->in_pnext;
}
/*
* When the redirect-to address is set to 0.0.0.0, just
- * assume a blank `forwarding' of the packet. We don't
- * setup any translation for this either.
+ * assume a blank `forwarding' of the packet.
*/
- if (in.s_addr == 0) {
- if (nport == dport)
- goto badnat;
- in.s_addr = ntohl(ip->ip_dst.s_addr);
- }
+ if (in.s_addr == 0)
+ in.s_addr = ntohl(fin->fin_daddr);
nat->nat_inip.s_addr = htonl(in.s_addr);
- nat->nat_outip = ip->ip_dst;
- nat->nat_oip = ip->ip_src;
+ nat->nat_outip = fin->fin_dst;
+ nat->nat_oip = fin->fin_src;
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr)) + ntohs(dport);
+ sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport);
sum2 = LONG_SUM(in.s_addr) + ntohs(nport);
if (flags & IPN_TCPUDP) {
@@ -1405,8 +1420,8 @@ int direction;
if (direction == NAT_OUTBOUND)
sum1 = LONG_SUM(ntohl(in.s_addr));
else
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
- sum1 += LONG_SUM(ntohl(ip->ip_dst.s_addr));
+ sum1 = LONG_SUM(ntohl(fin->fin_saddr));
+ sum1 += LONG_SUM(ntohl(fin->fin_daddr));
sum1 += IPPROTO_TCP;
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
nat->nat_sumd[1] = NAT_HW_CKSUM|(sum1 & 0xffff);
@@ -1416,9 +1431,9 @@ int direction;
if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) {
if (direction == NAT_OUTBOUND)
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
+ sum1 = LONG_SUM(ntohl(fin->fin_saddr));
else
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr));
+ sum1 = LONG_SUM(ntohl(fin->fin_daddr));
sum2 = LONG_SUM(in.s_addr);
@@ -1429,15 +1444,13 @@ int direction;
in.s_addr = htonl(in.s_addr);
-#ifdef _KERNEL
strncpy(nat->nat_ifname, IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- nat_insert(nat);
+ nat->nat_me = natsave;
nat->nat_dir = direction;
nat->nat_ifp = fin->fin_ifp;
nat->nat_ptr = np;
- nat->nat_p = ip->ip_p;
+ nat->nat_p = fin->fin_p;
nat->nat_bytes = 0;
nat->nat_pkts = 0;
nat->nat_fr = fin->fin_fr;
@@ -1451,6 +1464,13 @@ int direction;
if (flags & IPN_TCPUDP)
tcp->th_dport = nport;
}
+
+ nat_insert(nat);
+
+ if ((np->in_apr != NULL) && (np->in_dport == 0 ||
+ (tcp != NULL && dport == np->in_dport)))
+ (void) appr_new(fin, ip, nat);
+
np->in_use++;
#ifdef IPFILTER_LOG
nat_log(nat, (u_int)np->in_redir);
@@ -1465,6 +1485,10 @@ badnat:
}
+/*
+ * 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.
+ */
void nat_insert(nat)
nat_t *nat;
{
@@ -1492,10 +1516,10 @@ nat_t *nat;
hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2 + nat->nat_oport,
ipf_nattable_sz);
} else {
- hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0, 0xffffffff);
- hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1, ipf_nattable_sz);
- hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0, 0xffffffff);
- hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2, ipf_nattable_sz);
+ hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, nat->nat_inip.s_addr,
+ ipf_nattable_sz);
+ hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, nat->nat_outip.s_addr,
+ ipf_nattable_sz);
}
natp = &nat_table[0][hv1];
@@ -1581,25 +1605,36 @@ int dir;
else if (oip->ip_p == IPPROTO_UDP)
flags = IPN_UDP;
if (flags & IPN_TCPUDP) {
+ u_short data[2];
+ nat_t *nat;
+
minlen += 8; /* + 64bits of data to get ports */
if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
return NULL;
+
+ data[0] = fin->fin_data[0];
+ data[1] = fin->fin_data[1];
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
- if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
- else
- return nat_outlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
+ fin->fin_data[0] = ntohs(tcp->th_dport);
+ fin->fin_data[1] = ntohs(tcp->th_sport);
+
+ if (dir == NAT_INBOUND) {
+ nat = nat_inlookup(fin, flags, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
+ } else {
+ nat = nat_outlookup(fin, flags, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
+ }
+ fin->fin_data[0] = data[0];
+ fin->fin_data[1] = data[1];
+ return nat;
}
if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
+ return nat_inlookup(fin, 0, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
else
- return nat_outlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
+ return nat_outlookup(fin, 0, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
}
@@ -1619,7 +1654,7 @@ int dir;
udphdr_t *udp;
nat_t *nat;
ip_t *oip;
- int flags = 0;
+ int flags;
if ((fin->fin_fl & FI_SHORT) || (fin->fin_off != 0))
return NULL;
@@ -1628,6 +1663,8 @@ int dir;
*/
if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir)))
return NULL;
+
+ flags = 0;
*nflags = IPN_ICMPERR;
icmp = (icmphdr_t *)fin->fin_dp;
oip = (ip_t *)&icmp->icmp_ip;
@@ -1917,23 +1954,32 @@ int dir;
* we're looking for a table entry, based on the destination address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
-nat_t *nat_inlookup(ifp, flags, p, src, mapdst, ports, rw)
-void *ifp;
+nat_t *nat_inlookup(fin, flags, p, src, mapdst, rw)
+fr_info_t *fin;
register u_int flags, p;
struct in_addr src , mapdst;
-u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
register int nflags;
register u_32_t dst;
+ ipnat_t *ipn;
+ void *ifp;
u_int hv;
+ if (fin != NULL)
+ ifp = fin->fin_ifp;
+ else
+ ifp = NULL;
dst = mapdst.s_addr;
- dport = ports >> 16;
- sport = ports & 0xffff;
- flags &= IPN_TCPUDP;
+ if (flags & IPN_TCPUDP) {
+ sport = htons(fin->fin_data[0]);
+ dport = htons(fin->fin_data[1]);
+ } else {
+ sport = 0;
+ dport = 0;
+ }
hv = NAT_HASH_FN(dst, dport, 0xffffffff);
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
@@ -1943,19 +1989,34 @@ int rw;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst &&
- (((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
- ((nat->nat_outport == dport) || (nflags & FI_W_SPORT)))))
+ ((p == 0) || (p == nat->nat_p))) {
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ if (nat->nat_oport != sport)
+ continue;
+ if (nat->nat_outport != dport)
+ continue;
+ break;
+ default :
+ break;
+ }
+
+ ipn = nat->nat_ptr;
+ if ((ipn != NULL) && (nat->nat_aps != NULL))
+ if (appr_match(fin, nat) != 0)
+ continue;
return nat;
+ }
}
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
+ if (!nat_stats.ns_wilds || !(flags & FI_WILDP))
return NULL;
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
hv = NAT_HASH_FN(dst, 0, 0xffffffff);
- hv = NAT_HASH_FN(src.s_addr, hv, ipf_nattable_sz);
+ hv = NAT_HASH_FN(src.s_addr, dst, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -1964,8 +2025,6 @@ int rw;
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
if (!(nflags & FI_WILDP))
continue;
if (nat->nat_oip.s_addr != src.s_addr ||
@@ -1973,7 +2032,7 @@ int rw;
continue;
if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
- nat_tabmove(nat, ports);
+ nat_tabmove(fin, nat);
break;
}
}
@@ -1989,21 +2048,18 @@ int rw;
* original was placed in the table without hashing on the ports and we now
* want to include hashing on port numbers.
*/
-static void nat_tabmove(nat, ports)
+static void nat_tabmove(fin, nat)
+fr_info_t *fin;
nat_t *nat;
-u_32_t ports;
{
register u_short sport, dport;
+ u_int hv, nflags;
nat_t **natp;
- u_int hv;
- dport = ports >> 16;
- sport = ports & 0xffff;
+ nflags = nat->nat_flags;
- if (nat->nat_oport == dport) {
- nat->nat_inport = sport;
- nat->nat_outport = sport;
- }
+ sport = ntohs(fin->fin_data[0]);
+ dport = ntohs(fin->fin_data[1]);
/*
* Remove the NAT entry from the old location
@@ -2045,23 +2101,29 @@ u_32_t ports;
* we're looking for a table entry, based on the source address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
-nat_t *nat_outlookup(ifp, flags, p, src, dst, ports, rw)
-void *ifp;
+nat_t *nat_outlookup(fin, flags, p, src, dst, rw)
+fr_info_t *fin;
register u_int flags, p;
struct in_addr src , dst;
-u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
register int nflags;
+ ipnat_t *ipn;
u_32_t srcip;
+ void *ifp;
u_int hv;
- sport = ports & 0xffff;
- dport = ports >> 16;
- flags &= IPN_TCPUDP;
+ ifp = fin->fin_ifp;
srcip = src.s_addr;
+ if (flags & IPN_TCPUDP) {
+ sport = ntohs(fin->fin_data[0]);
+ dport = ntohs(fin->fin_data[1]);
+ } else {
+ sport = 0;
+ dport = 0;
+ }
hv = NAT_HASH_FN(srcip, sport, 0xffffffff);
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
@@ -2072,19 +2134,34 @@ int rw;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
- (((p == 0) && (flags == (nflags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- ((nat->nat_inport == sport || nflags & FI_W_SPORT) &&
- (nat->nat_oport == dport || nflags & FI_W_DPORT))))
+ ((p == 0) || (p == nat->nat_p))) {
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ if (nat->nat_oport != dport)
+ continue;
+ if (nat->nat_inport != sport)
+ continue;
+ break;
+ default :
+ break;
+ }
+
+ ipn = nat->nat_ptr;
+ if ((ipn != NULL) && (nat->nat_aps != NULL))
+ if (appr_match(fin, nat) != 0)
+ continue;
return nat;
+ }
}
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
+ if (!nat_stats.ns_wilds || !(flags & FI_WILDP))
return NULL;
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
- hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
- hv = NAT_HASH_FN(dst.s_addr, hv, ipf_nattable_sz);
+
+ hv = NAT_HASH_FN(dst.s_addr, srcip, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -2093,8 +2170,6 @@ int rw;
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
if (!(nflags & FI_WILDP))
continue;
if ((nat->nat_inip.s_addr != srcip) ||
@@ -2102,7 +2177,7 @@ int rw;
continue;
if (((nat->nat_inport == sport) || (nflags & FI_W_SPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_DPORT))) {
- nat_tabmove(nat, ports);
+ nat_tabmove(fin, nat);
break;
}
}
@@ -2119,16 +2194,19 @@ int rw;
nat_t *nat_lookupredir(np)
register natlookup_t *np;
{
- u_32_t ports;
nat_t *nat;
+ fr_info_t fi;
+
+ bzero((char *)&fi, sizeof(fi));
+ fi.fin_data[0] = np->nl_inport;
+ fi.fin_data[1] = np->nl_outport;
- ports = (np->nl_outport << 16) | np->nl_inport;
/*
* 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(NULL, np->nl_flags, 0, np->nl_inip,
- np->nl_outip, ports, 0))) {
+ if ((nat = nat_outlookup(&fi, np->nl_flags, 0, np->nl_inip,
+ np->nl_outip, 0))) {
np->nl_realip = nat->nat_outip;
np->nl_realport = nat->nat_outport;
}
@@ -2146,7 +2224,7 @@ ip_t *ip;
if (ip->ip_v != 4)
return 0;
- if (np->in_p && ip->ip_p != np->in_p)
+ if (np->in_p && fin->fin_p != np->in_p)
return 0;
if (fin->fin_out) {
if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
@@ -2196,6 +2274,7 @@ fr_info_t *fin;
u_int nflags = 0, hv, msk;
struct ifnet *ifp;
frentry_t *fr;
+ void *sifp;
u_32_t iph;
nat_t *nat;
@@ -2203,15 +2282,17 @@ fr_info_t *fin;
return 0;
if ((fr = fin->fin_fr) && !(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;
+ fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1) {
+ sifp = fin->fin_ifp;
+ fin->fin_ifp = fr->fr_tif.fd_ifp;
+ } else
+ sifp = fin->fin_ifp;
+ ifp = fin->fin_ifp;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if (ip->ip_p == IPPROTO_TCP)
+ if (fin->fin_p == IPPROTO_TCP)
nflags = IPN_TCP;
- else if (ip->ip_p == IPPROTO_UDP)
+ else if (fin->fin_p == IPPROTO_UDP)
nflags = IPN_UDP;
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
@@ -2220,27 +2301,28 @@ fr_info_t *fin;
}
}
- ipa = ip->ip_src.s_addr;
+ ipa = fin->fin_saddr;
READ_ENTER(&ipf_nat);
- if ((ip->ip_p == IPPROTO_ICMP) &&
+ if ((fin->fin_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
icmpset = 1;
else if ((fin->fin_fl & FI_FRAG) &&
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
- else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p,
- ip->ip_src, ip->ip_dst,
- (dport << 16) | sport, 0))) {
+ else if ((nat = nat_outlookup(fin, nflags|FI_WILDP|FI_WILDA,
+ (u_int)fin->fin_p, fin->fin_src,
+ fin->fin_dst, 0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nflags & FI_W_SPORT) &&
(nat->nat_inport != sport))
nat->nat_inport = sport;
- else if ((nflags & FI_W_DPORT) &&
- (nat->nat_oport != dport))
+ if ((nflags & FI_W_DPORT) &&
+ (nat->nat_oport != dport))
nat->nat_oport = dport;
+
if (nat->nat_outport == 0)
nat->nat_outport = sport;
nat->nat_flags &= ~(FI_W_DPORT|FI_W_SPORT);
@@ -2249,13 +2331,15 @@ fr_info_t *fin;
}
} else {
RWLOCK_EXIT(&ipf_nat);
+
+ msk = 0xffffffff;
+ i = 32;
+
WRITE_ENTER(&ipf_nat);
/*
* If there is no current entry in the nat table for this IP#,
* create one for it (if there is a matching rule).
*/
- msk = 0xffffffff;
- i = 32;
maskloop:
iph = ipa & htonl(msk);
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
@@ -2271,22 +2355,13 @@ maskloop:
continue;
} else if ((ipa & np->in_inmsk) != np->in_inip)
continue;
- if (np->in_redir & (NAT_MAP|NAT_MAPBLK)) {
- if (*np->in_plabel && !appr_ok(ip, tcp, np))
- continue;
- /*
- * If it's a redirection, then we don't want to
- * create new outgoing port stuff.
- * Redirections are only for incoming
- * connections.
- */
- if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
- continue;
- if ((nat = nat_new(np, ip, fin, (u_int)nflags,
- NAT_OUTBOUND))) {
- np->in_hits++;
- break;
- }
+ if (*np->in_plabel && !appr_ok(ip, tcp, np))
+ continue;
+ nat = nat_new(fin, ip, np, NULL,
+ (u_int)nflags, NAT_OUTBOUND);
+ if (nat != NULL) {
+ np->in_hits++;
+ break;
}
}
if ((np == NULL) && (i > 0)) {
@@ -2308,7 +2383,14 @@ maskloop:
if (natadd && (fin->fin_fl & FI_FRAG) && np)
ipfr_nat_newfrag(ip, fin, 0, nat);
MUTEX_ENTER(&nat->nat_lock);
- nat->nat_age = fr_defnatage;
+ if (fin->fin_p != IPPROTO_TCP) {
+ if (np && np->in_age[1])
+ nat->nat_age = np->in_age[1];
+ else if (!icmpset && (fin->fin_p == IPPROTO_ICMP))
+ nat->nat_age = fr_defnaticmpage;
+ else
+ nat->nat_age = fr_defnatage;
+ }
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
MUTEX_EXIT(&nat->nat_lock);
@@ -2320,16 +2402,16 @@ maskloop:
if (nflags == IPN_ICMPERR) {
u_32_t s1, s2, sumd;
- s1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
+ s1 = LONG_SUM(ntohl(fin->fin_saddr));
s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
CALC_SUMD(s1, s2, sumd);
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(fin, &ip->ip_sum, sumd);
- else
fix_outcksum(fin, &ip->ip_sum, sumd);
+ else
+ fix_incksum(fin, &ip->ip_sum, sumd);
}
-#if SOLARIS || defined(__sgi)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
else {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
@@ -2337,16 +2419,19 @@ maskloop:
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
}
#endif
+ /*
+ * Only change the packet contents, not what is filtered upon.
+ */
ip->ip_src = nat->nat_outip;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
+ if ((nat->nat_outport != 0) && (tcp != NULL)) {
tcp->th_sport = nat->nat_outport;
fin->fin_data[0] = ntohs(tcp->th_sport);
}
- if (ip->ip_p == IPPROTO_TCP) {
+ if (fin->fin_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
MUTEX_ENTER(&nat->nat_lock);
fr_tcp_age(&nat->nat_age,
@@ -2366,25 +2451,24 @@ maskloop:
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
MUTEX_EXIT(&nat->nat_lock);
- } else if (ip->ip_p == IPPROTO_UDP) {
+ } else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
- } else if (ip->ip_p == IPPROTO_ICMP) {
- if (!icmpset)
- nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(fin, csump, nat->nat_sumd[1]);
+ fix_outcksum(fin, csump,
+ nat->nat_sumd[1]);
else
- fix_incksum(fin, csump, nat->nat_sumd[1]);
+ fix_incksum(fin, csump,
+ nat->nat_sumd[1]);
}
}
- if ((np->in_apr != NULL) && (np->in_dport == 0 ||
+ if (np && (np->in_apr != NULL) && (np->in_dport == 0 ||
(tcp != NULL && dport == np->in_dport))) {
i = appr_check(ip, fin, nat);
if (i == 0)
@@ -2393,9 +2477,11 @@ maskloop:
i = 1;
ATOMIC_INCL(nat_stats.ns_mapped[1]);
RWLOCK_EXIT(&ipf_nat); /* READ */
+ fin->fin_ifp = sifp;
return i;
}
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
+ fin->fin_ifp = sifp;
return 0;
}
@@ -2423,37 +2509,36 @@ fr_info_t *fin;
return 0;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if (ip->ip_p == IPPROTO_TCP)
+ if (fin->fin_p == IPPROTO_TCP)
nflags = IPN_TCP;
- else if (ip->ip_p == IPPROTO_UDP)
+ else if (fin->fin_p == IPPROTO_UDP)
nflags = IPN_UDP;
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
- dport = tcp->th_dport;
sport = tcp->th_sport;
+ dport = tcp->th_dport;
}
}
- in = ip->ip_dst;
+ in = fin->fin_dst;
/* make sure the source address is to be redirected */
- src = ip->ip_src;
+ src = fin->fin_src;
READ_ENTER(&ipf_nat);
- if ((ip->ip_p == IPPROTO_ICMP) &&
+ if ((fin->fin_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND)))
icmpset = 1;
else if ((fin->fin_fl & FI_FRAG) &&
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
- else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p,
- ip->ip_src, in, (dport << 16) | sport,
- 0))) {
+ else if ((nat = nat_inlookup(fin, nflags|FI_WILDP|FI_WILDA,
+ (u_int)fin->fin_p, fin->fin_src, in, 0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT))
nat->nat_oport = sport;
- else if ((nat->nat_outport != dport) &&
+ if ((nat->nat_outport != dport) &&
(nflags & FI_W_SPORT))
nat->nat_outport = dport;
nat->nat_flags &= ~(FI_W_SPORT|FI_W_DPORT);
@@ -2462,19 +2547,21 @@ fr_info_t *fin;
}
} else {
RWLOCK_EXIT(&ipf_nat);
+
+ msk = 0xffffffff;
+ i = 32;
+
WRITE_ENTER(&ipf_nat);
/*
* If there is no current entry in the nat table for this IP#,
* create one for it (if there is a matching rule).
*/
- msk = 0xffffffff;
- i = 32;
maskloop:
iph = in.s_addr & htonl(msk);
hv = NAT_HASH_FN(iph, 0, ipf_rdrrules_sz);
for (np = rdr_rules[hv]; np; np = np->in_rnext) {
if ((np->in_ifp && (np->in_ifp != ifp)) ||
- (np->in_p && (np->in_p != ip->ip_p)) ||
+ (np->in_p && (np->in_p != fin->fin_p)) ||
(np->in_flags && !(nflags & np->in_flags)))
continue;
if (np->in_flags & IPN_FILTER) {
@@ -2482,11 +2569,10 @@ maskloop:
continue;
} else if ((in.s_addr & np->in_outmsk) != np->in_outip)
continue;
- if ((np->in_redir & NAT_REDIRECT) &&
- (!np->in_pmin || (np->in_flags & IPN_FILTER) ||
+ if ((!np->in_pmin || (np->in_flags & IPN_FILTER) ||
((ntohs(np->in_pmax) >= ntohs(dport)) &&
(ntohs(dport) >= ntohs(np->in_pmin)))))
- if ((nat = nat_new(np, ip, fin, nflags,
+ if ((nat = nat_new(fin, ip, np, NULL, nflags,
NAT_INBOUND))) {
np->in_hits++;
break;
@@ -2512,8 +2598,8 @@ maskloop:
fin->fin_fr = nat->nat_fr;
if (natadd && (fin->fin_fl & FI_FRAG) && np)
ipfr_nat_newfrag(ip, fin, 0, nat);
- if ((np->in_apr != NULL) && (np->in_dport == 0 ||
- (tcp != NULL && sport == np->in_dport))) {
+ if (np && (np->in_apr != NULL) && (np->in_dport == 0 ||
+ (tcp != NULL && sport == np->in_dport))) {
i = appr_check(ip, fin, nat);
if (i == -1) {
RWLOCK_EXIT(&ipf_nat);
@@ -2522,9 +2608,14 @@ maskloop:
}
MUTEX_ENTER(&nat->nat_lock);
- if (nflags != IPN_ICMPERR)
- nat->nat_age = fr_defnatage;
-
+ if (fin->fin_p != IPPROTO_TCP) {
+ if (np && np->in_age[0])
+ nat->nat_age = np->in_age[0];
+ else if (!icmpset && (fin->fin_p == IPPROTO_ICMP))
+ nat->nat_age = fr_defnaticmpage;
+ else
+ nat->nat_age = fr_defnatage;
+ }
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
MUTEX_EXIT(&nat->nat_lock);
@@ -2535,7 +2626,7 @@ maskloop:
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
-#if SOLARIS || defined(__sgi)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
else
@@ -2543,12 +2634,12 @@ maskloop:
#endif
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) {
+ if ((nat->nat_inport != 0) && (tcp != NULL)) {
tcp->th_dport = nat->nat_inport;
fin->fin_data[1] = ntohs(tcp->th_dport);
}
- if (ip->ip_p == IPPROTO_TCP) {
+ if (fin->fin_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
MUTEX_ENTER(&nat->nat_lock);
fr_tcp_age(&nat->nat_age,
@@ -2568,21 +2659,20 @@ maskloop:
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
MUTEX_EXIT(&nat->nat_lock);
- } else if (ip->ip_p == IPPROTO_UDP) {
+ } else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
- } else if (ip->ip_p == IPPROTO_ICMP) {
- if (!icmpset)
- nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(fin, csump, nat->nat_sumd[0]);
+ fix_incksum(fin, csump,
+ nat->nat_sumd[0]);
else
- fix_outcksum(fin, csump, nat->nat_sumd[0]);
+ fix_outcksum(fin, csump,
+ nat->nat_sumd[0]);
}
}
ATOMIC_INCL(nat_stats.ns_mapped[0]);
@@ -2757,3 +2847,13 @@ u_int type;
(void) ipllog(IPL_LOGNAT, NULL, items, sizes, types, 1);
}
#endif
+
+
+#if defined(__OpenBSD__)
+void nat_ifdetach(ifp)
+void *ifp;
+{
+ frsync();
+ return;
+}
+#endif
diff --git a/contrib/ipfilter/ip_nat.h b/contrib/ipfilter/ip_nat.h
index f712dfcd9c5e..4b2acc485283 100644
--- a/contrib/ipfilter/ip_nat.h
+++ b/contrib/ipfilter/ip_nat.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.17.2.20 2001/06/26 10:43:15 darrenr Exp $
+ * $Id: ip_nat.h,v 2.17.2.25 2002/01/01 15:10:49 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -88,6 +88,7 @@ typedef struct nat {
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_phnext[2];
+ struct nat **nat_me;
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
@@ -118,6 +119,7 @@ typedef struct ipnat {
struct in_addr in_out[2];
struct in_addr in_src[2];
struct frtuc in_tuc;
+ u_int in_age[2]; /* Aging for NAT entries. Not for TCP */
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
char in_ifname[IFNAMSIZ];
char in_plabel[APR_LABELLEN]; /* proxy label */
@@ -286,23 +288,27 @@ extern nat_t **nat_table[2];
extern nat_t *nat_instances;
extern ipnat_t **nat_rules;
extern ipnat_t **rdr_rules;
+extern ipnat_t *nat_list;
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 nat_ioctl __P((caddr_t, u_long, int));
#else
extern int nat_ioctl __P((caddr_t, int, int));
#endif
extern int nat_init __P((void));
-extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
-extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
- struct in_addr));
+extern nat_t *nat_new __P((fr_info_t *, ip_t *, ipnat_t *, nat_t **,
+ u_int, int));
+extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
+ struct in_addr, int));
+extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
+ struct in_addr, int));
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmplookup __P((ip_t *, fr_info_t *, int));
extern nat_t *nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
+extern int nat_clearlist __P((void));
extern void nat_insert __P((nat_t *));
extern int ip_natout __P((ip_t *, fr_info_t *));
diff --git a/contrib/ipfilter/ip_proxy.c b/contrib/ipfilter/ip_proxy.c
index 325f36259ec2..a4ce80a5da97 100644
--- a/contrib/ipfilter/ip_proxy.c
+++ b/contrib/ipfilter/ip_proxy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-2001 by Darren Reed.
+ * Copyright (C) 1997-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -7,6 +7,9 @@
# define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -16,7 +19,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
-#include <sys/uio.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
@@ -65,34 +67,38 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.6 2001/07/15 22:06:15 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.21 2002/03/06 09:44:14 darrenr Exp $";
#endif
+#if defined(_KERNEL) && (SOLARIS || defined(__sgi))
+extern KRWLOCK_T ipf_nat, ipf_state;
+#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
-static ap_session_t *appr_new_session __P((aproxy_t *, ip_t *,
- fr_info_t *, nat_t *));
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
#define AP_SESS_SIZE 53
-#if defined(_KERNEL) && !defined(linux)
+#if defined(_KERNEL)
#include "netinet/ip_ftp_pxy.c"
#include "netinet/ip_rcmd_pxy.c"
#include "netinet/ip_raudio_pxy.c"
+#include "netinet/ip_netbios_pxy.c"
+#include "netinet/ip_h323_pxy.c"
#endif
+#include "netinet/ip_ipsec_pxy.c"
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
@@ -100,20 +106,39 @@ aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
- ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
+ ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL },
#endif
#ifdef IPF_RCMD_PROXY
{ NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
- ippr_rcmd_new, NULL, ippr_rcmd_out },
+ ippr_rcmd_new, NULL, NULL, ippr_rcmd_out, NULL },
#endif
#ifdef IPF_RAUDIO_PROXY
{ NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
- ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
+ ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL },
+#endif
+#ifdef IPF_IPSEC_PROXY
+ { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, ippr_ipsec_init, NULL,
+ ippr_ipsec_new, ippr_ipsec_del, NULL, ippr_ipsec_out,
+ ippr_ipsec_match },
#endif
- { NULL, "", '\0', 0, 0, NULL, NULL }
+#ifdef IPF_NETBIOS_PROXY
+ { NULL, "netbios", (char)IPPROTO_TCP, 0, 0, ippr_netbios_init, NULL,
+ NULL, NULL, NULL, ippr_netbios_out, NULL },
+#endif
+#ifdef IPF_H323_PROXY
+ { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, NULL,
+ ippr_h323_new, ippr_h323_del, ippr_h323_in, ippr_h323_out, NULL },
+ { NULL, "h245", (char)IPPROTO_TCP, 0, 0, ippr_h245_init, NULL,
+ ippr_h245_new, NULL, NULL, ippr_h245_out, NULL },
+#endif
+ { NULL, "", '\0', 0, 0, NULL, NULL, NULL }
};
+/*
+ * Dynamically add a new kernel proxy. Ensure that it is unique in the
+ * collection compiled in and dynamically added.
+ */
int appr_add(ap)
aproxy_t *ap;
{
@@ -125,7 +150,7 @@ aproxy_t *ap;
sizeof(ap->apr_label)))
return -1;
- for (a = ap_proxylist; a->apr_p; a = a->apr_next)
+ for (a = ap_proxylist; a && 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)))
@@ -136,6 +161,11 @@ aproxy_t *ap;
}
+/*
+ * Delete a proxy that has been added dynamically from those available.
+ * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1
+ * if it cannot be matched.
+ */
int appr_del(ap)
aproxy_t *ap;
{
@@ -143,15 +173,19 @@ aproxy_t *ap;
for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
if (a == ap) {
+ a->apr_flags |= APR_DELETE;
+ *app = a->apr_next;
if (ap->apr_ref != 0)
return 1;
- *app = a->apr_next;
return 0;
}
return -1;
}
+/*
+ * Return 1 if the packet is a good match against a proxy, else 0.
+ */
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@@ -160,34 +194,64 @@ ipnat_t *nat;
aproxy_t *apr = nat->in_apr;
u_short dport = nat->in_dport;
- if (!apr || (apr->apr_flags & APR_DELETE) ||
+ if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
(ip->ip_p != apr->apr_p))
return 0;
- if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
+ if (((tcp != NULL) && (tcp->th_dport != dport)) || (!tcp && dport))
return 0;
return 1;
}
/*
+ * If a proxy has a match function, call that to do extended packet
+ * matching.
+ */
+int appr_match(fin, nat)
+fr_info_t *fin;
+nat_t *nat;
+{
+ aproxy_t *apr;
+ ipnat_t *ipn;
+
+ ipn = nat->nat_ptr;
+ if (ipn == NULL)
+ return -1;
+ apr = ipn->in_apr;
+ if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
+ (nat->nat_aps == NULL))
+ return -1;
+ if (apr->apr_match != NULL)
+ if ((*apr->apr_match)(fin, nat->nat_aps, nat) != 0)
+ return -1;
+ return 0;
+}
+
+
+/*
* Allocate a new application proxy structure and fill it in with the
* relevant details. call the init function once complete, prior to
* returning.
*/
-static ap_session_t *appr_new_session(apr, ip, fin, nat)
-aproxy_t *apr;
-ip_t *ip;
+int appr_new(fin, ip, nat)
fr_info_t *fin;
+ip_t *ip;
nat_t *nat;
{
register ap_session_t *aps;
+ aproxy_t *apr;
+
+ if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL))
+ return -1;
+
+ apr = nat->nat_ptr->in_apr;
if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p))
- return NULL;
+ return -1;
KMALLOC(aps, ap_session_t *);
if (!aps)
- return NULL;
+ return -1;
bzero((char *)aps, sizeof(*aps));
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
@@ -195,13 +259,18 @@ nat_t *nat;
aps->aps_psiz = 0;
if (apr->apr_new != NULL)
if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
+ if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) {
+ KFREES(aps->aps_data, aps->aps_psiz);
+ }
KFREE(aps);
- return NULL;
+ return -1;
}
aps->aps_nat = nat;
aps->aps_next = ap_sess_list;
ap_sess_list = aps;
- return aps;
+ nat->nat_aps = aps;
+
+ return 0;
}
@@ -225,9 +294,6 @@ nat_t *nat;
short rv;
int err;
- if (nat->nat_aps == NULL)
- nat->nat_aps = appr_new_session(nat->nat_ptr->in_apr, ip,
- fin, nat);
aps = nat->nat_aps;
if ((aps != NULL) && (aps->aps_p == ip->ip_p)) {
if (ip->ip_p == IPPROTO_TCP) {
@@ -263,8 +329,13 @@ nat_t *nat;
}
rv = APR_EXIT(err);
- if (rv == -1)
- return rv;
+ if (rv == 1)
+ return -1;
+ if (rv == 2) {
+ appr_free(apr);
+ nat->nat_aps = NULL;
+ return -1;
+ }
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, APR_INC(err));
@@ -283,7 +354,10 @@ nat_t *nat;
}
-aproxy_t *appr_match(pr, name)
+/*
+ * Search for an proxy by the protocol it is being used with and its name.
+ */
+aproxy_t *appr_lookup(pr, name)
u_int pr;
char *name;
{
@@ -317,6 +391,7 @@ void aps_free(aps)
ap_session_t *aps;
{
ap_session_t *a, **ap;
+ aproxy_t *apr;
if (!aps)
return;
@@ -327,6 +402,10 @@ ap_session_t *aps;
break;
}
+ apr = aps->aps_apr;
+ if ((apr != NULL) && (apr->apr_del != NULL))
+ (*apr->apr_del)(aps);
+
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
@@ -432,6 +511,10 @@ int inc;
}
+/*
+ * Initialise hook for kernel application proxies.
+ * Call the initialise routine for all the compiled in kernel proxies.
+ */
int appr_init()
{
aproxy_t *ap;
@@ -446,6 +529,10 @@ int appr_init()
}
+/*
+ * Unload hook for kernel application proxies.
+ * Call the finialise routine for all the compiled in kernel proxies.
+ */
void appr_unload()
{
aproxy_t *ap;
diff --git a/contrib/ipfilter/ip_proxy.h b/contrib/ipfilter/ip_proxy.h
index b8c8eb086cae..0f1ab8469b2d 100644
--- a/contrib/ipfilter/ip_proxy.h
+++ b/contrib/ipfilter/ip_proxy.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_proxy.h,v 2.8.2.7 2001/06/26 10:43:16 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.8.2.12 2002/01/01 13:41:43 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -74,10 +74,12 @@ typedef struct aproxy {
void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
+ void (* apr_del) __P((ap_session_t *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_outpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
+ int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *));
} aproxy_t;
#define APR_DELETE 1
@@ -96,6 +98,7 @@ typedef struct ftpside {
u_32_t ftps_seq;
u_32_t ftps_len;
int ftps_junk;
+ int ftps_cmds;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
@@ -108,7 +111,7 @@ typedef struct ftpinfo {
/*
* Real audio proxy structure and #defines
*/
-typedef struct {
+typedef struct raudio_s {
int rap_seenpna;
int rap_seenver;
int rap_version;
@@ -136,6 +139,19 @@ typedef struct {
#define RAP_M_TCP 4
#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
+/*
+ * IPSec proxy
+ */
+typedef u_32_t ipsec_cookie_t[2];
+
+typedef struct ipsec_pxy {
+ ipsec_cookie_t ipsc_icookie;
+ ipsec_cookie_t ipsc_rcookie;
+ int ipsc_rckset;
+ ipnat_t ipsc_rule;
+ nat_t *ipsc_nat;
+ ipstate_t *ipsc_state;
+} ipsec_pxy_t;
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
@@ -147,9 +163,11 @@ extern int appr_del __P((aproxy_t *));
extern int appr_init __P((void));
extern void appr_unload __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
+extern int appr_match __P((fr_info_t *, struct nat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
-extern aproxy_t *appr_match __P((u_int, char *));
+extern aproxy_t *appr_lookup __P((u_int, char *));
+extern int appr_new __P((fr_info_t *, ip_t *, struct nat *));
#endif /* __IP_PROXY_H__ */
diff --git a/contrib/ipfilter/ip_raudio_pxy.c b/contrib/ipfilter/ip_raudio_pxy.c
index 476e15949f35..ddd5ea3014b4 100644
--- a/contrib/ipfilter/ip_raudio_pxy.c
+++ b/contrib/ipfilter/ip_raudio_pxy.c
@@ -1,5 +1,5 @@
/*
- * $Id: ip_raudio_pxy.c,v 1.7.2.6 2001/07/23 04:17:56 darrenr Exp $
+ * $Id: ip_raudio_pxy.c,v 1.7.2.8 2002/01/13 04:58:29 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -78,7 +78,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
bzero(membuf, sizeof(membuf));
#if SOLARIS
m = fin->fin_qfm;
@@ -194,7 +194,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
@@ -283,11 +283,13 @@ nat_t *nat;
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
fi.fin_out = 0;
- ipn = nat_new(nat->nat_ptr, ip, &fi,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL,
IPN_UDP | (sp ? 0 : FI_W_SPORT), NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_IGNOREPKT|FI_NORULE|
+ (sp ? 0 : FI_W_SPORT));
}
}
@@ -298,11 +300,12 @@ nat_t *nat;
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
fi.fin_out = 1;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP|FI_W_DPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_UDP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT|FI_NORULE);
}
}
diff --git a/contrib/ipfilter/ip_rcmd_pxy.c b/contrib/ipfilter/ip_rcmd_pxy.c
index d017cf94c1d6..641d303c023e 100644
--- a/contrib/ipfilter/ip_rcmd_pxy.c
+++ b/contrib/ipfilter/ip_rcmd_pxy.c
@@ -1,5 +1,5 @@
/*
- * $Id: ip_rcmd_pxy.c,v 1.4.2.4 2000/11/01 14:34:20 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.4.2.5 2001/10/30 16:38:14 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -82,10 +82,10 @@ nat_t *nat;
{
char portbuf[8], *s;
struct in_addr swip;
- u_short sp, dp;
int off, dlen;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
fr_info_t fi;
+ u_short sp;
nat_t *ipn;
mb_t *m;
#if SOLARIS
@@ -103,7 +103,7 @@ nat_t *nat;
(tcp->th_seq != *(u_32_t *)aps->aps_data))
return 0;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
@@ -128,33 +128,33 @@ nat_t *nat;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = htons(sp);
- dp = htons(fin->fin_data[1]);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = sp;
+ fi.fin_data[1] = fin->fin_data[1];
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
+ tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_off = 5;
- fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_dlen = sizeof(*tcp2);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
fi.fin_fr = &rcmdfr;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
diff --git a/contrib/ipfilter/ip_sfil.c b/contrib/ipfilter/ip_sfil.c
index 26ef65ff1a32..e134f6562b6b 100644
--- a/contrib/ipfilter/ip_sfil.c
+++ b/contrib/ipfilter/ip_sfil.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.12 2001/07/18 14:57:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.15 2001/12/26 22:28:51 darrenr Exp $";
#endif
#include <sys/types.h>
@@ -375,14 +375,14 @@ caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
- frentry_t fr;
- frdest_t *fdp;
frgroup_t *fg = NULL;
- u_int *p, *pp;
- int error = 0, in;
+ int error = 0, in, i;
+ u_int *p, *pp;
+ frdest_t *fdp;
+ frentry_t fr;
u_32_t group;
- ill_t *ill;
ipif_t *ipif;
+ ill_t *ill;
ire_t *ire;
fp = &fr;
@@ -448,11 +448,16 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
- if (*fp->fr_ifname) {
- fp->fr_ifa = (void *)get_unit((char *)fp->fr_ifname,
- (int)fp->fr_v);
- if (!fp->fr_ifa)
- fp->fr_ifa = (struct ifnet *)-1;
+ for (i = 0; i < 4; i++) {
+ if ((fp->fr_ifnames[i][1] == '\0') &&
+ ((fp->fr_ifnames[i][0] == '-') ||
+ (fp->fr_ifnames[i][0] == '*'))) {
+ fp->fr_ifas[i] = NULL;
+ } else if (*fp->fr_ifnames[i]) {
+ fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v);
+ if (!fp->fr_ifas[i])
+ fp->fr_ifas[i] = (void *)-1;
+ }
}
fdp = &fp->fr_dif;
@@ -583,6 +588,7 @@ caddr_t data;
fixskip(fprev, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
+ f->fr_ref--;
if (f->fr_ref == 0)
KFREE(f);
}
diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c
index 649ad939ddf8..255bdad61f75 100644
--- a/contrib/ipfilter/ip_state.c
+++ b/contrib/ipfilter/ip_state.c
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 1995-2001 by Darren Reed.
+ * Copyright (C) 1995-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -35,7 +38,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/time.h>
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -77,7 +79,6 @@
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_state.h"
#ifdef USE_INET6
#include <netinet/icmp6.h>
@@ -92,7 +93,7 @@
#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.30.2.38 2001/07/23 13:49:46 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.61 2002/03/06 14:07:36 darrenr Exp $";
#endif
#ifndef MIN
@@ -102,7 +103,6 @@ static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.38 2001/07/23 13:49:46
#define TCP_CLOSE (TH_FIN|TH_RST)
static ipstate_t **ips_table = NULL;
-static ipstate_t *ips_list = NULL;
static int ips_num = 0;
static int ips_wild = 0;
static ips_stat_t ips_stats;
@@ -145,8 +145,12 @@ int fr_statemax = IPSTATE_MAX,
fr_statesize = IPSTATE_SIZE;
int fr_state_doflush = 0,
fr_state_lock = 0;
+ipstate_t *ips_list = NULL;
static int icmpreplytype4[ICMP_MAXTYPE + 1];
+#ifdef USE_INET6
+static int icmpreplytype6[ICMP6_MAXTYPE + 1];
+#endif
int fr_stateinit()
{
@@ -165,6 +169,16 @@ int fr_stateinit()
icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY;
icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY;
icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY;
+#ifdef USE_INET6
+ /* fill icmp reply type table */
+ for (i = 0; i <= ICMP6_MAXTYPE; i++)
+ icmpreplytype6[i] = -1;
+ icmpreplytype6[ICMP6_ECHO_REQUEST] = ICMP6_ECHO_REPLY;
+ icmpreplytype6[ICMP6_MEMBERSHIP_QUERY] = ICMP6_MEMBERSHIP_REPORT;
+ icmpreplytype6[ICMP6_NI_QUERY] = ICMP6_NI_REPLY;
+ icmpreplytype6[ND_ROUTER_SOLICIT] = ND_ROUTER_ADVERT;
+ icmpreplytype6[ND_NEIGHBOR_SOLICIT] = ND_NEIGHBOR_ADVERT;
+#endif
return 0;
}
@@ -184,15 +198,18 @@ static ips_stat_t *fr_statetstats()
* which == 0 : flush all state table entries
* which == 1 : flush TCP connections which have started to close but are
* stuck for some reason.
+ * which == 2 : flush TCP connections which have been idle for a long time,
+ * starting at > 4 days idle and working back in successive half-
+ * days to at most 12 hours old.
*/
static int fr_state_flush(which)
int which;
{
- register ipstate_t *is, **isp;
+ ipstate_t *is, **isp;
#if defined(_KERNEL) && !SOLARIS
int s;
#endif
- int delete, removed = 0;
+ int delete, removed = 0, try;
SPL_NET(s);
for (isp = &ips_list; (is = *isp); ) {
@@ -204,6 +221,7 @@ int which;
delete = 1;
break;
case 1 :
+ case 2 :
if (is->is_p != IPPROTO_TCP)
break;
if ((is->is_state[0] != TCPS_ESTABLISHED) ||
@@ -225,6 +243,40 @@ int which;
} else
isp = &is->is_next;
}
+
+ /*
+ * Asked to remove inactive entries, try again if first attempt
+ * failed. In this case, 86400 is half a day because the counter is
+ * activated every half second.
+ */
+ if ((which == 2) && (removed == 0)) {
+ try = 86400; /* half a day */
+ for (; (try < FIVE_DAYS) && (removed == 0); try += 86400) {
+ for (isp = &ips_list; (is = *isp); ) {
+ delete = 0;
+ if ((is->is_p == IPPROTO_TCP) &&
+ ((is->is_state[0] == TCPS_ESTABLISHED) ||
+ (is->is_state[1] == TCPS_ESTABLISHED)) &&
+ (is->is_age < try)) {
+ ips_stats.iss_fin++;
+ delete = 1;
+ } else if ((is->is_p != IPPROTO_TCP) &&
+ (is->is_pkts > 1)) {
+ ips_stats.iss_expire++;
+ delete = 1;
+ }
+ if (delete) {
+#ifdef IPFILTER_LOG
+ ipstate_log(is, ISL_FLUSH);
+#endif
+ fr_delstate(is);
+ removed++;
+ } else
+ isp = &is->is_next;
+ }
+ }
+ }
+
SPL_X(s);
return removed;
}
@@ -337,19 +389,19 @@ int mode;
}
+/*
+ * Copy out state information from the kernel to a user space process.
+ */
int fr_stgetent(data)
caddr_t data;
{
register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
+ ipstate_save_t ips;
int error;
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
+ error = IRCOPYPTR(data, (caddr_t)&ips, sizeof(ips));
if (error)
- return EFAULT;
+ return error;
isn = ips.ips_next;
if (!isn) {
@@ -376,7 +428,7 @@ caddr_t data;
if (isn->is_rule)
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
+ error = IWCOPYPTR((caddr_t)&ips, data, sizeof(ips));
if (error)
error = EFAULT;
return error;
@@ -387,16 +439,14 @@ int fr_stputent(data)
caddr_t data;
{
register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
- int error, out;
+ ipstate_save_t ips;
+ int error, out, i;
frentry_t *fr;
+ char *name;
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
+ error = IRCOPYPTR(data, (caddr_t)&ips, sizeof(ips));
if (error)
- return EFAULT;
+ return error;
KMALLOC(isn, ipstate_t *);
if (isn == NULL)
@@ -415,24 +465,34 @@ caddr_t data;
out = fr->fr_flags & FR_OUTQUE ? 1 : 0;
isn->is_rule = fr;
ips.ips_is.is_rule = fr;
- if (*fr->fr_ifname) {
- fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_v);
- if (fr->fr_ifa == NULL)
- fr->fr_ifa = (void *)-1;
-#ifdef _KERNEL
- else {
- strncpy(isn->is_ifname[out],
- IFNAME(fr->fr_ifa), IFNAMSIZ);
- isn->is_ifp[out] = fr->fr_ifa;
+
+ /*
+ * Look up all the interface names in the rule.
+ */
+ 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] = GETUNIT(name,
+ fr->fr_v);
+ if (fr->fr_ifas[i] == NULL)
+ fr->fr_ifas[i] = (void *)-1;
+ else {
+ strncpy(isn->is_ifname[i],
+ IFNAME(fr->fr_ifas[i]),
+ IFNAMSIZ);
+ }
}
-#endif
- } else
- fr->fr_ifa = NULL;
+ isn->is_ifp[out] = fr->fr_ifas[i];
+ }
+
/*
* send a copy back to userland of what we ended up
* to allow for verification.
*/
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
+ error = IWCOPYPTR((caddr_t)&ips, data, sizeof(ips));
if (error) {
KFREE(isn);
KFREE(fr);
@@ -453,22 +513,34 @@ caddr_t data;
}
+/*
+ * Insert a state table entry manually.
+ */
void fr_stinsert(is)
register ipstate_t *is;
{
register u_int hv = is->is_hv;
+ char *name;
+ int i;
MUTEX_INIT(&is->is_lock, "ipf state entry", NULL);
- is->is_ifname[0][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[0][0] != '\0') {
- is->is_ifp[0] = GETUNIT(is->is_ifname[0], is->is_v);
- }
- is->is_ifname[1][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[1][0] != '\0') {
- is->is_ifp[1] = GETUNIT(is->is_ifname[1], is->is_v);
+ /*
+ * 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] = GETUNIT(name, is->is_v);
+ if (is->is_ifp[i] == NULL)
+ is->is_ifp[i] = (void *)-1;
+ }
}
+
/*
* add into list table.
*/
@@ -491,16 +563,19 @@ register ipstate_t *is;
/*
* Create a new ipstate structure and hang it off the hash table.
*/
-ipstate_t *fr_addstate(ip, fin, flags)
+ipstate_t *fr_addstate(ip, fin, stsave, flags)
ip_t *ip;
fr_info_t *fin;
+ipstate_t **stsave;
u_int flags;
{
register tcphdr_t *tcp = NULL;
register ipstate_t *is;
register u_int hv;
+ struct icmp *ic;
ipstate_t ips;
u_int pass;
+ void *ifp;
int out;
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
@@ -514,8 +589,6 @@ u_int flags;
is = &ips;
bzero((char *)is, sizeof(*is));
ips.is_age = 1;
- ips.is_state[0] = 0;
- ips.is_state[1] = 0;
/*
* Copy and calculate...
*/
@@ -526,14 +599,21 @@ u_int flags;
hv += is->is_daddr;
#ifdef USE_INET6
if (fin->fin_v == 6) {
- if (is->is_p == IPPROTO_ICMPV6) {
- if (IN6_IS_ADDR_MULTICAST(&is->is_dst.in6))
- flags |= FI_W_DADDR;
- if (out)
- hv -= is->is_daddr;
- else
- hv -= is->is_saddr;
+ if ((is->is_p == IPPROTO_ICMPV6) &&
+ IN6_IS_ADDR_MULTICAST(&is->is_dst.in6)) {
+ /*
+ * So you can do keep state with neighbour discovery.
+ */
+ flags |= FI_W_DADDR;
+ hv -= is->is_daddr;
+ } else {
+ hv += is->is_dst.i6[1];
+ hv += is->is_dst.i6[2];
+ hv += is->is_dst.i6[3];
}
+ hv += is->is_src.i6[1];
+ hv += is->is_src.i6[2];
+ hv += is->is_src.i6[3];
}
#endif
@@ -541,30 +621,35 @@ u_int flags;
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
-#endif
- case IPPROTO_ICMP :
- {
- struct icmp *ic = (struct icmp *)fin->fin_dp;
-
-#ifdef USE_INET6
- if ((is->is_p == IPPROTO_ICMPV6) &&
- ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0))
+ ic = (struct icmp *)fin->fin_dp;
+ if ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0)
return NULL;
-#endif
+
switch (ic->icmp_type)
{
-#ifdef USE_INET6
case ICMP6_ECHO_REQUEST :
- is->is_icmp.ics_type = ICMP6_ECHO_REPLY;
+ is->is_icmp.ics_type = ic->icmp_type;
hv += (is->is_icmp.ics_id = ic->icmp_id);
hv += (is->is_icmp.ics_seq = ic->icmp_seq);
break;
case ICMP6_MEMBERSHIP_QUERY :
case ND_ROUTER_SOLICIT :
case ND_NEIGHBOR_SOLICIT :
- is->is_icmp.ics_type = ic->icmp_type + 1;
+ case ICMP6_NI_QUERY :
+ is->is_icmp.ics_type = ic->icmp_type;
break;
+ default :
+ return NULL;
+ }
+ ATOMIC_INCL(ips_stats.iss_icmp);
+ is->is_age = fr_icmptimeout;
+ break;
#endif
+ case IPPROTO_ICMP :
+ ic = (struct icmp *)fin->fin_dp;
+
+ switch (ic->icmp_type)
+ {
case ICMP_ECHO :
case ICMP_TSTAMP :
case ICMP_IREQ :
@@ -579,9 +664,7 @@ u_int flags;
ATOMIC_INCL(ips_stats.iss_icmp);
is->is_age = fr_icmptimeout;
break;
- }
case IPPROTO_TCP :
- {
tcp = (tcphdr_t *)fin->fin_dp;
if (tcp->th_flags & TH_RST)
@@ -590,11 +673,11 @@ u_int flags;
* The endian of the ports doesn't matter, but the ack and
* sequence numbers do as we do mathematics on them later.
*/
- is->is_dport = tcp->th_dport;
- is->is_sport = tcp->th_sport;
+ is->is_sport = htons(fin->fin_data[0]);
+ is->is_dport = htons(fin->fin_data[1]);
if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
- hv += tcp->th_dport;
- hv += tcp->th_sport;
+ hv += is->is_sport;
+ hv += is->is_dport;
}
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
(tcp->th_off << 2) +
@@ -613,23 +696,22 @@ u_int flags;
*/
ATOMIC_INCL(ips_stats.iss_tcp);
break;
- }
+
case IPPROTO_UDP :
- {
tcp = (tcphdr_t *)fin->fin_dp;
- is->is_dport = tcp->th_dport;
- is->is_sport = tcp->th_sport;
+ is->is_sport = htons(fin->fin_data[0]);
+ is->is_dport = htons(fin->fin_data[1]);
if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
- hv += tcp->th_dport;
- hv += tcp->th_sport;
+ hv += is->is_sport;
+ hv += is->is_dport;
}
ATOMIC_INCL(ips_stats.iss_udp);
is->is_age = fr_udptimeout;
break;
- }
default :
- return NULL;
+ is->is_age = fr_udptimeout;
+ break;
}
KMALLOC(is, ipstate_t *);
@@ -644,19 +726,47 @@ u_int flags;
if (is->is_rule != NULL) {
ATOMIC_INC32(is->is_rule->fr_ref);
pass = is->is_rule->fr_flags;
+ is->is_frage[0] = is->is_rule->fr_age[0];
+ is->is_frage[1] = is->is_rule->fr_age[1];
+ if (is->is_frage[0] != 0)
+ is->is_age = is->is_frage[0];
+
+ is->is_ifp[(out << 1) + 1] = is->is_rule->fr_ifas[1];
+ is->is_ifp[(1 - out) << 1] = is->is_rule->fr_ifas[2];
+ is->is_ifp[((1 - out) << 1) + 1] = is->is_rule->fr_ifas[3];
+
+ if (((ifp = is->is_rule->fr_ifas[1]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[(out << 1) + 1],
+ IFNAME(ifp), IFNAMSIZ);
+ if (((ifp = is->is_rule->fr_ifas[2]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[(1 - out) << 1],
+ IFNAME(ifp), IFNAMSIZ);
+ if (((ifp = is->is_rule->fr_ifas[3]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[((1 - out) << 1) + 1],
+ IFNAME(ifp), IFNAMSIZ);
} else
pass = fr_flags;
+
+ is->is_ifp[out << 1] = fin->fin_ifp;
+ strncpy(is->is_ifname[out << 1], IFNAME(fin->fin_ifp), IFNAMSIZ);
+
WRITE_ENTER(&ipf_state);
is->is_pass = pass;
- is->is_pkts = 1;
- is->is_bytes = fin->fin_dlen + fin->fin_hlen;
+ if ((flags & FI_IGNOREPKT) == 0) {
+ is->is_pkts = 1;
+ is->is_bytes = fin->fin_dlen + fin->fin_hlen;
+ }
/*
* 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_fi.fi_v;
+ is->is_v = fin->fin_v;
+ is->is_rulen = fin->fin_rule;
is->is_opt = fin->fin_fi.fi_optmsk;
is->is_optmsk = 0xffffffff;
is->is_sec = fin->fin_fi.fi_secmsk;
@@ -668,20 +778,14 @@ u_int flags;
is->is_flags |= flags & (FI_WILDP|FI_WILDA);
if (flags & (FI_WILDP|FI_WILDA))
ips_wild++;
- is->is_ifp[1 - out] = NULL;
- is->is_ifp[out] = fin->fin_ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- is->is_ifname[1 - out][0] = '\0';
+
if (pass & FR_LOGFIRST)
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
fr_stinsert(is);
+ is->is_me = stsave;
if (is->is_p == IPPROTO_TCP) {
- MUTEX_ENTER(&is->is_lock);
fr_tcp_age(&is->is_age, is->is_state, fin,
0); /* 0 = packet from the source */
- MUTEX_EXIT(&is->is_lock);
}
#ifdef IPFILTER_LOG
ipstate_log(is, ISL_NEW);
@@ -801,19 +905,25 @@ tcphdr_t *tcp;
}
+/*
+ * Match a state table entry against an IP packet.
+ */
static int fr_matchsrcdst(is, src, dst, fin, tcp)
ipstate_t *is;
union i6addr src, dst;
fr_info_t *fin;
tcphdr_t *tcp;
{
- int ret = 0, rev, out, flags;
+ int ret = 0, rev, out, flags, idx;
u_short sp, dp;
void *ifp;
rev = IP6NEQ(is->is_dst, dst);
ifp = fin->fin_ifp;
out = fin->fin_out;
+ flags = is->is_flags & (FI_WILDA|FI_WILDP);
+ sp = 0;
+ dp = 0;
if (tcp != NULL) {
flags = is->is_flags;
@@ -825,44 +935,28 @@ tcphdr_t *tcp;
else if (!(flags & FI_W_DPORT) && (dp != is->is_dport))
rev = 1;
}
- } else {
- flags = is->is_flags & FI_WILDA;
- sp = 0;
- dp = 0;
}
- if (rev == 0) {
- if (!out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- } else {
- if (out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- }
+ idx = (out << 1) + rev;
+
+ if ((is->is_ifp[idx] == NULL &&
+ (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) ||
+ is->is_ifp[idx] == ifp)
+ ret = 1;
+
if (ret == 0)
return 0;
ret = 0;
if (rev == 0) {
- if (
- (IP6EQ(is->is_dst, dst) || (flags & FI_W_DADDR)) &&
+ if ((IP6EQ(is->is_dst, dst) || (flags & FI_W_DADDR)) &&
(IP6EQ(is->is_src, src) || (flags & FI_W_SADDR)) &&
(!tcp || ((sp == is->is_sport || flags & FI_W_SPORT) &&
(dp == is->is_dport || flags & FI_W_DPORT)))) {
ret = 1;
}
} else {
- if (
- (IP6EQ(is->is_dst, src) || (flags & FI_W_DADDR)) &&
+ if ((IP6EQ(is->is_dst, src) || (flags & FI_W_DADDR)) &&
(IP6EQ(is->is_src, dst) || (flags & FI_W_SADDR)) &&
(!tcp || ((sp == is->is_dport || flags & FI_W_DPORT) &&
(dp == is->is_sport || flags & FI_W_SPORT)))) {
@@ -885,6 +979,26 @@ tcphdr_t *tcp;
(fin->fin_fi.fi_auth != is->is_auth))
return 0;
+ flags = is->is_flags & (FI_WILDA|FI_WILDP);
+ if ((flags & (FI_W_SADDR|FI_W_DADDR))) {
+ if ((flags & FI_W_SADDR) != 0) {
+ if (rev == 0) {
+ is->is_src = fin->fin_fi.fi_src;
+ } else {
+ is->is_src = fin->fin_fi.fi_dst;
+ }
+ } else if ((flags & FI_W_DPORT) != 0) {
+ if (rev == 0) {
+ is->is_dst = fin->fin_fi.fi_dst;
+ } else {
+ is->is_dst = fin->fin_fi.fi_src;
+ }
+ }
+ is->is_flags &= ~(FI_W_SADDR|FI_W_DADDR);
+ if ((is->is_flags & (FI_WILDA|FI_WILDP)) == 0)
+ ips_wild--;
+ }
+
if ((flags & (FI_W_SPORT|FI_W_DPORT))) {
if ((flags & FI_W_SPORT) != 0) {
if (rev == 0) {
@@ -911,30 +1025,14 @@ tcphdr_t *tcp;
ret = -1;
- if (!rev) {
- if (out) {
- if (!is->is_ifpout)
- ret = 1;
- } else {
- if (!is->is_ifpin)
- ret = 0;
- }
- } else {
- if (out) {
- if (!is->is_ifpin)
- ret = 0;
- } else {
- if (!is->is_ifpout)
- ret = 1;
- }
- }
+ if (is->is_ifp[idx] == NULL &&
+ (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*'))
+ ret = idx;
if (ret >= 0) {
is->is_ifp[ret] = ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[ret], IFNAME(fin->fin_ifp),
+ strncpy(is->is_ifname[ret], IFNAME(ifp),
sizeof(is->is_ifname[ret]));
-#endif
}
fin->fin_rev = rev;
return 1;
@@ -951,20 +1049,24 @@ icmphdr_t *icmp;
* it will still be the same type.
*/
if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype4[is->is_type] == icmp->icmp_type)) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
+ (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
+ if (icmp->icmp_type != ICMP_ECHOREPLY)
+ return 1;
+ if ((icmp->icmp_id == is->is_icmp.ics_id) &&
+ (icmp->icmp_seq == is->is_icmp.ics_seq))
+ return 1;
+ }
}
#ifdef USE_INET6
else if (is->is_v == 6) {
- if ((is->is_type == ICMP6_ECHO_REPLY) &&
- (icmp->icmp_type == ICMP6_ECHO_REQUEST) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
+ if (((icmp->icmp_type == is->is_type) ||
+ (icmpreplytype6[is->is_type] == icmp->icmp_type))) {
+ if (icmp->icmp_type != ICMP6_ECHO_REPLY)
+ return 1;
+ if ((icmp->icmp_id == is->is_icmp.ics_id) &&
+ (icmp->icmp_seq == is->is_icmp.ics_seq))
+ return 1;
+ }
}
#endif
return 0;
@@ -996,6 +1098,7 @@ fr_info_t *fin;
if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
(fin->fin_plen < ICMPERR_MINPKTLEN))
return NULL;
+
ic = (struct icmp *)fin->fin_dp;
type = ic->icmp_type;
/*
@@ -1049,8 +1152,11 @@ fr_info_t *fin;
*/
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
+ fr = NULL;
- if (oip->ip_p == IPPROTO_ICMP) {
+ switch (oip->ip_p)
+ {
+ case IPPROTO_ICMP :
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
/*
@@ -1096,15 +1202,17 @@ fr_info_t *fin;
is->is_pkts++;
is->is_bytes += ip->ip_len;
fr = is->is_rule;
- RWLOCK_EXIT(&ipf_state);
- return fr;
+ break;
}
RWLOCK_EXIT(&ipf_state);
+ return fr;
+
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ break;
+ default :
return NULL;
- };
-
- if ((oip->ip_p != IPPROTO_TCP) && (oip->ip_p != IPPROTO_UDP))
- return NULL;
+ }
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
dport = tcp->th_dport;
@@ -1156,15 +1264,18 @@ fr_info_t *fin;
* for the accompanying state table entry.
* It remains to be seen if that is correct. XXX
*/
- RWLOCK_EXIT(&ipf_state);
- return fr;
+ break;
}
}
RWLOCK_EXIT(&ipf_state);
- return NULL;
+ return fr;
}
+/*
+ * Move a state hash table entry from its old location at is->is_hv to
+ * its new location, indexed by hv % fr_statesize.
+ */
static void fr_ipsmove(isp, is, hv)
ipstate_t **isp, *is;
u_int hv;
@@ -1211,6 +1322,7 @@ fr_info_t *fin;
struct icmp *ic;
frentry_t *fr;
tcphdr_t *tcp;
+ int rev;
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
return NULL;
@@ -1227,42 +1339,113 @@ fr_info_t *fin;
/*
* Search the hash table for matching packet header info.
+ * At the bottom of this switch statement, the following is expected:
+ * is == NULL, no lock on ipf_state is held.
+ * is != NULL, a lock on ipf_state is held.
*/
v = fin->fin_fi.fi_v;
- switch (fin->fin_fi.fi_p)
+#ifdef USE_INET6
+ if (v == 6) {
+ hv += fin->fin_fi.fi_src.i6[1];
+ hv += fin->fin_fi.fi_src.i6[2];
+ hv += fin->fin_fi.fi_src.i6[3];
+
+ if ((fin->fin_p == IPPROTO_ICMPV6) &&
+ IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_dst.in6)) {
+ hv -= dst.in4.s_addr;
+ } else {
+ hv += fin->fin_fi.fi_dst.i6[1];
+ hv += fin->fin_fi.fi_dst.i6[2];
+ hv += fin->fin_fi.fi_dst.i6[3];
+ }
+ }
+#endif
+
+ switch (fin->fin_p)
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
+ tcp = NULL;
+ tryagain = 0;
if (v == 6) {
- if (fin->fin_out)
- hv -= dst.in4.s_addr;
- else
- hv -= src.in4.s_addr;
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);
+icmp6again:
+ hvm = hv % fr_statesize;
+ for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
+ if ((is->is_p == pr) && (is->is_v == v) &&
+ fr_matchsrcdst(is, src, dst, fin, NULL) &&
+ fr_matchicmpqueryreply(v, is, ic)) {
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
+ is->is_age = fr_icmpacktimeout;
+ else
+ is->is_age = fr_icmptimeout;
+ break;
+ }
+
+ if (is != NULL) {
+ if (tryagain && !(is->is_flags & FI_W_DADDR)) {
+ hv += fin->fin_fi.fi_src.i6[0];
+ hv += fin->fin_fi.fi_src.i6[1];
+ hv += fin->fin_fi.fi_src.i6[2];
+ hv += fin->fin_fi.fi_src.i6[3];
+ fr_ipsmove(isp, is, hv);
+ MUTEX_DOWNGRADE(&ipf_state);
+ }
+ break;
+ }
+ RWLOCK_EXIT(&ipf_state);
+
+ /*
+ * No matching icmp state entry. Perhaps this is a
+ * response to another state entry.
+ */
+ if ((ips_wild != 0) && (v == 6) && (tryagain == 0) &&
+ !IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_src.in6)) {
+ hv -= fin->fin_fi.fi_src.i6[0];
+ hv -= fin->fin_fi.fi_src.i6[1];
+ hv -= fin->fin_fi.fi_src.i6[2];
+ hv -= fin->fin_fi.fi_src.i6[3];
+ tryagain = 1;
+ WRITE_ENTER(&ipf_state);
+ goto icmp6again;
+ }
+
+ fr = fr_checkicmp6matchingstate((ip6_t *)ip, fin);
+ if (fr)
+ return fr;
+ break;
#endif
case IPPROTO_ICMP :
+ tcp = NULL;
if (v == 4) {
hv += ic->icmp_id;
hv += ic->icmp_seq;
}
- hv %= fr_statesize;
+ hvm = hv % fr_statesize;
READ_ENTER(&ipf_state);
- for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
+ for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, NULL) &&
fr_matchicmpqueryreply(v, is, ic)) {
- if (fin->fin_rev)
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
is->is_age = fr_icmpacktimeout;
else
is->is_age = fr_icmptimeout;
break;
}
- }
+
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
@@ -1270,28 +1453,21 @@ fr_info_t *fin;
* No matching icmp state entry. Perhaps this is a
* response to another state entry.
*/
-#ifdef USE_INET6
- if (v == 6)
- fr = fr_checkicmp6matchingstate((ip6_t *)ip, fin);
- else
-#endif
- fr = fr_checkicmpmatchingstate(ip, fin);
+ fr = fr_checkicmpmatchingstate(ip, fin);
if (fr)
return fr;
break;
case IPPROTO_TCP :
- {
- register u_short dport, sport;
- register int i;
-
- i = tcp->th_flags;
/*
* Just plain ignore RST flag set with either FIN or SYN.
*/
- if ((i & TH_RST) &&
- ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
+ if ((tcp->th_flags & TH_RST) &&
+ ((tcp->th_flags & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
break;
case IPPROTO_UDP :
+ {
+ register u_short dport, sport;
+
dport = tcp->th_dport;
sport = tcp->th_sport;
tryagain = 0;
@@ -1303,12 +1479,15 @@ retry_tcpudp:
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
+ rev = fin->fin_rev;
if ((pr == IPPROTO_TCP)) {
if (!fr_tcpstate(is, fin, ip, tcp)) {
continue;
}
} else if ((pr == IPPROTO_UDP)) {
- if (fin->fin_rev)
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
is->is_age = fr_udpacktimeout;
else
is->is_age = fr_udptimeout;
@@ -1336,47 +1515,74 @@ retry_tcpudp:
break;
}
default :
+ tcp = NULL;
+ hv %= fr_statesize;
+ READ_ENTER(&ipf_state);
+ for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
+ if ((is->is_p == pr) && (is->is_v == v) &&
+ fr_matchsrcdst(is, src, dst, fin, NULL)) {
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else
+ is->is_age = fr_udptimeout;
+ break;
+ }
+ }
+ if (is == NULL) {
+ RWLOCK_EXIT(&ipf_state);
+ }
break;
}
+
if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_miss);
return NULL;
}
+
MUTEX_ENTER(&is->is_lock);
is->is_bytes += fin->fin_plen;
ips_stats.iss_hits++;
is->is_pkts++;
MUTEX_EXIT(&is->is_lock);
fr = is->is_rule;
+ fin->fin_rule = is->is_rulen;
+ if (fr != NULL) {
+ fin->fin_group = fr->fr_group;
+ fin->fin_icode = fr->fr_icode;
+ }
fin->fin_fr = fr;
pass = is->is_pass;
-#ifndef _KERNEL
- if (tcp->th_flags & TCP_CLOSE)
- fr_delstate(is);
-#endif
RWLOCK_EXIT(&ipf_state);
if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
+#ifndef _KERNEL
+ if ((tcp != NULL) && (tcp->th_flags & TCP_CLOSE))
+ fr_delstate(is);
+#endif
return fr;
}
+/*
+ * Sync. state entries. If interfaces come or go or just change position,
+ * this is needed.
+ */
void ip_statesync(ifp)
void *ifp;
{
register ipstate_t *is;
+ int i;
WRITE_ENTER(&ipf_state);
for (is = ips_list; is; is = is->is_next) {
- if (is->is_ifpin == ifp) {
- is->is_ifpin = GETUNIT(is->is_ifname[0], is->is_v);
- if (!is->is_ifpin)
- is->is_ifpin = (void *)-1;
- }
- if (is->is_ifpout == ifp) {
- is->is_ifpout = GETUNIT(is->is_ifname[1], is->is_v);
- if (!is->is_ifpout)
- is->is_ifpout = (void *)-1;
+ for (i = 0; i < 4; i++) {
+ if (is->is_ifp[i] == ifp) {
+ is->is_ifpin = GETUNIT(is->is_ifname[i],
+ is->is_v);
+ if (!is->is_ifp[i])
+ is->is_ifp[i] = (void *)-1;
+ }
}
}
RWLOCK_EXIT(&ipf_state);
@@ -1401,6 +1607,8 @@ ipstate_t *is;
*is->is_phnext = is->is_hnext;
if (ips_table[is->is_hv] == NULL)
ips_stats.iss_inuse--;
+ if (is->is_me)
+ *is->is_me = NULL;
fr = is->is_rule;
if (fr != NULL) {
@@ -1462,7 +1670,7 @@ void fr_timeoutstate()
} else
isp = &is->is_next;
if (fr_state_doflush) {
- (void) fr_state_flush(1);
+ (void) fr_state_flush(2);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
@@ -1546,8 +1754,11 @@ int dir;
*/
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
- state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
+ if (state[1 - dir] == TCPS_CLOSED ||
+ state[1 - dir] == TCPS_ESTABLISHED) {
+ state[dir] = TCPS_ESTABLISHED;
+ *age = fr_tcpidletimeout;
+ }
}
/*
* TODO: besides regular ACK packets we can have other
@@ -1736,9 +1947,11 @@ u_int type;
ipsl.isl_state[0] = is->is_state[0];
ipsl.isl_state[1] = is->is_state[1];
}
- } else if (ipsl.isl_p == IPPROTO_ICMP)
+ } else if (ipsl.isl_p == IPPROTO_ICMP) {
+ ipsl.isl_itype = is->is_icmp.ics_type;
+ } else if (ipsl.isl_p == IPPROTO_ICMPV6) {
ipsl.isl_itype = is->is_icmp.ics_type;
- else {
+ } else {
ipsl.isl_ps.isl_filler[0] = 0;
ipsl.isl_ps.isl_filler[1] = 0;
}
@@ -1891,10 +2104,6 @@ fr_info_t *fin;
fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
fr = is->is_rule;
ips_stats.iss_hits++;
- /*
- * we must swap src and dst here because the icmp
- * comes the other way around
- */
is->is_pkts++;
is->is_bytes += fin->fin_plen;
/*
diff --git a/contrib/ipfilter/ip_state.h b/contrib/ipfilter/ip_state.h
index b940d774ade6..fe6a505fe66d 100644
--- a/contrib/ipfilter/ip_state.h
+++ b/contrib/ipfilter/ip_state.h
@@ -4,7 +4,7 @@
* 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.13.2.4 2001/06/26 10:43:17 darrenr Exp $
+ * $Id: ip_state.h,v 2.13.2.10 2002/03/06 14:07:38 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -57,17 +57,20 @@ typedef struct ipstate {
struct ipstate **is_pnext;
struct ipstate *is_hnext;
struct ipstate **is_phnext;
+ struct ipstate **is_me;
u_long is_age;
+ u_int is_frage[2]; /* age from filter rule, forward & reverse */
u_int is_pass;
U_QUAD_T is_pkts;
U_QUAD_T is_bytes;
- void *is_ifp[2];
+ void *is_ifp[4];
frentry_t *is_rule;
union i6addr is_src;
union i6addr is_dst;
u_char is_p; /* Protocol */
u_char is_v;
u_int is_hv;
+ u_32_t is_rulen; /* rule number */
u_32_t is_flags;
u_32_t is_opt; /* packet options set */
u_32_t is_optmsk; /* " " mask */
@@ -80,7 +83,7 @@ typedef struct ipstate {
tcpstate_t is_ts;
udpstate_t is_us;
} is_ps;
- char is_ifname[2][IFNAMSIZ];
+ char is_ifname[4][IFNAMSIZ];
#if SOLARIS || defined(__sgi)
kmutex_t is_lock;
#endif
@@ -103,7 +106,7 @@ typedef struct ipstate {
#define is_dport is_tcp.ts_dport
#define is_state is_tcp.ts_state
#define is_ifpin is_ifp[0]
-#define is_ifpout is_ifp[1]
+#define is_ifpout is_ifp[2]
#define TH_OPENING (TH_SYN|TH_ACK)
/*
@@ -177,12 +180,15 @@ extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_tcphalfclosed;
extern u_long fr_udptimeout;
+extern u_long fr_udpacktimeout;
extern u_long fr_icmptimeout;
+extern u_long fr_icmpacktimeout;
+extern ipstate_t *ips_list;
extern int fr_state_lock;
extern int fr_stateinit __P((void));
extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
-extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int));
-extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
+extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, ipstate_t **, u_int));
+extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
extern void ip_statesync __P((void *));
extern void fr_timeoutstate __P((void));
extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));
diff --git a/contrib/ipfilter/ipf.c b/contrib/ipfilter/ipf.c
index 4d25fcedde52..b983781d8f60 100644
--- a/contrib/ipfilter/ipf.c
+++ b/contrib/ipfilter/ipf.c
@@ -12,6 +12,9 @@
# endif
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -47,7 +50,7 @@
#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 2.10.2.10 2001/07/18 11:34:19 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.13 2002/02/22 15:32:53 darrenr Exp $";
#endif
#if SOLARIS
@@ -64,9 +67,7 @@ void zerostats __P((void));
int main __P((int, char *[]));
int opts = 0;
-#ifdef USE_INET6
int use_inet6 = 0;
-#endif
static int fd = -1;
@@ -105,11 +106,9 @@ char *argv[];
while ((c = getopt(argc, argv, OPTS)) != -1) {
switch (c)
{
-#ifdef USE_INET6
case '6' :
use_inet6 = 1;
break;
-#endif
case 'A' :
opts &= ~OPT_INACTIVE;
break;
diff --git a/contrib/ipfilter/ipf.h b/contrib/ipfilter/ipf.h
index e7a70ca7245f..e9c3a025dea5 100644
--- a/contrib/ipfilter/ipf.h
+++ b/contrib/ipfilter/ipf.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipf.h 1.12 6/5/96
- * $Id: ipf.h,v 2.9.2.3 2001/06/26 10:43:18 darrenr Exp $
+ * $Id: ipf.h,v 2.9.2.6 2002/01/03 08:00:12 darrenr Exp $
*/
#ifndef __IPF_H__
@@ -38,6 +38,7 @@
#define OPT_STATETOP 0x400000
#define OPT_FLUSH 0x800000
#define OPT_CLEAR 0x1000000
+#define OPT_HEX 0x2000000
#define OPT_NODO 0x80000000
#define OPT_STAT OPT_FRSTATES
@@ -52,7 +53,10 @@
# endif
#endif
+struct ipstate;
struct frpcmp;
+struct ipnat;
+struct nat;
#ifdef ultrix
extern char *strdup __P((char *));
@@ -90,9 +94,15 @@ extern int genmask __P((char *, u_32_t *));
extern int hostnum __P((u_32_t *, char *, int));
extern u_32_t optname __P((char ***, u_short *, int));
extern void printpacket __P((ip_t *));
+extern void printpacket6 __P((ip_t *));
extern void printportcmp __P((int, struct frpcmp *));
extern void printhostmask __P((int, u_32_t *, u_32_t *));
extern void printbuf __P((char *, int, int));
+extern char *hostname __P((int, void *));
+extern struct ipstate *printstate __P((struct ipstate *, int));
+extern void printnat __P((struct ipnat *, int));
+extern void printactivenat __P((struct nat *, int));
+
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
extern int gethostname __P((char *, int ));
diff --git a/contrib/ipfilter/ipfs.c b/contrib/ipfilter/ipfs.c
index baf3d1c83aa5..b111bfd90506 100644
--- a/contrib/ipfilter/ipfs.c
+++ b/contrib/ipfilter/ipfs.c
@@ -45,7 +45,7 @@
#include "ipf.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.7 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.8 2001/09/14 18:52:21 darrenr Exp $";
#endif
#ifndef IPF_SAVEDIR
@@ -237,13 +237,13 @@ char *argv[];
opts |= OPT_DONOTHING;
break;
case 'N' :
- if ((ns > 0) || dirname || (rw != -1) || set)
+ if ((ns >= 0) || dirname || (rw != -1) || set)
usage();
ns = 0;
set = 1;
break;
case 'r' :
- if ((ns > 0) || dirname || (rw != -1))
+ if ((ns >= 0) || dirname || (rw != -1))
usage();
rw = 0;
set = 1;
@@ -253,7 +253,7 @@ char *argv[];
set = 1;
break;
case 'S' :
- if ((ns > 0) || dirname || (rw != -1) || set)
+ if ((ns >= 0) || dirname || (rw != -1) || set)
usage();
ns = 1;
set = 1;
@@ -268,7 +268,7 @@ char *argv[];
opts |= OPT_VERBOSE;
break;
case 'w' :
- if ((ns > 0) || dirname || (rw != -1) || (ns == -1))
+ if (dirname || (rw != -1) || (ns == -1))
usage();
rw = 1;
set = 1;
@@ -283,7 +283,7 @@ char *argv[];
}
if (ifs) {
- if (!filename || ns<0)
+ if (!filename || ns < 0)
usage();
if (ns == 0)
return changenatif(ifs, filename);
diff --git a/contrib/ipfilter/ipft_ef.c b/contrib/ipfilter/ipft_ef.c
index 0cb4623b58ed..8344d5f027ba 100644
--- a/contrib/ipfilter/ipft_ef.c
+++ b/contrib/ipfilter/ipft_ef.c
@@ -17,6 +17,9 @@ etherfind -n -t
0.32 91 04 131.170.1.10 128.250.133.13
0.33 566 udp 128.250.37.155 128.250.133.3 901 901
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@@ -49,7 +52,7 @@ etherfind -n -t
#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 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.2 2002/02/22 15:32:53 darrenr Exp $";
#endif
static int etherf_open __P((char *));
diff --git a/contrib/ipfilter/ipft_hx.c b/contrib/ipfilter/ipft_hx.c
index 2be1698afe5c..2ce233534fc8 100644
--- a/contrib/ipfilter/ipft_hx.c
+++ b/contrib/ipfilter/ipft_hx.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
@@ -40,7 +43,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 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.2.2.5 2002/02/22 15:32:54 darrenr Exp $";
#endif
extern int opts;
@@ -91,6 +94,14 @@ int cnt, *dir;
char line[513];
ip_t *ip;
+ /*
+ * interpret start of line as possibly "[ifname]" or
+ * "[in/out,ifname]".
+ */
+ if (ifn)
+ *ifn = NULL;
+ if (dir)
+ *dir = 0;
ip = (ip_t *)buf;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n'))) {
@@ -107,21 +118,14 @@ int cnt, *dir;
fflush(stdout);
}
- /*
- * interpret start of line as possibly "[ifname]" or
- * "[in/out,ifname]".
- */
- if (ifn)
- *ifn = NULL;
- if (dir)
- *dir = 0;
- if ((*buf == '[') && (s = index(line, ']'))) {
- t = buf + 1;
- if (t - s > 0) {
+ if ((*line == '[') && (s = index(line, ']'))) {
+ t = line + 1;
+ if (s - t > 0) {
+ *s++ = '\0';
if ((u = index(t, ',')) && (u < s)) {
u++;
if (ifn)
- *ifn = u;
+ *ifn = strdup(u);
if (dir) {
if (*t == 'i')
*dir = 0;
@@ -130,7 +134,6 @@ int cnt, *dir;
}
} else if (ifn)
*ifn = t;
- *s++ = '\0';
}
} else
s = line;
diff --git a/contrib/ipfilter/ipft_pc.c b/contrib/ipfilter/ipft_pc.c
index eced91fa3ab1..8b80fecd64ae 100644
--- a/contrib/ipfilter/ipft_pc.c
+++ b/contrib/ipfilter/ipft_pc.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@@ -31,7 +34,7 @@
#include "ipt.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2.2.2 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2.2.3 2002/02/22 15:32:54 darrenr Exp $";
#endif
struct llc {
diff --git a/contrib/ipfilter/ipft_sn.c b/contrib/ipfilter/ipft_sn.c
index 1b5e219cbbc7..1a8f5a271ddd 100644
--- a/contrib/ipfilter/ipft_sn.c
+++ b/contrib/ipfilter/ipft_sn.c
@@ -7,6 +7,9 @@
/*
* Written to comply with the recent RFC 1761 from Sun.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@@ -35,7 +38,7 @@
#include "ipt.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2.2.2 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2.2.3 2002/02/22 15:32:54 darrenr Exp $";
#endif
struct llc {
diff --git a/contrib/ipfilter/ipft_td.c b/contrib/ipfilter/ipft_td.c
index 5f470eed2da4..253aa860fbe9 100644
--- a/contrib/ipfilter/ipft_td.c
+++ b/contrib/ipfilter/ipft_td.c
@@ -26,6 +26,9 @@ tcpdump -nqte
8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@@ -58,7 +61,7 @@ tcpdump -nqte
#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 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.2 2002/02/22 15:32:54 darrenr Exp $";
#endif
static int tcpd_open __P((char *));
diff --git a/contrib/ipfilter/ipft_tx.c b/contrib/ipfilter/ipft_tx.c
index 1e650f5177df..f61b0d09f86c 100644
--- a/contrib/ipfilter/ipft_tx.c
+++ b/contrib/ipfilter/ipft_tx.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
@@ -41,7 +44,7 @@
#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 2.3.2.4 2001/06/26 10:43:18 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.3.2.6 2002/03/13 03:55:15 darrenr Exp $";
#endif
extern int opts;
@@ -261,7 +264,7 @@ int *out;
tx_proto = "udp";
} else {
ip->ip_p = IPPROTO_ICMP;
- ip->ip_len += sizeof(struct icmp);
+ ip->ip_len += ICMPERR_IPICMPHLEN;
tx_proto = "icmp";
}
cpp++;
diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h
index 472bcce2f4f0..75f9d67efaf2 100644
--- a/contrib/ipfilter/ipl.h
+++ b/contrib/ipfilter/ipl.h
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.15.2.23 2001/07/23 13:52:10 darrenr Exp $
+ * $Id: ipl.h,v 2.15.2.31 2002/03/13 03:57:42 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.20"
+#define IPL_VERSION "IP Filter: v3.4.25"
#endif
diff --git a/contrib/ipfilter/iplang/iplang_y.y b/contrib/ipfilter/iplang/iplang_y.y
index 56d705b4cb6f..3d77bf58f86a 100644
--- a/contrib/ipfilter/iplang/iplang_y.y
+++ b/contrib/ipfilter/iplang/iplang_y.y
@@ -6,9 +6,12 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * $Id: iplang_y.y,v 2.2.2.1 2000/08/05 14:43:39 darrenr Exp $
+ * $Id: iplang_y.y,v 2.2.2.2 2002/02/22 15:32:57 darrenr Exp $
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
diff --git a/contrib/ipfilter/ipmon.c b/contrib/ipfilter/ipmon.c
index 0ccc94765fa5..6a894039c4ff 100644
--- a/contrib/ipfilter/ipmon.c
+++ b/contrib/ipfilter/ipmon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -7,6 +7,9 @@
#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun)
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
@@ -46,7 +49,6 @@
#include <arpa/nameser.h>
#include <resolv.h>
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
# include <netinet/ip_var.h>
@@ -61,13 +63,12 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.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 2.12.2.13 2001/07/19 12:24:59 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.32 2002/03/13 03:30:18 darrenr Exp $";
#endif
@@ -84,6 +85,23 @@ struct flags {
char flag;
};
+
+typedef struct icmp_subtype {
+ int ist_val;
+ char *ist_name;
+} icmp_subtype_t;
+
+typedef struct icmp_type {
+ int it_val;
+ struct icmp_subtype *it_subtable;
+ size_t it_stsize;
+ char *it_name;
+} icmp_type_t;
+
+
+#define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t))
+
+
struct flags tcpfl[] = {
{ TH_ACK, 'A' },
{ TH_RST, 'R' },
@@ -122,6 +140,9 @@ static void dumphex __P((FILE *, u_char *, int));
static int read_log __P((int, int *, char *, int));
static void write_pid __P((char *));
static char *icmpname __P((u_int, u_int));
+static char *icmpname6 __P((u_int, u_int));
+static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t));
+static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t));
char *hostname __P((int, int, u_32_t *));
char *portname __P((int, char *, u_int));
@@ -134,7 +155,6 @@ static char *getproto __P((u_int));
static char **protocols = NULL;
static char **udp_ports = NULL;
static char **tcp_ports = NULL;
-static char *argv0 = "ipmon";
#define OPT_SYSLOG 0x001
#define OPT_RESOLVE 0x002
@@ -156,47 +176,198 @@ static char *argv0 = "ipmon";
#endif
-#define ICMPUNREACHNAMES 14
-static char *icmpunreachnames[ICMPUNREACHNAMES] = {
- "net",
- "host",
- "protocol",
- "port",
- "needfrag",
- "srcfail",
- "net_unknown",
- "host_unknown",
- "isolated",
- "net_prohib",
- "host_prohib",
- "tosnet",
- "toshost",
- "admin_prohibit"
+static icmp_subtype_t icmpunreachnames[] = {
+ { ICMP_UNREACH_NET, "net" },
+ { ICMP_UNREACH_HOST, "host" },
+ { ICMP_UNREACH_PROTOCOL, "protocol" },
+ { ICMP_UNREACH_PORT, "port" },
+ { ICMP_UNREACH_NEEDFRAG, "needfrag" },
+ { ICMP_UNREACH_SRCFAIL, "srcfail" },
+ { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" },
+ { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" },
+ { ICMP_UNREACH_NET, "isolated" },
+ { ICMP_UNREACH_NET_PROHIB, "net_prohib" },
+ { ICMP_UNREACH_NET_PROHIB, "host_prohib" },
+ { ICMP_UNREACH_TOSNET, "tosnet" },
+ { ICMP_UNREACH_TOSHOST, "toshost" },
+ { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" },
+ { -2, NULL }
+};
+
+static icmp_subtype_t redirectnames[] = {
+ { ICMP_REDIRECT_NET, "net" },
+ { ICMP_REDIRECT_HOST, "host" },
+ { ICMP_REDIRECT_TOSNET, "tosnet" },
+ { ICMP_REDIRECT_TOSHOST, "toshost" },
+ { -2, NULL }
+};
+
+static icmp_subtype_t timxceednames[] = {
+ { ICMP_TIMXCEED_INTRANS, "transit" },
+ { ICMP_TIMXCEED_REASS, "reassem" },
+ { -2, NULL }
+};
+
+static icmp_subtype_t paramnames[] = {
+ { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" },
+ { ICMP_PARAMPROB_OPTABSENT, "optmissing" },
+ { ICMP_PARAMPROB_LENGTH, "length" },
+ { -2, NULL }
+};
+
+static icmp_type_t icmptypes[] = {
+ { ICMP_ECHOREPLY, NULL, 0, "echoreply" },
+ { -1, NULL, 0, NULL },
+ { -1, NULL, 0, NULL },
+ { ICMP_UNREACH, icmpunreachnames,
+ IST_SZ(icmpunreachnames),"unreach" },
+ { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" },
+ { ICMP_REDIRECT, redirectnames,
+ IST_SZ(redirectnames), "redirect" },
+ { -1, NULL, 0, NULL },
+ { -1, NULL, 0, NULL },
+ { ICMP_ECHO, NULL, 0, "echo" },
+ { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" },
+ { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" },
+ { ICMP_TIMXCEED, timxceednames,
+ IST_SZ(timxceednames), "timxceed" },
+ { ICMP_PARAMPROB, paramnames,
+ IST_SZ(paramnames), "paramprob" },
+ { ICMP_TSTAMP, NULL, 0, "timestamp" },
+ { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" },
+ { ICMP_IREQ, NULL, 0, "inforeq" },
+ { ICMP_IREQREPLY, NULL, 0, "inforeply" },
+ { ICMP_MASKREQ, NULL, 0, "maskreq" },
+ { ICMP_MASKREPLY, NULL, 0, "maskreply" },
+ { -2, NULL, 0, NULL }
+};
+
+static icmp_subtype_t icmpredirect6[] = {
+ { ICMP6_DST_UNREACH_NOROUTE, "noroute" },
+ { ICMP6_DST_UNREACH_ADMIN, "admin" },
+ { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" },
+ { ICMP6_DST_UNREACH_ADDR, "address" },
+ { ICMP6_DST_UNREACH_NOPORT, "noport" },
+ { -2, NULL }
};
-#define ICMPTYPES 19
-static char *icmptypes[ICMPTYPES] = {
- "echoreply",
- NULL,
- NULL,
- "unreach",
- "sourcequench",
- "redirect",
- NULL,
- NULL,
- "echo",
- "routeradvert",
- "routersolicit",
- "timxceed",
- "paramprob",
- "timestamp",
- "timestampreply",
- "inforeq",
- "inforeply",
- "maskreq",
- "maskreply"
+static icmp_subtype_t icmptimexceed6[] = {
+ { ICMP6_TIME_EXCEED_TRANSIT, "intransit" },
+ { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" },
+ { -2, NULL }
};
+static icmp_subtype_t icmpparamprob6[] = {
+ { ICMP6_PARAMPROB_HEADER, "header" },
+ { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" },
+ { ICMP6_PARAMPROB_OPTION, "option" },
+ { -2, NULL }
+};
+
+static icmp_subtype_t icmpquerysubject6[] = {
+ { ICMP6_NI_SUBJ_IPV6, "ipv6" },
+ { ICMP6_NI_SUBJ_FQDN, "fqdn" },
+ { ICMP6_NI_SUBJ_IPV4, "ipv4" },
+ { -2, NULL },
+};
+
+static icmp_subtype_t icmpnodeinfo6[] = {
+ { ICMP6_NI_SUCCESS, "success" },
+ { ICMP6_NI_REFUSED, "refused" },
+ { ICMP6_NI_UNKNOWN, "unknown" },
+ { -2, NULL }
+};
+
+static icmp_subtype_t icmprenumber6[] = {
+ { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" },
+ { ICMP6_ROUTER_RENUMBERING_RESULT, "result" },
+ { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" },
+ { -2, NULL }
+};
+
+static icmp_type_t icmptypes6[] = {
+ { 0, NULL, 0, NULL },
+ { ICMP6_DST_UNREACH, icmpredirect6,
+ IST_SZ(icmpredirect6), "unreach" },
+ { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" },
+ { ICMP6_TIME_EXCEEDED, icmptimexceed6,
+ IST_SZ(icmptimexceed6), "timxceed" },
+ { ICMP6_PARAM_PROB, icmpparamprob6,
+ IST_SZ(icmpparamprob6), "paramprob" },
+ { ICMP6_ECHO_REQUEST, NULL, 0, "echo" },
+ { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" },
+ { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6,
+ IST_SZ(icmpquerysubject6), "groupmemberquery" },
+ { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" },
+ { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" },
+ { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" },
+ { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" },
+ { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" },
+ { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" },
+ { ND_REDIRECT, NULL, 0, "redirect" },
+ { ICMP6_ROUTER_RENUMBERING, icmprenumber6,
+ IST_SZ(icmprenumber6), "routerrenumber" },
+ { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" },
+ { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" },
+ { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" },
+ { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" },
+ { ICMP6_NI_QUERY, icmpnodeinfo6,
+ IST_SZ(icmpnodeinfo6), "nodeinforequest" },
+ { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" },
+ { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" },
+ { MLD6_MTRACE, NULL, 0, "mtracerequest" },
+ { -2, NULL, 0, NULL }
+};
+
+static icmp_subtype_t *find_icmpsubtype(type, table, tablesz)
+int type;
+icmp_subtype_t *table;
+size_t tablesz;
+{
+ icmp_subtype_t *ist;
+ int i;
+
+ if (tablesz < 2)
+ return NULL;
+
+ if ((type < 0) || (type > table[tablesz - 2].ist_val))
+ return NULL;
+
+ i = type;
+ if (table[type].ist_val == type)
+ return table + type;
+
+ for (i = 0, ist = table; ist->ist_val != -2; i++, ist++)
+ if (ist->ist_val == type)
+ return ist;
+ return NULL;
+}
+
+
+static icmp_type_t *find_icmptype(type, table, tablesz)
+int type;
+icmp_type_t *table;
+size_t tablesz;
+{
+ icmp_type_t *it;
+ int i;
+
+ if (tablesz < 2)
+ return NULL;
+
+ if ((type < 0) || (type > table[tablesz - 2].it_val))
+ return NULL;
+
+ i = type;
+ if (table[type].it_val == type)
+ return table + type;
+
+ for (i = 0, it = table; it->it_val != -2; i++, it++)
+ if (it->it_val == type)
+ return it;
+ return NULL;
+}
+
static void handlehup(sig)
int sig;
@@ -229,7 +400,7 @@ static void init_tabs()
setprotoent(1);
while ((p = getprotoent()) != NULL)
if (p->p_proto >= 0 && p->p_proto <= 255 &&
- p->p_name != NULL)
+ p->p_name != NULL && protocols[p->p_proto] == NULL)
protocols[p->p_proto] = strdup(p->p_name);
endprotoent();
}
@@ -320,10 +491,11 @@ u_32_t *ip;
ipa.s_addr = *ip;
if (!res)
return inet_ntoa(ipa);
- hp = gethostbyaddr((char *)ip, sizeof(ip), AF_INET);
+ hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET);
if (!hp)
return inet_ntoa(ipa);
- sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, inet_ntoa(ipa));
+ sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name,
+ inet_ntoa(ipa));
return hname;
}
#ifdef USE_INET6
@@ -360,62 +532,64 @@ u_int port;
}
-#define TYPECODE(x,y) (((x) << 8) | (y))
-
static char *icmpname(type, code)
u_int type;
u_int code;
{
static char name[80];
- char codeval[8], *s;
- u_int typecode;
-
- sprintf(codeval, "%d", code);
+ icmp_subtype_t *ist;
+ icmp_type_t *it;
+ char *s;
s = NULL;
- if (type < ICMPTYPES)
- s = icmptypes[type];
+ it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it));
+ if (it != NULL)
+ s = it->it_name;
+
if (s == NULL)
sprintf(name, "icmptype(%d)/", type);
else
sprintf(name, "%s/", s);
- if (type == ICMP_UNREACH) {
- if (code >= ICMPUNREACHNAMES)
- sprintf(name + strlen(name), "%d", code);
- else
- strcat(name, icmpunreachnames[code]);
- } else {
- typecode = (type << 8) | code;
+ ist = NULL;
+ if (it != NULL && it->it_subtable != NULL)
+ ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize);
- switch (typecode)
- {
- case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_NET) :
- strcat(name, "net");
- break;
- case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_HOST) :
- strcat(name, "host");
- break;
- case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_TOSNET) :
- strcat(name, "tosnet");
- break;
- case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST) :
- strcat(name, "toshost");
- break;
- case TYPECODE(ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS) :
- strcat(name, "intrans");
- break;
- case TYPECODE(ICMP_TIMXCEED, ICMP_TIMXCEED_REASS) :
- strcat(name, "reass");
- break;
- case TYPECODE(ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT) :
- strcat(name, "optabsent");
- break;
- default:
- strcat(name, codeval);
- break;
- }
- }
+ if (ist != NULL && ist->ist_name != NULL)
+ strcat(name, ist->ist_name);
+ else
+ sprintf(name + strlen(name), "%d", code);
+
+ return name;
+}
+
+static char *icmpname6(type, code)
+u_int type;
+u_int code;
+{
+ static char name[80];
+ icmp_subtype_t *ist;
+ icmp_type_t *it;
+ char *s;
+
+ s = NULL;
+ it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it));
+ if (it != NULL)
+ s = it->it_name;
+
+ if (s == NULL)
+ sprintf(name, "icmpv6type(%d)/", type);
+ else
+ sprintf(name, "%s/", s);
+
+ ist = NULL;
+ if (it != NULL && it->it_subtable != NULL)
+ ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize);
+
+ if (ist != NULL && ist->ist_name != NULL)
+ strcat(name, ist->ist_name);
+ else
+ sprintf(name + strlen(name), "%d", code);
return name;
}
@@ -430,6 +604,10 @@ int len;
int i, j, k;
u_char *s = buf, *t = (u_char *)line;
+ if (len == 0 || buf == 0)
+ return;
+ *line = '\0';
+
for (i = len, j = 0; i; i--, j++, s++) {
if (j && !(j & 0xf)) {
*t++ = '\n';
@@ -445,7 +623,7 @@ int len;
t += 2;
if (!((j + 1) & 0xf)) {
s -= 15;
- sprintf((char *)t, " ");
+ sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
*t++ = (isprint(*s) ? *s : '.');
@@ -489,7 +667,7 @@ int blen;
int res, i, len;
char *proto;
- nl = (struct natlog *)((char *)ipl + sizeof(*ipl));
+ nl = (struct natlog *)((char *)ipl + IPLOG_SIZE);
res = (opts & OPT_RESOLVE) ? 1 : 0;
tm = localtime((time_t *)&ipl->ipl_sec);
len = sizeof(line);
@@ -563,7 +741,7 @@ int blen;
struct tm *tm;
int res, i, len;
- sl = (struct ipslog *)((char *)ipl + sizeof(*ipl));
+ sl = (struct ipslog *)((char *)ipl + IPLOG_SIZE);
res = (opts & OPT_RESOLVE) ? 1 : 0;
tm = localtime((time_t *)&ipl->ipl_sec);
len = sizeof(line);
@@ -612,6 +790,13 @@ int blen;
(void) sprintf(t, "%s PR icmp %d",
hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
+ } else if (sl->isl_p == IPPROTO_ICMPV6) {
+ (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
+ (u_32_t *)&sl->isl_src));
+ t += strlen(t);
+ (void) sprintf(t, "%s PR icmpv6 %d",
+ hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
+ sl->isl_itype);
}
t += strlen(t);
if (sl->isl_type != ISL_NEW) {
@@ -706,7 +891,7 @@ int blen;
#endif
ipl = (iplog_t *)buf;
- ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
+ ipf = (ipflog_t *)((char *)buf + IPLOG_SIZE);
ip = (ip_t *)((char *)ipf + sizeof(*ipf));
v = ip->ip_v;
res = (opts & OPT_RESOLVE) ? 1 : 0;
@@ -736,13 +921,20 @@ int blen;
#if (SOLARIS || \
(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
- len = (int)sizeof(ipf->fl_ifname);
- (void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
+ {
+ char ifname[sizeof(ipf->fl_ifname) + 1];
+
+ strncpy(ifname, (char *)ipf->fl_ifname, sizeof(ipf->fl_ifname));
+ ifname[sizeof(ipf->fl_ifname)] = '\0';
+ (void) sprintf(t, "%s", ifname);
t += strlen(t);
# if SOLARIS
- if (isalpha(*(t - 1)))
- *t++ = '0' + ipf->fl_unit;
+ if (isalpha(*(t - 1))) {
+ sprintf(t, "%d", ipf->fl_unit);
+ t += strlen(t);
+ }
# endif
+ }
#else
for (len = 0; len < 3; len++)
if (ipf->fl_ifname[len] == '\0')
@@ -752,7 +944,15 @@ int blen;
(void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
t += strlen(t);
#endif
- (void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
+ if (ipf->fl_group == 0xffffffff)
+ strcat(t, " @-1:");
+ else
+ (void) sprintf(t, " @%u:", ipf->fl_group);
+ t += strlen(t);
+ if (ipf->fl_rule == 0xffffffff)
+ strcat(t, "-1 ");
+ else
+ (void) sprintf(t, "%u ", ipf->fl_rule + 1);
t += strlen(t);
if (ipf->fl_flags & FF_SHORT) {
@@ -811,17 +1011,18 @@ int blen;
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) {
tp = (tcphdr_t *)((char *)ip + hl);
- if (!(ipf->fl_flags & (FI_SHORT << 16))) {
+ if (!(ipf->fl_flags & FF_SHORT)) {
(void) sprintf(t, "%s,%s -> ", hostname(res, v, s),
portname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
- (void) sprintf(t, "%s,%s PR %s len %hu %hu ",
+ (void) sprintf(t, "%s,%s PR %s len %hu %hu",
hostname(res, v, d),
portname(res, proto, (u_int)tp->th_dport),
proto, hl, plen);
t += strlen(t);
if (p == IPPROTO_TCP) {
+ *t++ = ' ';
*t++ = '-';
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
@@ -841,13 +1042,20 @@ int blen;
(void) sprintf(t, "%s PR %s len %hu %hu",
hostname(res, v, d), proto, hl, plen);
}
+ } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) {
+ ic = (struct icmp *)((char *)ip + hl);
+ (void) sprintf(t, "%s -> ", hostname(res, v, s));
+ t += strlen(t);
+ (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s",
+ hostname(res, v, d), hl, plen,
+ icmpname6(ic->icmp_type, ic->icmp_code));
} else if ((p == IPPROTO_ICMP) && !off && (v == 4)) {
ic = (struct icmp *)((char *)ip + hl);
(void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR icmp len %hu %hu icmp %s",
hostname(res, v, d), hl, plen,
- icmpname((u_int) ic->icmp_type, (u_int) ic->icmp_code));
+ icmpname(ic->icmp_type, ic->icmp_code));
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
ic->icmp_type == ICMP_PARAMPROB ||
@@ -929,9 +1137,9 @@ int blen;
t += strlen(t);
}
- if (ipf->fl_flags & FR_INQUE)
+ if (ipf->fl_dir == 0)
strcpy(t, " IN");
- else if (ipf->fl_flags & FR_OUTQUE)
+ else if (ipf->fl_dir == 1)
strcpy(t, " OUT");
t += strlen(t);
printipflog:
@@ -984,7 +1192,8 @@ FILE *log;
int fd, flushed = 0;
if ((fd = open(file, O_RDWR)) == -1) {
- (void) fprintf(stderr, "%s: open: %s\n", file,STRERROR(errno));
+ (void) fprintf(stderr, "%s: open: %s\n",
+ file, STRERROR(errno));
exit(1);
}
@@ -1048,7 +1257,7 @@ char *argv[];
int fd[3], doread, n, i;
int tr, nr, regular[3], c;
int fdt[3], devices = 0, make_daemon = 0;
- char buf[512], *iplfile[3];
+ char buf[IPLLOGSIZE], *iplfile[3], *s;
extern int optind;
extern char *optarg;
@@ -1058,12 +1267,6 @@ char *argv[];
iplfile[1] = IPNAT_NAME;
iplfile[2] = IPSTATE_NAME;
- argv0 = strrchr(argv[0], '/');
- if (argv0 == NULL)
- argv0 = argv[0];
- else
- argv0++;
-
while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
@@ -1114,7 +1317,12 @@ char *argv[];
pidfile = optarg;
break;
case 's' :
- openlog(argv0, LOG_NDELAY|LOG_PID, LOGFAC);
+ s = strrchr(argv[0], '/');
+ if (s == NULL)
+ s = argv[0];
+ else
+ s++;
+ openlog(s, LOG_NDELAY|LOG_PID, LOGFAC);
opts |= OPT_SYSLOG;
log = NULL;
break;
@@ -1138,7 +1346,7 @@ char *argv[];
default :
case 'h' :
case '?' :
- usage(argv0);
+ usage(argv[0]);
}
init_tabs();
@@ -1163,8 +1371,8 @@ char *argv[];
/* NOTREACHED */
}
if (fstat(fd[i], &sb) == -1) {
- (void) fprintf(stderr, "%d: fstat: %s\n",fd[i],
- STRERROR(errno));
+ (void) fprintf(stderr, "%d: fstat: %s\n",
+ fd[i], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@@ -1177,8 +1385,8 @@ char *argv[];
logfile = argv[optind];
log = logfile ? fopen(logfile, "a") : stdout;
if (log == NULL) {
- (void) fprintf(stderr, "%s: fopen: %s\n", argv[optind],
- STRERROR(errno));
+ (void) fprintf(stderr, "%s: fopen: %s\n",
+ argv[optind], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@@ -1194,8 +1402,8 @@ char *argv[];
if ((pid = fork()) > 0)
exit(0);
if (pid < 0) {
- (void) fprintf(stderr, "%s: fork() failed: %s\n", argv0,
- STRERROR(errno));
+ (void) fprintf(stderr, "%s: fork() failed: %s\n",
+ argv[0], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@@ -1220,7 +1428,8 @@ char *argv[];
if (!regular[i]) {
if (ioctl(fd[i], FIONREAD, &tr) == -1) {
if (opts & OPT_SYSLOG)
- syslog(LOG_CRIT, "ioctl(FIONREAD): %m");
+ syslog(LOG_CRIT,
+ "ioctl(FIONREAD): %m");
else
perror("ioctl(FIONREAD)");
exit(1);
diff --git a/contrib/ipfilter/ipnat.c b/contrib/ipfilter/ipnat.c
index b8cb37ee14b3..e19edb86a75e 100644
--- a/contrib/ipfilter/ipnat.c
+++ b/contrib/ipfilter/ipnat.c
@@ -1,10 +1,13 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@@ -39,10 +42,12 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
+#include <nlist.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#include "ipf.h"
#include "kmem.h"
@@ -55,32 +60,32 @@ 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 2.16.2.9 2001/07/18 15:06:33 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.20 2002/02/22 15:32:55 darrenr Exp $";
#endif
#if SOLARIS
#define bzero(a,b) memset(a,0,b)
#endif
-#ifdef USE_INET6
int use_inet6 = 0;
-#endif
-
-static char thishost[MAXHOSTNAMELEN];
-
+char thishost[MAXHOSTNAMELEN];
extern char *optarg;
extern ipnat_t *natparse __P((char *, int));
extern void natparsefile __P((int, char *, int));
-extern void printnat __P((ipnat_t *, int, void *));
+extern void printnat __P((ipnat_t *, int));
+extern void printactivenat __P((nat_t *, int));
+extern void printhostmap __P((hostmap_t *, u_int));
+extern char *getsumd __P((u_32_t));
-void dostats __P((int, int)), flushtable __P((int, int));
+void dostats __P((natstat_t *, int)), flushtable __P((int, int));
void usage __P((char *));
int countbits __P((u_32_t));
char *getnattype __P((ipnat_t *));
int main __P((int, char*[]));
void printaps __P((ap_session_t *, int));
-char *getsumd __P((u_32_t));
+void showhostmap __P((natstat_t *nsp));
+void natstat_dead __P((natstat_t *, char *));
void usage(name)
@@ -91,27 +96,22 @@ char *name;
}
-char *getsumd(sum)
-u_32_t sum;
-{
- static char sumdbuf[17];
-
- if (sum & NAT_HW_CKSUM)
- sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff);
- else
- sprintf(sumdbuf, "%#0x", sum);
- return sumdbuf;
-}
-
-
int main(argc, argv)
int argc;
char *argv[];
{
- int fd = -1, opts = 0, c, mode = O_RDWR;
- char *file = NULL, *core = NULL;
+ natstat_t ns, *nsp = &ns;
+ char *file, *core, *kernel;
+ int fd, opts, c, mode;
+
+ fd = -1;
+ opts = 0;
+ file = NULL;
+ core = NULL;
+ kernel = NULL;
+ mode = O_RDWR;
- while ((c = getopt(argc, argv, "CdFf:hlM:nrsv")) != -1)
+ while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1)
switch (c)
{
case 'C' :
@@ -136,6 +136,9 @@ char *argv[];
case 'M' :
core = optarg;
break;
+ case 'N' :
+ kernel = optarg;
+ break;
case 'n' :
opts |= OPT_NODO;
mode = O_RDONLY;
@@ -154,21 +157,40 @@ char *argv[];
usage(argv[0]);
}
- if (core != NULL) {
- if (openkmem(core) == -1)
- exit(1);
+ if ((kernel != NULL) || (core != NULL)) {
(void) setgid(getgid());
(void) setuid(getuid());
}
+ bzero((char *)&ns, sizeof(ns));
+
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
- if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, mode)) == -1) &&
- ((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
- (void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
- STRERROR(errno));
- exit(-1);
+ if (!(opts & OPT_NODO) && (kernel == NULL) && (core == NULL)) {
+ if (openkmem(kernel, core) == -1)
+ exit(1);
+
+ if (((fd = open(IPL_NAT, mode)) == -1) &&
+ ((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
+ (void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
+ STRERROR(errno));
+ exit(1);
+ }
+ if (ioctl(fd, SIOCGNATS, &nsp) == -1) {
+ perror("ioctl(SIOCGNATS)");
+ exit(1);
+ }
+ (void) setgid(getgid());
+ (void) setuid(getuid());
+ } else if ((kernel != NULL) || (core != NULL)) {
+ if (openkmem(kernel, core) == -1)
+ exit(1);
+
+ natstat_dead(nsp, kernel);
+ if (opts & (OPT_LIST|OPT_STAT))
+ dostats(nsp, opts);
+ exit(0);
}
if (opts & (OPT_FLUSH|OPT_CLEAR))
@@ -176,172 +198,113 @@ char *argv[];
if (file)
natparsefile(fd, file, opts);
if (opts & (OPT_LIST|OPT_STAT))
- dostats(fd, opts);
+ dostats(nsp, opts);
return 0;
}
-void printaps(aps, opts)
-ap_session_t *aps;
-int opts;
+/*
+ * Read nat statistic information in using a symbol table and memory file
+ * rather than doing ioctl's.
+ */
+void natstat_dead(nsp, kernel)
+natstat_t *nsp;
+char *kernel;
{
- ap_session_t ap;
- ftpinfo_t ftp;
- aproxy_t apr;
- raudio_t ra;
-
- if (kmemcpy((char *)&ap, (long)aps, sizeof(ap)))
- return;
- if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr)))
+ struct nlist nat_nlist[10] = {
+ { "nat_table" }, /* 0 */
+ { "nat_list" },
+ { "maptable" },
+ { "ipf_nattable_sz" },
+ { "ipf_natrules_sz" },
+ { "ipf_rdrrules_sz" }, /* 5 */
+ { "ipf_hostmap_sz" },
+ { "nat_instances" },
+ { "ap_sess_list" },
+ { NULL }
+ };
+ void *tables[2];
+
+ if (nlist(kernel, nat_nlist) == -1) {
+ fprintf(stderr, "nlist error\n");
return;
- printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label,
- apr.apr_p, apr.apr_ref, apr.apr_flags);
- printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags);
-#ifdef USE_QUAD_T
- printf("%qu pkts %qu", (unsigned long long)ap.aps_bytes,
- (unsigned long long)ap.aps_pkts);
-#else
- printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts);
-#endif
- printf(" data %p psiz %d\n", ap.aps_data, ap.aps_psiz);
- if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) {
- printf("\t\tstate[%u,%u], sel[%d,%d]\n",
- ap.aps_state[0], ap.aps_state[1],
- ap.aps_sel[0], ap.aps_sel[1]);
-#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \
- (__FreeBSD_version >= 300000) || defined(OpenBSD)
- printf("\t\tseq: off %hd/%hd min %x/%x\n",
- ap.aps_seqoff[0], ap.aps_seqoff[1],
- ap.aps_seqmin[0], ap.aps_seqmin[1]);
- printf("\t\tack: off %hd/%hd min %x/%x\n",
- ap.aps_ackoff[0], ap.aps_ackoff[1],
- ap.aps_ackmin[0], ap.aps_ackmin[1]);
-#else
- printf("\t\tseq: off %hd/%hd min %lx/%lx\n",
- ap.aps_seqoff[0], ap.aps_seqoff[1],
- ap.aps_seqmin[0], ap.aps_seqmin[1]);
- printf("\t\tack: off %hd/%hd min %lx/%lx\n",
- ap.aps_ackoff[0], ap.aps_ackoff[1],
- ap.aps_ackmin[0], ap.aps_ackmin[1]);
-#endif
}
- if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) {
- if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra)))
- return;
- printf("\tReal Audio Proxy:\n");
- printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n",
- ra.rap_seenpna, ra.rap_version, ra.rap_eos);
- printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf);
- printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n",
- ra.rap_plport, ra.rap_prport, ra.rap_srport);
- } else if (!strcmp(apr.apr_label, "ftp") &&
- (ap.aps_psiz == sizeof(ftp))) {
- if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp)))
- return;
- printf("\tFTP Proxy:\n");
- printf("\t\tpassok: %d\n", ftp.ftp_passok);
- ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0';
- ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0';
- printf("\tClient:\n");
- printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
- ftp.ftp_side[0].ftps_rptr, ftp.ftp_side[0].ftps_wptr,
- ftp.ftp_side[0].ftps_seq, ftp.ftp_side[0].ftps_len,
- ftp.ftp_side[0].ftps_junk);
- printf("\t\tbuf [");
- printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1);
- printf("]\n\tServer:\n");
- printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
- ftp.ftp_side[1].ftps_rptr, ftp.ftp_side[1].ftps_wptr,
- ftp.ftp_side[1].ftps_seq, ftp.ftp_side[1].ftps_len,
- ftp.ftp_side[1].ftps_junk);
- printf("\t\tbuf [");
- printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1);
- printf("]\n");
- }
+ /*
+ * Normally the ioctl copies all of these values into the structure
+ * for us, before returning it to useland, so here we must copy each
+ * one in individually.
+ */
+ kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
+ nsp->ns_table[0] = tables[0];
+ nsp->ns_table[1] = tables[1];
+
+ kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
+ sizeof(nsp->ns_list));
+ kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value,
+ sizeof(nsp->ns_maptable));
+ kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value,
+ sizeof(nsp->ns_nattab_sz));
+ kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value,
+ sizeof(nsp->ns_rultab_sz));
+ kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value,
+ sizeof(nsp->ns_rdrtab_sz));
+ kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value,
+ sizeof(nsp->ns_hostmap_sz));
+ kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
+ sizeof(nsp->ns_instances));
+ kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
+ sizeof(nsp->ns_apslist));
}
/*
- * Get a nat filter type given its kernel address.
+ * Display NAT statistics.
*/
-char *getnattype(ipnat)
-ipnat_t *ipnat;
-{
- char *which;
- ipnat_t ipnatbuff;
-
- if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat,
- sizeof(ipnatbuff))))
- return "???";
-
- switch (ipnatbuff.in_redir)
- {
- case NAT_MAP :
- which = "MAP";
- break;
- case NAT_MAPBLK :
- which = "MAP-BLOCK";
- break;
- case NAT_REDIRECT :
- which = "RDR";
- break;
- case NAT_BIMAP :
- which = "BIMAP";
- break;
- default :
- which = "unknown";
- break;
- }
- return which;
-}
-
-
-void dostats(fd, opts)
-int fd, opts;
+void dostats(nsp, opts)
+natstat_t *nsp;
+int opts;
{
- hostmap_t hm, *hmp, **maptable;
- natstat_t ns, *nsp = &ns;
nat_t **nt[2], *np, nat;
- u_int hv, hv1, hv2;
ipnat_t ipn;
- bzero((char *)&ns, sizeof(ns));
-
- if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &nsp) == -1) {
- perror("ioctl(SIOCGNATS)");
- return;
- }
-
+ /*
+ * Show statistics ?
+ */
if (opts & OPT_STAT) {
printf("mapped\tin\t%lu\tout\t%lu\n",
- ns.ns_mapped[0], ns.ns_mapped[1]);
+ nsp->ns_mapped[0], nsp->ns_mapped[1]);
printf("added\t%lu\texpired\t%lu\n",
- ns.ns_added, ns.ns_expire);
+ nsp->ns_added, nsp->ns_expire);
printf("no memory\t%lu\tbad nat\t%lu\n",
- ns.ns_memfail, ns.ns_badnat);
- printf("inuse\t%lu\nrules\t%lu\n", ns.ns_inuse, ns.ns_rules);
- printf("wilds\t%u\n", ns.ns_wilds);
+ nsp->ns_memfail, nsp->ns_badnat);
+ printf("inuse\t%lu\nrules\t%lu\n",
+ nsp->ns_inuse, nsp->ns_rules);
+ printf("wilds\t%u\n", nsp->ns_wilds);
if (opts & OPT_VERBOSE)
- printf("table %p list %p\n", ns.ns_table, ns.ns_list);
+ printf("table %p list %p\n",
+ nsp->ns_table, nsp->ns_list);
}
+
+ /*
+ * Show list of NAT rules and NAT sessions ?
+ */
if (opts & OPT_LIST) {
printf("List of active MAP/Redirect filters:\n");
- while (ns.ns_list) {
- if (kmemcpy((char *)&ipn, (long)ns.ns_list,
+ while (nsp->ns_list) {
+ if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
sizeof(ipn))) {
perror("kmemcpy");
break;
}
if (opts & OPT_HITS)
printf("%d ", ipn.in_hits);
- printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE),
- (void *)ns.ns_list);
- ns.ns_list = ipn.in_next;
+ printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
+ nsp->ns_list = ipn.in_next;
}
nt[0] = (nat_t **)malloc(sizeof(*nt) * NAT_SIZE);
- if (kmemcpy((char *)nt[0], (long)ns.ns_table[0],
+ if (kmemcpy((char *)nt[0], (long)nsp->ns_table[0],
sizeof(**nt) * NAT_SIZE)) {
perror("kmemcpy");
return;
@@ -349,89 +312,59 @@ int fd, opts;
printf("\nList of active sessions:\n");
- for (np = ns.ns_instances; np; np = nat.nat_next) {
+ for (np = nsp->ns_instances; np; np = nat.nat_next) {
if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
break;
-
- printf("%s %-15s %-5hu <- ->", getnattype(nat.nat_ptr),
- inet_ntoa(nat.nat_inip), ntohs(nat.nat_inport));
- printf(" %-15s %-5hu", inet_ntoa(nat.nat_outip),
- ntohs(nat.nat_outport));
- printf(" [%s %hu]", inet_ntoa(nat.nat_oip),
- ntohs(nat.nat_oport));
- if (opts & OPT_VERBOSE) {
- printf("\n\tage %lu use %hu sumd %s/",
- nat.nat_age, nat.nat_use,
- getsumd(nat.nat_sumd[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),
- printf("%s pr %u bkt %d/%d flags %x ",
- getsumd(nat.nat_sumd[1]), nat.nat_p,
- hv1, hv2, nat.nat_flags);
-#ifdef USE_QUAD_T
- printf("bytes %qu pkts %qu",
- (unsigned long long)nat.nat_bytes,
- (unsigned long long)nat.nat_pkts);
-#else
- printf("bytes %lu pkts %lu",
- nat.nat_bytes, nat.nat_pkts);
-#endif
-#if SOLARIS
- printf(" %lx", nat.nat_ipsumd);
-#endif
- }
- putchar('\n');
- if (nat.nat_aps)
- printaps(nat.nat_aps, opts);
+ printactivenat(&nat, opts);
}
- if (opts & OPT_VERBOSE) {
- printf("\nList of active host mappings:\n");
-
- maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
- ns.ns_hostmap_sz);
- if (kmemcpy((char *)maptable, (u_long)ns.ns_maptable,
- sizeof(hostmap_t *) * ns.ns_hostmap_sz)) {
- perror("kmemcpy (maptable)");
+ if (opts & OPT_VERBOSE)
+ showhostmap(nsp);
+ free(nt[0]);
+ }
+}
+
+
+/*
+ * display the active host mapping table.
+ */
+void showhostmap(nsp)
+natstat_t *nsp;
+{
+ hostmap_t hm, *hmp, **maptable;
+ u_int hv;
+
+ printf("\nList of active host mappings:\n");
+
+ maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
+ nsp->ns_hostmap_sz);
+ if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
+ sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
+ perror("kmemcpy (maptable)");
+ return;
+ }
+
+ for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
+ hmp = maptable[hv];
+
+ while (hmp) {
+ if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
+ perror("kmemcpy (hostmap)");
return;
}
- for (hv = 0; hv < ns.ns_hostmap_sz; hv++) {
- hmp = maptable[hv];
-
- while(hmp) {
-
- if (kmemcpy((char *)&hm, (u_long)hmp,
- sizeof(hostmap_t))) {
- perror("kmemcpy (hostmap)");
- return;
- }
-
- printf("%s -> ",
- inet_ntoa(hm.hm_realip));
- printf("%s ", inet_ntoa(hm.hm_mapip));
- printf("(use = %d hv = %u)\n",
- hm.hm_ref, hv);
- hmp = hm.hm_next;
- }
- }
- free(maptable);
+ printhostmap(&hm, hv);
+ hmp = hm.hm_next;
}
- free(nt[0]);
}
+ free(maptable);
}
+/*
+ * Issue an ioctl to flush either the NAT rules table or the active mapping
+ * table or both.
+ */
void flushtable(fd, opts)
int fd, opts;
{
diff --git a/contrib/ipfilter/ipsend/44arp.c b/contrib/ipfilter/ipsend/44arp.c
index 7a16c5a87a9e..920c7e10c552 100644
--- a/contrib/ipfilter/ipsend/44arp.c
+++ b/contrib/ipfilter/ipsend/44arp.c
@@ -1,6 +1,9 @@
/*
* Based upon 4.4BSD's /usr/sbin/arp
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c
index 898815acada8..307f4cb6547c 100644
--- a/contrib/ipfilter/ipsend/arp.c
+++ b/contrib/ipfilter/ipsend/arp.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
@@ -26,7 +29,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: arp.c,v 2.1.4.2 2001/07/15 22:00:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: arp.c,v 2.1.4.3 2002/02/22 15:32:57 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/ip.c b/contrib/ipfilter/ipsend/ip.c
index db6d477956d5..dc2b816489b9 100644
--- a/contrib/ipfilter/ipsend/ip.c
+++ b/contrib/ipfilter/ipsend/ip.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,7 +32,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995";
-static const char rcsid[] = "@(#)$Id: ip.c,v 2.1.4.3 2001/07/15 22:00:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip.c,v 2.1.4.4 2002/02/22 15:32:57 darrenr Exp $";
#endif
static char *ipbuf = NULL, *ethbuf = NULL;
diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c
index 4a4ec1cc966b..ea63ab29caee 100644
--- a/contrib/ipfilter/ipsend/ipresend.c
+++ b/contrib/ipfilter/ipsend/ipresend.c
@@ -8,12 +8,16 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -30,7 +34,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1.4.2 2001/07/15 22:00:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1.4.3 2002/02/22 15:32:57 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c
index 74f624e4d76d..86a1e3f0ba0e 100644
--- a/contrib/ipfilter/ipsend/ipsend.c
+++ b/contrib/ipfilter/ipsend/ipsend.c
@@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -32,7 +35,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.2.2.3 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.2.2.4 2002/02/22 15:32:57 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/ipsopt.c b/contrib/ipfilter/ipsend/ipsopt.c
index 691ee7d69521..27bb5138abef 100644
--- a/contrib/ipfilter/ipsend/ipsopt.c
+++ b/contrib/ipfilter/ipsend/ipsopt.c
@@ -3,6 +3,10 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
+#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -21,7 +25,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.2 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.3 2002/02/22 15:32:58 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c
index d4d37ba6707b..463fd4f116f7 100644
--- a/contrib/ipfilter/ipsend/iptest.c
+++ b/contrib/ipfilter/ipsend/iptest.c
@@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
@@ -34,7 +37,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2.2.2 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2.2.3 2002/02/22 15:32:58 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c
index a133e346fd05..cc64f6008acc 100644
--- a/contrib/ipfilter/ipsend/iptests.c
+++ b/contrib/ipfilter/ipsend/iptests.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -76,7 +79,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: iptests.c,v 2.1.4.2 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: iptests.c,v 2.1.4.5 2002/02/22 15:32:58 darrenr Exp $";
#endif
@@ -299,14 +302,14 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (63 * 1024 + 768); i += 768) {
- ip->ip_off = htons(IP_MF | (i >> 3));
+ ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
fflush(stdout);
PAUSE();
}
ip->ip_len = 896 + 20;
- ip->ip_off = htons(i >> 3);
+ ip->ip_off = htons((i >> 3) & 0x1fff);
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
putchar('\n');
@@ -333,7 +336,7 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (63 * 1024 + 768); i += 768) {
- ip->ip_off = htons(IP_MF | (i >> 3));
+ ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
if ((rand() & 0x1f) != 0) {
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
@@ -343,7 +346,7 @@ int ptest;
PAUSE();
}
ip->ip_len = 896 + 20;
- ip->ip_off = htons(i >> 3);
+ ip->ip_off = htons((i >> 3) & 0x1fff);
if ((rand() & 0x1f) != 0) {
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
@@ -370,14 +373,14 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (32 * 1024 + 768); i += 768) {
- ip->ip_off = htons(IP_MF | (i >> 3));
+ ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
fflush(stdout);
PAUSE();
}
ip->ip_len = 896 + 20;
- ip->ip_off = htons(i >> 3);
+ ip->ip_off = htons((i >> 3) & 0x1fff);
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
putchar('\n');
@@ -1030,6 +1033,7 @@ int ptest;
struct sockaddr_in sin;
int fd, slen;
+ fd = -1;
bzero((char *)&sin, sizeof(sin));
for (i = 1; i < 63; i++) {
@@ -1262,7 +1266,7 @@ int ptest;
for (j = 768; j < 3584; j += 768) {
ip->ip_len = sizeof(*ip) + 768;
- ip->ip_off = htons(IP_MF|(j>>3));
+ ip->ip_off = htons(IP_MF|((j>>3) & 0x1fff));
(void) send_ip(nfd, 1500, ip, gwip, 1);
printf("%d %d\r", i, j);
fflush(stdout);
@@ -1270,7 +1274,7 @@ int ptest;
ip->ip_len = sizeof(*ip) + 128;
for (k = j - 768; k < j; k += 128) {
- ip->ip_off = htons(IP_MF|(k>>3));
+ ip->ip_off = htons(IP_MF|((k>>3) & 0x1fff));
(void) send_ip(nfd, 1500, ip, gwip, 1);
printf("%d %d\r", i, k);
fflush(stdout);
diff --git a/contrib/ipfilter/ipsend/lsock.c b/contrib/ipfilter/ipsend/lsock.c
index 058ab40e1895..56442c77663e 100644
--- a/contrib/ipfilter/ipsend/lsock.c
+++ b/contrib/ipfilter/ipsend/lsock.c
@@ -5,7 +5,10 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.2 2002/02/22 15:32:58 darrenr Exp $";
+#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <unistd.h>
diff --git a/contrib/ipfilter/ipsend/resend.c b/contrib/ipfilter/ipsend/resend.c
index 0d4102ce1e71..2cbfe75d33a3 100644
--- a/contrib/ipfilter/ipsend/resend.c
+++ b/contrib/ipfilter/ipsend/resend.c
@@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <netdb.h>
#include <string.h>
@@ -35,7 +38,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.3 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.4 2002/02/22 15:32:58 darrenr Exp $";
#endif
diff --git a/contrib/ipfilter/ipsend/sbpf.c b/contrib/ipfilter/ipsend/sbpf.c
index 5b8428c8486d..ec95b4933fd7 100644
--- a/contrib/ipfilter/ipsend/sbpf.c
+++ b/contrib/ipfilter/ipsend/sbpf.c
@@ -41,7 +41,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.1.4.2 2001/09/30 04:04:28 darrenr Exp $";
#endif
/*
@@ -61,6 +61,8 @@ int sport, tout;
char bpfname[16];
int fd, i;
+ fd = -1;
+
for (i = 0; i < 16; i++)
{
(void) sprintf(bpfname, "/dev/bpf%d", i);
diff --git a/contrib/ipfilter/ipsend/sirix.c b/contrib/ipfilter/ipsend/sirix.c
index 4178c0eaea94..403c7e9e1471 100644
--- a/contrib/ipfilter/ipsend/sirix.c
+++ b/contrib/ipfilter/ipsend/sirix.c
@@ -4,6 +4,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c
index b20bf932dd0f..3568f230ad65 100644
--- a/contrib/ipfilter/ipsend/sock.c
+++ b/contrib/ipfilter/ipsend/sock.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -62,7 +65,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.3 2001/07/15 22:00:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.5 2002/02/22 15:32:58 darrenr Exp $";
#endif
@@ -187,8 +190,6 @@ struct tcpiphdr *ti;
if (!(p = getproc()))
return NULL;
-printf("fl %x ty %x cn %d mc %d\n",
-f->f_flag, f->f_type, f->f_count, f->f_msgcount);
up = (struct user *)malloc(sizeof(*up));
#ifndef ultrix
if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1)
diff --git a/contrib/ipfilter/ipt.c b/contrib/ipfilter/ipt.c
index 4749e38948a0..189e35f3632f 100644
--- a/contrib/ipfilter/ipt.c
+++ b/contrib/ipfilter/ipt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -12,6 +12,9 @@
# endif
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <assert.h>
#include <string.h>
@@ -54,12 +57,13 @@
#include "ip_fil.h"
#include "ip_nat.h"
#include "ip_state.h"
+#include "ip_frag.h"
#include "ipf.h"
#include "ipt.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.2 2001/06/26 10:43:19 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.19 2002/03/11 03:30:51 darrenr Exp $";
#endif
extern char *optarg;
@@ -71,23 +75,42 @@ extern ipnat_t *natparse __P((char *, int));
extern int fr_running;
int opts = 0;
-#ifdef USE_INET6
int use_inet6 = 0;
-#endif
int main __P((int, char *[]));
+int loadrules __P((char *));
+int kmemcpy __P((char *, long, int));
+void dumpnat __P((void));
+void dumpstate __P((void));
+char *getifname __P((void *));
+void drain_log __P((char *));
int main(argc,argv)
int argc;
char *argv[];
{
- struct ipread *r = &iptext;
- u_long buf[2048];
+ char *datain, *iface, *ifname, *packet, *logout;
+ int fd, i, dir, c, loaded, dump, hlen;
struct ifnet *ifp;
- char *rules = NULL, *datain = NULL, *iface = NULL;
+ struct ipread *r;
+ u_long buf[2048];
ip_t *ip;
- int fd, i, dir = 0, c;
- while ((c = getopt(argc, argv, "6bdEHi:I:NoPr:STvX")) != -1)
+ dir = 0;
+ dump = 0;
+ loaded = 0;
+ r = &iptext;
+ iface = NULL;
+ logout = NULL;
+ ifname = "anon0";
+ datain = NULL;
+
+ nat_init();
+ fr_stateinit();
+ initparse();
+ ipflog_init();
+ fr_running = 1;
+
+ while ((c = getopt(argc, argv, "6bdDEHi:I:l:NoPr:STvxX")) != -1)
switch (c)
{
#ifdef USE_INET6
@@ -101,17 +124,25 @@ char *argv[];
case 'd' :
opts |= OPT_DEBUG;
break;
+ case 'D' :
+ dump = 1;
+ break;
case 'i' :
datain = optarg;
break;
case 'I' :
- iface = optarg;
+ ifname = optarg;
+ break;
+ case 'l' :
+ logout = optarg;
break;
case 'o' :
opts |= OPT_SAVEOUT;
break;
case 'r' :
- rules = optarg;
+ if (loadrules(optarg) == -1)
+ return -1;
+ loaded = 1;
break;
case 'v' :
opts |= OPT_VERBOSE;
@@ -134,80 +165,19 @@ char *argv[];
case 'T' :
r = &tcpd;
break;
+ case 'x' :
+ opts |= OPT_HEX;
+ break;
case 'X' :
r = &iptext;
break;
}
- if (!rules) {
- (void)fprintf(stderr,"no rule file present\n");
+ if (loaded == 0) {
+ (void)fprintf(stderr,"no rules loaded\n");
exit(-1);
}
- nat_init();
- fr_stateinit();
- initparse();
- fr_running = 1;
-
- if (rules) {
- char line[513], *s;
- void *fr;
- FILE *fp;
- int linenum = 0;
-
- if (!strcmp(rules, "-"))
- fp = stdin;
- else if (!(fp = fopen(rules, "r"))) {
- (void)fprintf(stderr, "couldn't open %s\n", rules);
- exit(-1);
- }
- if (!(opts & OPT_BRIEF))
- (void)printf("opening rule file \"%s\"\n", rules);
- while (fgets(line, sizeof(line)-1, fp)) {
- linenum++;
- /*
- * treat both CR and LF as EOL
- */
- if ((s = index(line, '\n')))
- *s = '\0';
- if ((s = index(line, '\r')))
- *s = '\0';
- /*
- * # is comment marker, everything after is a ignored
- */
- if ((s = index(line, '#')))
- *s = '\0';
-
- if (!*line)
- continue;
-
- /* fake an `ioctl' call :) */
-
- if ((opts & OPT_NAT) != 0) {
- if (!(fr = natparse(line, linenum)))
- continue;
- i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT,
- (caddr_t)&fr,
- FWRITE|FREAD);
- if (opts & OPT_DEBUG)
- fprintf(stderr,
- "iplioctl(ADNAT,%p,1) = %d\n",
- fr, i);
- } else {
- if (!(fr = parse(line, linenum)))
- continue;
- i = IPL_EXTERN(ioctl)(0, SIOCADAFR,
- (caddr_t)&fr,
- FWRITE|FREAD);
- if (opts & OPT_DEBUG)
- fprintf(stderr,
- "iplioctl(ADAFR,%p,1) = %d\n",
- fr, i);
- }
- }
- (void)fclose(fp);
- }
-
if (opts & OPT_SAVEOUT)
init_ifp();
@@ -222,13 +192,34 @@ char *argv[];
ip = (ip_t *)buf;
while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
&iface, &dir)) > 0) {
- ifp = iface ? get_unit(iface, ip->ip_v) : NULL;
- ip->ip_off = ntohs(ip->ip_off);
- ip->ip_len = ntohs(ip->ip_len);
- i = fr_check(ip, ip->ip_hl << 2, ifp, dir, (mb_t **)&buf);
+ if (iface == NULL || *iface == '\0')
+ iface = ifname;
+ ifp = get_unit(iface, ip->ip_v);
+ hlen = 0;
+ if (!use_inet6) {
+ ip->ip_off = ntohs(ip->ip_off);
+ ip->ip_len = ntohs(ip->ip_len);
+ hlen = ip->ip_hl << 2;
+ }
+#ifdef USE_INET6
+ else
+ hlen = sizeof(ip6_t);
+#endif
+ packet = (char *)buf;
+ /* ipfr_slowtimer(); */
+ i = fr_check(ip, hlen, ifp, dir, (mb_t **)&packet);
if ((opts & OPT_NAT) == 0)
switch (i)
{
+ case -5 :
+ (void)printf("block return-icmp-as-dest");
+ break;
+ case -4 :
+ (void)printf("block return-icmp");
+ break;
+ case -3 :
+ (void)printf("block return-rst");
+ break;
case -2 :
(void)printf("auth");
break;
@@ -242,6 +233,10 @@ char *argv[];
(void)printf("nomatch");
break;
}
+ if (!use_inet6) {
+ ip->ip_off = htons(ip->ip_off);
+ ip->ip_len = htons(ip->ip_len);
+ }
if (!(opts & OPT_BRIEF)) {
putchar(' ');
@@ -250,17 +245,232 @@ char *argv[];
} else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF))
printpacket((ip_t *)buf);
#ifndef linux
- if (dir && ifp && ip->ip_v)
-# ifdef __sgi
- (*ifp->if_output)(ifp, (void *)buf, NULL);
+ if (dir && (ifp != NULL) && ip->ip_v && (packet != NULL))
+# if defined(__sgi) && (IRIX < 605)
+ (*ifp->if_output)(ifp, (void *)packet, NULL);
# else
- (*ifp->if_output)(ifp, (void *)buf, NULL, 0);
+ (*ifp->if_output)(ifp, (void *)packet, NULL, 0);
# endif
#endif
if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF))
putchar('\n');
dir = 0;
+ if (iface != ifname) {
+ free(iface);
+ iface = ifname;
+ }
}
(*r->r_close)();
+
+ if (logout != NULL) {
+ drain_log(logout);
+ }
+
+ if (dump == 1) {
+ dumpnat();
+ dumpstate();
+ }
+
return 0;
}
+
+
+/*
+ * Load in either NAT or ipf rules from a file, which is treated as stdin
+ * if the name is "-". NOTE, stdin can only be used once as the file is
+ * closed after use.
+ */
+int loadrules(file)
+char *file;
+{
+ char line[513], *s;
+ int linenum, i;
+ void *fr;
+ FILE *fp;
+
+ if (!strcmp(file, "-"))
+ fp = stdin;
+ else if (!(fp = fopen(file, "r"))) {
+ (void)fprintf(stderr, "couldn't open %s\n", file);
+ return (-1);
+ }
+
+ if (!(opts & OPT_BRIEF))
+ (void)printf("opening rule file \"%s\"\n", file);
+
+ linenum = 0;
+
+ while (fgets(line, sizeof(line) - 1, fp)) {
+ linenum++;
+
+ /*
+ * treat both CR and LF as EOL
+ */
+ if ((s = index(line, '\n')))
+ *s = '\0';
+ if ((s = index(line, '\r')))
+ *s = '\0';
+
+ /*
+ * # is comment marker, everything after is a ignored
+ */
+ if ((s = index(line, '#')))
+ *s = '\0';
+
+ if (!*line)
+ continue;
+
+ /* fake an `ioctl' call :) */
+
+ if ((opts & OPT_NAT) != 0) {
+ if (!(fr = natparse(line, linenum)))
+ continue;
+
+ i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT,
+ (caddr_t)&fr, FWRITE|FREAD);
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "iplioctl(ADNAT,%p,1) = %d\n",
+ fr, i);
+ } else {
+ if (!(fr = parse(line, linenum)))
+ continue;
+
+ i = IPL_EXTERN(ioctl)(0, SIOCADAFR, (caddr_t)&fr,
+ FWRITE|FREAD);
+ if (opts & OPT_DEBUG)
+ fprintf(stderr, "iplioctl(ADAFR,%p,1) = %d\n",
+ fr, i);
+ }
+ }
+ (void)fclose(fp);
+
+ return 0;
+}
+
+
+int kmemcpy(addr, offset, size)
+char *addr;
+long offset;
+int size;
+{
+ bcopy((char *)offset, addr, size);
+ return 0;
+}
+
+
+/*
+ * Display the built up NAT table rules and mapping entries.
+ */
+void dumpnat()
+{
+ ipnat_t *ipn;
+ nat_t *nat;
+
+ printf("List of active MAP/Redirect filters:\n");
+ 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)
+ printactivenat(nat, opts);
+}
+
+
+/*
+ * Display the built up state table rules and mapping entries.
+ */
+void dumpstate()
+{
+ ipstate_t *ips;
+
+ printf("List of active state sessions:\n");
+ for (ips = ips_list; ips != NULL; )
+ ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE));
+}
+
+
+/*
+ * Given a pointer to an interface in the kernel, return a pointer to a
+ * string which is the interface name.
+ */
+char *getifname(ptr)
+void *ptr;
+{
+#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
+ defined(__OpenBSD__)
+#else
+ char buf[32], *s;
+ int len;
+#endif
+ struct ifnet netif;
+
+ if (ptr == (void *)-1)
+ return "!";
+ if (ptr == NULL)
+ return "-";
+
+ if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
+ return "X";
+#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
+ defined(__OpenBSD__)
+ return strdup(netif.if_xname);
+#else
+ if (kmemcpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
+ return "X";
+ if (netif.if_unit < 10)
+ len = 2;
+ else if (netif.if_unit < 1000)
+ len = 3;
+ else if (netif.if_unit < 10000)
+ len = 4;
+ else
+ len = 5;
+ buf[sizeof(buf) - len] = '\0';
+ for (s = buf; *s && !isdigit(*s); s++)
+ ;
+ if (isdigit(*s))
+ *s = '\0';
+ sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
+ return strdup(buf);
+#endif
+}
+
+
+void drain_log(filename)
+char *filename;
+{
+ char buffer[IPLLOGSIZE];
+ struct iovec iov;
+ struct uio uio;
+ size_t resid;
+ int fd;
+
+ fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
+ if (fd == -1) {
+ perror("drain_log:open");
+ 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)
+ break;
+ write(fd, buffer, resid - uio.uio_resid);
+ } else
+ break;
+ }
+
+ close(fd);
+}
diff --git a/contrib/ipfilter/kmem.c b/contrib/ipfilter/kmem.c
index 3cad5a0531c1..eec8b3c450d1 100644
--- a/contrib/ipfilter/kmem.c
+++ b/contrib/ipfilter/kmem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -8,13 +8,37 @@
* returns 0 on success, -1 on error.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
+#include <sys/param.h>
#include <sys/types.h>
-#include <sys/uio.h>
#include <unistd.h>
+#include <string.h>
#include <fcntl.h>
+#include <stdlib.h>
#include <sys/file.h>
+#ifndef __sgi
+#include <kvm.h>
+#endif
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <net/if.h>
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
+
#include "kmem.h"
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "ipf.h"
+
#ifndef __STDC__
# define const
@@ -22,23 +46,68 @@
#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 2.2.2.3 2001/07/15 22:06:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.12 2002/03/06 09:44:16 darrenr Exp $";
#endif
-static int kmemfd = -1;
+#ifndef __sgi
+
+static kvm_t *kvm_f = NULL;
-int openkmem(core)
-char *core;
+#else
+
+typedef int kvm_t;
+
+static kvm_t kvm_f = -1;
+static char *kvm_errstr;
+
+kvm_t kvm_open(kernel, core, swap, mode, errstr)
+char *kernel, *core, *swap;
+int mode;
+char *errstr;
{
- if (core == NULL)
- core = KMEM;
+ kvm_t fd;
+
+ kvm_errstr = errstr;
+
+ fd = open(core, mode);
+ return fd;
+}
+
+int kvm_read(kvm, pos, buffer, size)
+kvm_t kvm;
+u_long pos;
+char *buffer;
+size_t size;
+{
+ int r, left;
+ char *bufp;
+
+ if (lseek(kvm, pos, 0) == -1) {
+ fprintf(stderr, "%s", kvm_errstr);
+ perror("lseek");
+ return -1;
+ }
+
+ for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
+ r = read(kvm, bufp, 1);
+ if (r <= 0)
+ return -1;
+ }
+ return 0;
+}
+#endif
- if ((kmemfd = open(core, O_RDONLY)) == -1)
+
+int openkmem(kern, core)
+char *kern, *core;
+{
+ kvm_f = kvm_open(kern, core, NULL, O_RDONLY, "");
+ if (kvm_f == NULL)
{
- perror("kmeminit:open");
+ perror("openkmem:open");
return -1;
}
- return kmemfd;
+ return (int)kvm_f;
}
int kmemcpy(buf, pos, n)
@@ -50,23 +119,22 @@ register int n;
if (!n)
return 0;
- if (kmemfd == -1)
- if (openkmem(NULL) == -1)
+
+ if (kvm_f == NULL)
+ if (openkmem(NULL, NULL) == -1)
return -1;
- if (lseek(kmemfd, pos, 0) == -1)
- {
- perror("kmemcpy:lseek");
- return -1;
- }
- while ((r = read(kmemfd, buf, n)) < n)
+
+ while ((r = kvm_read(kvm_f, pos, buf, n)) < n)
if (r <= 0)
{
+ fprintf(stderr, "pos=0x%x ", (u_int)pos);
perror("kmemcpy:read");
return -1;
}
else
{
buf += r;
+ pos += r;
n -= r;
}
return 0;
@@ -81,19 +149,18 @@ register int n;
if (!n)
return 0;
- if (kmemfd == -1)
- if (openkmem(NULL) == -1)
+
+ if (kvm_f == NULL)
+ if (openkmem(NULL, NULL) == -1)
return -1;
- if (lseek(kmemfd, pos, 0) == -1)
+
+ while (n > 0)
{
- perror("kmemcpy:lseek");
- return -1;
- }
- while (n > 0) {
- r = read(kmemfd, buf, 1);
+ r = kvm_read(kvm_f, pos, buf, 1);
if (r <= 0)
{
- perror("kmemcpy:read");
+ fprintf(stderr, "pos=0x%x ", (u_int)pos);
+ perror("kstrncpy:read");
return -1;
}
else
@@ -101,8 +168,70 @@ register int n;
if (*buf == '\0')
break;
buf++;
+ pos++;
n--;
}
- }
+ }
return 0;
}
+
+
+/*
+ * Given a pointer to an interface in the kernel, return a pointer to a
+ * string which is the interface name.
+ */
+char *getifname(ptr)
+void *ptr;
+{
+#if SOLARIS
+ char *ifname;
+ ill_t ill;
+
+ if (ptr == (void *)-1)
+ return "!";
+ if (ptr == NULL)
+ return "-";
+
+ if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
+ return "X";
+ ifname = malloc(ill.ill_name_length + 1);
+ if (kmemcpy(ifname, (u_long)ill.ill_name,
+ ill.ill_name_length) == -1)
+ return "X";
+ return ifname;
+#else
+# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
+ defined(__OpenBSD__)
+#else
+ char buf[32];
+ int len;
+# endif
+ struct ifnet netif;
+
+ if (ptr == (void *)-1)
+ return "!";
+ if (ptr == NULL)
+ return "-";
+
+ if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
+ return "X";
+# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
+ defined(__OpenBSD__)
+ return strdup(netif.if_xname);
+# else
+ if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
+ return "X";
+ if (netif.if_unit < 10)
+ len = 2;
+ else if (netif.if_unit < 1000)
+ len = 3;
+ else if (netif.if_unit < 10000)
+ len = 4;
+ else
+ len = 5;
+ buf[sizeof(buf) - len] = '\0';
+ sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
+ return strdup(buf);
+# endif
+#endif
+}
diff --git a/contrib/ipfilter/kmem.h b/contrib/ipfilter/kmem.h
index 08a6c5ecac95..f7056c2cf867 100644
--- a/contrib/ipfilter/kmem.h
+++ b/contrib/ipfilter/kmem.h
@@ -2,7 +2,7 @@
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
- * $Id: kmem.h,v 2.2.2.2 2001/06/26 10:43:19 darrenr Exp $
+ * $Id: kmem.h,v 2.2.2.4 2002/01/01 13:43:48 darrenr Exp $
*/
#ifndef __KMEM_H__
@@ -15,9 +15,10 @@
# define __P(x) ()
# endif
#endif
-extern int openkmem __P((char *));
+extern int openkmem __P((char *, char *));
extern int kmemcpy __P((char *, long, int));
extern int kstrncpy __P((char *, long, int));
+extern char *getifname __P((void *));
#if defined(__NetBSD__) || defined(__OpenBSD)
# include <paths.h>
diff --git a/contrib/ipfilter/man/Makefile b/contrib/ipfilter/man/Makefile
index c83337accf62..05164d7c818f 100644
--- a/contrib/ipfilter/man/Makefile
+++ b/contrib/ipfilter/man/Makefile
@@ -10,7 +10,7 @@ all:
install:
$(INSTALL) -m 0644 -c -o root -g bin ipftest.1 $(MANDIR)/man1
- $(INSTALL) -m 0644 -c -o root -g bin ipnat.1 $(MANDIR)/man1
+ $(INSTALL) -m 0644 -c -o root -g bin ipnat.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipf.4 $(MANDIR)/man4
$(INSTALL) -m 0644 -c -o root -g bin ipl.4 $(MANDIR)/man4
$(INSTALL) -m 0644 -c -o root -g bin ipnat.4 $(MANDIR)/man4
diff --git a/contrib/ipfilter/man/ipf.4 b/contrib/ipfilter/man/ipf.4
index 0e080a0cf3b1..1bd1503aa5fe 100644
--- a/contrib/ipfilter/man/ipf.4
+++ b/contrib/ipfilter/man/ipf.4
@@ -35,8 +35,8 @@ However, the full complement is as follows:
ioctl(fd, SIOCFRSYN, u_int *)
ioctl(fd, SIOCFRZST, struct friostat **)
ioctl(fd, SIOCZRLST, struct frentry **)
- ioctl(fd, SIOCAUTHW, struct fr_info **)
- ioctl(fd, SIOCAUTHR, struct fr_info **)
+ ioctl(fd, SIOCAUTHW, struct frauth_t **)
+ ioctl(fd, SIOCAUTHR, struct frauth_t **)
ioctl(fd, SIOCATHST, struct fr_authstat **)
.fi
.PP
@@ -122,7 +122,7 @@ Flags which are recognised in fr_flags:
FR_RETRST 0x000080 /* return a TCP RST packet if blocked */
FR_RETICMP 0x000100 /* return an ICMP packet if blocked */
FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
- FR_NOMATCH 0x000200 /* no match occured */
+ FR_NOMATCH 0x000200 /* No match occurred */
FR_ACCOUNT 0x000400 /* count packet bytes */
FR_KEEPFRAG 0x000800 /* keep fragment information */
FR_KEEPSTATE 0x001000 /* keep `connection' state information */
diff --git a/contrib/ipfilter/man/ipfilter.5 b/contrib/ipfilter/man/ipfilter.5
index 95116e24e470..0bba0f4bad02 100644
--- a/contrib/ipfilter/man/ipfilter.5
+++ b/contrib/ipfilter/man/ipfilter.5
@@ -1,10 +1,10 @@
.TH IPFILTER 1
.SH NAME
-IP FIlter
+IP Filter
.SH DESCRIPTION
.PP
IP Filter is a package providing packet filtering capabilities for a variety
of operating systems. On a properly setup system, it can be used to build a
firewall.
.SH SEE ALSO
-ipf(8), ipf(1), ipf(5), ipnat(1), ipnat(5), mkfilters(1)
+ipf(8), ipf(1), ipf(5), ipnat(8), ipnat(5), mkfilters(1)
diff --git a/contrib/ipfilter/man/ipfs.8 b/contrib/ipfilter/man/ipfs.8
index a120744138ae..04b886319553 100644
--- a/contrib/ipfilter/man/ipfs.8
+++ b/contrib/ipfilter/man/ipfs.8
@@ -52,6 +52,7 @@ Change the default directory used with
and
.B \-W
options for saving state information.
+.TP
.B \-n
Don't actually take any action that would effect information stored in
the kernel or on disk.
@@ -59,6 +60,11 @@ the kernel or on disk.
.B \-v
Provides a verbose description of what's being done.
.TP
+.B \-i <ifname1>,<ifname2>
+Change all instances of interface name ifname1 in the state save file to
+ifname2. Useful if you're restoring state information after a hardware
+reconfiguration or change.
+.TP
.B \-N
Operate on NAT information.
.TP
@@ -69,7 +75,7 @@ Operate on filtering state information.
Unlock state tables in the kernel.
.TP
.B \-l
-Unlock state tables in the kernel.
+Lock state tables in the kernel.
.TP
.B \-r
Read information in from the specified file and load it into the
diff --git a/contrib/ipfilter/man/ipl.4 b/contrib/ipfilter/man/ipl.4
index 15f587bc83f4..7c6d46ec5b72 100644
--- a/contrib/ipfilter/man/ipl.4
+++ b/contrib/ipfilter/man/ipl.4
@@ -49,7 +49,7 @@ When reading from the \fBipl\fP device, it is necessary to call read(2) with
a buffer big enough to hold at least 1 complete log record - reading of partial
log records is not supported.
.PP
-If the packet contents is more then 128 bytes when \fBlog body\fP is used,
+If the packet contents are more than 128 bytes when \fBlog body\fP is used,
then only 128 bytes of the packet contents is logged.
.PP
Although it is only possible to read from the \fBipl\fP device, opening it
diff --git a/contrib/ipfilter/man/ipmon.8 b/contrib/ipfilter/man/ipmon.8
index 7cd98f67df17..386f3a29346a 100644
--- a/contrib/ipfilter/man/ipmon.8
+++ b/contrib/ipfilter/man/ipmon.8
@@ -4,7 +4,7 @@ ipmon \- monitors /dev/ipl for logged packets
.SH SYNOPSIS
.B ipmon
[
-.B \-aDFhnpstvxX
+.B \-abDFhnpstvxX
] [
.B "\-N <device>"
] [
@@ -76,6 +76,10 @@ In order for \fBipmon\fP to properly work, the kernel option
Open all of the device logfiles for reading log entries from. All entries
are displayed to the same output 'device' (stderr or syslog).
.TP
+.B \-b
+For rules which log the body of a packet, generate hex output representing
+the packet contents afte the headers.
+.TP
.B \-D
Cause ipmon to turn itself into a daemon. Using subshells or backgrounding
of ipmon is not required to turn it into an orphan so it can run indefinately.
diff --git a/contrib/ipfilter/man/ipnat.5 b/contrib/ipfilter/man/ipnat.5
index ec53059d7f71..7fb2e90582cb 100644
--- a/contrib/ipfilter/man/ipnat.5
+++ b/contrib/ipfilter/man/ipnat.5
@@ -10,10 +10,11 @@ ipmap :: = mapblock | redir | map .
map ::= mapit ifname ipmask "->" ipmask [ mapport ] .
map ::= mapit ifname fromto "->" ipmask [ mapport ] .
mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] .
-redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] [ ports ] options .
+redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport options .
dport ::= "port" portnum [ "-" portnum ] .
ports ::= "ports" numports | "auto" .
+rdrport ::= "port" portnum .
mapit ::= "map" | "bimap" .
fromto ::= "from" object "to" object .
ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
@@ -199,6 +200,7 @@ own. As opposed to the above use of \fBmap\fP, if for some reason the user
of (say) 172.192.0.2 wanted 260 simultaneous connections going out, they would
be limited to 252 with \fBmap-block\fP but would just \fImove on\fP to the next
IP address with the \fBmap\fP command.
+.SH FILES
/dev/ipnat
.br
/etc/services
diff --git a/contrib/ipfilter/misc.c b/contrib/ipfilter/misc.c
index df65e2c2839e..45c48a61de2c 100644
--- a/contrib/ipfilter/misc.c
+++ b/contrib/ipfilter/misc.c
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#if (SOLARIS2 >= 7)
# define _SYS_VARARGS_H
# define _VARARGS_H
@@ -50,7 +53,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: misc.c,v 2.2.2.1 2001/06/26 10:43:19 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: misc.c,v 2.2.2.7 2002/02/22 15:32:55 darrenr Exp $";
#endif
extern int opts;
@@ -60,9 +63,38 @@ void printpacket(ip)
ip_t *ip;
{
tcphdr_t *tcp;
+ u_short len;
+
+ if (ip->ip_v == 4)
+ len = ntohs(ip->ip_len);
+ else if (ip->ip_v == 6)
+ len = ntohs(((u_short *)ip)[2]) + 40;
+ else
+ len = 0;
+
+ if ((opts & OPT_HEX) == OPT_HEX) {
+ u_char *s;
+ int i;
+
+ for (s = (u_char *)ip, i = 0; i < len; i++) {
+ printf("%02x", *s++ & 0xff);
+ if (len - i > 1) {
+ i++;
+ printf("%02x", *s++ & 0xff);
+ }
+ putchar(' ');
+ }
+ putchar('\n');
+ return;
+ }
+
+ if (ip->ip_v == 6) {
+ printpacket6(ip);
+ return;
+ }
tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2));
- printf("ip %d(%d) %d", ip->ip_len, ip->ip_hl << 2, ip->ip_p);
+ printf("ip %d(%d) %d", ntohs(ip->ip_len), ip->ip_hl << 2, ip->ip_p);
if (ip->ip_off & IP_OFFMASK)
printf(" @%d", ip->ip_off << 3);
(void)printf(" %s", inet_ntoa(ip->ip_src));
@@ -78,6 +110,48 @@ ip_t *ip;
}
+/*
+ * This is meant to work without the IPv6 header files being present or
+ * the inet_ntop() library.
+ */
+void printpacket6(ip)
+ip_t *ip;
+{
+ u_char *buf, p, hops;
+ u_short plen, *addrs;
+ tcphdr_t *tcp;
+ u_32_t flow;
+
+ buf = (u_char *)ip;
+ tcp = (tcphdr_t *)(buf + 40);
+ p = buf[6];
+ hops = buf[7];
+ flow = ntohl(*(u_32_t *)buf);
+ flow &= 0xfffff;
+ plen = ntohs(*((u_short *)buf +2));
+ addrs = (u_short *)buf + 4;
+
+ printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p);
+ printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]),
+ ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]),
+ ntohs(addrs[6]), ntohs(addrs[7]));
+ if (plen >= 4)
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP)
+ (void)printf(",%d", ntohs(tcp->th_sport));
+ printf(" >");
+ addrs += 8;
+ printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]),
+ ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]),
+ ntohs(addrs[6]), ntohs(addrs[7]));
+ if (plen >= 4)
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP)
+ (void)printf(",%d", ntohs(tcp->th_dport));
+ putchar('\n');
+}
+
+
#if defined(__STDC__)
void verbose(char *fmt, ...)
#else
diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c
index 50c2d94a34c6..00f7d226178a 100644
--- a/contrib/ipfilter/mlf_ipl.c
+++ b/contrib/ipfilter/mlf_ipl.c
@@ -117,8 +117,12 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
&fr_tcpclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
+ &fr_udpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
+ &fr_icmpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
&fr_defnatage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
diff --git a/contrib/ipfilter/mlfk_ipl.c b/contrib/ipfilter/mlfk_ipl.c
index 0dc4ff202723..f33de37f30ab 100644
--- a/contrib/ipfilter/mlfk_ipl.c
+++ b/contrib/ipfilter/mlfk_ipl.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mlfk_ipl.c,v 2.1.2.6 2000/11/18 03:58:29 darrenr Exp $
+ * $Id: mlfk_ipl.c,v 2.1.2.7 2001/08/27 21:14:04 darrenr Exp $
*/
@@ -76,8 +76,12 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
+ &fr_udpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
+ &fr_icmpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
&fr_defnatage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
diff --git a/contrib/ipfilter/mli_ipl.c b/contrib/ipfilter/mli_ipl.c
index 24120296070a..94b1bc2ab83e 100644
--- a/contrib/ipfilter/mli_ipl.c
+++ b/contrib/ipfilter/mli_ipl.c
@@ -62,7 +62,12 @@ static __psunsigned_t ipfk_code[4];
typedef struct nif {
struct nif *nf_next;
struct ifnet *nf_ifp;
+#if IRIX < 605
int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *);
+#else
+ int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
+#endif
char nf_name[IFNAMSIZ];
int nf_unit;
} nif_t;
@@ -74,7 +79,12 @@ extern int in_interfaces;
extern ipnat_t *nat_list;
static int
+#if IRIX < 605
ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
+#else
+ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+ struct rtentry *rt)
+#endif
{
nif_t *nif;
@@ -112,19 +122,19 @@ ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
#if IPFDEBUG >= 4
if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
- return (*nif->nf_output)(ifp, m, dst);
+ goto done;
}
#endif
if (m->m_len < sizeof(char)) {
printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags));
- return (*nif->nf_output)(ifp, m, dst);
+ goto done;
}
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
#if IPFDEBUG >= 4
printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
#endif
- return (*nif->nf_output)(ifp, m, dst);
+ goto done;
}
hlen = ip->ip_hl << 2;
@@ -142,7 +152,12 @@ ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
break;
}
}
+done:
+#if IRIX < 605
return (*nif->nf_output)(ifp, m, dst);
+#else
+ return (*nif->nf_output)(ifp, m, dst, rt);
+#endif
}
int
diff --git a/contrib/ipfilter/mln_ipl.c b/contrib/ipfilter/mln_ipl.c
index bda0f2e42cf9..33dce6392358 100644
--- a/contrib/ipfilter/mln_ipl.c
+++ b/contrib/ipfilter/mln_ipl.c
@@ -235,7 +235,7 @@ static int ipl_load()
*/
(void)ipl_remove();
- error = iplattach();
+ error = ipl_enable();
if (error)
return error;
diff --git a/contrib/ipfilter/natparse.c b/contrib/ipfilter/natparse.c
index f2377086084e..e484316a858e 100644
--- a/contrib/ipfilter/natparse.c
+++ b/contrib/ipfilter/natparse.c
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@@ -39,8 +42,9 @@
#include <ctype.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#include "ipf.h"
#if defined(sun) && !SOLARIS2
@@ -52,7 +56,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: natparse.c,v 1.17.2.11 2001/07/17 14:33:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.23 2002/02/22 15:32:55 darrenr Exp $";
#endif
@@ -60,191 +64,15 @@ static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.11 2001/07/17 14:33:09
#define bzero(a,b) memset(a,0,b)
#endif
+extern void printnat __P((ipnat_t *, int));
extern int countbits __P((u_32_t));
extern char *proto;
ipnat_t *natparse __P((char *, int));
-void printnat __P((ipnat_t *, int, void *));
void natparsefile __P((int, char *, int));
void nat_setgroupmap __P((struct ipnat *));
-void printnat(np, opts, ptr)
-ipnat_t *np;
-int opts;
-void *ptr;
-{
- struct protoent *pr;
- struct servent *sv;
- int bits;
-
- switch (np->in_redir)
- {
- case NAT_REDIRECT :
- printf("rdr");
- break;
- case NAT_MAP :
- printf("map");
- break;
- case NAT_MAPBLK :
- printf("map-block");
- break;
- case NAT_BIMAP :
- printf("bimap");
- break;
- default :
- fprintf(stderr, "unknown value for in_redir: %#x\n",
- np->in_redir);
- break;
- }
-
- printf(" %s ", np->in_ifname);
-
- if (np->in_flags & IPN_FILTER) {
- if (np->in_flags & IPN_NOTSRC)
- printf("! ");
- printf("from ");
- if (np->in_redir == NAT_REDIRECT) {
- printhostmask(4, (u_32_t *)&np->in_srcip,
- (u_32_t *)&np->in_srcmsk);
- if (np->in_scmp)
- printportcmp(np->in_p, &np->in_tuc.ftu_src);
- } else {
- printhostmask(4, (u_32_t *)&np->in_inip,
- (u_32_t *)&np->in_inmsk);
- if (np->in_dcmp)
- printportcmp(np->in_p, &np->in_tuc.ftu_dst);
- }
-
- if (np->in_flags & IPN_NOTDST)
- printf(" !");
- printf(" to ");
- if (np->in_redir == NAT_REDIRECT) {
- printhostmask(4, (u_32_t *)&np->in_outip,
- (u_32_t *)&np->in_outmsk);
- if (np->in_dcmp)
- printportcmp(np->in_p, &np->in_tuc.ftu_dst);
- } else {
- printhostmask(4, (u_32_t *)&np->in_srcip,
- (u_32_t *)&np->in_srcmsk);
- if (np->in_scmp)
- printportcmp(np->in_p, &np->in_tuc.ftu_src);
- }
- }
-
- if (np->in_redir == NAT_REDIRECT) {
- if (!(np->in_flags & IPN_FILTER)) {
- printf("%s", inet_ntoa(np->in_out[0]));
- bits = countbits(np->in_out[1].s_addr);
- if (bits != -1)
- printf("/%d ", bits);
- else
- printf("/%s ", inet_ntoa(np->in_out[1]));
- if (np->in_pmin)
- 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]));
- if (np->in_flags & IPN_SPLIT)
- printf(",%s", inet_ntoa(np->in_in[1]));
- if (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");
- if (np->in_flags & IPN_ROUNDR)
- printf(" round-robin");
- if (np->in_flags & IPN_FRAG)
- printf(" frag");
- printf("\n");
- if (opts & OPT_DEBUG)
- printf("\t%p %lu %#x %u %p %d\n", np->in_ifp,
- np->in_space, np->in_flags, np->in_pmax, np,
- np->in_use);
- } else {
- np->in_nextip.s_addr = htonl(np->in_nextip.s_addr);
- if (!(np->in_flags & IPN_FILTER)) {
- printf("%s/", inet_ntoa(np->in_in[0]));
- bits = countbits(np->in_in[1].s_addr);
- if (bits != -1)
- printf("%d ", bits);
- else
- printf("%s", inet_ntoa(np->in_in[1]));
- }
- printf(" -> ");
- if (np->in_flags & IPN_IPRANGE) {
- printf("range %s-", inet_ntoa(np->in_out[0]));
- printf("%s", inet_ntoa(np->in_out[1]));
- } else {
- printf("%s/", inet_ntoa(np->in_out[0]));
- bits = countbits(np->in_out[1].s_addr);
- if (bits != -1)
- printf("%d ", bits);
- else
- printf("%s", inet_ntoa(np->in_out[1]));
- }
- if (*np->in_plabel) {
- pr = getprotobynumber(np->in_p);
- printf(" proxy port");
- 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);
- else
- printf(" %hu", ntohs(np->in_dport));
- }
- printf(" %.*s/", (int)sizeof(np->in_plabel),
- np->in_plabel);
- if (pr != NULL)
- fputs(pr->p_name, stdout);
- else
- printf("%d", np->in_p);
- } else if (np->in_redir == NAT_MAPBLK) {
- printf(" ports %d", np->in_pmin);
- if (opts & OPT_VERBOSE)
- printf("\n\tip modulous %d", np->in_pmax);
- } else if (np->in_pmin || np->in_pmax) {
- printf(" portmap");
- if (np->in_flags & IPN_AUTOPORTMAP) {
- printf(" auto");
- if (opts & OPT_DEBUG)
- printf(" [%d:%d %d %d]",
- ntohs(np->in_pmin),
- ntohs(np->in_pmax),
- np->in_ippip, np->in_ppip);
- } else {
- 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");
- printf(" %d:%d", ntohs(np->in_pmin),
- ntohs(np->in_pmax));
- }
- }
- if (np->in_flags & IPN_FRAG)
- printf(" frag");
- printf("\n");
- if (opts & OPT_DEBUG) {
- printf("\tifp %p space %lu nextip %s pnext %d",
- np->in_ifp, np->in_space,
- inet_ntoa(np->in_nextip), np->in_pnext);
- printf(" flags %x use %u\n",
- np->in_flags, np->in_use);
- }
- }
-}
-
-
void nat_setgroupmap(n)
ipnat_t *n;
{
@@ -268,7 +96,9 @@ ipnat_t *n;
}
-
+/*
+ * Parse a line of input from the ipnat configuration file
+ */
ipnat_t *natparse(line, linenum)
char *line;
int linenum;
@@ -278,9 +108,13 @@ int linenum;
char *dnetm = NULL, *dport = NULL;
char *s, *t, *cps[31], **cpp;
int i, cnt;
+ char *port1a = NULL, *port1b = NULL, *port2a = NULL;
proto = NULL;
+ /*
+ * Search for end of line and comment marker, advance of leading spaces
+ */
if ((s = strchr(line, '\n')))
*s = '\0';
if ((s = strchr(line, '#')))
@@ -293,6 +127,9 @@ int linenum;
bzero((char *)&ipn, sizeof(ipn));
cnt = 0;
+ /*
+ * split line upto into segments.
+ */
for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++)
cps[++i] = strtok(NULL, " \b\t\r\n");
@@ -305,6 +142,9 @@ int linenum;
cpp = cps;
+ /*
+ * Check first word is a recognised keyword and then is the interface
+ */
if (!strcasecmp(*cpp, "map"))
ipn.in_redir = NAT_MAP;
else if (!strcasecmp(*cpp, "map-block"))
@@ -325,6 +165,10 @@ int linenum;
ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0';
cpp++;
+ /*
+ * If the first word after the interface is "from" or is a ! then
+ * the expanded syntax is being used so parse it differently.
+ */
if (!strcasecmp(*cpp, "from") || (**cpp == '!')) {
if (!strcmp(*cpp, "!")) {
cpp++;
@@ -349,19 +193,17 @@ int linenum;
ipn.in_flags |= IPN_FILTER;
cpp++;
if (ipn.in_redir == NAT_REDIRECT) {
- if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
- (u_32_t *)&ipn.in_srcmsk,
- &ipn.in_sport, &ipn.in_scmp,
- &ipn.in_stop, linenum)) {
- return NULL;
- }
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
+ (u_32_t *)&ipn.in_srcmsk, &ipn.in_sport,
+ &ipn.in_scmp, &ipn.in_stop, linenum)) {
+ return NULL;
+ }
} else {
- if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
- (u_32_t *)&ipn.in_inmsk,
- &ipn.in_sport, &ipn.in_scmp,
- &ipn.in_stop, linenum)) {
- return NULL;
- }
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
+ (u_32_t *)&ipn.in_inmsk, &ipn.in_sport,
+ &ipn.in_scmp, &ipn.in_stop, linenum)) {
+ return NULL;
+ }
}
if (!strcmp(*cpp, "!")) {
@@ -388,28 +230,30 @@ int linenum;
return NULL;
}
if (ipn.in_redir == NAT_REDIRECT) {
- if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
- (u_32_t *)&ipn.in_outmsk,
- &ipn.in_dport, &ipn.in_dcmp,
- &ipn.in_dtop, linenum)) {
- return NULL;
- }
- ipn.in_pmin = htons(ipn.in_dport);
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
+ (u_32_t *)&ipn.in_outmsk, &ipn.in_dport,
+ &ipn.in_dcmp, &ipn.in_dtop, linenum)) {
+ return NULL;
+ }
+ ipn.in_pmin = htons(ipn.in_dport);
} else {
- if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
- (u_32_t *)&ipn.in_srcmsk,
- &ipn.in_dport, &ipn.in_dcmp,
- &ipn.in_dtop, linenum)) {
- return NULL;
- }
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
+ (u_32_t *)&ipn.in_srcmsk, &ipn.in_dport,
+ &ipn.in_dcmp, &ipn.in_dtop, linenum)) {
+ return NULL;
+ }
}
} else {
s = *cpp;
- if (!s)
+ if (!s) {
+ fprintf(stderr, "%d: short line\n", linenum);
return NULL;
+ }
t = strchr(s, '/');
- if (!t)
+ if (!t) {
+ fprintf(stderr, "%d: no netmask on LHS\n", linenum);
return NULL;
+ }
*t++ = '\0';
if (ipn.in_redir == NAT_REDIRECT) {
if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1)
@@ -425,10 +269,16 @@ int linenum;
}
}
cpp++;
- if (!*cpp)
+ if (!*cpp) {
+ fprintf(stderr, "%d: short line\n", linenum);
return NULL;
+ }
}
+ /*
+ * If it is a standard redirect then we expect it to have a port
+ * match after the hostmask.
+ */
if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
if (strcasecmp(*cpp, "port")) {
fprintf(stderr, "%d: missing fields - 1st port\n",
@@ -450,24 +300,23 @@ int linenum;
else
s = NULL;
- if (!portnum(*cpp, &ipn.in_pmin, linenum))
- return NULL;
- ipn.in_pmin = htons(ipn.in_pmin);
- cpp++;
+ port1a = *cpp++;
if (!strcmp(*cpp, "-")) {
cpp++;
s = *cpp++;
}
- if (s) {
- if (!portnum(s, &ipn.in_pmax, linenum))
- return NULL;
- ipn.in_pmax = htons(ipn.in_pmax);
- } else
+ if (s)
+ port1b = s;
+ else
ipn.in_pmax = ipn.in_pmin;
}
+ /*
+ * In the middle of the NAT rule syntax is -> to indicate the
+ * direction of translation.
+ */
if (!*cpp) {
fprintf(stderr, "%d: missing fields (->)\n", linenum);
return NULL;
@@ -537,6 +386,8 @@ int linenum;
if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1)
return NULL;
} else {
+ if (!strcmp(*cpp, ipn.in_ifname))
+ *cpp = "0";
if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1)
return NULL;
}
@@ -556,11 +407,18 @@ int linenum;
} else
ipn.in_pmin = 0;
} else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
- if (!*cpp || strrchr(*cpp, '/') != NULL) {
+ if (*cpp && (strrchr(*cpp, '/') != NULL)) {
fprintf(stderr, "%d: No netmask supported in %s\n",
linenum, "destination host for redirect");
return NULL;
}
+
+ if (!*cpp) {
+ fprintf(stderr, "%d: Missing destination port %s\n",
+ linenum, "in redirect");
+ return NULL;
+ }
+
/* If it's a in_redir, expect target port */
if (strcasecmp(*cpp, "port")) {
@@ -575,10 +433,8 @@ int linenum;
linenum);
return NULL;
}
- if (!portnum(*cpp, &ipn.in_pnext, linenum))
- return NULL;
- ipn.in_pnext = htons(ipn.in_pnext);
- cpp++;
+
+ port2a = *cpp++;
}
if (dnetm && *dnetm == '/')
*dnetm++ = '\0';
@@ -601,25 +457,32 @@ int linenum;
ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */
proto = "tcp";
} else {
- if (!strcasecmp(*cpp, "tcp"))
+ proto = *cpp++;
+ if (!strcasecmp(proto, "tcp"))
ipn.in_flags |= IPN_TCP;
- else if (!strcasecmp(*cpp, "udp"))
+ else if (!strcasecmp(proto, "udp"))
ipn.in_flags |= IPN_UDP;
- else if (!strcasecmp(*cpp, "tcp/udp"))
+ else if (!strcasecmp(proto, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(*cpp, "tcpudp"))
+ else if (!strcasecmp(proto, "tcpudp")) {
ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(*cpp, "ip"))
+ proto = "tcp/udp";
+ } else if (!strcasecmp(proto, "ip"))
ipn.in_flags |= IPN_ANY;
else {
ipn.in_flags |= IPN_ANY;
- if ((pr = getprotobyname(*cpp)))
+ if ((pr = getprotobyname(proto)))
ipn.in_p = pr->p_proto;
- else
- ipn.in_p = atoi(*cpp);
+ else {
+ if (!isdigit(*proto)) {
+ fprintf(stderr,
+ "%d: Unknown protocol %s\n",
+ linenum, proto);
+ return NULL;
+ } else
+ ipn.in_p = atoi(proto);
+ }
}
- proto = *cpp;
- cpp++;
if (*cpp && !strcasecmp(*cpp, "round-robin")) {
cpp++;
@@ -631,15 +494,51 @@ int linenum;
ipn.in_flags |= IPN_FRAG;
}
+ if (*cpp && !strcasecmp(*cpp, "age")) {
+ cpp++;
+ if (!*cpp) {
+ fprintf(stderr,
+ "%d: age with no parameters\n",
+ linenum);
+ return NULL;
+ }
+
+ ipn.in_age[0] = atoi(*cpp);
+ s = index(*cpp, '/');
+ if (s != NULL)
+ ipn.in_age[1] = atoi(s + 1);
+ else
+ ipn.in_age[1] = ipn.in_age[0];
+ cpp++;
+ }
+
if (*cpp) {
fprintf(stderr,
- "%d: extra junk at the end of rdr: %s\n",
+ "%d: extra junk at the end of the line: %s\n",
linenum, *cpp);
return NULL;
}
}
}
+ if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
+ if (!portnum(port1a, &ipn.in_pmin, linenum))
+ return NULL;
+ ipn.in_pmin = htons(ipn.in_pmin);
+ if (port1b != NULL) {
+ if (!portnum(port1b, &ipn.in_pmax, linenum))
+ return NULL;
+ ipn.in_pmax = htons(ipn.in_pmax);
+ } else
+ ipn.in_pmax = ipn.in_pmin;
+ }
+
+ if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
+ if (!portnum(port2a, &ipn.in_pnext, linenum))
+ return NULL;
+ ipn.in_pnext = htons(ipn.in_pnext);
+ }
+
if (!(ipn.in_flags & IPN_SPLIT))
ipn.in_inip &= ipn.in_inmsk;
if ((ipn.in_flags & IPN_IPRANGE) == 0)
@@ -665,6 +564,11 @@ int linenum;
}
if (!strcasecmp(*cpp, "proxy")) {
+ if (ipn.in_redir == NAT_BIMAP) {
+ fprintf(stderr, "%d: cannot use proxy with bimap\n",
+ linenum);
+ return NULL;
+ }
cpp++;
if (!*cpp) {
fprintf(stderr,
@@ -720,63 +624,85 @@ int linenum;
linenum);
return NULL;
}
- return &ipn;
- }
+ } else if (!strcasecmp(*cpp, "portmap")) {
+ if (ipn.in_redir == NAT_BIMAP) {
+ fprintf(stderr, "%d: cannot use portmap with bimap\n",
+ linenum);
+ return NULL;
+ }
+ cpp++;
+ if (!*cpp) {
+ fprintf(stderr,
+ "%d: missing expression following portmap\n",
+ linenum);
+ return NULL;
+ }
- if (strcasecmp(*cpp, "portmap")) {
- fprintf(stderr,
- "%d: expected \"portmap\" - got \"%s\"\n", linenum,
- *cpp);
- return NULL;
- }
- cpp++;
- if (!*cpp) {
- fprintf(stderr, "%d: missing expression following portmap\n",
- linenum);
- return NULL;
- }
+ if (!strcasecmp(*cpp, "tcp"))
+ ipn.in_flags |= IPN_TCP;
+ else if (!strcasecmp(*cpp, "udp"))
+ ipn.in_flags |= IPN_UDP;
+ else if (!strcasecmp(*cpp, "tcpudp"))
+ ipn.in_flags |= IPN_TCPUDP;
+ else if (!strcasecmp(*cpp, "tcp/udp"))
+ ipn.in_flags |= IPN_TCPUDP;
+ else {
+ fprintf(stderr,
+ "%d: expected protocol name - got \"%s\"\n",
+ linenum, *cpp);
+ return NULL;
+ }
+ proto = *cpp;
+ cpp++;
- if (!strcasecmp(*cpp, "tcp"))
- ipn.in_flags |= IPN_TCP;
- else if (!strcasecmp(*cpp, "udp"))
- ipn.in_flags |= IPN_UDP;
- else if (!strcasecmp(*cpp, "tcpudp"))
- ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(*cpp, "tcp/udp"))
- ipn.in_flags |= IPN_TCPUDP;
- else {
- fprintf(stderr,
- "%d: expected protocol name - got \"%s\"\n",
- linenum, *cpp);
- return NULL;
- }
- proto = *cpp;
- cpp++;
+ if (!*cpp) {
+ fprintf(stderr, "%d: no port range found\n", linenum);
+ return NULL;
+ }
- if (!*cpp) {
- fprintf(stderr, "%d: no port range found\n", linenum);
- return NULL;
+ if (!strcasecmp(*cpp, "auto")) {
+ ipn.in_flags |= IPN_AUTOPORTMAP;
+ ipn.in_pmin = htons(1024);
+ ipn.in_pmax = htons(65535);
+ nat_setgroupmap(&ipn);
+ cpp++;
+ } else {
+ if (!(t = strchr(*cpp, ':'))) {
+ fprintf(stderr,
+ "%d: no port range in \"%s\"\n",
+ linenum, *cpp);
+ return NULL;
+ }
+ *t++ = '\0';
+ if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
+ !portnum(t, &ipn.in_pmax, linenum))
+ return NULL;
+ ipn.in_pmin = htons(ipn.in_pmin);
+ ipn.in_pmax = htons(ipn.in_pmax);
+ cpp++;
+ }
}
- if (!strcasecmp(*cpp, "auto")) {
- ipn.in_flags |= IPN_AUTOPORTMAP;
- ipn.in_pmin = htons(1024);
- ipn.in_pmax = htons(65535);
- nat_setgroupmap(&ipn);
- return &ipn;
+ if (*cpp && !strcasecmp(*cpp, "age")) {
+ cpp++;
+ if (!*cpp) {
+ fprintf(stderr, "%d: age with no parameters\n",
+ linenum);
+ return NULL;
+ }
+ s = index(*cpp, '/');
+ if (s != NULL)
+ ipn.in_age[1] = atoi(s + 1);
+ else
+ ipn.in_age[1] = ipn.in_age[0];
+ cpp++;
}
- if (!(t = strchr(*cpp, ':'))) {
- fprintf(stderr, "%d: no port range in \"%s\"\n",
+ if (*cpp) {
+ fprintf(stderr, "%d: extra junk at the end of the line: %s\n",
linenum, *cpp);
return NULL;
}
- *t++ = '\0';
- if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
- !portnum(t, &ipn.in_pmax, linenum))
- return NULL;
- ipn.in_pmin = htons(ipn.in_pmin);
- ipn.in_pmax = htons(ipn.in_pmax);
return &ipn;
}
@@ -812,7 +738,7 @@ int opts;
linenum, line);
} else {
if ((opts & OPT_VERBOSE) && np)
- printnat(np, opts, NULL);
+ printnat(np, opts);
if (!(opts & OPT_NODO)) {
if (!(opts & OPT_REMOVE)) {
if (ioctl(fd, SIOCADNAT, &np) == -1) {
diff --git a/contrib/ipfilter/opt.c b/contrib/ipfilter/opt.c
index e0dd125d9a8d..cad104505bd3 100644
--- a/contrib/ipfilter/opt.c
+++ b/contrib/ipfilter/opt.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -25,7 +28,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: opt.c,v 2.2.2.1 2001/06/26 10:43:20 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: opt.c,v 2.2.2.2 2002/02/22 15:32:56 darrenr Exp $";
#endif
extern int opts;
diff --git a/contrib/ipfilter/parse.c b/contrib/ipfilter/parse.c
index 56bc3fcb5f2b..6a2a04ed5327 100644
--- a/contrib/ipfilter/parse.c
+++ b/contrib/ipfilter/parse.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
@@ -44,9 +47,7 @@ static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 da
extern struct ipopt_names ionames[], secclass[];
extern int opts;
-#ifdef USE_INET6
extern int use_inet6;
-#endif
int addicmp __P((char ***, struct frentry *, int));
int extras __P((char ***, struct frentry *, int));
@@ -57,6 +58,7 @@ void print_toif __P((char *, frdest_t *));
void optprint __P((u_short *, u_long, u_long));
int loglevel __P((char **, u_int *, int));
void printlog __P((frentry_t *));
+void printifname __P((char *, char *, void *));
extern char *proto;
extern char flagset[];
@@ -72,8 +74,8 @@ char *line;
int linenum;
{
static struct frentry fil;
+ char *cps[31], **cpp, *endptr, *s;
struct protoent *p = NULL;
- char *cps[31], **cpp, *endptr;
int i, cnt = 1, j, ch;
u_int k;
@@ -84,11 +86,7 @@ int linenum;
bzero((char *)&fil, sizeof(fil));
fil.fr_mip.fi_v = 0xf;
-#ifdef USE_INET6
fil.fr_ip.fi_v = use_inet6 ? 6 : 4;
-#else
- fil.fr_ip.fi_v = 4;
-#endif
fil.fr_loglevel = 0xffff;
/*
@@ -106,10 +104,18 @@ int linenum;
}
cpp = cps;
+ /*
+ * The presence of an '@' followed by a number gives the position in
+ * the current rule list to insert this one.
+ */
if (**cpp == '@')
fil.fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1;
+ /*
+ * Check the first keyword in the rule and any options that are
+ * expected to follow it.
+ */
if (!strcasecmp("block", *cpp)) {
fil.fr_flags |= FR_BLOCK;
if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) &&
@@ -149,6 +155,8 @@ int linenum;
fil.fr_flags |= FR_ACCOUNT;
} else if (!strcasecmp("pass", *cpp)) {
fil.fr_flags |= FR_PASS;
+ } else if (!strcasecmp("nomatch", *cpp)) {
+ fil.fr_flags |= FR_NOMATCH;
} else if (!strcasecmp("auth", *cpp)) {
fil.fr_flags |= FR_AUTH;
} else if (!strcasecmp("preauth", *cpp)) {
@@ -194,6 +202,10 @@ int linenum;
return NULL;
}
+ /*
+ * Get the direction for filtering. Impose restrictions on direction
+ * if blocking with returning ICMP or an RST has been requested.
+ */
if (!strcasecmp("in", *cpp))
fil.fr_flags |= FR_INQUE;
else if (!strcasecmp("out", *cpp)) {
@@ -252,19 +264,39 @@ int linenum;
}
if (*cpp && !strcasecmp("quick", *cpp)) {
+ if (fil.fr_skip != 0) {
+ fprintf(stderr, "%d: cannot use skip with quick\n",
+ linenum);
+ return NULL;
+ }
cpp++;
fil.fr_flags |= FR_QUICK;
}
+ /*
+ * Parse rule options that are available if a rule is tied to an
+ * interface.
+ */
*fil.fr_ifname = '\0';
+ *fil.fr_oifname = '\0';
if (*cpp && !strcasecmp(*cpp, "on")) {
if (!*++cpp) {
fprintf(stderr, "%d: interface name missing\n",
linenum);
return NULL;
}
- (void)strncpy(fil.fr_ifname, *cpp, IFNAMSIZ-1);
- fil.fr_ifname[IFNAMSIZ-1] = '\0';
+
+ s = index(*cpp, ',');
+ if (s != NULL) {
+ *s++ = '\0';
+ (void)strncpy(fil.fr_ifnames[1], s, IFNAMSIZ - 1);
+ fil.fr_ifnames[1][IFNAMSIZ - 1] = '\0';
+ } else
+ strcpy(fil.fr_ifnames[1], "*");
+
+ (void)strncpy(fil.fr_ifnames[0], *cpp, IFNAMSIZ - 1);
+ fil.fr_ifnames[0][IFNAMSIZ - 1] = '\0';
+
cpp++;
if (!*cpp) {
if ((fil.fr_flags & FR_RETMASK) == FR_RETRST) {
@@ -299,6 +331,33 @@ int linenum;
cpp++;
}
}
+
+ /*
+ * Set the "other" interface name. Lets you specify both
+ * inbound and outbound interfaces for state rules. Do not
+ * prevent both interfaces from being the same.
+ */
+ strcpy(fil.fr_ifnames[3], "*");
+ if ((*cpp != NULL) && (*(cpp + 1) != NULL) &&
+ ((((fil.fr_flags & FR_INQUE) != 0) &&
+ (strcasecmp(*cpp, "out-via") == 0)) ||
+ (((fil.fr_flags & FR_OUTQUE) != 0) &&
+ (strcasecmp(*cpp, "in-via") == 0)))) {
+ cpp++;
+
+ s = index(*cpp, ',');
+ if (s != NULL) {
+ *s++ = '\0';
+ (void)strncpy(fil.fr_ifnames[3], s,
+ IFNAMSIZ - 1);
+ fil.fr_ifnames[3][IFNAMSIZ - 1] = '\0';
+ }
+
+ (void)strncpy(fil.fr_ifnames[2], *cpp, IFNAMSIZ - 1);
+ fil.fr_ifnames[2][IFNAMSIZ - 1] = '\0';
+ cpp++;
+ } else
+ strcpy(fil.fr_ifnames[2], "*");
}
if (*cpp && !strcasecmp(*cpp, "tos")) {
if (!*++cpp) {
@@ -340,6 +399,10 @@ int linenum;
if (!strcasecmp(proto, "tcp/udp")) {
fil.fr_ip.fi_fl |= FI_TCPUDP;
fil.fr_mip.fi_fl |= FI_TCPUDP;
+ } else if (use_inet6 && !strcasecmp(proto, "icmp")) {
+ fprintf(stderr,
+"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n",
+ linenum);
} else {
if (!(p = getprotobyname(proto)) && !isdigit(*proto)) {
fprintf(stderr,
@@ -411,6 +474,15 @@ int linenum;
return NULL;
}
+ if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
+ (fil.fr_proto != IPPROTO_UDP) &&
+ !(fil.fr_ip.fi_fl & FI_TCPUDP)) {
+ fprintf(stderr,
+ "%d: cannot use port and neither tcp or udp\n",
+ linenum);
+ return NULL;
+ }
+
fil.fr_scmp = ch;
if (!*cpp) {
fprintf(stderr, "%d: missing to fields\n", linenum);
@@ -447,6 +519,15 @@ int linenum;
&fil.fr_dtop, linenum)) {
return NULL;
}
+ if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
+ (fil.fr_proto != IPPROTO_UDP) &&
+ !(fil.fr_ip.fi_fl & FI_TCPUDP)) {
+ fprintf(stderr,
+ "%d: cannot use port and neither tcp or udp\n",
+ linenum);
+ return NULL;
+ }
+
fil.fr_dcmp = ch;
}
@@ -489,7 +570,8 @@ int linenum;
* icmp types for use with the icmp protocol
*/
if (*cpp && !strcasecmp(*cpp, "icmp-type")) {
- if (fil.fr_proto != IPPROTO_ICMP) {
+ if (fil.fr_proto != IPPROTO_ICMP &&
+ fil.fr_proto != IPPROTO_ICMPV6) {
fprintf(stderr,
"%d: icmp with wrong protocol (%d)\n",
linenum, fil.fr_proto);
@@ -509,9 +591,27 @@ int linenum;
return NULL;
/*
+ * This is here to enforce the old interface binding behaviour.
+ * That is, "on X" is equivalent to "<dir> on X <!dir>-via -,X"
+ */
+ if (fil.fr_flags & FR_KEEPSTATE) {
+ if (*fil.fr_ifnames[0] && !*fil.fr_ifnames[3]) {
+ bcopy(fil.fr_ifnames[0], fil.fr_ifnames[3],
+ sizeof(fil.fr_ifnames[3]));
+ strncpy(fil.fr_ifnames[2], "*",
+ sizeof(fil.fr_ifnames[3]));
+ }
+ }
+
+ /*
* head of a new group ?
*/
if (*cpp && !strcasecmp(*cpp, "head")) {
+ if (fil.fr_skip != 0) {
+ fprintf(stderr, "%d: cannot use skip with head\n",
+ linenum);
+ return NULL;
+ }
if (!*++cpp) {
fprintf(stderr, "%d: head without group #\n", linenum);
return NULL;
@@ -658,6 +758,15 @@ frdest_t *fdp;
{
printf("%s %s%s", tag, fdp->fd_ifname,
(fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)");
+#ifdef USE_INET6
+ if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) {
+ char ipv6addr[80];
+
+ inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr,
+ sizeof(fdp->fd_ip6));
+ printf(":%s", ipv6addr);
+ } else
+#endif
if (fdp->fd_ip.s_addr)
printf(":%s", inet_ntoa(fdp->fd_ip));
putchar(' ');
@@ -685,9 +794,9 @@ int linenum;
return -1;
while (**cp && (!strncasecmp(**cp, "ipopt", 5) ||
- !strncasecmp(**cp, "not", 3) || !strncasecmp(**cp, "opt", 3) ||
- !strncasecmp(**cp, "frag", 4) || !strncasecmp(**cp, "no", 2) ||
- !strncasecmp(**cp, "short", 5))) {
+ !strcasecmp(**cp, "not") || !strncasecmp(**cp, "opt", 3) ||
+ !strncasecmp(**cp, "frag", 4) || !strcasecmp(**cp, "no") ||
+ !strcasecmp(**cp, "short"))) {
if (***cp == 'n' || ***cp == 'N') {
notopt = 1;
(*cp)++;
@@ -899,10 +1008,10 @@ char *icmptypes[] = {
/*
* set the icmp field to the correct type if "icmp" word is found
*/
-int addicmp(cp, fp, linenum)
-char ***cp;
-struct frentry *fp;
-int linenum;
+int addicmp(cp, fp, linenum)
+char ***cp;
+struct frentry *fp;
+int linenum;
{
char **t;
int i;
@@ -910,8 +1019,7 @@ int linenum;
(*cp)++;
if (!**cp)
return -1;
- if (!fp->fr_proto) /* to catch lusers */
- fp->fr_proto = IPPROTO_ICMP;
+
if (isdigit(***cp)) {
if (!ratoi(**cp, &i, 0, 255)) {
fprintf(stderr,
@@ -919,6 +1027,10 @@ int linenum;
linenum, **cp);
return -1;
}
+ } else if (fp->fr_proto == IPPROTO_ICMPV6) {
+ fprintf(stderr, "%d: Unknown ICMPv6 type (%s) specified, %s",
+ linenum, **cp, "(use numeric value instead\n");
+ return -1;
} else {
for (t = icmptypes, i = 0; ; t++, i++) {
if (!*t)
@@ -973,10 +1085,10 @@ int linenum;
#define MAX_ICMPCODE 15
char *icmpcodes[] = {
- "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",
- NULL };
+ "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", NULL };
/*
* Return the number for the associated ICMP unreachable code.
*/
@@ -1006,47 +1118,73 @@ char *str;
/*
* set the icmp field to the correct type if "icmp" word is found
*/
-int addkeep(cp, fp, linenum)
-char ***cp;
-struct frentry *fp;
-int linenum;
+int addkeep(cp, fp, linenum)
+char ***cp;
+struct frentry *fp;
+int linenum;
{
- if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP &&
-#ifdef USE_INET6
- fp->fr_proto != IPPROTO_ICMPV6 &&
-#endif
- fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) {
- fprintf(stderr, "%d: Can only use keep with UDP/ICMP/TCP\n",
- linenum);
- return -1;
- }
+ char *s;
(*cp)++;
if (!**cp) {
- fprintf(stderr, "%d: Missing state/frag after keep\n",
+ fprintf(stderr, "%d: Missing keyword after keep\n",
linenum);
return -1;
}
- if (strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
+
+ if (strcasecmp(**cp, "state") == 0)
+ fp->fr_flags |= FR_KEEPSTATE;
+ else if (strncasecmp(**cp, "frag", 4) == 0)
+ fp->fr_flags |= FR_KEEPFRAG;
+ else if (strcasecmp(**cp, "state-age") == 0) {
+ if (fp->fr_ip.fi_p == IPPROTO_TCP) {
+ fprintf(stderr, "%d: cannot use state-age with tcp\n",
+ linenum);
+ return -1;
+ }
+ if ((fp->fr_flags & FR_KEEPSTATE) == 0) {
+ fprintf(stderr, "%d: state-age with no 'keep state'\n",
+ linenum);
+ return -1;
+ }
+ (*cp)++;
+ if (!**cp) {
+ fprintf(stderr, "%d: state-age with no arg\n",
+ linenum);
+ return -1;
+ }
+ fp->fr_age[0] = atoi(**cp);
+ s = index(**cp, '/');
+ if (s != NULL) {
+ s++;
+ fp->fr_age[1] = atoi(s);
+ } else
+ fp->fr_age[1] = fp->fr_age[0];
+ } else {
fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n",
linenum, **cp);
return -1;
}
-
- if (***cp == 's' || ***cp == 'S')
- fp->fr_flags |= FR_KEEPSTATE;
- else if (***cp == 'f' || ***cp == 'F')
- fp->fr_flags |= FR_KEEPFRAG;
(*cp)++;
return 0;
}
+void printifname(format, name, ifp)
+char *format, *name;
+void *ifp;
+{
+ printf("%s%s", format, name);
+ if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*"))
+ printf("(!)");
+}
+
+
/*
* print the filter structure in a useful way
*/
-void printfr(fp)
-struct frentry *fp;
+void printfr(fp)
+struct frentry *fp;
{
struct protoent *p;
u_short sec[2];
@@ -1056,6 +1194,8 @@ struct frentry *fp;
if (fp->fr_flags & FR_PASS)
printf("pass");
+ if (fp->fr_flags & FR_NOMATCH)
+ printf("nomatch");
else if (fp->fr_flags & FR_BLOCK) {
printf("block");
if (fp->fr_flags & FR_RETICMP) {
@@ -1098,8 +1238,11 @@ struct frentry *fp;
printf("quick ");
if (*fp->fr_ifname) {
- printf("on %s%s ", fp->fr_ifname,
- (fp->fr_ifa || (long)fp->fr_ifa == -1) ? "" : "(!)");
+ printifname("on ", fp->fr_ifname, fp->fr_ifa);
+ 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)
@@ -1107,7 +1250,26 @@ struct frentry *fp;
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_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]);
+ putchar(' ');
+ }
}
+
if (fp->fr_mip.fi_tos)
printf("tos %#x ", fp->fr_tos);
if (fp->fr_mip.fi_ttl)
@@ -1161,7 +1323,7 @@ struct frentry *fp;
printf(" frag");
}
}
- if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) {
+ if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm != 0) {
int type = fp->fr_icmp, code;
type = ntohs(fp->fr_icmp);
@@ -1175,6 +1337,16 @@ struct frentry *fp;
if (ntohs(fp->fr_icmpm) & 0xff)
printf(" code %d", code);
}
+ if (fp->fr_proto == IPPROTO_ICMPV6 && fp->fr_icmpm != 0) {
+ int type = fp->fr_icmp, code;
+
+ type = ntohs(fp->fr_icmp);
+ code = type & 0xff;
+ type /= 256;
+ printf(" icmp-type %d", type);
+ if (ntohs(fp->fr_icmpm) & 0xff)
+ printf(" code %d", code);
+ }
if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
printf(" flags ");
if (fp->fr_tcpf & ~TCPF_ALL)
@@ -1198,6 +1370,8 @@ struct frentry *fp;
printf(" keep state");
if (fp->fr_flags & FR_KEEPFRAG)
printf(" keep frags");
+ if (fp->fr_age[0] != 0 || fp->fr_age[1]!= 0)
+ printf(" state-age %u/%u", fp->fr_age[0], fp->fr_age[1]);
if (fp->fr_grhead)
printf(" head %d", fp->fr_grhead);
if (fp->fr_group)
diff --git a/contrib/ipfilter/samples/Makefile b/contrib/ipfilter/samples/Makefile
index 5bd03b316a7d..1dad07900c86 100644
--- a/contrib/ipfilter/samples/Makefile
+++ b/contrib/ipfilter/samples/Makefile
@@ -1,10 +1,22 @@
CC=gcc
+all:
+ @echo "Please do one of the following:"
+ @echo "make bsd"
+ @echo "make bsdi"
+ @echo "make freebsd"
+ @echo "make freebsd22"
+ @echo "make netbsd"
+ @echo "make openbsd"
+ @echo "make sunos4"
+ @echo "make sunos5"
sunos5:
- $(CC) -I.. userauth.c -o userauth -lsocket -lnsl
- $(CC) -I.. proxy.c -o proxy -lsocket -lnsl
+ $(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \
+ -I.. userauth.c -o userauth -lsocket -lnsl
+ $(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \
+ -I.. proxy.c -o proxy -lsocket -lnsl
-freebsd freebsd22 netbsd bsd bsdi sunos4:
+freebsd freebsd22 netbsd bsd bsdi sunos4 openbsd:
$(CC) -I.. userauth.c -o userauth
$(CC) -I.. proxy.c -o proxy
diff --git a/contrib/ipfilter/samples/proxy.c b/contrib/ipfilter/samples/proxy.c
index 7ac6ec98c68e..ef9a69c356e8 100644
--- a/contrib/ipfilter/samples/proxy.c
+++ b/contrib/ipfilter/samples/proxy.c
@@ -41,6 +41,8 @@
#include <ctype.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
@@ -81,19 +83,25 @@ char *argv[];
bzero((char *)&natlook, sizeof(natlook));
natlook.nl_outip = sin.sin_addr;
natlook.nl_inip = sloc.sin_addr;
- natlook.nl_flags = IPN_TCP;
- natlook.nl_outport = sin.sin_port;
- natlook.nl_inport = sloc.sin_port;
+ natlook.nl_flags = IPN_TCPUDP;
+ natlook.nl_outport = ntohs(sin.sin_port);
+ natlook.nl_inport = ntohs(sloc.sin_port);
/*
* Open the NAT device and lookup the mapping pair.
*/
fd = open(IPL_NAT, O_RDONLY);
if (ioctl(fd, SIOCGNATL, &natlookp) == -1) {
- perror("ioctl");
+ perror("ioctl(SIOCGNATL)");
exit(-1);
}
- close(fd);
+
+#define DO_NAT_OUT
+#ifdef DO_NAT_OUT
+ if (argc > 1)
+ do_nat_out(0, 1, fd, &natlook, argv[1]);
+#else
+
/*
* Log it
*/
@@ -109,4 +117,181 @@ char *argv[];
if (write(1, buffer, n) != n)
break;
close(0);
+#endif
}
+
+
+#ifdef DO_NAT_OUT
+do_nat_out(in, out, fd, nlp, extif)
+int fd;
+natlookup_t *nlp;
+char *extif;
+{
+ nat_save_t ns, *nsp = &ns;
+ struct sockaddr_in usin;
+ u_32_t sum1, sum2, sumd;
+ int onoff, ofd, slen;
+ ipnat_t *ipn;
+ nat_t *nat;
+
+ bzero((char *)&ns, sizeof(ns));
+
+ nat = &ns.ipn_nat;
+ nat->nat_p = IPPROTO_TCP;
+ nat->nat_dir = NAT_OUTBOUND;
+ if ((extif != NULL) && (*extif != '\0')) {
+ strncpy(nat->nat_ifname, extif, sizeof(nat->nat_ifname));
+ nat->nat_ifname[sizeof(nat->nat_ifname) - 1] = '\0';
+ }
+
+ ofd = socket(AF_INET, SOCK_DGRAM, 0);
+ bzero((char *)&usin, sizeof(usin));
+ usin.sin_family = AF_INET;
+ usin.sin_addr = nlp->nl_realip;
+ usin.sin_port = nlp->nl_realport;
+ (void) connect(ofd, (struct sockaddr *)&usin, sizeof(usin));
+ slen = sizeof(usin);
+ (void) getsockname(ofd, (struct sockaddr *)&usin, &slen);
+ close(ofd);
+printf("local IP# to use: %s\n", inet_ntoa(usin.sin_addr));
+
+ if ((ofd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ perror("socket");
+ usin.sin_port = 0;
+ if (bind(ofd, (struct sockaddr *)&usin, sizeof(usin)))
+ perror("bind");
+ slen = sizeof(usin);
+ if (getsockname(ofd, (struct sockaddr *)&usin, &slen))
+ perror("getsockname");
+printf("local port# to use: %d\n", ntohs(usin.sin_port));
+
+ nat->nat_inip = usin.sin_addr;
+ nat->nat_outip = nlp->nl_outip;
+ nat->nat_oip = nlp->nl_realip;
+
+ sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr)) + ntohs(usin.sin_port);
+ sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)) + ntohs(nlp->nl_outport);
+ CALC_SUMD(sum1, sum2, sumd);
+ nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
+ nat->nat_sumd[1] = nat->nat_sumd[0];
+
+ sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr));
+ sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
+ CALC_SUMD(sum1, sum2, sumd);
+ nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
+
+ nat->nat_inport = usin.sin_port;
+ nat->nat_outport = nlp->nl_outport;
+ nat->nat_oport = nlp->nl_realport;
+
+ nat->nat_flags = IPN_TCPUDP;
+
+ onoff = 1;
+ if (ioctl(fd, SIOCSTLCK, &onoff) == 0) {
+ if (ioctl(fd, SIOCSTPUT, &nsp) != 0)
+ perror("SIOCSTPUT");
+ onoff = 0;
+ if (ioctl(fd, SIOCSTLCK, &onoff) != 0)
+ perror("SIOCSTLCK");
+ }
+
+ usin.sin_addr = nlp->nl_realip;
+ usin.sin_port = nlp->nl_realport;
+printf("remote end for connection: %s,%d\n", inet_ntoa(usin.sin_addr),
+ntohs(usin.sin_port));
+fflush(stdout);
+ if (connect(ofd, (struct sockaddr *)&usin, sizeof(usin)))
+ perror("connect");
+
+ relay(in, out, ofd);
+}
+
+
+relay(in, out, net)
+int in, out, net;
+{
+ char netbuf[1024], outbuf[1024];
+ char *nwptr, *nrptr, *owptr, *orptr;
+ size_t nsz, osz;
+ fd_set rd, wr;
+ int i, n, maxfd;
+
+ n = 0;
+ maxfd = in;
+ if (out > maxfd)
+ maxfd = out;
+ if (net > maxfd)
+ maxfd = net;
+
+ nrptr = netbuf;
+ nwptr = netbuf;
+ nsz = sizeof(netbuf);
+ orptr = outbuf;
+ owptr = outbuf;
+ osz = sizeof(outbuf);
+
+ while (n >= 0) {
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+
+ if (nrptr - netbuf < sizeof(netbuf))
+ FD_SET(in, &rd);
+ if (orptr - outbuf < sizeof(outbuf))
+ FD_SET(net, &rd);
+
+ if (nsz < sizeof(netbuf))
+ FD_SET(net, &wr);
+ if (osz < sizeof(outbuf))
+ FD_SET(out, &wr);
+
+ n = select(maxfd + 1, &rd, &wr, NULL, NULL);
+
+ if ((n > 0) && FD_ISSET(in, &rd)) {
+ i = read(in, nrptr, sizeof(netbuf) - (nrptr - netbuf));
+ if (i <= 0)
+ break;
+ nsz -= i;
+ nrptr += i;
+ n--;
+ }
+
+ if ((n > 0) && FD_ISSET(net, &rd)) {
+ i = read(net, orptr, sizeof(outbuf) - (orptr - outbuf));
+ if (i <= 0)
+ break;
+ osz -= i;
+ orptr += i;
+ n--;
+ }
+
+ if ((n > 0) && FD_ISSET(out, &wr)) {
+ i = write(out, owptr, orptr - owptr);
+ if (i <= 0)
+ break;
+ osz += i;
+ if (osz == sizeof(outbuf) || owptr == orptr) {
+ orptr = outbuf;
+ owptr = outbuf;
+ } else
+ owptr += i;
+ n--;
+ }
+
+ if ((n > 0) && FD_ISSET(net, &wr)) {
+ i = write(net, nwptr, nrptr - nwptr);
+ if (i <= 0)
+ break;
+ nsz += i;
+ if (nsz == sizeof(netbuf) || nwptr == nrptr) {
+ nrptr = netbuf;
+ nwptr = netbuf;
+ } else
+ nwptr += i;
+ }
+ }
+
+ close(net);
+ close(out);
+ close(in);
+}
+#endif
diff --git a/contrib/ipfilter/solaris.c b/contrib/ipfilter/solaris.c
index b526327b1f8c..4ff13dfbf2b4 100644
--- a/contrib/ipfilter/solaris.c
+++ b/contrib/ipfilter/solaris.c
@@ -1,10 +1,10 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/
-#pragma ident "@(#)$Id: solaris.c,v 2.15.2.20 2001/07/18 14:58:28 darrenr Exp $"
+#pragma ident "@(#)$Id: solaris.c,v 2.15.2.29 2002/01/15 14:36:54 darrenr Exp $"
#include <sys/systm.h>
#include <sys/types.h>
@@ -93,10 +93,16 @@ extern void ipfr_slowtimer __P((void));
int ipfr_timer_id;
static int synctimeoutid = 0;
#endif
+int ipf_debug = 0;
+int ipf_debug_verbose = 0;
+/* #undef IPFDEBUG 1 */
+/* #undef IPFDEBUG_VERBOSE 1 */
#ifdef IPFDEBUG
void printire __P((ire_t *));
#endif
+#define isdigit(x) ((x) >= '0' && (x) <= '9')
+
static int fr_precheck __P((mblk_t **, queue_t *, qif_t *, int));
@@ -150,7 +156,7 @@ static size_t hdrsizes[57][2] = {
{ IFT_X25DDN, 0 },
{ IFT_X25, 0 },
{ IFT_ETHER, 14 },
- { IFT_ISO88023, 0 },
+ { IFT_ISO88023, 14 },
{ IFT_ISO88024, 0 },
{ IFT_ISO88025, 0 },
{ IFT_ISO88026, 0 },
@@ -210,7 +216,8 @@ int _init()
ipfinst = mod_install(&modlink1);
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
#endif
return ipfinst;
}
@@ -222,7 +229,8 @@ int _fini(void)
ipfinst = mod_remove(&modlink1);
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
#endif
return ipfinst;
}
@@ -235,7 +243,9 @@ struct modinfo *modinfop;
ipfinst = mod_info(&modlink1, modinfop);
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x", modinfop, ipfinst);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x",
+ modinfop, ipfinst);
#endif
if (fr_running > 0)
ipfsync();
@@ -249,7 +259,8 @@ dev_info_t *dip;
if (fr_running < 0)
return DDI_PROBE_FAILURE;
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_probe(%x)", dip);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: ipf_probe(%x)", dip);
#endif
return DDI_PROBE_SUCCESS;
}
@@ -259,7 +270,8 @@ static int ipf_identify(dip)
dev_info_t *dip;
{
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
#endif
if (strcmp(ddi_get_name(dip), "ipf") == 0)
return (DDI_IDENTIFIED);
@@ -299,7 +311,8 @@ ddi_attach_cmd_t cmd;
#ifdef IPFDEBUG
int instance;
- cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
#endif
switch (cmd) {
case DDI_ATTACH:
@@ -308,6 +321,7 @@ ddi_attach_cmd_t cmd;
#ifdef IPFDEBUG
instance = ddi_get_instance(dip);
+ if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: attach ipf instance %d", instance);
#endif
if (ddi_create_minor_node(dip, "ipf", S_IFCHR, IPL_LOGIPF,
@@ -344,7 +358,8 @@ ddi_attach_cmd_t cmd;
solattach();
solipdrvattach();
RWLOCK_EXIT(&ipf_solaris);
- cmn_err(CE_CONT, "%s, attaching complete.\n", ipfilter_version);
+ cmn_err(CE_CONT, "%s, attaching complete.\n",
+ ipfilter_version);
sync();
if (fr_running == 0)
fr_running = 1;
@@ -383,7 +398,8 @@ ddi_detach_cmd_t cmd;
int i;
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
#endif
switch (cmd) {
case DDI_DETACH:
@@ -459,7 +475,9 @@ void *arg, **result;
return DDI_FAILURE;
error = DDI_FAILURE;
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)", dip, infocmd, arg);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)",
+ dip, infocmd, arg);
#endif
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
@@ -784,15 +802,7 @@ fixalign:
#endif
) {
m->b_rptr -= off;
- if (!synced) {
- synced = 1;
- RWLOCK_EXIT(&ipfs_mutex);
- ipfsync();
- READ_ENTER(&ipfs_mutex);
- goto tryagain;
- }
- frstats[out].fr_notip++;
- return (fr_flags & FF_BLOCKNONIP) ? -1 : 0;
+ return -2;
}
#ifndef sparc
@@ -969,27 +979,40 @@ mblk_t *mb;
int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0;
qif_t qf, *qif;
+#ifdef IPFDEBUG_VERBOSE
+ if (ipf_debug_verbose)
+ cmn_err(CE_CONT,
+ "fr_qin(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n",
+ q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref,
+ msgdsize(mb));
+#endif
+
+ /*
+ * IPFilter is still in the packet path but not enabled. Drop whatever
+ * it is that has come through.
+ */
if (fr_running <= 0) {
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
return 0;
}
+ type = MTYPE(mb);
+
+ /*
+ * If a mblk has more than one reference, make a copy, filter that and
+ * free a reference to the original.
+ */
if (mb->b_datap->db_ref > 1) {
mblk_t *m1;
m1 = copymsg(mb);
if (!m1) {
frstats[0].fr_drop++;
- mb->b_next = NULL;
mb->b_prev = NULL;
freemsg(mb);
return 0;
}
- m1->b_next = mb->b_next;
- mb->b_next = NULL;
- m1->b_prev = mb->b_prev;
mb->b_prev = NULL;
freemsg(mb);
mb = m1;
@@ -999,10 +1022,9 @@ mblk_t *mb;
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
- RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
READ_ENTER(&ipfs_mutex);
@@ -1030,7 +1052,7 @@ again:
}
cmn_err(CE_WARN,
"!IP Filter: dropped: fr_qin(%x,%x): type %x qif %x",
- q, mb, MTYPE(mb), qif);
+ q, mb, type, qif);
cmn_err(CE_CONT,
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
@@ -1044,40 +1066,52 @@ again:
#endif
);
frstats[0].fr_drop++;
- RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
+ qif->qf_incnt++;
pnext = qif->qf_rqinfo->qi_putp;
- type = MTYPE(mb);
if (type == M_IOCACK)
fr_qif_update(qif, mb);
- else {
- bcopy((char *)qif, (char *)&qf, sizeof(qf));
-
- if (datamsg(type) || (type == M_BREAK))
- err = fr_precheck(&mb, q, &qf, 0);
- }
+ bcopy((char *)qif, (char *)&qf, sizeof(qf));
+ if (datamsg(type) || (type == M_BREAK))
+ err = fr_precheck(&mb, q, &qf, 0);
RWLOCK_EXIT(&ipfs_mutex);
- RWLOCK_EXIT(&ipf_solaris);
if ((err == 0) && (mb != NULL)) {
- if (pnext)
+ if (pnext) {
+ RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
+ }
cmn_err(CE_WARN,
"!IP Filter: inp NULL: qif %x %s q %x info %x",
- &qf, qf.qf_name, q, q->q_qinfo);
+ qif, qf.qf_name, q, q->q_qinfo);
+ }
+
+ if (err == -2) {
+ if (synced == 0) {
+ ipfsync();
+ synced = 1;
+ goto again;
+ }
+ frstats[0].fr_notip++;
+ if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) {
+ RWLOCK_EXIT(&ipf_solaris);
+ return (*pnext)(q, mb);
+ }
}
+
+
if (mb) {
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
}
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
@@ -1089,13 +1123,22 @@ mblk_t *mb;
int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0;
qif_t qf, *qif;
+#ifdef IPFDEBUG_VERBOSE
+ if (ipf_debug_verbose)
+ cmn_err(CE_CONT,
+ "fr_qout(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n",
+ q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref,
+ msgdsize(mb));
+#endif
+
if (fr_running <= 0) {
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
return 0;
}
+ type = MTYPE(mb);
+
#if SOLARIS2 >= 6
if ((!dohwcksum || mb->b_ick_flag != ICK_VALID) &&
(mb->b_datap->db_ref > 1))
@@ -1108,14 +1151,10 @@ mblk_t *mb;
m1 = copymsg(mb);
if (!m1) {
frstats[1].fr_drop++;
- mb->b_next = NULL;
mb->b_prev = NULL;
freemsg(mb);
return 0;
}
- m1->b_next = mb->b_next;
- mb->b_next = NULL;
- m1->b_prev = mb->b_prev;
mb->b_prev = NULL;
freemsg(mb);
mb = m1;
@@ -1125,10 +1164,9 @@ mblk_t *mb;
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
- RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
READ_ENTER(&ipfs_mutex);
@@ -1156,7 +1194,7 @@ again:
}
cmn_err(CE_WARN,
"!IP Filter: dropped: fr_qout(%x,%x): type %x: qif %x",
- q, mb, MTYPE(mb), qif);
+ q, mb, type, qif);
cmn_err(CE_CONT,
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
@@ -1180,40 +1218,51 @@ again:
q->q_nbsrv->q_qinfo, q->q_nbsrv->q_next,
q->q_nbsrv->q_ptr);
frstats[1].fr_drop++;
- RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
+ qif->qf_outcnt++;
pnext = qif->qf_wqinfo->qi_putp;
- type = MTYPE(mb);
if (type == M_IOCACK)
fr_qif_update(qif, mb);
- else {
- bcopy((char *)qif, (char *)&qf, sizeof(qf));
-
- if (datamsg(type) || (type == M_BREAK))
- err = fr_precheck(&mb, q, &qf, 1);
- }
+ bcopy((char *)qif, (char *)&qf, sizeof(qf));
+ if (datamsg(type) || (type == M_BREAK))
+ err = fr_precheck(&mb, q, &qf, 1);
RWLOCK_EXIT(&ipfs_mutex);
- RWLOCK_EXIT(&ipf_solaris);
if ((err == 0) && (mb != NULL)) {
- if (pnext)
+ if (pnext) {
+ RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
+ }
cmn_err(CE_WARN,
"!IP Filter: outp NULL: qif %x %s q %x info %x",
- &qf, qf.qf_name, q, q->q_qinfo);
+ qif, qf.qf_name, q, q->q_qinfo);
}
+
+ if (err == -2) {
+ if (synced == 0) {
+ ipfsync();
+ synced = 1;
+ goto again;
+ }
+ frstats[1].fr_notip++;
+ if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) {
+ RWLOCK_EXIT(&ipf_solaris);
+ return (*pnext)(q, mb);
+ }
+ }
+
if (mb) {
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
}
+ RWLOCK_EXIT(&ipf_solaris);
return 0;
}
@@ -1241,7 +1290,6 @@ mblk_t *mb;
if (fr_running <= 0) {
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
return 0;
}
@@ -1253,7 +1301,6 @@ mblk_t *mb;
if (fr_running <= 0) {
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
return 0;
}
@@ -1269,8 +1316,10 @@ mblk_t *mb;
case SIOCSIFADDR:
case SIOCSIFFLAGS:
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: ipf_ip_qin() M_IOCTL type=0x%x",
- ioc->ioc_cmd);
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: ipf_ip_qin() M_IOCTL type=0x%x",
+ ioc->ioc_cmd);
#endif
WRITE_ENTER(&ipfs_mutex);
if (synctimeoutid == 0) {
@@ -1294,8 +1343,9 @@ extern struct streamtab ipinfo;
void solipdrvattach()
{
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: solipdrvattach() %d ipinfo=0x%lx",
- ipdrvattcnt, &ipinfo);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: solipdrvattach() %d ipinfo=0x%lx",
+ ipdrvattcnt, &ipinfo);
#endif
if (++ipdrvattcnt == 1) {
@@ -1309,8 +1359,9 @@ void solipdrvattach()
int solipdrvdetach()
{
#ifdef IPFDEBUG
- cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() %d ipinfo=0x%lx",
- ipdrvattcnt, &ipinfo);
+ if (ipf_debug)
+ cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() %d ipinfo=0x%lx",
+ ipdrvattcnt, &ipinfo);
#endif
WRITE_ENTER(&ipfs_mutex);
@@ -1362,7 +1413,8 @@ void solattach()
RWLOCK_EXIT(&ipfs_mutex);
continue;
}
-#ifdef IPFDEBUG
+#ifdef IPFDEBUGX
+ if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: il %x ipt %x opt %x ipu %x opu %x i %x/%x",
il, in->q_ptr, out->q_ptr, in->q_qinfo->qi_putp,
@@ -1384,7 +1436,8 @@ void solattach()
break;
}
if (!qf2) {
-#ifdef IPFDEBUG
+#ifdef IPFDEBUGX
+ if (ipf_debug)
cmn_err(CE_WARN,
"IP Filter: rq:%s put %x qi %x",
il->ill_name, in->q_qinfo->qi_putp,
@@ -1404,7 +1457,8 @@ void solattach()
break;
}
if (!qf2) {
-#ifdef IPFDEBUG
+#ifdef IPFDEBUGX
+ if (ipf_debug)
cmn_err(CE_WARN,
"IP Filter: wq:%s put %x qi %x",
il->ill_name, out->q_qinfo->qi_putp,
@@ -1447,6 +1501,15 @@ void solattach()
(hdrsizes[il->ill_type][0] == il->ill_type))
qif->qf_hl = hdrsizes[il->ill_type][1];
+ /* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */
+ if (il->ill_type == IFT_ETHER &&
+ il->ill_name[0] == 'c' && il->ill_name[1] == 'e' &&
+ isdigit(il->ill_name[2]) && il->ill_name_length >= 6) {
+ cmn_err(CE_NOTE, "VLAN HACK ENABLED");
+ qif->qf_hl += 4;
+ }
+ /* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */
+
if (qif->qf_hl == 0 && il->ill_type != IFT_OTHER)
cmn_err(CE_WARN,
"Unknown layer 2 header size for %s type %d",
@@ -1524,10 +1587,10 @@ void solattach()
sizeof(struct qinit));
qif->qf_rqinit.qi_putp = fr_qin;
#ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: solattach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
- in, in->q_qinfo, &qif->qf_rqinit
- );
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: solattach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
+ in, in->q_qinfo, &qif->qf_rqinit);
#endif
in->q_qinfo = &qif->qf_rqinit;
@@ -1535,10 +1598,10 @@ void solattach()
sizeof(struct qinit));
qif->qf_wqinit.qi_putp = fr_qout;
#ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: solattach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
- out, out->q_qinfo, &qif->qf_wqinit
- );
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: solattach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
+ out, out->q_qinfo, &qif->qf_wqinit);
#endif
out->q_qinfo = &qif->qf_wqinit;
@@ -1638,19 +1701,19 @@ int ipfsync()
in = qif->qf_in;
if (in) {
# ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: ipfsync: in queue(%lx)->q_qinfo FROM %lx TO %lx",
- in, in->q_qinfo, qif->qf_rqinfo
- );
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: ipfsync: in queue(%lx)->q_qinfo FROM %lx TO %lx",
+ in, in->q_qinfo, qif->qf_rqinfo);
# endif
in->q_qinfo = qif->qf_rqinfo;
}
if (out) {
# ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: ipfsync: out queue(%lx)->q_qinfo FROM %lx TO %lx",
- out, out->q_qinfo, qif->qf_wqinfo
- );
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: ipfsync: out queue(%lx)->q_qinfo FROM %lx TO %lx",
+ out, out->q_qinfo, qif->qf_wqinfo);
# endif
out->q_qinfo = qif->qf_wqinfo;
}
@@ -1719,9 +1782,10 @@ int soldetach()
);
#ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: soldetach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
- in, in->q_qinfo, qif->qf_rqinfo);
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: soldetach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
+ in, in->q_qinfo, qif->qf_rqinfo);
#endif
in->q_qinfo = qif->qf_rqinfo;
@@ -1729,9 +1793,10 @@ int soldetach()
* and the write queue...
*/
#ifdef IPFDEBUG
- cmn_err(CE_NOTE,
- "IP Filter: soldetach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
- out, out->q_qinfo, qif->qf_wqinfo);
+ if (ipf_debug)
+ cmn_err(CE_NOTE,
+ "IP Filter: soldetach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
+ out, out->q_qinfo, qif->qf_wqinfo);
#endif
out->q_qinfo = qif->qf_wqinfo;
}
@@ -1746,6 +1811,8 @@ int soldetach()
void printire(ire)
ire_t *ire;
{
+ if (!ipf_debug)
+ return;
printf("ire: ll_hdr_mp %p rfq %p stq %p src_addr %x max_frag %d\n",
# if SOLARIS2 >= 8
NULL,
@@ -1812,7 +1879,6 @@ frdest_t *fdp;
mp = (*mpp)->b_cont;
(*mpp)->b_cont = NULL;
(*mpp)->b_prev = NULL;
- (*mpp)->b_next = NULL;
freemsg(*mpp);
*mpp = mp;
}
@@ -1951,7 +2017,6 @@ frdest_t *fdp;
q = WR(ir->ire_rfq);
if (q) {
mb->b_prev = NULL;
- mb->b_next = NULL;
mb->b_queue = q;
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
@@ -1979,7 +2044,6 @@ frdest_t *fdp;
}
bad_fastroute:
mb->b_prev = NULL;
- mb->b_next = NULL;
freemsg(mb);
ipl_frouteok[1]++;
*mpp = NULL;
diff --git a/contrib/ipfilter/test/Makefile b/contrib/ipfilter/test/Makefile
index 385c1dec9d55..2d93c7f6ddb1 100644
--- a/contrib/ipfilter/test/Makefile
+++ b/contrib/ipfilter/test/Makefile
@@ -9,19 +9,23 @@ BINDEST=/usr/local/bin
SBINDEST=/sbin
MANDIR=/usr/share/man
-tests: first 0 ftests ptests ntests
+tests: first 0 ftests ptests ntests nitests logtests
first:
-mkdir -p results
# Filtering tests
-ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14
+ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16
# Rule parsing tests
ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11
ntests: n1 n2 n3 n4 n5 n6 n7
+nitests: ni1 ni2
+
+logtests: l1
+
0:
@(cd ..; make ipftest; )
@@ -31,13 +35,25 @@ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f14:
f12 f13:
@/bin/sh ./hextest $@
+f15 f16:
+ @/bin/sh ./mtest $@
+
i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11:
@/bin/sh ./itest $@
n1 n2 n3 n4 n5 n6 n7:
@/bin/sh ./nattest $@
+ni1 ni2:
+ @/bin/sh ./natipftest $@
+
+l1:
+ @/bin/sh ./logtest $@
+
clean:
- /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f13 f12 f14 results/*
+ /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f13 f12 f14 f15 f16
/bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11
/bin/rm -f n1 n2 n3 n4 n5 n6 n7
+ /bin/rm -f ni1 ni2
+ /bin/rm -f l1
+ /bin/rm -f results/*
diff --git a/contrib/ipfilter/todo b/contrib/ipfilter/todo
index 1a7bdb51a91f..4c2adf1e9868 100644
--- a/contrib/ipfilter/todo
+++ b/contrib/ipfilter/todo
@@ -91,6 +91,7 @@ IPv6:
BSD:
* "to <if>" and "to <if>:<ip>" are not supported, but "fastroute" is.
+fixed.
Solaris:
* "to <if>:<ip>" is not supported, but "fastroute" is and "to <if>" are.