Import of ipfilter 3.3.3 in anticipation of its revival.

More to come in the next days.
This commit is contained in:
guido 1999-11-08 20:51:23 +00:00
parent 9529c38ad8
commit 0539756f3d
210 changed files with 20286 additions and 4405 deletions

View File

@ -11,9 +11,9 @@ proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
group = [ "head" decnumber ] [ "group" decnumber ] .
block = "block" [ "return-icmp"[return-code] | "return-rst" ] .
block = "block" [ icmp [return-code] | "return-rst" ] .
auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
call = "call" [ "now" ] function-name .
skip = "skip" decnumber .
dup = "dup-to" interface-name[":"ipaddr] .
@ -22,6 +22,8 @@ protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
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 ] .
port-comp = "port" compare port-num .
@ -55,6 +57,12 @@ icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" |
"sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" |
"visa" | "imitd" | "eip" | "finn" .
facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" |
"lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" |
"audit" | "logalert" | "local0" | "local1" | "local2" |
"local3" | "local4" | "local5" | "local6" | "local7" .
priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" |
"info" | "debug" .
hexnumber = "0" "x" hexstring .
hexstring = hexdigit [ hexstring ] .

View File

@ -0,0 +1,213 @@
#
# Copyright (C) 1993-1998 by Darren Reed.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and due credit is given
# to the original author and the contributors.
#
BINDEST=/usr/sbin
SBINDEST=/sbin
MANDIR=/usr/share/man
CC=cc -Wall -Wuninitialized -Wstrict-prototypes -Werror -O
CFLAGS=-g -I$(TOP)
#
# For NetBSD/FreeBSD
#
DEVFS!=/usr/bin/lsvfs 2>&1 | sed -n 's/.*devfs.*/-DDEVFS/p'
CPU!=uname -m
INC=-I/usr/include -I/sys -I/sys/sys -I/sys/arch
DEF=-D$(CPU) -D__$(CPU)__ -DINET -DKERNEL -D_KERNEL $(INC) $(DEVFS)
IPDEF=$(DEF) -DGATEWAY -DDIRECTED_BROADCAST
VNODESHDIR=/sys/kern
MLD=$(ML) vnode_if.h
ML=mln_ipl.c
IPFILC=ip_fil.c
LKM=if_ipl.o
DLKM=
MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)"
#
########## ########## ########## ########## ########## ########## ##########
#
CP=/bin/cp
RM=/bin/rm
CHMOD=/bin/chmod
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)
IPF=ipf.o parse.o opt.o facpri.o
IPT=ipt.o parse.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
FILS=fils.o parse.o kmem.o opt.o facpri.o
build all: ipf ipfstat ipftest ipmon ipnat $(LKM)
ipfstat: $(FILS)
$(CC) $(DEBUG) $(CFLAGS) $(FILS) -o $@ $(LIBS)
ipf: $(IPF)
$(CC) $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
/bin/rm -f $(TOP)/ipf
ln -s `pwd`/ipf $(TOP)
ipftest: $(IPT)
$(CC) $(DEBUG) $(CFLAGS) $(IPT) -o $@ $(LIBS)
/bin/rm -f $(TOP)/ipftest
ln -s `pwd`/ipftest $(TOP)
ipnat: ipnat.o kmem.o natparse.o
$(CC) $(DEBUG) $(CFLAGS) ipnat.o kmem.o natparse.o -o $@ $(LIBS)
tests:
(cd test; make )
fils.o: $(TOP)/fils.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_frag.h \
$(TOP)/ip_compat.h $(TOP)/ip_state.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/fils.c -o $@
fil.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/fil.c -o $@
fil_k.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) $(POLICY) $(DFLAGS) -c $(TOP)/fil.c -o $@
ipf.o: $(TOP)/ipf.c $(TOP)/ip_fil.h $(TOP)/ipf.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipf.c -o $@
ipt.o: $(TOP)/ipt.c $(TOP)/ip_fil.h $(TOP)/ipt.h $(TOP)/ipf.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipt.c -o $@
misc.o: $(TOP)/misc.c $(TOP)/ip_fil.h $(TOP)/ipt.h $(TOP)/ipf.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/misc.c -o $@
opt.o: $(TOP)/opt.c $(TOP)/ip_fil.h $(TOP)/ipf.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/opt.c -o $@
ipnat.o: $(TOP)/ipnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipnat.c -o $@
natparse.o: $(TOP)/natparse.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/natparse.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 $@
ipft_ef.o: $(TOP)/ipft_ef.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_ef.c -o $@
ipft_td.o: $(TOP)/ipft_td.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_td.c -o $@
ipft_pc.o: $(TOP)/ipft_pc.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_pc.c -o $@
ipft_tx.o: $(TOP)/ipft_tx.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_tx.c -o $@
ipft_hx.o: $(TOP)/ipft_hx.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_hx.c -o $@
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
$(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 \
$(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_frag.c -o $@
ip_state_u.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_state.c -o $@
ip_auth_u.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_auth.c -o $@
ip_fil_u.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/$(IPFILC) -o $@
if_ipl.o: $(MODOBJS)
ld -r $(MODOBJS) -o $(LKM)
${RM} -f if_ipl
ip_nat.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_nat.c -o $@
ip_frag.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_frag.c -o $@
ip_state.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_state.c -o $@
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
$(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 \
$(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_auth.c -o $@
ip_fil.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/$(IPFILC) -o $@
ip_log.o: $(TOP)/ip_log.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_log.c -o $@
vnode_if.h: $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src
mkdir -p ../sys
sh $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src
if [ -f ../sys/vnode_if.h ] ; then mv ../sys/vnode_if.h .; fi
rmdir ../sys
ml_ipl.o: $(TOP)/$(MLD) $(TOP)/ipl.h
-/bin/rm -f vnode_if.c
$(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/$(ML) -o $@
kmem.o: $(TOP)/kmem.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/kmem.c -o $@
parse.o: $(TOP)/parse.c $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/parse.c -o $@
facpri.o: $(TOP)/facpri.c $(TOP)/facpri.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/facpri.c -o $@
ipmon: $(TOP)/ipmon.c
$(CC) $(DEBUG) $(CFLAGS) $(LOGFAC) $(TOP)/ipmon.c -o $@ $(LIBS)
clean:
${RM} -f *.core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipnat \
vnode_if.h $(LKM) ioconf.h
${MAKE} -f Makefile.ipsend ${MFLAGS} clean
-(for i in *; do \
if [ -d $${i} -a -f $${i}/Makefile ] ; then \
cd $${i}; (make clean); cd ..; \
rm $${i}/Makefile $${i}/Makefile.ipsend; \
rmdir $${i}; \
fi \
done)
install:
-$(CP) $(TOP)/ip_fil.h /usr/include/netinet/ip_fil.h
-$(CHMOD) 444 /usr/include/netinet/ip_fil.h
-if [ -d /lkm -a -f if_ipl.o ] ; then \
cp if_ipl.o /lkm; \
fi
-$(INSTALL) -cs -g wheel -m 755 -o root ipfstat ipf ipnat $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipmon ipftest $(BINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipftest ipftest $(BINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipf ipftest $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipnat ipftest $(SBINDEST)
(cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP))

View File

@ -0,0 +1,101 @@
OBJS=ipsend.o ip.o ipsopt.o y.tab.o lex.yy.o
IPFTO=ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o
ROBJS=ipresend.o ip.o resend.o $(IPFTO) opt.o
TOBJS=iptest.o iptests.o ip.o
UNIXOBJS=sbpf.o sock.o 44arp.o
CC=gcc -Wuninitialized -Wstrict-prototypes -O
CFLAGS=-g -I$(TOP)
#
MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)"
#
all build bsd-bpf : ipsend ipresend iptest
y.tab.o: $(TOP)/iplang/iplang_y.y
(cd $(TOP)/iplang; $(MAKE) ../BSD/$(CPUDIR)/$@ $(MFLAGS) 'DESTDIR=../BSD/$(CPUDIR)' )
lex.yy.o: $(TOP)/iplang/iplang_l.l
(cd $(TOP)/iplang; $(MAKE) ../BSD/$(CPUDIR)/$@ $(MFLAGS) 'DESTDIR=../BSD/$(CPUDIR)' )
.c.o:
$(CC) $(DEBUG) $(CFLAGS) -c $< -o $@
ipsend: $(OBJS) $(UNIXOBJS)
$(CC) $(DEBUG) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS) -ll
ipresend: $(ROBJS) $(UNIXOBJS)
$(CC) $(DEBUG) $(ROBJS) $(UNIXOBJS) -o $@ $(LIBS)
iptest: $(TOBJS) $(UNIXOBJS)
$(CC) $(DEBUG) $(TOBJS) $(UNIXOBJS) -o $@ $(LIBS)
clean:
rm -rf *.o core a.out ipsend ipresend iptest
ipsend.o: $(TOP)/ipsend/ipsend.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/ipsend.c -o $@
ipsopt.o: $(TOP)/ipsend/ipsopt.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/ipsopt.c -o $@
ipresend.o: $(TOP)/ipsend/ipresend.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/ipresend.c -o $@
ip.o: $(TOP)/ipsend/ip.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/ip.c -o $@
resend.o: $(TOP)/ipsend/resend.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/resend.c -o $@
ipft_sn.o: $(TOP)/ipft_sn.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_sn.c -o $@
ipft_pc.o: $(TOP)/ipft_pc.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_pc.c -o $@
iptest.o: $(TOP)/ipsend/iptest.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/iptest.c -o $@
iptests.o: $(TOP)/ipsend/iptests.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/iptests.c -o $@
sbpf.o: $(TOP)/ipsend/sbpf.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/sbpf.c -o $@
snit.o: $(TOP)/ipsend/snit.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/snit.c -o $@
sock.o: $(TOP)/ipsend/sock.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/sock.c -o $@
arp.o: $(TOP)/ipsend/arp.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/arp.c -o $@
44arp.o: $(TOP)/ipsend/44arp.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/44arp.c -o $@
lsock.o: $(TOP)/ipsend/lsock.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/lsock.c -o $@
slinux.o: $(TOP)/ipsend/slinux.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/slinux.c -o $@
larp.o: $(TOP)/ipsend/larp.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/larp.c -o $@
dlcommon.o: $(TOP)/ipsend/dlcommon.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/dlcommon.c -o $@
sdlpi.o: $(TOP)/ipsend/sdlpi.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/sdlpi.c -o $@
arp.o: $(TOP)/ipsend/arp.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/arp.c -o $@
install:
-$(INSTALL) -cs -g wheel -m 755 -o root ipsend ipresend iptest $(BINDEST)

View File

@ -0,0 +1,26 @@
#!/bin/sh
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin; export PATH
# try to bomb out fast if anything fails....
set -e
argv0=`basename $0`
dir=`pwd`
karch=`uname -m`
archdir="/sys/arch/$karch"
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
echo -n "$i "
cp $i /sys/netinet/
chmod 644 /sys/netinet/$i
done
echo ""
if [ -f /sys/netinet/ip_fil_compat.h ] ; then
echo "Linking /sys/netinet/ip_compat.h to /sys/netinet/ip_fil_compat.h"
rm /sys/netinet/ip_fil_compat.h
ln -s /sys/netinet/ip_compat.h /sys/netinet/ip_fil_compat.h
fi
exit 0

View File

@ -0,0 +1,28 @@
#!/bin/sh
os=`uname -s`-`uname -r`
case "$os" in
FreeBSD-2.2*)
major=79
;;
FreeBSD-*)
major=20
;;
NetBSD-*)
echo "see /dev/MAKEDEV"
exit 0
;;
OpenBSD-*)
echo "see /dev/MAKEDEV"
exit 0
;;
*)
;;
esac
umask 037
mknod /dev/ipl c $major 0
mknod /dev/ipnat c $major 1
mknod /dev/ipstate c $major 2
mknod /dev/ipauth c $major 3

View File

@ -1,7 +1,3 @@
If you have BOTH GNU make and the normal make shipped with your system,
DO NOT use the GNU make to build this package. If you have any errors
relating to "(" or "TOP", check that you are using /usr/ccs/bin/make as
shipped with Solaris 2.
If you get the following error whilst compiling:
@ -10,10 +6,6 @@ In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3/include/
from ../ip_nat.c:15:
/usr/include/sys/psw.h:19: #error Kernel include of psw.h
That means that you have a version of gcc build under on older release
of Solaris 2.x
You need to reinstall gcc after each Solaris upgrade; gcc creates its own
set of modified system include files which are only valid for the exact
release on which gcc was build.
Remove (comment out) the line in
/usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3include/sys/user.h
which includes psw.h

View File

@ -0,0 +1,19 @@
If you have BOTH GNU make and the normal make shipped with your system,
DO NOT use the GNU make to build this package. If you have any errors
relating to "(" or "TOP", check that you are using /usr/ccs/bin/make as
shipped with Solaris 2.
If you get the following error whilst compiling:
In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3/include/sys/user.h:48,
from /usr/include/sys/file.h:15,
from ../ip_nat.c:15:
/usr/include/sys/psw.h:19: #error Kernel include of psw.h
That means that you have a version of gcc build under on older release
of Solaris 2.x
You need to reinstall gcc after each Solaris upgrade; gcc creates its own
set of modified system include files which are only valid for the exact
release on which gcc was build.

View File

@ -4,7 +4,7 @@
*** 11,31 ****
--- 11,41 ----
*/
static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.0.2.3 1997/06/22 07:06:02 darrenr Exp $";
static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.1 1999/08/04 17:30:30 darrenr Exp $";
+ /*
+ * Patches for IP Filter NAT extensions written by Darren Reed, 7/7/96

View File

@ -124,7 +124,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris
***************
*** 11,30 ****
#
# RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.0.2.1 1997/02/23 10:38:36 darrenr Exp $"
# RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.1 1999/08/04 17:40:48 darrenr Exp $"
# Your C compiler (eg, "cc" or "gcc")
@ -145,7 +145,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris
-Dgethostbyaddr=res_gethostbyaddr -Dgetnetbyname=res_getnetbyname \
--- 11,34 ----
#
# RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.0.2.1 1997/02/23 10:38:36 darrenr Exp $"
# RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.1 1999/08/04 17:40:48 darrenr Exp $"
+ #
+ # Path to sources of ip_filter (ip_nat.h required in lib/hnam.c)

View File

@ -0,0 +1,82 @@
*** tproxy.c.orig Fri Dec 20 10:53:24 1996
--- tproxy.c Sun Jan 3 11:33:55 1999
***************
*** 135,140 ****
--- 135,144 ----
#include <netinet/in.h>
#include <sys/signal.h>
#include <syslog.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include <net/if.h>
#include "tproxy.h"
#ifdef AIX
***************
*** 147,152 ****
--- 151,159 ----
#define bzero(buf,size) memset(buf, '\0', size);
#endif /* SYSV */
+ #include "ip_compat.h"
+ #include "ip_fil.h"
+ #include "ip_nat.h"
/* socket to audio server */
***************
*** 324,329 ****
--- 331,369 ----
char localbuf[2048];
void timeout();
extern int errno;
+ /*
+ * IP-Filter block
+ */
+ struct sockaddr_in laddr, faddr;
+ struct natlookup natlookup;
+ int slen, natfd;
+
+ bzero((char *)&laddr, sizeof(laddr));
+ bzero((char *)&faddr, sizeof(faddr));
+ slen = sizeof(laddr);
+ if (getsockname(0, (struct sockaddr *)&laddr, &slen) < 0)
+ return -1;
+ slen = sizeof(faddr);
+ if (getpeername(0, (struct sockaddr *)&faddr, &slen) < 0)
+ return -1;
+ natlookup.nl_inport = laddr.sin_port;
+ natlookup.nl_outport = faddr.sin_port;
+ natlookup.nl_inip = laddr.sin_addr;
+ natlookup.nl_outip = faddr.sin_addr;
+ natlookup.nl_flags = IPN_TCP;
+ if ((natfd = open(IPL_NAT, O_RDONLY)) < 0)
+ return -1;
+ if (ioctl(natfd, SIOCGNATL, &natlookup) == -1) {
+ syslog(LOG_ERR, "SIOCGNATL failed: %m\n");
+ close(natfd);
+ return -1;
+ }
+ close(natfd);
+ strcpy(hostname, inet_ntoa(natlookup.nl_realip));
+ serverport = ntohs(natlookup.nl_realport);
+ /*
+ * End of IP-Filter block
+ */
/* setup a timeout in case dialog doesn't finish */
signal(SIGALRM, timeout);
***************
*** 337,344 ****
--- 377,386 ----
* and modify the call to (and subroutine) serverconnect() as
* appropriate.
*/
+ #if 0
strcpy(hostname, "randomhostname");
serverport = 7070;
+ #endif
/* Can we connect to the server */
if ( (serverfd = serverconnect(hostname, serverport)) < 0 ) {
/* errno may still be set from previous call */

View File

@ -9,7 +9,7 @@ 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_pxy.c mlf_ipl.c ipl.h ip_compat.h \
ip_proxy.[ch] ip_{ftp,rcmd}_pxy.c mlf_ipl.c ipl.h ip_compat.h \
ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet

View File

@ -0,0 +1,24 @@
To build a kernel with the IP filter, follow these steps:
1. do "make freebsd3"
2. do "make install-bsd"
(probably has to be done as root)
3. run "FreeBSD-3/kinstall" as root
4. build a new kernel
5. install the new kernel
6. If not using DEVFS, create devices for IP Filter as follows:
mknod /dev/ipl c 79 0
mknod /dev/ipnat c 79 1
mknod /dev/ipstate c 79 2
mknod /dev/ipauth c 79 3
7. reboot
Darren Reed
darrenr@pobox.com

View File

@ -0,0 +1,46 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
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_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
ln -s /usr/include/osreldate.h /sys/sys/osreldate.h
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
echo "Rewriting $newconfig..."
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak}
endif
awk '{print $0;if($2=="INET"){print"options IPFILTER\noptions IPFILTER_LOG"}}'\
$confdir/$newconfig.bak > $confdir/$newconfig
echo "You will now need to run config on $newconfig and build a new kernel."
exit 0

View File

@ -0,0 +1,44 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Uninstalling "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_auth.[ch] ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c ip_compat.h \
ip_log.c mlf_ipl.c ipl.h)
echo -n "$i ";
/bin/rm -f /sys/netinet/$i
end
echo ""
echo "Removing link from /usr/include/osreldate.h to /sys/sys/osreldate.h"
rm /sys/sys/osreldate.h
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak}
endif
egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig
echo 'You will now need to run "config" and build a new kernel.'
exit 0

View File

@ -0,0 +1,46 @@
*** conf.c.orig Sun Jan 14 15:39:32 1996
--- conf.c Sun Jan 14 15:48:21 1996
***************
*** 1128,1133 ****
--- 1128,1149 ----
#define labpcioctl nxioctl
#endif
+ #ifdef IPFILTER
+ d_open_t iplopen;
+ d_close_t iplclose;
+ d_ioctl_t iplioctl;
+ # ifdef IPFILTER_LOG
+ d_read_t iplread;
+ # else
+ #define iplread nxread
+ # endif
+ #else
+ #define iplopen nxopen
+ #define iplclose nxclose
+ #define iplioctl nxioctl
+ #define iplread nxread
+ #endif
+
/* open, close, read, write, ioctl, stop, reset, ttys, select, mmap, strat */
struct cdevsw cdevsw[] =
{
***************
*** 1199,1206 ****
* Otherwise, simply use the one reserved for local use.
*/
/* character device 20 is reserved for local use */
! { nxopen, nxclose, nxread, nxwrite, /*20*/
! nxioctl, nxstop, nxreset, nxdevtotty,/* reserved */
nxselect, nxmmap, NULL },
{ psmopen, psmclose, psmread, nowrite, /*21*/
psmioctl, nostop, nullreset, nodevtotty,/* psm mice */
--- 1215,1222 ----
* Otherwise, simply use the one reserved for local use.
*/
/* character device 20 is reserved for local use */
! { iplopen, iplclose, iplread, nxwrite, /*20*/
! iplioctl, nxstop, nxreset, nxdevtotty,/* reserved */
nxselect, nxmmap, NULL },
{ psmopen, psmclose, psmread, nowrite, /*21*/
psmioctl, nostop, nullreset, nodevtotty,/* psm mice */

View File

@ -0,0 +1,19 @@
*** files.orig Sat Sep 30 18:01:55 1995
--- files Sun Jan 14 14:32:25 1996
***************
*** 208,213 ****
--- 208,221 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
+ netinet/ip_fil.c optional ipfilter inet
+ netinet/fil.c optional ipfilter inet
+ netinet/ip_nat.c optional ipfilter inet
+ netinet/ip_frag.c optional ipfilter inet
+ netinet/ip_state.c optional ipfilter inet
+ netinet/ip_auth.c optional ipfilter inet
+ netinet/ip_proxy.c optional ipfilter inet
+ netinet/ip_log.c optional ipfilter inet
netiso/clnp_debug.c optional iso
netiso/clnp_er.c optional iso
netiso/clnp_frag.c optional iso

View File

@ -0,0 +1,19 @@
*** files.newconf.orig Sun Jun 25 02:17:29 1995
--- files.newconf Sun Jun 25 02:19:10 1995
***************
*** 161,166 ****
--- 161,174 ----
file netinet/ip_input.c inet
file netinet/ip_mroute.c inet
file netinet/ip_output.c inet
+ file netinet/ip_fil.c ipfilter
+ file netinet/fil.c ipfilter
+ file netinet/ip_nat.c ipfilter
+ file netinet/ip_frag.c ipfilter
+ file netinet/ip_state.c ipfilter
+ file netinet/ip_proxy.c ipfilter
+ file netinet/ip_auth.c ipfilter
+ file netinet/ip_log.c ipfilter
file netinet/raw_ip.c inet
file netinet/tcp_debug.c inet
file netinet/tcp_input.c inet

View File

@ -0,0 +1,19 @@
*** files.oldconf.orig Sat Apr 29 19:59:31 1995
--- files.oldconf Sun Apr 23 17:54:18 1995
***************
*** 180,185 ****
--- 180,193 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
+ netinet/ip_fil.c optional ipfilter requires inet
+ netinet/fil.c optional ipfilter requires inet
+ netinet/ip_nat.c optional ipfilter requires inet
+ netinet/ip_frag.c optional ipfilter requires inet
+ netinet/ip_state.c optional ipfilter requires inet
+ netinet/ip_proxy.c optional ipfilter requires inet
+ netinet/ip_auth.c optional ipfilter requires inet
+ netinet/ip_log.c optional ipfilter requires inet
netiso/clnp_debug.c optional iso
netiso/clnp_er.c optional iso
netiso/clnp_frag.c optional iso

View File

@ -0,0 +1,19 @@
*** files.orig Sat Apr 29 20:00:02 1995
--- files Sun Apr 23 17:53:58 1995
***************
*** 222,227 ****
--- 222,235 ----
file netinet/tcp_timer.c inet
file netinet/tcp_usrreq.c inet
file netinet/udp_usrreq.c inet
+ file netinet/ip_fil.c ipfilter
+ file netinet/fil.c ipfilter
+ file netinet/ip_nat.c ipfilter
+ file netinet/ip_frag.c ipfilter
+ file netinet/ip_state.c ipfilter
+ file netinet/ip_proxy.c ipfilter
+ file netinet/ip_auth.c ipfilter
+ file netinet/ip_log.c ipfilter
file netiso/clnp_debug.c iso
file netiso/clnp_er.c iso
file netiso/clnp_frag.c iso

View File

@ -0,0 +1,16 @@
*** in_proto.c.orig Wed Sep 6 20:31:34 1995
--- in_proto.c Mon Mar 11 22:40:03 1996
***************
*** 81,86 ****
--- 81,91 ----
void eoninput(), eonctlinput(), eonprotoinit();
#endif /* EON */
+ #ifdef IPFILTER
+ void iplinit();
+ #define ip_init iplinit
+ #endif
+
void rsvp_input(struct mbuf *, int);
void ipip_input(struct mbuf *, int);

View File

@ -0,0 +1,88 @@
*** /sys/netinet/ip_input.c.orig Thu Oct 24 22:27:27 1996
--- /sys/netinet/ip_input.c Tue Feb 18 21:18:19 1997
***************
*** 93,98 ****
--- 93,102 ----
int ipqmaxlen = IFQ_MAXLEN;
struct in_ifaddr *in_ifaddr; /* first inet address */
struct ifqueue ipintrq;
+ #if defined(IPFILTER_LKM) || defined(IPFILTER)
+ int fr_check __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+ int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+ #endif
struct ipstat ipstat;
struct ipq ipq;
***************
*** 219,226 ****
}
ip = mtod(m, struct ip *);
}
! ip->ip_sum = in_cksum(m, hlen);
! if (ip->ip_sum) {
ipstat.ips_badsum++;
goto bad;
}
--- 223,229 ----
}
ip = mtod(m, struct ip *);
}
! if (in_cksum(m, hlen)) {
ipstat.ips_badsum++;
goto bad;
}
***************
*** 267,272 ****
--- 270,288 ----
goto next;
}
+ #if defined(IPFILTER) || defined(IPFILTER_LKM)
+ /*
+ * Check if we want to allow this packet to be processed.
+ * Consider it to be bad if not.
+ */
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m1) || !m1)
+ goto next;
+ ip = mtod(m = m1, struct ip *);
+ }
+ #endif
/*
* Process options and, if not destined for us,
* ship it on. ip_dooptions returns 1 when an
***************
*** 527,532 ****
--- 533,540 ----
* if they are completely covered, dequeue them.
*/
while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
+ struct mbuf *m0;
+
i = (ip->ip_off + ip->ip_len) - q->ip_off;
if (i < q->ip_len) {
q->ip_len -= i;
***************
*** 526,534 ****
m_adj(dtom(q), i);
break;
}
q = q->ipf_next;
- m_freem(dtom(q->ipf_prev));
ip_deq(q->ipf_prev);
}
insert:
--- 542,551 ----
m_adj(dtom(q), i);
break;
}
+ m0 = dtom(q);
q = q->ipf_next;
ip_deq(q->ipf_prev);
+ m_freem(m0);
}
insert:

View File

@ -0,0 +1,36 @@
*** /sys/netinet/ip_output.c.orig Thu Oct 24 22:27:28 1996
--- /sys/netinet/ip_output.c Tue Feb 18 21:38:23 1997
***************
*** 65,70 ****
--- 65,74 ----
static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
static void ip_mloopback
__P((struct ifnet *, struct mbuf *, struct sockaddr_in *));
+ #if defined(IPFILTER_LKM) || defined(IPFILTER)
+ extern int fr_check __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+ #endif
/*
* IP output. The packet in mbuf chain m contains a skeletal IP
***************
*** 330,335 ****
--- 334,351 ----
m->m_flags &= ~M_BCAST;
sendit:
+ #if defined(IPFILTER) || defined(IPFILTER_LKM)
+ /*
+ * looks like most checking has been done now...do a filter check
+ */
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1)
+ goto done;
+ ip = mtod(m = m1, struct ip *);
+ }
+ #endif
/*
* Check with the firewall...
*/

View File

@ -0,0 +1,61 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
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)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
end
echo ""
echo "Patching $archdir/$karch/conf.c"
cat FreeBSD/conf.c.diffs | (cd $archdir/$karch; patch)
echo "Patching ip_input.c, ip_output.c and in_proto.c"
cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \
(cd /sys/netinet; patch)
if ( -f /sys/conf/files.newconf ) then
echo "Patching /sys/conf/files.newconf"
cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch)
echo "Patching /sys/conf/files"
cat FreeBSD/files.diffs | (cd /sys/conf; patch)
endif
if ( -f /sys/conf/files.oldconf ) then
echo "Patching /sys/conf/files.oldconf"
cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch)
echo "Patching /sys/conf/files"
cat FreeBSD/filez.diffs | (cd /sys/conf; patch)
endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
echo "Re-config'ing $newconfig..."
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak}
endif
awk '{print $0;if($2=="INET"){print"options IPFILTER"}}' \
$confdir/$newconfig.bak > $confdir/$newconfig
echo 'You will now need to run "config" and build a new kernel.'
exit 0

View File

@ -0,0 +1,51 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD ) cd ..
echo "Patching ip_input.c, ip_output.c and in_proto.c"
cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \
(cd /sys/netinet; patch)
if ( -f /sys/conf/files.newconf ) then
echo "Patching /sys/conf/files.newconf"
cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch)
echo "Patching /sys/conf/files"
cat FreeBSD/files.diffs | (cd /sys/conf; patch)
endif
if ( -f /sys/conf/files.oldconf ) then
echo "Patching /sys/conf/files.oldconf"
cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch)
echo "Patching /sys/conf/files"
cat FreeBSD/filez.diffs | (cd /sys/conf; patch)
endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
echo "Re-config'ing $newconfig..."
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.$bak
endif
awk '{print $0;if($2=="INET"){print"options IPFILTER_LKM"}}' \
$confdir/$newconfig.bak > $confdir/$newconfig
echo 'You will now need to run "config" and build a new kernel.'
exit 0

View File

@ -0,0 +1,58 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD ) cd ..
echo -n "Uninstalling "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_compat.h ip_auth.[ch] ip_proxy.[ch] ip_ftp_pxy.c ip_log.c)
echo -n "$i ";
/bin/rm -f /sys/netinet/$i
end
echo ""
echo "Unpatching $archdir/$karch/conf.c"
cat FreeBSD/conf.c.diffs | (cd $archdir/$karch; patch -R)
echo "Unpatching ip_input.c, ip_output.c and in_proto.c"
cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \
(cd /sys/netinet; patch -R)
if ( -f /sys/conf/files.newconf ) then
echo "Unpatching /sys/conf/files.newconf"
cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch -R)
echo "Unpatching /sys/conf/files"
cat FreeBSD/files.diffs | (cd /sys/conf; patch -R)
endif
if ( -f /sys/conf/files.oldconf ) then
echo "Unpatching /sys/conf/files.oldconf"
cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch -R)
echo "Unpatching /sys/conf/files"
cat FreeBSD/filez.diffs | (cd /sys/conf; patch -R)
endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak}
endif
egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig
echo 'You will now need to run "config" and build a new kernel.'
exit 0

View File

@ -0,0 +1,49 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD ) cd ..
echo "Unpatching ip_input.c, ip_output.c and in_proto.c"
cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \
(cd /sys/netinet; patch -R)
if ( -f /sys/conf/files.newconf ) then
echo "Unpatching /sys/conf/files.newconf"
cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch -R)
echo "Unpatching /sys/conf/files"
cat FreeBSD/files.diffs | (cd /sys/conf; patch -R)
endif
if ( -f /sys/conf/files.oldconf ) then
echo "Unpatching /sys/conf/files.oldconf"
cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch -R)
echo "Unpatching /sys/conf/files"
cat FreeBSD/filez.diffs | (cd /sys/conf; patch -R)
endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.$bak
endif
grep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig
echo 'You will now need to run "config" and build a new kernel.'
exit 0

View File

@ -2,15 +2,295 @@
# NOTE: Quite a few patches and suggestions come from other sources, to whom
# I'm greatly indebted, even if no names are mentioned.
#
# Thanks to Craig Bishop of connect.com.au and Sun Microsystems for the
# loan of a machine to work on a Solaris 2.x port of this software.
# Thanks to the Coombs Computing Unit at the ANU for their continued support
# in providing a very available location for the IP Filter home page and
# distribution center.
#
# Thanks to Tel.Net Media for allowing me to maintain and further develop
# IP Filter as part of my job and supplying Sun equipment for testing the
# move to 64bits.
#
# Thanks to BSDI for providing object files for BSD/OS 3.1 and the means
# to further support development of IP Filter under BSDI.
#
# Thanks to Craig Bishop of connect.com.au and Sun Microsystems for the
# loan of a machine to work on a Solaris 2.x port of this software.
#
# Thanks also to all those who have contributed patches and other code,
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.3.3 22/10/1999 - Released
add -g command line option to ipfstat to show groups still define.
fix problem with fragment table not recording rule pointer when called
from state functions (fin_fr not set).
fixup fastroute problems with keep state rules.
load rules into inactive set first, so we don't disable things like NIS
lookups half way through processing - found by Kevin Littlejohn
fix handling of unaligned ip pointer for solaris
patch for fr_newauth from Rudi Sluijtman
fixed htons() bug in fr_tcpsum() where ip_p wasn't cast to u_short
3.3.2 23/09/1999 - Released
patches from Scott Presnell to fix rcmd proxy
patches from Greg to fix Solaris detachment of interfaces
add openbsd compatibility fixes
fix free'ing already freed memory in ipfr_slowtimer()
fix for deferencing invalid memory in cleaning up after a device disappears
3.3.1 14/8/1999 - Released
remove include file sys/user.h for irix
prevent people from running buildsunos directly
fix up some problems with the saving of rule pointers so that NAT saves
that information in case it should need to call fr_addstate() from a proxy.
fix up scanning for the end of FTP messages
don't remove /etc/opt/ipf in postremove
attempt to prevent people running buildsolaris script without doing a
"make solaris"
fix timeout losing on freebsd3
3.3 7/8/1999 - Released
NAT: information (rules, mappings) are stored in hash tables; setup some
basic NAT regression testing.
display version name of installed kernel code when initializing.
add -V command line option to ipf, showing version (program and kernel
module) as well as the run-status of the kernel code.
fix problem with "log" rules actually affecting result of filtering.
automatically use SUNWspro if available and on a 64bit Solaris system for
compiling.
add kernel proxies for rcmd(3) and RealAudio (PNA)
use timeout/untimeout on SunOS4/BSD platforms too rather than hijacking
ip_slowtimo
fix IP headers generated through parsing of text information
fix NAT rules to be in the correct order again.
make keep-state work with to/fastroute keywords and enforce usage of those
interfaces.
update keep-state code with new algorithm from Guido
add FreeBSD-3 support
add return-icmp-as-dest option to retrun an ICMP packet using the original
destination as the source rather than a local IP address
add "level [facility.]<priority>" option to filter language
add changes from Guido to state code.
add code to return EPERM if the device is opened for writing and we're
in securelevel 2 or greater.
authentication code patches from Guido
fix real audio proxy
fix ipmon rule printing of interfaces and add IN/OUT to the end of ipmon
log output.
fix bimap rules with hash tables
update addresses used in NAT mappings for 0/32 rules for any protocol but TCP
if it changes on the interface - check every ip_natexpire()
add redirect regression test
count buckets used in the state hash table.
fix sending of RST's with return-rst to use the ack number provided in
the packet being replied to in addition to the sequence number.
fix to compile as a 64bit application on solaris7-64bit
add NAT IP mapping to ranges of IP addresses that aren't CIDR specified
fix calculation of in_space parameter for NAT
fix `wrapping' when incrementing the next ip address for use in NAT
fix free'ing of kernel memory in ip_natunload on solaris
fix -l/-U command line options from interfering with each other
fix fastroute under solaris2 and cleanup compilation for solaris7
add install scripts and compile cleanly on BSD/OS 4.0
safely open files in /tmp for writing device output when testing.
fix uninitialized pointer bug in NAT
fix SIOCZRLST (zero list rule stats) bug with groups
change some usage of u_short to u_int in function calling
fix compilation for Solaris7 (SUNWspro)
change solaris makefiles to build for either sparc or i386 rather than
per-cpu (sun4u, etc).
fixed bug in ipllog
add patches from George Michaelson for FreeBSD 3.0
add patch from Guido to provide ICMP checking for known state in the same
manner as is done for NAT.
enable FTP PASV proxying and enable wildcarding in NAT/state code for ports
for better PORT/PASV support with FTP.
bring into main tree static nat features: map-block and "auto" portmapping.
add in source host filtering for redirects (alan jones)
3.2.10 22/11/98 - Released
3.2.10beta9 17/11/98 - Released
fix fr_tcpsum problems in handling mbufs with an odd number of bytes
and/or split across an mbuf boundary
fix NAT list entry comparisons and allow multiple entries for the same
proxy (but on different ports).
don't create duplicate NAT entries for repeated PORT commands.
3.2.10beta8 14/11/98 - Released
always exit an rwlock before expecting to enter it again on solaris
fix loop in nat_new for pre-existing nat
don't setup state for an ftp connection if creating nat fails.
3.2.10beta7 05/11/98 - Released
set fake window in ipft_tx.c to ensure code passes tests.
cleaned up/enhanced ipnat -l/ipnat -lv output
fixed NAT handling of non-TCP/UDP packets, esp. for ICMP errors returned.
Solaris recusive mutex on icmp-error/tcp-reset - requires rwlock's rather
than mutexes.
3.2.10beta6 03/11/98 - Released
fix mixed use of krwlock_t and kmutex_t on Solaris2
fix FTP proxy back up, splitting pasv code out of port code.
3.2.10beta5 02/11/98 - Released
fixed port translation in ICMP reply handling
3.2.10beta4 01/11/98 - Released
increase useful statistic collection on solaris
filter DL_UNITDATA_REQ as well as DL_UNITDATA_IND on solaris
disable PASV reply translation for now
fail with an error if we try to load a NAT rule with a non-existant
proxy name - Guido
fix portmap usage with 0/0 and 0/32 map rules
remove ap_unload/ap_expire - automatically done when NAT is cleaned up
print "STATE:CLOSED" from ipmon if the connection progresses past established
rather than "STATE:EXPIRED"
3.2.10beta3 26/10/98 - Released
fixed traceroute/nat problem
rewrote nat/proxy interface
ipnat now lists associated proxy sessions for each NAT where applicable
3.2.10beta2 13/10/98 - Released
use KRWLOCK_T in place of krwlock_t for solaris as well as irix
disable use of read-write lock acquisition by default
add in mb_t for linux, non-kernel
some changes to progress compilation on linux with glibc
change PASV as well as PORT when passed through kernel ftp proxy.
don't allow window to become 0 in tcp state code
make ipmon compile cleaner
irix patches
3.2.10beta 11/09/98 - Released
stop fr_tcpsum() thinking it has run out of data when it hasn't.
stop solaris panics due to fin_dp being something wild.
revisit usage of ATOMIC_*()
log closing state of TCP connection in "keep state"
fix fake-arp table code for ipsend.
ipmon now writes pid to a file.
fix "ipmon -a" to actually activate all logging devices.
add patches for BSDOS4.
perl scripts for log analysis donated.
3.2.9 22/06/98 - Released
fix byte order for ICMP packets generated on Solaris
fix some locking problems.
fix malloc bug in NAT (introduced in 3.2.8).
patch from guido for state connections that get fragmented
3.2.8 08/06/98 - Released
use readers/writers locks in Solaris2 in place of some mutexes.
Solaris2 installation enhancements - Martin Forssen (maf@carlstedt.se)
3.2.7 24/05/98 - Released

View File

@ -0,0 +1,35 @@
BSD/OS users.
-------------
First, you need to build IP Filter. Do this from the "ip_fil3.2.x"
directory with the command "make bsdos". If this completes successfully,
install the various bits and pieces with "make install-bsd".
Prior to starting, it is a good idea for you to know what your kernel config
file is (it appears that the script guesses incorrectly at present).
Once you have that in mind, run the 'kinstall' script in the correct
BSDOS3 or BSDOS4 directory. This will attempt to patch a bunch of files
or install the relevant .o files if you don't have kernel source.
It will also go and install all the IP Filter .c and .h files where they
can be find when it comes time to build the kernel.
The script will then pause and ask you for your kernel configuration
file. After you enter this, it will add "options IPFILTER" to your
kernel configuration file. IF YOU WANT TO DO LOGGING, ADD
"options IPFILTER_LOG" to your kernel configuration file NOW!
Now that you've got your kernel configuration file done, use config
to setup a new kernel build and complete with make.
When the kernel rebuilt is complete, put it into / and reboot with
your new kernel. If IP Filter has been configured into your kernel
correctly, you will see a message like this when your system boots:
IP Filter: initialized. Default = pass all, Logging = enabled
Upon logging in, the IP Filter commands ipfstat, et al, should all
function properly.
Darren

View File

@ -1,5 +1,7 @@
*** IF you are using FreeBSD 2.2 or later, see the file "INST.FreeBSD-2.2" ***
*** 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

View File

@ -1,8 +1,9 @@
For those running Solaris 2.5, please read COMPILE.2.5 before building
IP Filter.
For those running Solaris 2.5 or later, please read COMPILE.2.5 before
building IP Filter.
Type "make solaris" to build all the required binaries.
Type "make solaris" to build all the required binaries. DO NOT USE THE
GNU make!!!
Once IP Filter has been successfully compiled, you may then install it using
the usual package method (using pkgadd), however, the package needs to be

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 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.

View File

@ -1,18 +1,18 @@
#
# Copyright (C) 1993-1997 by Darren Reed.
# Copyright (C) 1993-1998 by Darren Reed.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and due credit is given
# to the original author and the contributors.
#
# $Id: Makefile,v 2.0.2.26.2.10 1998/05/23 05:01:23 darrenr Exp $
# $Id: Makefile,v 2.2 1999/08/04 17:29:52 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
MANDIR=/usr/local/man
#To test prototyping
#CC=gcc -Wstrict-prototypes -Wmissing-prototypes -Werror
CC=gcc
CC=gcc -Wstrict-prototypes -Wmissing-prototypes
#CC=gcc
#CC=cc -Dconst=
DEBUG=-g
CFLAGS=-I$$(TOP)
@ -39,11 +39,12 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
MFLAGS1="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)"
MFLAGS=$(MFLAGS1) "IPFLKM=$(IPFLKM)"
#
SHELL=/bin/sh
#
@ -58,11 +59,12 @@ INSTALL=install
all:
@echo "Chose one of the following targets for making IP filter:"
@echo ""
@echo "solaris - auto-selects SunOS4.1.x/Solaris 2.[45]/Solaris2.[45]-x86"
@echo "solaris - auto-selects SunOS4.1.x/Solaris 2.3-6/Solaris2.4-6x86"
@echo "netbsd - compile for NetBSD"
@echo "openbsd - compile for OpenBSD"
@echo "freebsd - compile for FreeBSD 2.0, 2.1 or earlier"
@echo "freebsd22 - compile for FreeBSD-2.2 or greater"
@echo "freebsd3 - compile for FreeBSD-3.x"
@echo "bsd - compile for generic 4.4BSD systems"
@echo "bsdi - compile for BSD/OS"
@echo "irix - compile for SGI IRIX"
@ -74,9 +76,8 @@ tests:
else echo test directory not present, sorry; fi
include:
if [ ! -d netinet -o ! -f netinet/done ] ; then \
mkdir -p netinet; \
(cd netinet; ln -s ../*.h .; ln -s ../ip_ftp_pxy.c .); \
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 ../ipsend/tcpip.h tcpip.h); \
touch netinet/done; \
fi
@ -84,12 +85,12 @@ include:
sunos solaris: include
./buildsunos
freebsd22 freebsd30: include
freebsd22: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
-rm -f BSD/$(CPUDIR)/ioconf.h
@if [ -n $(IPFILKERN) ] ; then \
if [ -f /sys/$(IPFILKERN)/compile/ioconf.h ] ; then \
ln -s /sys/$(IPFILKERN)/compile/ioconf.h BSD/$(CPUDIR); \
if [ -f /sys/compile/$(IPFILKERN)/ioconf.h ] ; then \
ln -s /sys/compile/$(IPFILKERN)/ioconf.h BSD/$(CPUDIR); \
else \
ln -s /sys/$(IPFILKERN)/ioconf.h BSD/$(CPUDIR); \
fi \
@ -102,6 +103,11 @@ freebsd22 freebsd30: include
fi
make freebsd
freebsd3 freebsd30: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS1) "ML=mlf_ipl.c" LKM= ; cd ..)
(cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..)
netbsd: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
@ -146,10 +152,9 @@ setup:
-ln -s ../Makefile $(TARGOS)/$(CPUDIR)/Makefile
-ln -s ../Makefile.ipsend $(TARGOS)/$(CPUDIR)/Makefile.ipsend
clean:
${RM} -rf netinet
clean: clean-include
${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \
vnode_if.h $(LKM)
vnode_if.h $(LKM) *~
if [ "`uname -s`" = "SunOS" ]; then (cd SunOS4; make clean); fi
if [ "`uname -s`" = "SunOS" ]; then (cd SunOS5; make clean); fi
(cd BSD; make clean)
@ -158,19 +163,23 @@ clean:
[ -d test ] && (cd test; make clean)
(cd ipsend; make clean)
clean-bsd:
clean-include:
sh -c 'cd netinet; for i in *; do if [ -h $$i ] ; then /bin/rm -f $$i; fi; done'
${RM} -f netinet/done
clean-bsd: clean-include
(cd BSD; make clean)
clean-sunos4:
clean-sunos4: clean-include
(cd SunOS4; make clean)
clean-sunos5:
clean-sunos5: clean-include
(cd SunOS5; make clean)
clean-irix:
clean-irix: clean-include
(cd IRIX; make clean)
clean-linux:
clean-linux: clean-include
(cd Linux; make clean)
get:

View File

@ -0,0 +1,10 @@
NOTE: To all those upgrading from versions prior to 3.2.11 who used NAT
AND setup ACL's to allow untranslated address through from outside,
THIS HAS BEEN FIXED
so your ACL's will now be `broken'. Please correct your ACL's to
match the the untranslated addresses (the way it was meant to work).
Darren

View File

@ -1,24 +1,49 @@
#! /bin/sh
# $Id: buildsunos,v 2.0.2.4.2.1 1998/05/21 14:46:04 darrenr Exp $
if [ ! -f netinet/done ] ; then
echo "Do NOT run this script directly, do 'make solaris'!"
exit 1
fi
# $Id: buildsunos,v 2.1.2.1 1999/08/08 13:55:20 darrenr Exp $
:
rev=`uname -r | sed -e 's/^\([^\.]*\)\..*/\1/'`
cpu=`uname -m`
cpudir=${cpu}-`uname -r`
if [ -d /usr/ccs/bin ] ; then
PATH=/usr/ccs/bin:${PATH}
fi
if [ $rev = 5 ] ; then
cpu=`uname -p`
cpudir=${cpu}-`uname -r`
solrev=`uname -r | sh -c 'IFS=. read j n x; echo $n'`
mkdir -p SunOS5/${cpudir}
if [ ! -d SunOS5/${cpudir} -a ! -h SunOS5/${cpudir} ] ; then
mkdir -p SunOS5/${cpudir}
fi
/bin/rm -f SunOS5/${cpudir}/Makefile
/bin/rm -f SunOS5/${cpudir}/Makefile.ipsend
ln -s ../Makefile SunOS5/${cpudir}/Makefile
ln -s ../Makefile.ipsend SunOS5/${cpudir}/Makefile.ipsend
ln -s `pwd`/SunOS5/Makefile SunOS5/${cpudir}/Makefile
ln -s `pwd`/SunOS5/Makefile.ipsend SunOS5/${cpudir}/Makefile.ipsend
ARCHINC=
XARCH=
if [ -d /opt/SUNWspro/bin ] ; then
CC="/opt/SUNWspro/bin/cc ${CFL}"
export CC
/bin/optisa sparcv9 >/dev/null 2>&1
if [ $? -eq 0 ] ; then
ARCHINC="-I/usr/include/v9"
XARCH="-xarch=v9 -xchip=ultra -dalign -xcode=abs32"
fi
else
CC=gcc
fi
else
cpu=`uname -m`
cpudir=${cpu}-`uname -r`
fi
if [ $cpu = i86pc ] ; then
make ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU=${cpu} CPUDIR=${cpudir}
if [ $cpu = i386 ] ; then
make ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH" XARCH="$XARCH" ARCHINC="$ARCHINC"
exit $?
fi
if [ x$solrev = x ] ; then
make ${1+"$@"} sunos$rev "ARCH=`uname -m`"
exit $?
fi
make ${1+"$@"} sunos$rev SOLARIS2="-DSOLARIS2=$solrev" CPU=${cpu} CPUDIR=${cpudir}
make ${1+"$@"} sunos$rev SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH" XARCH="$XARCH" ARCHINC="$ARCHINC"
exit $?

File diff suppressed because it is too large Load Diff

146
contrib/ipfilter/facpri.c Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <syslog.h>
#include "facpri.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: facpri.c,v 1.2 1999/08/01 11:10:45 darrenr Exp $";
#endif
typedef struct table {
char *name;
int value;
} table_t;
table_t facs[] = {
{ "kern", LOG_KERN }, { "user", LOG_USER },
{ "mail", LOG_MAIL }, { "daemon", LOG_DAEMON },
{ "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG },
{ "lpr", LOG_LPR }, { "news", LOG_NEWS },
{ "uucp", LOG_UUCP },
#if LOG_CRON == LOG_CRON2
{ "cron2", LOG_CRON1 },
#else
{ "cron", LOG_CRON1 },
#endif
#ifdef LOG_FTP
{ "ftp", LOG_FTP },
#endif
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV },
#endif
#ifdef LOG_AUDIT
{ "audit", LOG_AUDIT },
#endif
#ifdef LOG_LFMT
{ "logalert", LOG_LFMT },
#endif
#if LOG_CRON == LOG_CRON1
{ "cron", LOG_CRON2 },
#else
{ "cron2", LOG_CRON2 },
#endif
{ "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 },
{ NULL, 0 }
};
/*
* map a facility number to its name
*/
char *
fac_toname(facpri)
int facpri;
{
int i, j, fac;
fac = facpri & LOG_FACMASK;
j = fac >> 3;
if (j < 24) {
if (facs[j].value == fac)
return facs[j].name;
for (i = 0; facs[i].name; i++)
if (fac == facs[i].value)
return facs[i].name;
}
return NULL;
}
/*
* map a facility name to its number
*/
int
fac_findname(name)
char *name;
{
int i;
for (i = 0; facs[i].name; i++)
if (!strcmp(facs[i].name, name))
return facs[i].value;
return -1;
}
table_t pris[] = {
{ "emerg", LOG_EMERG }, { "alert", LOG_ALERT },
{ "crit", LOG_CRIT }, { "err", LOG_ERR },
{ "warn", LOG_WARNING }, { "notice", LOG_NOTICE },
{ "info", LOG_INFO }, { "debug", LOG_DEBUG },
{ NULL, 0 }
};
/*
* map a priority name to its number
*/
int
pri_findname(name)
char *name;
{
int i;
for (i = 0; pris[i].name; i++)
if (!strcmp(pris[i].name, name))
return pris[i].value;
return -1;
}
/*
* map a priority number to its name
*/
char *
pri_toname(facpri)
int facpri;
{
int i, pri;
pri = facpri & LOG_PRIMASK;
if (pris[pri].value == pri)
return pris[pri].name;
for (i = 0; pris[i].name; i++)
if (pri == pris[i].value)
return pris[i].name;
return NULL;
}

42
contrib/ipfilter/facpri.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 1999 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: facpri.h,v 1.2 1999/08/01 11:10:46 darrenr Exp $
*/
#ifndef __FACPRI_H__
#define __FACPRI_H__
#ifndef __P
# define P_DEF
# ifdef __STDC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
extern char *fac_toname __P((int));
extern int fac_findname __P((char *));
extern char *pri_toname __P((int));
extern int pri_findname __P((char *));
#ifdef P_DEF
# undef __P
# undef P_DEF
#endif
#if LOG_CRON == (9<<3)
# define LOG_CRON1 LOG_CRON
# define LOG_CRON2 (15<<3)
#endif
#if LOG_CRON == (15<<3)
# define LOG_CRON1 (9<<3)
# define LOG_CRON2 LOG_CRON
#endif
#endif /* __FACPRI_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,17 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#ifdef __FreeBSD__
# include <osreldate.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
# include <strings.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
@ -27,6 +29,9 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
@ -41,17 +46,12 @@
#include "netinet/ip_auth.h"
#include "kmem.h"
#if defined(__NetBSD__) || (__OpenBSD__)
#include <paths.h>
# include <paths.h>
#endif
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.0.2.25.2.2 1997/11/20 12:41:04 darrenr Exp $";
#endif
#ifdef _PATH_UNIX
#define VMUNIX _PATH_UNIX
#else
#define VMUNIX "/vmunix"
static const char rcsid[] = "@(#)$Id: fils.c,v 2.2.2.3 1999/10/05 12:57:37 darrenr Exp $";
#endif
extern char *optarg;
@ -72,8 +72,10 @@ static void showfrstates __P((int, 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 showgroups __P((friostat_t *));
static void Usage __P((char *));
static void printlist __P((frentry_t *));
static char *get_ifname __P((void *));
static void Usage(name)
@ -101,7 +103,7 @@ char *argv[];
(void)setuid(getuid());
(void)setgid(getgid());
while ((c = getopt(argc, argv, "aAfhIinosvd:")) != -1)
while ((c = getopt(argc, argv, "aAfghIinosvd:")) != -1)
{
switch (c)
{
@ -117,6 +119,9 @@ char *argv[];
case 'f' :
opts |= OPT_FRSTATES;
break;
case 'g' :
opts |= OPT_GROUPS;
break;
case 'h' :
opts |= OPT_HITS;
break;
@ -197,6 +202,8 @@ char *argv[];
showfrstates(fd, &ifrst);
else if (opts & OPT_AUTHSTATS)
showauthstates(fd, &frauthst);
else if (opts & OPT_GROUPS)
showgroups(&fio);
else
showstats(fd, &fio);
}
@ -211,7 +218,7 @@ static void showstats(fd, fp)
int fd;
struct friostat *fp;
{
int frf = 0;
u_32_t frf = 0;
if (ioctl(fd, SIOCGETFF, &frf) == -1)
perror("ioctl(SIOCGETFF)");
@ -219,6 +226,10 @@ struct friostat *fp;
#if SOLARIS
PRINTF("dropped packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_drop, fp->f_st[1].fr_drop);
PRINTF("non-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_notdata, fp->f_st[1].fr_notdata);
PRINTF("no-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_nodata, fp->f_st[1].fr_nodata);
PRINTF("non-ip packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_notip, fp->f_st[1].fr_notip);
PRINTF(" bad packets:\t\tin %lu\tout %lu\n",
@ -365,19 +376,19 @@ ips_stat_t *ipsp;
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);
PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, ipsp->iss_miss);
PRINTF("\t%lu maximum\n\t%lu no memory\n",
ipsp->iss_max, ipsp->iss_nomem);
PRINTF("\t%lu maximum\n\t%lu no memory\n\tbuckets in use\t%lu\n",
ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse);
PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n",
ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
return;
for (i = 0; i < IPSTATE_SIZE; i++)
for (i = 0; i < IPSTATE_SIZE; i++) {
while (istab[i]) {
if (kmemcpy((char *)&ips, (u_long)istab[i],
sizeof(ips)) == -1)
break;
PRINTF("%s -> ", inet_ntoa(ips.is_src));
PRINTF("%s ttl %ld pass %d pr %d state %d/%d\n",
PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n",
inet_ntoa(ips.is_dst), ips.is_age,
ips.is_pass, ips.is_p, ips.is_state[0],
ips.is_state[1]);
@ -389,30 +400,48 @@ ips_stat_t *ipsp;
ips.is_pkts, ips.is_bytes);
#endif
if (ips.is_p == IPPROTO_TCP)
PRINTF("\t%hu -> %hu %lu:%lu %hu:%hu\n",
#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_seq, ips.is_ack,
ips.is_swin, ips.is_dwin);
ips.is_send, ips.is_dend,
ips.is_maxswin, ips.is_maxdwin);
#else
PRINTF("\t%hu -> %hu %lx:%lx %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\n", ntohs(ips.is_sport),
PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
ntohs(ips.is_dport));
else if (ips.is_p == IPPROTO_ICMP)
PRINTF(" %hu %hu %d\n", ips.is_icmp.ics_id,
PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
ips.is_icmp.ics_seq,
ips.is_icmp.ics_type);
/* phil@ultimate.com ... */
PRINTF("\t");
/* from "printfr()" */
PRINTF("\n\t");
if (ips.is_pass & FR_PASS) {
PRINTF("pass");
} else if (ips.is_pass & FR_BLOCK) {
PRINTF("block");
if (ips.is_pass & FR_RETICMP)
switch (ips.is_pass & FR_RETMASK)
{
case FR_RETICMP :
PRINTF(" return-icmp");
if (ips.is_pass & FR_RETRST)
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)
@ -427,7 +456,7 @@ ips_stat_t *ipsp;
else
PRINTF(" in");
if ((ips.is_pass & (FR_LOGB|FR_LOGP)) != 0) {
if ((ips.is_pass & FR_LOG) != 0) {
PRINTF(" log");
if (ips.is_pass & FR_LOGBODY)
PRINTF(" body");
@ -444,10 +473,21 @@ ips_stat_t *ipsp;
if (ips.is_pass & FR_KEEPSTATE)
PRINTF(" keep state");
PRINTF("\n");
/* ... phil@ultimate.com */
PRINTF("\tpkt_flags & %x = %x,\t", ips.is_flags & 0xf,
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);
istab[i] = ips.is_next;
PRINTF("interfaces: in %s[%p] ",
get_ifname(ips.is_ifpin), ips.is_ifpin);
PRINTF("out %s[%p]\n",
get_ifname(ips.is_ifpout), ips.is_ifpout);
}
}
}
@ -456,6 +496,7 @@ int fd;
ipfrstat_t *ifsp;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
frentry_t fr;
int i;
PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
@ -471,10 +512,13 @@ ipfrstat_t *ifsp;
sizeof(ifr)) == -1)
break;
PRINTF("%s -> ", inet_ntoa(ifr.ipfr_src));
if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
sizeof(fr)) == -1)
break;
PRINTF("%s %d %d %d %#02x = %#x\n",
inet_ntoa(ifr.ipfr_dst), ifr.ipfr_id,
ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
ifr.ipfr_pass);
fr.fr_flags);
ipfrtab[i] = ifr.ipfr_next;
}
}
@ -484,6 +528,8 @@ static void showauthstates(fd, asp)
int fd;
fr_authstat_t *asp;
{
frauthent_t *frap, fra;
#ifdef USE_QUAD_T
printf("Authorisation hits: %qd\tmisses %qd\n", asp->fas_hits,
asp->fas_miss);
@ -496,4 +542,98 @@ fr_authstat_t *asp;
asp->fas_sendok);
printf("queok %ld\nquefail %ld\nexpire %ld\n",
asp->fas_queok, asp->fas_quefail, asp->fas_expire);
frap = asp->fas_faelist;
while (frap) {
if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1)
break;
printf("age %ld\t", fra.fae_age);
printfr(&fra.fae_fr);
frap = fra.fae_next;
}
}
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
}
static void showgroups(fiop)
struct friostat *fiop;
{
static char *gnames[3] = { "Filter", "Accounting", "Authentication" };
frgroup_t *fp, grp;
int on, off, i;
on = fiop->f_active;
off = 1 - on;
for (i = 0; i < 3; i++) {
printf("%s groups (active):\n", gnames[i]);
for (fp = fiop->f_groups[i][on]; fp; fp = grp.fg_next)
if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp)))
break;
else
printf("%hu\n", grp.fg_num);
printf("%s groups (inactive):\n", gnames[i]);
for (fp = fiop->f_groups[i][off]; fp; fp = grp.fg_next)
if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp)))
break;
else
printf("%hu\n", grp.fg_num);
}
}

View File

@ -55,7 +55,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.0.2.6 1997/10/19 15:39:21 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.1 1999/08/04 17:29:54 darrenr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>

View File

@ -1,23 +1,24 @@
/*
* Copyright (C) 1997 by Darren Reed & Guido van Rooij.
* Copyright (C) 1998 by Darren Reed & Guido van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:29 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.1 1999/09/28 11:44:04 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdlib.h>
# include <string.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
@ -39,34 +40,39 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:
#else
# include <sys/filio.h>
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# ifdef _KERNEL
# include <sys/dditypes.h>
# endif
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#if _BSDI_VERSION >= 199802
# include <sys/queue.h>
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi)
# include <machine/cpu.h>
#endif
#include <net/if.h>
#ifdef sun
#include <net/af.h>
# include <net/af.h>
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifndef KERNEL
#define KERNEL
#define NOT_KERNEL
# define KERNEL
# define NOT_KERNEL
#endif
#ifndef linux
# include <netinet/ip_var.h>
#endif
#ifdef NOT_KERNEL
#undef KERNEL
# undef KERNEL
#endif
#ifdef __sgi
# ifdef IFF_DRVRLOCK /* IRIX6 */
#include <sys/hashing.h>
# include <sys/hashing.h>
# endif
#endif
#include <netinet/tcp.h>
@ -74,6 +80,9 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:
extern struct ifqueue ipintrq; /* ip packet input queue */
#else
# ifndef linux
# if __FreeBSD_version >= 300000
# include <net/if_var.h>
# endif
# include <netinet/in_var.h>
# include <netinet/tcp_fsm.h>
# endif
@ -90,10 +99,19 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
# include <machine/cpufunc.h>
# endif
#endif
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
# include <sys/libkern.h>
# include <sys/systm.h>
# endif
#endif
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_auth;
extern KRWLOCK_T ipf_auth;
extern kmutex_t ipf_authmx;
# if SOLARIS
extern kcondvar_t ipfauthwait;
# endif
@ -118,7 +136,7 @@ frentry_t *ipauth = NULL;
* authorization result and that would result in a feedback loop (i.e. it
* will end up returning FR_AUTH) then return FR_BLOCK instead.
*/
int fr_checkauth(ip, fin)
u_32_t fr_checkauth(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
@ -126,7 +144,7 @@ fr_info_t *fin;
u_32_t pass;
int i;
MUTEX_ENTER(&ipf_auth);
READ_ENTER(&ipf_auth);
for (i = fr_authstart; i != fr_authend; ) {
/*
* index becomes -2 only after an SIOCAUTHW. Check this in
@ -141,6 +159,8 @@ fr_info_t *fin;
*/
if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH))
pass = FR_BLOCK;
RWLOCK_EXIT(&ipf_auth);
WRITE_ENTER(&ipf_auth);
fr_authstats.fas_hits++;
fr_auth[i].fra_index = -1;
fr_authused--;
@ -158,7 +178,7 @@ fr_info_t *fin;
fr_authstart = fr_authend = 0;
}
}
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return pass;
}
i++;
@ -166,7 +186,7 @@ fr_info_t *fin;
i = 0;
}
fr_authstats.fas_miss++;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
@ -189,16 +209,17 @@ ip_t *ip;
{
int i;
MUTEX_ENTER(&ipf_auth);
if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) {
WRITE_ENTER(&ipf_auth);
if (fr_authstart > fr_authend) {
fr_authstats.fas_nospace++;
MUTEX_EXIT(&ipf_auth);
return 0;
}
if (fr_authend - fr_authstart == FR_NUMAUTH - 1) {
fr_authstats.fas_nospace++;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
} else {
if ((fr_authstart == 0) && (fr_authend == FR_NUMAUTH - 1)) {
fr_authstats.fas_nospace++;
RWLOCK_EXIT(&ipf_auth);
return 0;
}
}
fr_authstats.fas_added++;
@ -206,7 +227,7 @@ ip_t *ip;
i = fr_authend++;
if (fr_authend == FR_NUMAUTH)
fr_authend = 0;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
fr_auth[i].fra_index = i;
fr_auth[i].fra_pass = 0;
fr_auth[i].fra_age = fr_defaultauthage;
@ -288,46 +309,58 @@ frentry_t *fr, **frptr;
if (!fae)
error = ESRCH;
else {
WRITE_ENTER(&ipf_auth);
*faep = fae->fae_next;
*frptr = fr->fr_next;
RWLOCK_EXIT(&ipf_auth);
KFREE(fae);
}
} else {
KMALLOC(fae, frauthent_t *, sizeof(*fae));
KMALLOC(fae, frauthent_t *);
if (fae != NULL) {
IRCOPY((char *)data, (char *)&fae->fae_fr,
sizeof(fae->fae_fr));
if (!fae->fae_age)
fae->fae_age = fr_defaultauthage;
WRITE_ENTER(&ipf_auth);
fae->fae_age = fr_defaultauthage;
fae->fae_fr.fr_hits = 0;
fae->fae_fr.fr_next = *frptr;
*frptr = &fae->fae_fr;
fae->fae_next = *faep;
*faep = fae;
ipauth = &fae_list->fae_fr;
RWLOCK_EXIT(&ipf_auth);
} else
error = ENOMEM;
}
break;
case SIOCATHST:
READ_ENTER(&ipf_auth);
fr_authstats.fas_faelist = fae_list;
RWLOCK_EXIT(&ipf_auth);
IWCOPY((char *)&fr_authstats, data, sizeof(fr_authstats));
break;
case SIOCAUTHW:
fr_authioctlloop:
MUTEX_ENTER(&ipf_auth);
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
IWCOPY((char *)&fr_auth[fr_authnext++], data,
IWCOPY((char *)&fr_auth[fr_authnext], data,
sizeof(fr_info_t));
RWLOCK_EXIT(&ipf_auth);
WRITE_ENTER(&ipf_auth);
fr_authnext++;
if (fr_authnext == FR_NUMAUTH)
fr_authnext = 0;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
#ifdef _KERNEL
# if SOLARIS
if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) {
mutex_exit(&ipf_auth);
mutex_enter(&ipf_authmx);
if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) {
mutex_exit(&ipf_authmx);
return EINTR;
}
mutex_exit(&ipf_authmx);
# else
# ifdef linux
interruptible_sleep_on(&ipfauthwait);
@ -338,17 +371,17 @@ frentry_t *fr, **frptr;
# endif
# endif
#endif
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
if (!error)
goto fr_authioctlloop;
break;
case SIOCAUTHR:
IRCOPY(data, (caddr_t)&auth, sizeof(auth));
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
i = au->fra_index;
if ((i < 0) || (i > FR_NUMAUTH) ||
(fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) {
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return EINVAL;
}
m = fr_authpkts[i];
@ -356,14 +389,19 @@ frentry_t *fr, **frptr;
fr_auth[i].fra_pass = au->fra_pass;
fr_authpkts[i] = NULL;
#ifdef _KERNEL
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
SPL_NET(s);
# ifndef linux
if (m && au->fra_info.fin_out) {
# if SOLARIS
error = fr_qout(fr_auth[i].fra_q, m);
# else /* SOLARIS */
# if _BSDI_VERSION >= 199802
error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
NULL);
# else
error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
# endif
# endif /* SOLARIS */
if (error)
fr_authstats.fas_sendfail++;
@ -439,7 +477,7 @@ void fr_authunload()
register frauthent_t *fae, **faep;
mb_t *m;
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
for (i = 0; i < FR_NUMAUTH; i++) {
if ((m = fr_authpkts[i])) {
FREE_MB_T(m);
@ -453,7 +491,8 @@ void fr_authunload()
*faep = fae->fae_next;
KFREE(fae);
}
MUTEX_EXIT(&ipf_auth);
ipauth = NULL;
RWLOCK_EXIT(&ipf_auth);
}
@ -472,7 +511,7 @@ void fr_authexpire()
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
FREE_MB_T(m);
@ -484,14 +523,15 @@ void fr_authexpire()
}
for (faep = &fae_list; (fae = *faep); ) {
if (!--fra->fra_age) {
if (!--fae->fae_age) {
*faep = fae->fae_next;
KFREE(fae);
fr_authstats.fas_expire++;
} else
faep = &fae->fae_next;
}
MUTEX_EXIT(&ipf_auth);
ipauth = &fae_list->fae_fr;
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
#endif

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 1997 by Darren Reed & Guido Van Rooij.
* Copyright (C) 1997-1998 by Darren Reed & Guido Van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_auth.h,v 2.0.2.10 1997/10/29 12:14:07 darrenr Exp $
* $Id: ip_auth.h,v 2.1 1999/08/04 17:29:54 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@ -13,18 +13,6 @@
#define FR_NUMAUTH 32
typedef struct fr_authstat {
U_QUAD_T fas_hits;
U_QUAD_T fas_miss;
u_long fas_nospace;
u_long fas_added;
u_long fas_sendfail;
u_long fas_sendok;
u_long fas_queok;
u_long fas_quefail;
u_long fas_expire;
} fr_authstat_t;
typedef struct frauth {
int fra_age;
int fra_index;
@ -41,6 +29,19 @@ typedef struct frauthent {
u_long fae_age;
} frauthent_t;
typedef struct fr_authstat {
U_QUAD_T fas_hits;
U_QUAD_T fas_miss;
u_long fas_nospace;
u_long fas_added;
u_long fas_sendfail;
u_long fas_sendok;
u_long fas_queok;
u_long fas_quefail;
u_long fas_expire;
frauthent_t *fas_faelist;
} fr_authstat_t;
extern frentry_t *ipauth;
extern struct fr_authstat fr_authstats;
@ -49,7 +50,7 @@ extern int fr_authstart;
extern int fr_authend;
extern int fr_authsize;
extern int fr_authused;
extern int fr_checkauth __P((ip_t *, fr_info_t *));
extern u_32_t fr_checkauth __P((ip_t *, fr_info_t *));
extern void fr_authexpire __P((void));
extern void fr_authunload __P((void));
extern mb_t *fr_authpkts[];

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.0.2.31.2.11 1998/05/23 14:29:36 darrenr Exp $
* $Id: ip_compat.h,v 2.1.2.1 1999/09/18 15:03:51 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -17,33 +17,39 @@
# define __P(x) x
# else
# define __P(x) ()
# define const
# endif
#endif
#ifndef __STDC__
# undef const
# define const
#endif
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#if defined(_KERNEL) && !defined(KERNEL)
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
# undef _KERNEL
# undef __KERNEL__
# define KERNEL
#endif
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#if!defined(__KERNEL__) && defined(KERNEL)
# define __KERNEL__
#endif
#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
#define index strchr
# if !defined(_KERNEL)
# if !defined(KERNEL)
# define bzero(a,b) memset(a,0,b)
# define bcmp memcmp
# define bcopy(a,b,c) memmove(b,a,c)
# endif
#endif
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#if defined(__sgi) || defined(bsdi)
struct ether_addr {
u_char ether_addr_octet[6];
@ -69,6 +75,7 @@ struct ether_addr {
#endif
#if SOLARIS
# define MTYPE(m) ((m)->b_datap->db_type)
# include <sys/isa_defs.h>
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
# include <sys/kmem.h>
@ -80,7 +87,7 @@ struct ether_addr {
# undef IPOPT_LSRR
# undef IPOPT_RR
# undef IPOPT_SSRR
# ifndef _KERNEL
# ifndef KERNEL
# define _KERNEL
# undef RES_INIT
# include <inet/common.h>
@ -92,6 +99,10 @@ struct ether_addr {
# include <inet/ip.h>
# include <inet/ip_ire.h>
# endif /* _KERNEL */
#else
# if !defined(__sgi)
typedef int minor_t;
#endif
#endif /* SOLARIS */
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
@ -118,7 +129,7 @@ typedef u_int32_t u_32_t;
/*
* Really, any arch where sizeof(long) != sizeof(int).
*/
# if defined(__alpha__) || defined(__alpha)
# if defined(__alpha__) || defined(__alpha) || defined(_LP64)
typedef unsigned int u_32_t;
# else
typedef unsigned long u_32_t;
@ -201,7 +212,32 @@ typedef unsigned long u_32_t;
*/
#ifdef KERNEL
# if SOLARIS
# define MUTEX_ENTER(x) mutex_enter(x)
# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
mutex_exit(&ipf_rw); }
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
mutex_exit(&ipf_rw); }
# define MUTEX_ENTER(x) mutex_enter(x)
# if 1
# define KRWLOCK_T krwlock_t
# define READ_ENTER(x) rw_enter(x, RW_READER)
# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
# define RW_UPGRADE(x) { if (rw_tryupgrade(x) == 0) { \
rw_exit(x); \
rw_enter(x, RW_WRITER); } \
}
# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
# define RWLOCK_INIT(x, y, z) rw_init((x), (y), RW_DRIVER, (z))
# define RWLOCK_EXIT(x) rw_exit(x)
# define RW_DESTROY(x) rw_destroy(x)
# else
# define KRWLOCK_T kmutex_t
# define READ_ENTER(x) mutex_enter(x)
# define WRITE_ENTER(x) mutex_enter(x)
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
# define RWLOCK_EXIT(x) mutex_exit(x)
# define RW_DESTROY(x) mutex_destroy(x)
# endif
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
@ -217,7 +253,8 @@ typedef unsigned long u_32_t;
# define htons(x) (x)
# define htonl(x) (x)
# endif /* sparc */
# define KMALLOC(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
typedef struct qif {
struct qif *qf_next;
@ -233,18 +270,19 @@ typedef struct qif {
struct qinit qf_rqinit;
mblk_t *qf_m; /* These three fields are for passing data up from */
queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
int qf_off;
int qf_len; /* this field is used for in ipfr_fastroute */
size_t qf_off;
size_t qf_len; /* this field is used for in ipfr_fastroute */
char qf_name[8];
/*
* in case the ILL has disappeared...
*/
int qf_hl; /* header length */
size_t qf_hl; /* header length */
} qif_t;
extern ill_t *get_unit __P((char *));
# define GETUNIT(n) get_unit((n))
# else /* SOLARIS */
# if defined(__sgi)
# define hz HZ
# include <sys/ksynch.h>
# define IPF_LOCK_PL plhi
# include <sys/sema.h>
@ -253,10 +291,27 @@ typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
(x)--; MUTEX_EXIT(&ipf_rw); }
# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
# define KRWLOCK_T kmutex_t
# define READ_ENTER(x) MUTEX_ENTER(x)
# define WRITE_ENTER(x) MUTEX_ENTER(x)
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
# else /* __sgi */
# define MUTEX_ENTER(x) ;
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# endif /* __sgi */
# ifndef linux
@ -291,11 +346,14 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# ifdef __sgi
# include <sys/kmem.h>
# include <sys/ddi.h>
# define KMALLOC(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
# else
# if !SOLARIS
# define KMALLOC(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
# define KMALLOC(a,b) (a) = (b)new_kmem_alloc(sizeof(*(a)), \
KMEM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
# endif /* SOLARIS */
# endif /* __sgi */
# endif /* sun && !linux */
@ -312,11 +370,13 @@ extern vm_map_t kmem_map;
# include <vm/vm_kern.h>
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# ifdef M_PFIL
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFIL, M_NOWAIT)
# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
# define KFREE(x) FREE((x), M_PFIL)
# define KFREES(x,s) FREE((x), M_PFIL)
# else
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
# define KFREE(x) FREE((x), M_TEMP)
# define KFREES(x,s) FREE((x), M_TEMP)
# endif /* M_PFIL */
@ -339,13 +399,21 @@ extern vm_map_t kmem_map;
# define SLEEP(x,y) ;
# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# define SPL_NET(x) ;
# define SPL_IMP(x) ;
# undef SPL_X
# define SPL_X(x) ;
# define KMALLOC(a,b,c) (a) = (b)malloc(c)
# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a))
# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
# define GETUNIT(x) get_unit(x)
@ -355,9 +423,26 @@ extern vm_map_t kmem_map;
#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
@ -492,6 +577,7 @@ typedef struct mbuf mb_t;
#endif /* linux || __sgi */
#ifdef linux
#include <linux/in_systm.h>
/*
* TCP States
*/
@ -513,8 +599,13 @@ typedef struct mbuf mb_t;
/*
* file flags.
*/
#ifdef WRITE
#define FWRITE WRITE
#define FREAD READ
#else
#define FWRITE _IOC_WRITE
#define FREAD _IOC_READ
#endif
/*
* mbuf related problems.
*/
@ -522,7 +613,10 @@ typedef struct mbuf mb_t;
#define m_len len
#define m_next next
#define IP_DF 0x8000
#ifdef IP_DF
#undef IP_DF
#endif
#define IP_DF 0x4000
typedef struct {
__u16 th_sport;
@ -574,15 +668,15 @@ typedef struct {
* Structure of an icmp header.
*/
typedef struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */
__u8 icmp_type; /* type of message, see below */
__u8 icmp_code; /* type sub code */
__u16 icmp_cksum; /* ones complement cksum of struct */
union {
u_char ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
n_short icd_id;
n_short icd_seq;
__u8 ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
__u16 icd_id;
__u16 icd_seq;
} ih_idseq;
int ih_void;
} icmp_hun;
@ -664,7 +758,8 @@ typedef struct uio {
# define UNITNAME(n) dev_get((n))
# define KMALLOC(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
# define KMALLOC(a,b) (a) = (b)kmalloc(sizeof(*(a)), GFP_ATOMIC)
# define KMALLOCS(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
# define KFREE(x) kfree_s((x), sizeof(*(x)))
# define KFREES(x,s) kfree_s((x), (s))
# define IRCOPY(a,b,c) { \
@ -723,5 +818,14 @@ struct ether_addr {
#ifndef ICMP_ROUTERSOLICIT
# define ICMP_ROUTERSOLICIT 10
#endif
/*
* ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
* another IP header and then 64 bits of data, totalling 56. Of course,
* the last 64 bits is dependant on that being available.
*/
#define ICMPERR_ICMPHLEN 8
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
#endif /* __IP_COMPAT_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:49 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.7 1999/10/15 13:49:43 darrenr Exp $";
#endif
#ifndef SOLARIS
@ -17,6 +17,11 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#include <sys/param.h>
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
defined(_KERNEL)
# include "opt_ipfilter_log.h"
#endif
#ifdef __FreeBSD__
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
@ -29,10 +34,10 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
# include <fcntl.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#if __FreeBSD_version >= 220000 && defined(_KERNEL)
# include <sys/fcntl.h>
@ -46,7 +51,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#endif
#include <sys/uio.h>
#if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603)
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
# else
# include <sys/dir.h>
@ -64,6 +69,9 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#endif
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include "opt_ipfilter.h"
# endif
#endif
#ifdef __sgi
#include <sys/debug.h>
@ -74,7 +82,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#include <net/route.h>
#include <netinet/in.h>
#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */
#include <netinet/in_var.h>
# include <netinet/in_var.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@ -84,6 +92,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#ifndef _KERNEL
# include <unistd.h>
# include <syslog.h>
#endif
#include "netinet/ip_compat.h"
@ -93,10 +102,14 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:4
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_auth.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
#if !SOLARIS && defined(_KERNEL)
#ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#if !SOLARIS && defined(_KERNEL) && !defined(__sgi)
# include <sys/kernel.h>
extern int ip_optcopy __P((struct ip *, struct ip *));
#endif
@ -108,11 +121,6 @@ extern struct protosw inetsw[];
static struct ifnet **ifneta = NULL;
static int nifs = 0;
#else
# if (BSD < 199306) && !defined(__sgi)
static int (*fr_saveslowtimo) __P((void));
# else
static void (*fr_saveslowtimo) __P((void));
# endif
# if (BSD < 199306) || defined(__sgi)
extern int tcp_ttl;
# endif
@ -122,9 +130,7 @@ int ipl_inited = 0;
int ipl_unreach = ICMP_UNREACH_FILTER;
u_long ipl_frouteok[2] = {0, 0};
static void fixskip __P((frentry_t **, frentry_t *, int));
static void frzerostats __P((caddr_t));
static void frsync __P((void));
#if defined(__NetBSD__) || defined(__OpenBSD__)
static int frrequest __P((int, u_long, caddr_t, int));
#else
@ -132,6 +138,10 @@ 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((struct mbuf *, ip_t *));
# ifdef __sgi
extern kmutex_t ipf_rw;
# endif
#else
int ipllog __P((void));
void init_ifp __P((void));
@ -147,6 +157,15 @@ static int write_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *));
# endif
#endif
#if defined(IPFILTER_LKM)
int fr_running = 1;
#else
int fr_running = 0;
#endif
#if (__FreeBSD_version >= 300000) && defined(_KERNEL)
struct callout_handle ipfr_slowtimer_ch;
#endif
#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
# include <sys/device.h>
@ -195,7 +214,8 @@ void
ipfilterattach(count)
int count;
{
iplattach();
if (iplattach() != 0)
printf("IP Filter failed to attach\n");
}
# endif
@ -215,6 +235,16 @@ int iplattach()
return EBUSY;
}
# ifdef IPFILTER_LOG
ipflog_init();
# endif
if (nat_init() == -1)
return -1;
if (fr_stateinit() == -1)
return -1;
if (appr_init() == -1)
return -1;
# ifdef NETBSD_PF
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
@ -229,15 +259,9 @@ int iplattach()
ipl_inited = 1;
bzero((char *)frcache, sizeof(frcache));
bzero((char *)nat_table, sizeof(nat_table));
fr_savep = fr_checkp;
fr_checkp = fr_check;
fr_saveslowtimo = inetsw[0].pr_slowtimo;
inetsw[0].pr_slowtimo = ipfr_slowtimer;
# ifdef IPFILTER_LOG
ipflog_init();
# endif
SPL_X(s);
if (fr_pass & FR_PASS)
defpass = "pass";
@ -253,6 +277,14 @@ int iplattach()
# else
"disabled");
# endif
printf("%s\n", ipfilter_version);
#ifdef _KERNEL
# if (__FreeBSD_version >= 300000) && defined(_KERNEL)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
#endif
return 0;
}
@ -265,6 +297,17 @@ int ipldetach()
{
int s, i = FR_INQUE|FR_OUTQUE;
#ifdef _KERNEL
# if (__FreeBSD_version >= 300000)
untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch);
# else
# ifdef __sgi
untimeout(ipfr_slowtimer);
# else
untimeout(ipfr_slowtimer, NULL);
# endif
# endif
#endif
SPL_NET(s);
if (!ipl_inited)
{
@ -274,8 +317,7 @@ int ipldetach()
}
fr_checkp = fr_savep;
inetsw[0].pr_slowtimo = fr_saveslowtimo;
frflush(IPL_LOGIPF, &i);
i = frflush(IPL_LOGIPF, i);
ipl_inited = 0;
# ifdef NETBSD_PF
@ -300,7 +342,7 @@ int ipldetach()
static void frzerostats(data)
caddr_t data;
{
struct friostat fio;
friostat_t fio;
bcopy((char *)frstats, (char *)fio.f_st,
sizeof(struct filterstats) * 2);
@ -332,14 +374,15 @@ int IPL_EXTERN(ioctl)(dev_t dev, int cmd, caddr_t data, int mode
#else
int IPL_EXTERN(ioctl)(dev, cmd, data, mode
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
(__FreeBSD_version >= 220000) || defined(__OpenBSD__)) && defined(_KERNEL)
, p)
struct proc *p;
#else
)
#endif
dev_t dev;
#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
#if defined(__NetBSD__) || defined(__OpenBSD__) || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
u_long cmd;
#else
int cmd;
@ -353,10 +396,16 @@ int mode;
#endif
int error = 0, unit = 0, tmp;
#if (BSD >= 199306) && defined(_KERNEL)
if ((securelevel >= 2) && (mode & FWRITE))
return EPERM;
#endif
#ifdef _KERNEL
unit = GET_MINOR(dev);
if ((IPL_LOGMAX < unit) || (unit < 0))
return ENXIO;
#else
unit = dev;
#endif
SPL_NET(s);
@ -387,10 +436,15 @@ int mode;
error = EPERM;
else {
IRCOPY(data, (caddr_t)&enable, sizeof(enable));
if (enable)
if (enable) {
error = iplattach();
else
if (error == 0)
fr_running = 1;
} else {
error = ipldetach();
if (error == 0)
fr_running = 0;
}
}
break;
}
@ -448,6 +502,21 @@ int mode;
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
fio.f_running = fr_running;
fio.f_groups[0][0] = ipfgroups[0][0];
fio.f_groups[0][1] = ipfgroups[0][1];
fio.f_groups[1][0] = ipfgroups[1][0];
fio.f_groups[1][1] = ipfgroups[1][1];
fio.f_groups[2][0] = ipfgroups[2][0];
fio.f_groups[2][1] = ipfgroups[2][1];
#ifdef IPFILTER_LOG
fio.f_logging = 1;
#else
fio.f_logging = 0;
#endif
fio.f_defpass = fr_pass;
strncpy(fio.f_version, ipfilter_version,
sizeof(fio.f_version));
IWCOPY((caddr_t)&fio, data, sizeof(fio));
break;
}
@ -462,7 +531,7 @@ int mode;
error = EPERM;
else {
IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
frflush(unit, &tmp);
tmp = frflush(unit, tmp);
IWCOPY((caddr_t)&tmp, data, sizeof(tmp));
}
break;
@ -505,37 +574,62 @@ int mode;
}
static void frsync()
void frsync()
{
#ifdef _KERNEL
struct ifnet *ifp;
register frentry_t *f;
register struct ifnet *ifp;
# if defined(__OpenBSD__) || (NetBSD >= 199511)
# if defined(__OpenBSD__) || ((NetBSD >= 199511) && (NetBSD < 1991011)) || \
(defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
# if (NetBSD >= 199905) || defined(__OpenBSD__)
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
# else
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
# endif
# else
for (ifp = ifnet; ifp; ifp = ifp->if_next)
# endif
ip_natsync(ifp);
WRITE_ENTER(&ipf_mutex);
for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
RWLOCK_EXIT(&ipf_mutex);
#endif
}
static void fixskip(listp, rp, addremove)
frentry_t **listp, *rp;
int addremove;
void fr_forgetifp(ifp)
void *ifp;
{
frentry_t *fp;
int rules = 0, rn = 0;
register frentry_t *f;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
;
if (!fp)
return;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
if (fp->fr_skip && (rn + fp->fr_skip >= rules))
fp->fr_skip += addremove;
WRITE_ENTER(&ipf_mutex);
for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == ifp)
f->fr_ifa = (void *)-1;
for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == ifp)
f->fr_ifa = (void *)-1;
for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == ifp)
f->fr_ifa = (void *)-1;
for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == ifp)
f->fr_ifa = (void *)-1;
RWLOCK_EXIT(&ipf_mutex);
ip_natsync(ifp);
}
@ -554,20 +648,22 @@ caddr_t data;
frentry_t frd;
frdest_t *fdp;
frgroup_t *fg = NULL;
int error = 0, in, group;
int error = 0, in;
u_int group;
fp = &frd;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
fp->fr_ref = 0;
/*
* Check that the group number does exist and that if a head group
* has been specified, doesn't exist.
*/
if (fp->fr_grhead &&
fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
if ((req != SIOCZRLST) && fp->fr_grhead &&
fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL))
return EEXIST;
if (fp->fr_group &&
!fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
if ((req != SIOCZRLST) && fp->fr_group &&
!fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL))
return ESRCH;
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
@ -594,6 +690,13 @@ caddr_t data;
if (!fp->fr_ifa)
fp->fr_ifa = (void *)-1;
}
#if BSD >= 199306
if (*fp->fr_oifname) {
fp->fr_oifa = GETUNIT(fp->fr_oifname);
if (!fp->fr_oifa)
fp->fr_oifa = (void *)-1;
}
#endif
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
@ -655,8 +758,8 @@ caddr_t data;
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
if (f->fr_grhead)
fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
set);
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
unit, set);
fixskip(fprev, f, -1);
*ftail = f->fr_next;
KFREE(f);
@ -667,7 +770,7 @@ caddr_t data;
else {
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
KMALLOC(f, frentry_t *, sizeof(*f));
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
fg->fg_head->fr_ref++;
@ -693,33 +796,33 @@ caddr_t data;
/*
* routines below for saving IP headers to buffer
*/
#ifdef __sgi
# ifdef _KERNEL
# ifdef __sgi
# ifdef _KERNEL
int IPL_EXTERN(open)(dev_t *pdev, int flags, int devtype, cred_t *cp)
# else
# else
int IPL_EXTERN(open)(dev_t dev, int flags)
# endif
#else
# endif
# else
int IPL_EXTERN(open)(dev, flags
# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000) || defined(__OpenBSD__)) && defined(_KERNEL)
, devtype, p)
int devtype;
struct proc *p;
# else
# else
)
# endif
# endif
dev_t dev;
int flags;
#endif /* __sgi */
# endif /* __sgi */
{
#if defined(__sgi) && defined(_KERNEL)
# if defined(__sgi) && defined(_KERNEL)
u_int min = geteminor(*pdev);
#else
# else
u_int min = GET_MINOR(dev);
#endif
# endif
if (2 < min)
if (IPL_LOGMAX < min)
min = ENXIO;
else
min = 0;
@ -727,25 +830,25 @@ int flags;
}
#ifdef __sgi
# ifdef __sgi
int IPL_EXTERN(close)(dev_t dev, int flags, int devtype, cred_t *cp)
#else
int IPL_EXTERN(close)(dev, flags
# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000) || defined(__OpenBSD__)) && defined(_KERNEL)
, devtype, p)
int devtype;
struct proc *p;
# else
# else
)
# endif
# endif
dev_t dev;
int flags;
#endif /* __sgi */
# endif /* __sgi */
{
u_int min = GET_MINOR(dev);
if (2 < min)
if (IPL_LOGMAX < min)
min = ENXIO;
else
min = 0;
@ -758,9 +861,9 @@ int flags;
* called during packet processing and cause an inconsistancy to appear in
* the filter lists.
*/
#ifdef __sgi
# ifdef __sgi
int IPL_EXTERN(read)(dev_t dev, uio_t *uio, cred_t *crp)
#else
# else
# if BSD >= 199306
int IPL_EXTERN(read)(dev, uio, ioflag)
int ioflag;
@ -769,13 +872,13 @@ int IPL_EXTERN(read)(dev, uio)
# endif
dev_t dev;
register struct uio *uio;
#endif /* __sgi */
# endif /* __sgi */
{
# ifdef IPFILTER_LOG
# ifdef IPFILTER_LOG
return ipflog_read(GET_MINOR(dev), uio);
# else
# else
return ENXIO;
# endif
# endif
}
@ -783,55 +886,72 @@ register struct uio *uio;
* send_reset - this could conceivably be a call to tcp_respond(), but that
* requires a large amount of setting up and isn't any more efficient.
*/
int send_reset(ti)
struct tcpiphdr *ti;
int send_reset(fin, oip)
fr_info_t *fin;
struct ip *oip;
{
struct tcphdr *tcp, *tcp2;
struct tcpiphdr *tp;
struct tcphdr *tcp;
struct mbuf *m;
int tlen = 0, err;
int tlen = 0;
ip_t *ip;
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
struct route ro;
# endif
if (ti->ti_flags & TH_RST)
tcp = (struct tcphdr *)fin->fin_dp;
if (tcp->th_flags & TH_RST)
return -1; /* feedback loop */
# if (BSD < 199306) || defined(__sgi)
m = m_get(M_DONTWAIT, MT_HEADER);
# else
m = m_gethdr(M_DONTWAIT, MT_HEADER);
m->m_data += max_linkhdr;
# endif
if (m == NULL)
return ENOBUFS;
if (m == NULL)
return -1;
if (ti->ti_flags & TH_SYN)
if (tcp->th_flags & TH_SYN)
tlen = 1;
m->m_len = sizeof (struct tcpiphdr);
m->m_len = sizeof(*tcp2) + sizeof(*ip);
# if BSD >= 199306
m->m_pkthdr.len = sizeof (struct tcpiphdr);
m->m_data += max_linkhdr;
m->m_pkthdr.len = m->m_len;
m->m_pkthdr.rcvif = (struct ifnet *)0;
# endif
bzero(mtod(m, char *), sizeof(struct tcpiphdr));
ip = mtod(m, struct ip *);
tp = mtod(m, struct tcpiphdr *);
tcp = (struct tcphdr *)((char *)ip + sizeof(struct ip));
tcp2 = (struct tcphdr *)((char *)ip + sizeof(*ip));
ip->ip_src.s_addr = ti->ti_dst.s_addr;
ip->ip_dst.s_addr = ti->ti_src.s_addr;
tcp->th_dport = ti->ti_sport;
tcp->th_sport = ti->ti_dport;
tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen);
tcp->th_off = sizeof(struct tcphdr) >> 2;
tcp->th_flags = TH_RST|TH_ACK;
tp->ti_pr = ((struct ip *)ti)->ip_p;
ip->ip_src.s_addr = oip->ip_dst.s_addr;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
tcp2->th_dport = tcp->th_sport;
tcp2->th_sport = tcp->th_dport;
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
tcp2->th_off = sizeof(*tcp2) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
tp->ti_pr = oip->ip_p;
tp->ti_len = htons(sizeof(struct tcphdr));
tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr));
tcp2->th_sum = in_cksum(m, sizeof(*ip) + sizeof(*tcp2));
ip->ip_tos = oip->ip_tos;
ip->ip_p = oip->ip_p;
ip->ip_len = sizeof(*ip) + sizeof(*tcp2);
return send_ip(m, ip);
}
static int send_ip(m, ip)
struct mbuf *m;
ip_t *ip;
{
# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) || \
(defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802))
struct route ro;
# endif
ip->ip_tos = ((struct ip *)ti)->ip_tos;
ip->ip_p = ((struct ip *)ti)->ip_p;
ip->ip_len = sizeof (struct tcpiphdr);
# if (BSD < 199306) || defined(__sgi)
ip->ip_ttl = tcp_ttl;
# else
@ -839,17 +959,91 @@ struct tcpiphdr *ti;
# endif
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
{
int err;
bzero((char *)&ro, sizeof(ro));
err = ip_output(m, (struct mbuf *)0, &ro, 0, 0);
if (ro.ro_rt)
RTFREE(ro.ro_rt);
return err;
}
# else
/*
* extra 0 in case of multicast
*/
err = ip_output(m, (struct mbuf *)0, 0, 0, 0);
# if _BSDI_VERSION >= 199802
return ip_output(m, (struct mbuf *)0, &ro, 0, 0, NULL);
# else
return ip_output(m, (struct mbuf *)0, 0, 0, 0);
# endif
# endif
return err;
}
int send_icmp_err(oip, type, code, ifp, dst)
ip_t *oip;
int type, code;
void *ifp;
struct in_addr dst;
{
struct icmp *icmp;
struct mbuf *m;
ip_t *nip;
# if (BSD < 199306) || defined(__sgi)
m = m_get(M_DONTWAIT, MT_HEADER);
# else
m = m_gethdr(M_DONTWAIT, MT_HEADER);
# endif
if (m == NULL)
return ENOBUFS;
m->m_len = sizeof(*nip) + sizeof(*icmp) + 8;
# if BSD >= 199306
m->m_data += max_linkhdr;
m->m_pkthdr.len = sizeof(*nip) + sizeof(*icmp) + 8;
m->m_pkthdr.rcvif = (struct ifnet *)0;
# endif
bzero(mtod(m, char *), (size_t)sizeof(*nip) + sizeof(*icmp) + 8);
nip = mtod(m, ip_t *);
icmp = (struct icmp *)(nip + 1);
nip->ip_v = IPVERSION;
nip->ip_hl = (sizeof(*nip) >> 2);
nip->ip_p = IPPROTO_ICMP;
nip->ip_id = oip->ip_id;
nip->ip_sum = 0;
nip->ip_ttl = 60;
nip->ip_tos = oip->ip_tos;
nip->ip_len = sizeof(*nip) + sizeof(*icmp) + 8;
if (dst.s_addr == 0) {
if (fr_ifpaddr(ifp, &dst) == -1)
return -1;
dst.s_addr = htonl(dst.s_addr);
}
nip->ip_src = dst;
nip->ip_dst = oip->ip_src;
icmp->icmp_type = type;
icmp->icmp_code = code;
icmp->icmp_cksum = 0;
bcopy((char *)oip, (char *)&icmp->icmp_ip, sizeof(*oip));
bcopy((char *)oip + (oip->ip_hl << 2),
(char *)&icmp->icmp_ip + sizeof(*oip), 8); /* 64 bits */
# ifndef sparc
{
register u_short __iplen, __ipoff;
ip_t *ip = &icmp->icmp_ip;
__iplen = ip->ip_len;
__ipoff = ip->ip_off;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
}
# endif
icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8);
return send_ip(m, nip);
}
@ -865,7 +1059,8 @@ void
# endif
iplinit()
{
(void) iplattach();
if (iplattach() != 0)
printf("IP Filter failed to attach\n");
ip_init();
}
# endif /* ! __NetBSD__ */
@ -882,7 +1077,7 @@ register struct mbuf *m0;
}
void ipfr_fastroute(m0, fin, fdp)
int ipfr_fastroute(m0, fin, fdp)
struct mbuf *m0;
fr_info_t *fin;
frdest_t *fdp;
@ -890,12 +1085,13 @@ frdest_t *fdp;
register struct ip *ip, *mhip;
register struct mbuf *m = m0;
register struct route *ro;
struct ifnet *ifp = fdp->fd_ifp;
int len, off, error = 0;
int hlen = fin->fin_hlen;
struct route iproute;
int len, off, error = 0, hlen;
struct sockaddr_in *dst;
struct route iproute;
struct ifnet *ifp;
frentry_t *fr;
hlen = fin->fin_hlen;
ip = mtod(m0, struct ip *);
/*
* Route packet.
@ -904,13 +1100,22 @@ frdest_t *fdp;
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
fr = fin->fin_fr;
ifp = fdp->fd_ifp;
/*
* In case we're here due to "to <if>" being used with "keep state",
* check that we're going in the correct direction.
*/
if ((fr != NULL) && (ifp != NULL) && (fin->fin_rev != 0) &&
(fdp == &fr->fr_tif))
return -1;
# ifdef __bsdi__
dst->sin_len = sizeof(*dst);
# endif
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
!defined(__OpenBSD__)
# ifdef RTF_CLONING
# ifdef RTF_CLONING
rtalloc_ign(ro, RTF_CLONING);
# else
rtalloc_ign(ro, RTF_PRCLONING);
@ -939,10 +1144,19 @@ frdest_t *fdp;
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
* NAT'd.
* NAT'd and counted.
*/
(void) ip_natout(ip, hlen, fin);
if (fin->fin_out)
fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
fin->fin_out = 1;
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
ATOMIC_INC(frstats[1].fr_acct);
}
fin->fin_fr = NULL;
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
} else
ip->ip_sum = 0;
/*
* If small enough for interface, can just send directly.
@ -988,7 +1202,11 @@ frdest_t *fdp;
m0 = m;
mhlen = sizeof (struct ip);
for (off = hlen + len; off < ip->ip_len; off += len) {
# ifdef MGETHDR
MGETHDR(m, M_DONTWAIT, MT_HEADER);
# else
MGET(m, M_DONTWAIT, MT_HEADER);
# endif
if (m == 0) {
error = ENOBUFS;
goto bad;
@ -1057,10 +1275,9 @@ frdest_t *fdp;
else
ipl_frouteok[1]++;
if (ro->ro_rt) {
if (ro->ro_rt)
RTFREE(ro->ro_rt);
}
return;
return 0;
bad:
m_freem(m);
goto done;
@ -1068,53 +1285,50 @@ frdest_t *fdp;
#else /* #ifdef _KERNEL */
#ifdef __sgi
# ifdef __sgi
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
#else
# else
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s, struct rtentry *rt))
#endif
# endif
{
return 0;
}
# ifdef __STDC__
#ifdef __sgi
# ifdef __sgi
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
#else
# else
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s, struct rtentry *rt))
#endif
{
# if !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
ip_t *ip = (ip_t *)m;
# endif
{
ip_t *ip = (ip_t *)m;
# else
static int write_output(ifp, ip)
struct ifnet *ifp;
ip_t *ip;
{
# endif
FILE *fp;
char fname[32];
int fd;
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
sprintf(fname, "/tmp/%s", ifp->if_xname);
if ((fp = fopen(fname, "a"))) {
fclose(fp);
}
# else
sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
if ((fp = fopen(fname, "a"))) {
fwrite((char *)ip, ntohs(ip->ip_len), 1, fp);
fclose(fp);
}
# endif
fd = open(fname, O_WRONLY|O_APPEND);
if (fd == -1) {
perror("open");
return -1;
}
write(fd, (char *)ip, ntohs(ip->ip_len));
close(fd);
return 0;
}
@ -1177,30 +1391,37 @@ char *name;
void init_ifp()
{
FILE *fp;
struct ifnet *ifp, **ifa;
char fname[32];
int fd;
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
ifp->if_output = write_output;
sprintf(fname, "/tmp/%s", ifp->if_xname);
if ((fp = fopen(fname, "w")))
fclose(fp);
fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
if (fd == -1)
perror("open");
else
close(fd);
}
# else
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
ifp->if_output = write_output;
sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
if ((fp = fopen(fname, "w")))
fclose(fp);
fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
if (fd == -1)
perror("open");
else
close(fd);
}
# endif
}
void ipfr_fastroute(ip, fin, fdp)
int ipfr_fastroute(ip, fin, fdp)
ip_t *ip;
fr_info_t *fin;
frdest_t *fdp;
@ -1208,7 +1429,7 @@ frdest_t *fdp;
struct ifnet *ifp = fdp->fd_ifp;
if (!ifp)
return; /* no routing table out here */
return 0; /* no routing table out here */
ip->ip_len = htons((u_short)ip->ip_len);
ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
@ -1218,6 +1439,7 @@ frdest_t *fdp;
#else
(*ifp->if_output)(ifp, (void *)ip, NULL, 0);
#endif
return 0;
}

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_fil.h,v 2.0.2.39.2.11 1998/05/23 14:29:37 darrenr Exp $
* $Id: ip_fil.h,v 2.3.2.4 1999/10/15 13:42:37 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -21,11 +21,11 @@
#define IPAUTH_NAME "/dev/ipauth"
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#if defined(KERNEL) && !defined(_KERNEL)
#define _KERNEL
# define _KERNEL
#endif
#ifndef __P
@ -37,45 +37,45 @@
#endif
#if defined(__STDC__) || defined(__GNUC__)
#define SIOCADAFR _IOW('r', 60, struct frentry)
#define SIOCRMAFR _IOW('r', 61, struct frentry)
#define SIOCSETFF _IOW('r', 62, u_int)
#define SIOCGETFF _IOR('r', 63, u_int)
#define SIOCGETFS _IOR('r', 64, struct friostat)
#define SIOCIPFFL _IOWR('r', 65, int)
#define SIOCIPFFB _IOR('r', 66, int)
#define SIOCADIFR _IOW('r', 67, struct frentry)
#define SIOCRMIFR _IOW('r', 68, struct frentry)
#define SIOCSWAPA _IOR('r', 69, u_int)
#define SIOCINAFR _IOW('r', 70, struct frentry)
#define SIOCINIFR _IOW('r', 71, struct frentry)
#define SIOCFRENB _IOW('r', 72, u_int)
#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 SIOCATHST _IOWR('r', 78, struct fr_authstat)
# define SIOCADAFR _IOW('r', 60, struct frentry)
# define SIOCRMAFR _IOW('r', 61, struct frentry)
# define SIOCSETFF _IOW('r', 62, u_int)
# define SIOCGETFF _IOR('r', 63, u_int)
# define SIOCGETFS _IOR('r', 64, struct friostat)
# define SIOCIPFFL _IOWR('r', 65, int)
# define SIOCIPFFB _IOR('r', 66, int)
# define SIOCADIFR _IOW('r', 67, struct frentry)
# define SIOCRMIFR _IOW('r', 68, struct frentry)
# define SIOCSWAPA _IOR('r', 69, u_int)
# define SIOCINAFR _IOW('r', 70, struct frentry)
# define SIOCINIFR _IOW('r', 71, struct frentry)
# define SIOCFRENB _IOW('r', 72, u_int)
# 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 SIOCATHST _IOWR('r', 78, struct fr_authstat)
#else
#define SIOCADAFR _IOW(r, 60, struct frentry)
#define SIOCRMAFR _IOW(r, 61, struct frentry)
#define SIOCSETFF _IOW(r, 62, u_int)
#define SIOCGETFF _IOR(r, 63, u_int)
#define SIOCGETFS _IOR(r, 64, struct friostat)
#define SIOCIPFFL _IOWR(r, 65, int)
#define SIOCIPFFB _IOR(r, 66, int)
#define SIOCADIFR _IOW(r, 67, struct frentry)
#define SIOCRMIFR _IOW(r, 68, struct frentry)
#define SIOCSWAPA _IOR(r, 69, u_int)
#define SIOCINAFR _IOW(r, 70, struct frentry)
#define SIOCINIFR _IOW(r, 71, struct frentry)
#define SIOCFRENB _IOW(r, 72, u_int)
#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 SIOCATHST _IOWR(r, 78, struct fr_authstat)
# define SIOCADAFR _IOW(r, 60, struct frentry)
# define SIOCRMAFR _IOW(r, 61, struct frentry)
# define SIOCSETFF _IOW(r, 62, u_int)
# define SIOCGETFF _IOR(r, 63, u_int)
# define SIOCGETFS _IOR(r, 64, struct friostat)
# define SIOCIPFFL _IOWR(r, 65, int)
# define SIOCIPFFB _IOR(r, 66, int)
# define SIOCADIFR _IOW(r, 67, struct frentry)
# define SIOCRMIFR _IOW(r, 68, struct frentry)
# define SIOCSWAPA _IOR(r, 69, u_int)
# define SIOCINAFR _IOW(r, 70, struct frentry)
# define SIOCINIFR _IOW(r, 71, struct frentry)
# define SIOCFRENB _IOW(r, 72, u_int)
# 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 SIOCATHST _IOWR(r, 78, struct fr_authstat)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
@ -84,47 +84,61 @@
typedef struct fr_ip {
u_char fi_v:4; /* IP version */
u_char fi_fl:4; /* packet flags */
u_char fi_tos;
u_char fi_ttl;
u_char fi_p;
struct in_addr fi_src;
struct in_addr fi_dst;
u_char fi_tos; /* IP packet TOS */
u_char fi_ttl; /* IP packet TTL */
u_char fi_p; /* IP packet protocol */
struct in_addr fi_src; /* source address from packet */
struct in_addr fi_dst; /* destination address from packet */
u_32_t fi_optmsk; /* bitmask composed from IP options */
u_short fi_secmsk; /* bitmask composed from IP security options */
u_short fi_auth;
u_short fi_auth; /* authentication code from IP sec. options */
} fr_ip_t;
#define FI_OPTIONS (FF_OPTIONS >> 24)
#define FI_TCPUDP (FF_TCPUDP >> 24) /* TCP/UCP implied comparison*/
#define FI_FRAG (FF_FRAG >> 24)
#define FI_SHORT (FF_SHORT >> 24)
#define FI_CMP (FI_OPTIONS|FI_TCPUDP|FI_SHORT)
/*
* These are both used by the state and NAT code to indicate that one port or
* the other should be treated as a wildcard.
*/
#define FI_W_SPORT 0x00000100
#define FI_W_DPORT 0x00000200
typedef struct fr_info {
struct fr_ip fin_fi;
u_short fin_data[2];
u_short fin_out;
u_short fin_hlen;
u_char fin_tcpf;
u_char fin_icode; /* From here on is packet specific */
u_short fin_rule;
u_short fin_group;
u_short fin_dlen;
u_short fin_id;
void *fin_ifp;
struct frentry *fin_fr;
void *fin_ifp; /* interface packet is `on' */
struct fr_ip fin_fi; /* IP Packet summary */
u_short fin_data[2]; /* TCP/UDP ports, ICMP code/type */
u_char fin_out; /* in or out ? 1 == out, 0 == in */
u_char fin_rev; /* state only: 1 = reverse */
u_short fin_hlen; /* length of IP header in bytes */
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_short fin_group; /* group number, -1 for none */
struct frentry *fin_fr; /* last matching rule */
char *fin_dp; /* start of data past IP header */
void *fin_mp;
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 */
#if SOLARIS && defined(_KERNEL)
void *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qif;
#endif
} fr_info_t;
/*
* Size for compares on fr_info structures
*/
#define FI_CSIZE (sizeof(struct fr_ip) + sizeof(u_short) * 4 + \
sizeof(u_char))
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
/*
* Size for copying cache fr_info structure
*/
#define FI_COPYSIZE (sizeof(fr_info_t) - sizeof(void *) * 2)
#define FI_COPYSIZE offsetof(fr_info_t, fin_dp)
typedef struct frdest {
void *fd_ifp;
@ -139,6 +153,9 @@ typedef struct frentry {
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
void *fr_ifa;
#if BSD >= 199306
void *fr_oifa;
#endif
/*
* These are only incremented when a packet matches this rule and
* it is the last match
@ -164,10 +181,14 @@ typedef struct frentry {
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
u_32_t fr_flags; /* per-rule flags && options (see below) */
int fr_skip; /* # of rules to skip */
u_short fr_skip; /* # of rules to skip */
u_short fr_loglevel; /* syslog log facility + priority */
int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
#if BSD >= 199306
char fr_oifname[IFNAMSIZ];
#endif
struct frdest fr_tif; /* "to" interface */
struct frdest fr_dif; /* duplicate packet interfaces */
} frentry_t;
@ -199,6 +220,7 @@ typedef struct frentry {
#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
#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 */
#define FR_NOMATCH 0x00200 /* no match occured */
#define FR_ACCOUNT 0x00400 /* count packet bytes */
#define FR_KEEPFRAG 0x00800 /* keep fragment information */
@ -213,8 +235,10 @@ typedef struct frentry {
#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
#define FR_AUTH 0x200000 /* use authentication */
#define FR_PREAUTH 0x400000 /* require preauthentication */
#define FR_DONTCACHE 0x800000 /* don't cache the result */
#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
#define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP)
/*
* These correspond to #define's for FI_* and are stored in fr_flags
@ -262,6 +286,8 @@ typedef struct filterstats {
u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
#if SOLARIS
u_long fr_notdata; /* PROTO/PCPROTO that have no data */
u_long fr_nodata; /* mblks that have no data */
u_long fr_bad; /* bad IP packets to the filter */
u_long fr_notip; /* packets passed through no on ip queue */
u_long fr_drop; /* packets dropped - no info for them! */
@ -278,8 +304,13 @@ typedef struct friostat {
struct frentry *f_acctin[2];
struct frentry *f_acctout[2];
struct frentry *f_auth;
struct frgroup *f_groups[3][2];
u_long f_froute[2];
int f_active;
int f_active; /* 1 or 0 - active rule set */
int f_defpass; /* default pass - from fr_pass */
int f_running; /* 1 if running, else 0 */
int f_logging; /* 1 if enabled, else 0 */
char f_version[32]; /* version string */
} friostat_t;
typedef struct optlist {
@ -305,11 +336,10 @@ typedef struct frgroup {
* structure which is then followed by any packet data.
*/
typedef struct iplog {
u_long ipl_magic;
u_32_t ipl_magic;
u_int ipl_count;
u_long ipl_sec;
u_long ipl_usec;
u_int ipl_len;
u_int ipl_count;
size_t ipl_dsize;
struct iplog *ipl_next;
} iplog_t;
@ -328,19 +358,21 @@ typedef struct ipflog {
u_char fl_hlen; /* length of IP headers saved */
u_short fl_rule; /* assume never more than 64k rules, total */
u_short fl_group;
u_short fl_loglevel; /* syslog log level */
u_32_t fl_flags;
u_32_t fl_lflags;
} ipflog_t;
#ifndef ICMP_UNREACH_FILTER
#define ICMP_UNREACH_FILTER 13
# define ICMP_UNREACH_FILTER 13
#endif
#ifndef IPF_LOGGING
#define IPF_LOGGING 0
# define IPF_LOGGING 0
#endif
#ifndef IPF_DEFAULT_PASS
#define IPF_DEFAULT_PASS FR_PASS
# define IPF_DEFAULT_PASS FR_PASS
#endif
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
@ -372,16 +404,32 @@ typedef struct ipflog {
# define CDEV_MAJOR 79
#endif
/*
* Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
* on those hooks. We don't need any special mods in non-IP Filter code
* with this!
*/
#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
(defined(NetBSD1_2) && NetBSD1_2 > 1)
# if (NetBSD >= 199905)
# define PFIL_HOOKS
# endif
# ifdef PFIL_HOOKS
# define NETBSD_PF
# endif
#endif
#ifndef _KERNEL
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 ipf_log __P((void));
extern void ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
extern int ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
extern struct ifnet *get_unit __P((char *));
# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
# if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
extern int iplioctl __P((dev_t, u_long, caddr_t, int));
# else
extern int iplioctl __P((dev_t, int, caddr_t, int));
@ -390,31 +438,34 @@ extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
#else /* #ifndef _KERNEL */
# if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern int ipfilterattach __P((int));
extern void ipfilterattach __P((int));
# endif
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((int));
extern int ipflog_read __P((int, struct uio *));
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, u_long, void **, size_t *, int *, int));
extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
# if SOLARIS
extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *,
int, qif_t *, mb_t **));
extern int icmp_error __P((ip_t *, int, int, qif_t *,
struct in_addr));
extern int iplioctl __P((dev_t, int, int, int, cred_t *, int *));
extern int icmp_error __P((ip_t *, int, int, qif_t *, struct in_addr));
# if SOLARIS2 >= 7
extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
# else
extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
# endif
extern int iplopen __P((dev_t *, int, int, cred_t *));
extern int iplclose __P((dev_t, int, int, cred_t *));
extern int ipfsync __P((void));
extern int send_reset __P((ip_t *, qif_t *));
extern int send_reset __P((fr_info_t *, ip_t *, qif_t *));
extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **,
fr_info_t *, frdest_t *));
extern void copyin_mblk __P((mblk_t *, int, int, char *));
extern void copyout_mblk __P((mblk_t *, int, int, char *));
extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *));
extern void copyout_mblk __P((mblk_t *, size_t, size_t, char *));
extern int fr_qin __P((queue_t *, mblk_t *));
extern int fr_qout __P((queue_t *, mblk_t *));
# ifdef IPFILTER_LOG
@ -426,9 +477,10 @@ extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
# ifdef linux
extern int send_reset __P((tcpiphdr_t *, struct ifnet *));
# else
extern int send_reset __P((tcpiphdr_t *));
extern int send_reset __P((fr_info_t *, struct ip *));
extern int send_icmp_err __P((ip_t *, int, int, void *, struct in_addr));
# endif
extern void ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
extern size_t mbufchainlen __P((mb_t *));
# ifdef __sgi
# include <sys/cred.h>
@ -445,8 +497,9 @@ extern void ipfilter_sgi_intfsync __P((void));
extern int iplidentify __P((char *));
# endif
# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
(NetBSD >= 199511)
# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701)
(NetBSD >= 199511) || defined(__OpenBSD__)
# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \
defined(__OpenBSD__) || (__FreeBSD_version >= 300000)
extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
# else
extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
@ -454,19 +507,12 @@ extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
extern int iplopen __P((dev_t, int, int, struct proc *));
extern int iplclose __P((dev_t, int, int, struct proc *));
# else
# if defined(__OpenBSD__)
extern int iplioctl __P((dev_t, u_long, caddr_t, int));
# else /* __OpenBSD__ */
# ifndef linux
extern int iplioctl __P((dev_t, int, caddr_t, int));
# else
extern int iplioctl(struct inode *, struct file *, u_int, u_long);
# endif
# endif /* __OpenBSD__ */
# ifndef linux
# ifndef linux
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
extern int iplioctl __P((dev_t, int, caddr_t, int));
# else
extern int iplioctl(struct inode *, struct file *, u_int, u_long);
extern int iplopen __P((struct inode *, struct file *));
extern void iplclose __P((struct inode *, struct file *));
# endif /* !linux */
@ -484,26 +530,22 @@ extern int iplread(struct inode *, struct file *, char *, int);
# endif /* SOLARIS */
#endif /* #ifndef _KERNEL */
/*
* Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
* on those hooks. We don't need any special mods in non-IP Filter code
* with this!
*/
#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
(defined(NetBSD1_2) && NetBSD1_2 > 1)
# define NETBSD_PF
#endif
extern void fixskip __P((frentry_t **, frentry_t *, int));
extern int countbits __P((u_32_t));
extern int ipldetach __P((void));
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *, int));
#define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
extern int fr_scanlist __P((int, ip_t *, fr_info_t *, void *));
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
extern u_short ipf_cksum __P((u_short *, int));
extern int fr_copytolog __P((int, char *, int));
extern void frflush __P((int, int *));
extern frgroup_t *fr_addgroup __P((u_short, frentry_t *, int, int));
extern frgroup_t *fr_findgroup __P((u_short, u_32_t, int, int, frgroup_t ***));
extern void fr_delgroup __P((u_short, u_32_t, int, int));
extern void fr_forgetifp __P((void *));
extern int frflush __P((minor_t, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_int, frentry_t *, minor_t, int));
extern frgroup_t *fr_findgroup __P((u_int, u_32_t, minor_t, int, frgroup_t ***));
extern void fr_delgroup __P((u_int, u_32_t, minor_t, int));
extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
extern int fr_ifpaddr __P((void *, struct in_addr *));
extern char *memstr __P((char *, char *, int, int));
extern int ipl_unreach;
extern int ipl_inited;
extern u_long ipl_frouteok[2];
@ -511,9 +553,10 @@ extern int fr_pass;
extern int fr_flags;
extern int fr_active;
extern fr_info_t frcache[2];
extern char ipfilter_version[];
#ifdef IPFILTER_LOG
extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
extern int iplused[IPL_LOGMAX + 1];
extern size_t iplused[IPL_LOGMAX + 1];
#endif
extern struct frentry *ipfilter[2][2], *ipacct[2][2];
extern struct frgroup *ipfgroups[3][2];

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,53 +7,62 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:21 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.3 1999/09/18 15:03:54 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <string.h>
# include <stdlib.h>
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
#include <sys/filio.h>
#include <sys/fcntl.h>
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
#include <sys/ioctl.h>
# include <sys/ioctl.h>
#endif
#include <sys/uio.h>
#ifndef linux
#include <sys/protosw.h>
# include <sys/protosw.h>
#endif
#include <sys/socket.h>
#if defined(_KERNEL) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
# if defined(_KERNEL) && !defined(__sgi)
# include <sys/kernel.h>
# endif
# ifndef linux
# include <sys/mbuf.h>
# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# ifdef _KERNEL
# include <sys/dditypes.h>
# endif
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#include <net/if.h>
#ifdef sun
#include <net/af.h>
# include <net/af.h>
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifndef linux
#include <netinet/ip_var.h>
# include <netinet/ip_var.h>
#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
@ -66,6 +75,17 @@ static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_auth.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# if (defined(KERNEL) || defined(_KERNEL))
# ifndef IPFILTER_LKM
# include <sys/libkern.h>
# include <sys/systm.h>
# endif
extern struct callout_handle ipfr_slowtimer_ch;
# endif
#endif
ipfr_t *ipfr_heads[IPFT_SIZE];
ipfr_t *ipfr_nattab[IPFT_SIZE];
@ -73,17 +93,26 @@ ipfrstat_t ipfr_stats;
int ipfr_inuse = 0,
fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
# if SOLARIS2 >= 7
extern timeout_id_t ipfr_timer_id;
# else
extern int ipfr_timer_id;
# endif
#endif
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_frag;
extern kmutex_t ipf_natfrag;
extern kmutex_t ipf_nat;
extern KRWLOCK_T ipf_frag, ipf_natfrag, ipf_nat, ipf_mutex;
# if SOLARIS
extern KRWLOCK_T ipf_solaris;
# else
KRWLOCK_T ipf_solaris;
# endif
extern kmutex_t ipf_rw;
#endif
static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, int, ipfr_t **));
static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, u_int, ipfr_t **));
static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, ipfr_t **));
static void ipfr_delete __P((ipfr_t *));
ipfrstat_t *ipfr_fragstats()
@ -102,10 +131,10 @@ ipfrstat_t *ipfr_fragstats()
static ipfr_t *ipfr_new(ip, fin, pass, table)
ip_t *ip;
fr_info_t *fin;
int pass;
u_int pass;
ipfr_t *table[];
{
ipfr_t **fp, *fr, frag;
ipfr_t **fp, *fra, frag;
u_int idx;
frag.ipfr_p = ip->ip_p;
@ -123,10 +152,10 @@ ipfr_t *table[];
/*
* first, make sure it isn't already there...
*/
for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src,
for (fp = &table[idx]; (fra = *fp); fp = &fra->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fra->ipfr_src,
IPFR_CMPSZ)) {
ipfr_stats.ifs_exists++;
ATOMIC_INC(ipfr_stats.ifs_exists);
return NULL;
}
@ -134,45 +163,49 @@ ipfr_t *table[];
* allocate some memory, if possible, if not, just record that we
* failed to do so.
*/
KMALLOC(fr, ipfr_t *, sizeof(*fr));
if (fr == NULL) {
ipfr_stats.ifs_nomem++;
KMALLOC(fra, ipfr_t *);
if (fra == NULL) {
ATOMIC_INC(ipfr_stats.ifs_nomem);
return NULL;
}
if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
ATOMIC_INC(fin->fin_fr->fr_ref);
}
/*
* Instert the fragment into the fragment table, copy the struct used
* in the search using bcopy rather than reassign each field.
* Set the ttl to the default and mask out logging from "pass"
*/
if ((fr->ipfr_next = table[idx]))
table[idx]->ipfr_prev = fr;
fr->ipfr_prev = NULL;
fr->ipfr_data = NULL;
table[idx] = fr;
bcopy((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ);
fr->ipfr_ttl = fr_ipfrttl;
fr->ipfr_pass = pass & ~(FR_LOGFIRST|FR_LOG);
if ((fra->ipfr_next = table[idx]))
table[idx]->ipfr_prev = fra;
fra->ipfr_prev = NULL;
fra->ipfr_data = NULL;
table[idx] = fra;
bcopy((char *)&frag.ipfr_src, (char *)&fra->ipfr_src, IPFR_CMPSZ);
fra->ipfr_ttl = fr_ipfrttl;
/*
* Compute the offset of the expected start of the next packet.
*/
fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3);
ipfr_stats.ifs_new++;
ipfr_inuse++;
return fr;
fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
ATOMIC_INC(ipfr_stats.ifs_new);
ATOMIC_INC(ipfr_inuse);
return fra;
}
int ipfr_newfrag(ip, fin, pass)
ip_t *ip;
fr_info_t *fin;
int pass;
u_int pass;
{
ipfr_t *ipf;
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
return ipf ? 0 : -1;
}
@ -180,17 +213,18 @@ int pass;
int ipfr_nat_newfrag(ip, fin, pass, nat)
ip_t *ip;
fr_info_t *fin;
int pass;
u_int pass;
nat_t *nat;
{
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
ipf->ipfr_data = nat;
nat->nat_data = ipf;
}
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
return ipf ? 0 : -1;
}
@ -251,13 +285,13 @@ ipfr_t *table[];
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
if ((off & 0x1fff) == f->ipfr_off) {
if ((off & IP_OFFMASK) == f->ipfr_off) {
if (!(off & IP_MF))
f->ipfr_ttl = 1;
else
f->ipfr_off = atoff;
}
ipfr_stats.ifs_hits++;
ATOMIC_INC(ipfr_stats.ifs_hits);
return f;
}
return NULL;
@ -274,20 +308,20 @@ fr_info_t *fin;
nat_t *nat;
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf) {
if (ipf != NULL) {
nat = ipf->ipfr_data;
/*
* This is the last fragment for this packet.
*/
if (ipf->ipfr_ttl == 1) {
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
} else
nat = NULL;
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
return nat;
}
@ -295,18 +329,19 @@ fr_info_t *fin;
/*
* functional interface for normal lookups of the fragment cache
*/
int ipfr_knownfrag(ip, fin)
frentry_t *ipfr_knownfrag(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
int ret;
ipfr_t *ipf;
frentry_t *fr = NULL;
ipfr_t *fra;
MUTEX_ENTER(&ipf_frag);
ipf = ipfr_lookup(ip, fin, ipfr_heads);
ret = ipf ? ipf->ipfr_pass : 0;
MUTEX_EXIT(&ipf_frag);
return ret;
READ_ENTER(&ipf_frag);
fra = ipfr_lookup(ip, fin, ipfr_heads);
if (fra != NULL)
fr = fra->ipfr_rule;
RWLOCK_EXIT(&ipf_frag);
return fr;
}
@ -319,13 +354,32 @@ void *nat;
ipfr_t *fr;
int idx;
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
if (fr->ipfr_data == nat)
fr->ipfr_data = NULL;
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
}
static void ipfr_delete(fra)
ipfr_t *fra;
{
frentry_t *fr;
fr = fra->ipfr_rule;
if (fr != NULL) {
ATOMIC_DEC(fr->fr_ref);
if (fr->fr_ref == 0)
KFREE(fr);
}
if (fra->ipfr_prev)
fra->ipfr_prev->ipfr_next = fra->ipfr_next;
if (fra->ipfr_next)
fra->ipfr_next->ipfr_prev = fra->ipfr_prev;
KFREE(fra);
}
@ -334,31 +388,32 @@ void *nat;
*/
void ipfr_unload()
{
ipfr_t **fp, *fr;
ipfr_t **fp, *fra;
nat_t *nat;
int idx;
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
KFREE(fr);
for (fp = &ipfr_heads[idx]; (fra = *fp); ) {
*fp = fra->ipfr_next;
ipfr_delete(fra);
}
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
MUTEX_ENTER(&ipf_nat);
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
if ((nat = (nat_t *)fr->ipfr_data)) {
if (nat->nat_data == fr)
for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
*fp = fra->ipfr_next;
nat = fra->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fra)
nat->nat_data = NULL;
}
KFREE(fr);
ipfr_delete(fra);
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
}
@ -368,21 +423,36 @@ void ipfr_unload()
* of this being called twice per second.
*/
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
# else
void ipfr_slowtimer __P((void *ptr))
# endif
# else
int ipfr_slowtimer()
# endif
{
ipfr_t **fp, *fr;
ipfr_t **fp, *fra;
nat_t *nat;
int s, idx;
int idx;
#if defined(_KERNEL)
# if !SOLARIS
int s;
# else
extern int fr_running;
if (fr_running <= 0)
return;
# endif
#endif
READ_ENTER(&ipf_solaris);
#ifdef __sgi
ipfilter_sgi_intfsync();
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
/*
* Go through the entire table, looking for entries to expire,
@ -390,23 +460,17 @@ int ipfr_slowtimer()
* remove it from the chain and free it.
*/
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
--fr->ipfr_ttl;
if (fr->ipfr_ttl == 0) {
if (fr->ipfr_prev)
fr->ipfr_prev->ipfr_next =
fr->ipfr_next;
if (fr->ipfr_next)
fr->ipfr_next->ipfr_prev =
fr->ipfr_prev;
*fp = fr->ipfr_next;
ipfr_stats.ifs_expire++;
ipfr_inuse--;
KFREE(fr);
for (fp = &ipfr_heads[idx]; (fra = *fp); ) {
--fra->ipfr_ttl;
if (fra->ipfr_ttl == 0) {
*fp = fra->ipfr_next;
ipfr_delete(fra);
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
} else
fp = &fr->ipfr_next;
fp = &fra->ipfr_next;
}
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
/*
* Same again for the NAT table, except that if the structure also
@ -415,31 +479,26 @@ int ipfr_slowtimer()
* NOTE: We need to grab both mutex's early, and in this order so as
* to prevent a deadlock if both try to expire at the same time.
*/
MUTEX_ENTER(&ipf_nat);
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
--fr->ipfr_ttl;
if (fr->ipfr_ttl == 0) {
if (fr->ipfr_prev)
fr->ipfr_prev->ipfr_next =
fr->ipfr_next;
if (fr->ipfr_next)
fr->ipfr_next->ipfr_prev =
fr->ipfr_prev;
*fp = fr->ipfr_next;
ipfr_stats.ifs_expire++;
ipfr_inuse--;
if ((nat = (nat_t *)fr->ipfr_data)) {
if (nat->nat_data == fr)
for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
--fra->ipfr_ttl;
if (fra->ipfr_ttl == 0) {
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
nat = fra->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fra)
nat->nat_data = NULL;
}
KFREE(fr);
*fp = fra->ipfr_next;
ipfr_delete(fra);
} else
fp = &fr->ipfr_next;
fp = &fra->ipfr_next;
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
fr_timeoutstate();
ip_natexpire();
@ -448,11 +507,16 @@ int ipfr_slowtimer()
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
# else
# ifndef linux
ip_slowtimo();
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
# endif
# if (BSD < 199306) && !defined(__sgi)
return 0;
# endif
# endif
RWLOCK_EXIT(&ipf_solaris);
}
#endif /* defined(_KERNEL) */

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.0.2.12.2.1 1998/05/23 14:29:39 darrenr Exp $
* $Id: ip_frag.h,v 2.2 1999/08/06 06:26:38 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@ -24,7 +24,7 @@ typedef struct ipfr {
u_char ipfr_tos;
u_short ipfr_off;
u_short ipfr_ttl;
u_char ipfr_pass;
frentry_t *ipfr_rule;
} ipfr_t;
@ -43,15 +43,19 @@ typedef struct ipfrstat {
extern int fr_ipfrttl;
extern ipfrstat_t *ipfr_fragstats __P((void));
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int));
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *));
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
extern int ipfr_knownfrag __P((ip_t *, fr_info_t *));
extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
extern void ipfr_forget __P((void *));
extern void ipfr_unload __P((void));
#if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
extern void ipfr_slowtimer __P((void));
# else
extern void ipfr_slowtimer __P((void *));
# endif
#else
extern int ipfr_slowtimer __P((void));
#endif

View File

@ -2,6 +2,9 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
#define isdigit(x) ((x) >= '0' && (x) <= '9')
@ -9,67 +12,29 @@
#define IPF_MINPORTLEN 18
#define IPF_MAXPORTLEN 30
#define IPF_MIN227LEN 39
#define IPF_MAX227LEN 51
int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
u_short ipf_ftp_atoi __P((char **));
int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
int ippr_ftp_init __P((void));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_portmsg __P((fr_info_t *, ip_t *, nat_t *));
int ippr_ftp_pasvmsg __P((fr_info_t *, ip_t *, nat_t *));
u_short ipf_ftp_atoi __P((char **));
static frentry_t natfr;
/*
* FTP application proxy initialization.
* Initialize local structures.
*/
int ippr_ftp_init(fin, ip, tcp, aps, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
int ippr_ftp_init()
{
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
return 0;
}
int ippr_ftp_in(fin, ip, tcp, aps, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
u_32_t sum1, sum2;
short sel;
if (tcp->th_sport == aps->aps_dport) {
sum2 = (u_32_t)ntohl(tcp->th_ack);
sel = aps->aps_sel;
if ((aps->aps_after[!sel] > aps->aps_after[sel]) &&
(sum2 > aps->aps_after[!sel])) {
sel = aps->aps_sel = !sel; /* switch to other set */
}
if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) {
sum1 = (u_32_t)aps->aps_seqoff[sel];
tcp->th_ack = htonl(sum2 - sum1);
return 2;
}
}
bzero((char *)&natfr, sizeof(natfr));
natfr.fr_ref = 1;
natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
@ -103,46 +68,51 @@ char **ptr;
}
int ippr_ftp_out(fin, ip, tcp, aps, nat)
int ippr_ftp_portmsg(fin, ip, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
register u_32_t sum1, sum2;
char newbuf[IPF_MAXPORTLEN+1];
char portbuf[IPF_MAXPORTLEN+1], *s;
int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2);
u_int a1, a2, a3, a4;
u_short a5, a6;
int olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
void *savep;
nat_t *ipn;
struct in_addr swip;
mb_t *m = *(mb_t **)fin->fin_mp;
char portbuf[IPF_MAXPORTLEN + 1], newbuf[IPF_MAXPORTLEN + 1], *s;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
size_t nlen = 0, dlen, olen;
u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
struct in_addr swip;
int off, inc = 0;
fr_info_t fi;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
/* skip any leading M_PROTOs */
while(m && (MTYPE(m) != M_DATA))
m = m->b_cont;
PANIC((!m),("ippr_ftp_out: no M_DATA"));
tcp = (tcphdr_t *)fin->fin_dp;
bzero(portbuf, sizeof(portbuf));
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
if (dlen > 0)
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
dlen = mbufchainlen(m) - off;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
portbuf[IPF_MAXPORTLEN] = '\0';
m = *(mb_t **)fin->fin_mp;
if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
goto adjust_seqack;
dlen = mbufchainlen(m) - off;
if (dlen > 0)
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
if (dlen == 0)
return 0;
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if (!strncmp(portbuf, "PORT ", 5)) {
if (dlen < IPF_MINPORTLEN)
return 0;
} else
return 0;
/*
* Skip the PORT command + space
@ -151,21 +121,38 @@ nat_t *nat;
/*
* Pick out the address components, two at a time.
*/
(void) ipf_ftp_atoi(&s);
a1 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
(void) ipf_ftp_atoi(&s);
return 0;
a2 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
return 0;
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
if (a1 != ntohl(nat->nat_inip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
return 0;
if (*s == ')')
s++;
/*
* check for CR-LF at the end.
*/
if (*s != '\n' || *(s - 1) != '\r')
goto adjust_seqack;
a6 = a5 & 0xff;
if (*s == '\n')
s--;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
} else
return 0;
a5 >>= 8;
/*
* Calculate new address parts for PORT command
@ -175,29 +162,34 @@ nat_t *nat;
a3 = (a1 >> 8) & 0xff;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf + 1;
(void) sprintf(newbuf, "PORT %d,%d,%d,%d,%d,%d\r\n",
a1, a2, a3, a4, a5, a6);
olen = s - portbuf;
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
#if SOLARIS
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if (inc > 0) {
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
mblk_t *nm;
/* alloc enough to keep same trailer space for lower driver */
nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, BPRI_MED);
nm = allocb(nlen, BPRI_MED);
PANIC((!nm),("ippr_ftp_out: allocb failed"));
nm->b_band = m1->b_band;
nm->b_wptr += nlen;
m1->b_wptr -= olen;
PANIC((m1->b_wptr < m1->b_rptr),("ippr_ftp_out: cannot handle fragmented data block"));
PANIC((m1->b_wptr < m1->b_rptr),
("ippr_ftp_out: cannot handle fragmented data block"));
linkb(m1, nm);
} else {
if (m1->b_datap->db_struiolim == m1->b_wptr)
m1->b_datap->db_struiolim += inc;
m1->b_datap->db_struioflag &= ~STRUIO_IP;
m1->b_wptr += inc;
}
copyin_mblk(m, off, nlen, newbuf);
@ -207,8 +199,10 @@ nat_t *nat;
/* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
#endif
if (inc) {
if (inc != 0) {
#if SOLARIS || defined(__sgi)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
sum2 = ip->ip_len + inc;
@ -222,48 +216,242 @@ nat_t *nat;
#endif
ip->ip_len += inc;
}
ch = 1;
/*
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
savep = fin->fin_dp;
fin->fin_dp = (char *)tcp2;
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(a5 << 8 | a6);
tcp2->th_dport = htons(20);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND)))
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE);
ip->ip_src = swip;
fin->fin_dp = (char *)savep;
adjust_seqack:
if (tcp->th_dport == aps->aps_dport) {
sum2 = (u_32_t)ntohl(tcp->th_seq);
off = aps->aps_sel;
if ((aps->aps_after[!off] > aps->aps_after[off]) &&
(sum2 > aps->aps_after[!off])) {
off = aps->aps_sel = !off; /* switch to other set */
}
if (aps->aps_seqoff[off]) {
sum1 = (u_32_t)aps->aps_after[off] -
aps->aps_seqoff[off];
if (sum2 > sum1) {
sum1 = (u_32_t)aps->aps_seqoff[off];
sum2 += sum1;
tcp->th_seq = htonl(sum2);
ch = 1;
}
}
if (inc && (sum2 > aps->aps_after[!off])) {
aps->aps_after[!off] = sum2 + nlen - 1;
aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc;
sp = htons(a5 << 8 | a6);
/*
* 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);
if (ipn == NULL) {
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = sp;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
ip->ip_src = swip;
}
return ch ? 2 : 0;
return inc;
}
int ippr_ftp_out(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
return ippr_ftp_portmsg(fin, ip, nat);
}
int ippr_ftp_pasvmsg(fin, ip, nat)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
{
char portbuf[IPF_MAX227LEN + 1], newbuf[IPF_MAX227LEN + 1], *s;
int off, olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
struct in_addr swip, swip2;
u_short a5, a6, dp, sp;
u_int a1, a2, a3, a4;
tcphdr_t *tcp;
fr_info_t fi;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
bzero(portbuf, sizeof(portbuf));
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
if (dlen > 0)
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
dlen = mbufchainlen(m) - off;
if (dlen > 0)
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
if (dlen == 0)
return 0;
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if (!strncmp(portbuf, "227 ", 4)) {
if (dlen < IPF_MIN227LEN)
return 0;
else if (strncmp(portbuf, "227 Entering Passive Mode", 25))
return 0;
} else
return 0;
/*
* Skip the PORT command + space
*/
s = portbuf + 25;
while (*s && !isdigit(*s))
s++;
/*
* Pick out the address components, two at a time.
*/
a1 = ipf_ftp_atoi(&s);
if (!s)
return 0;
a2 = ipf_ftp_atoi(&s);
if (!s)
return 0;
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
if (a1 != ntohl(nat->nat_oip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
if (!s)
return 0;
if (*s == ')')
s++;
if (*s == '\n')
s--;
/*
* check for CR-LF at the end.
*/
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
} else
return 0;
a5 >>= 8;
/*
* Calculate new address parts for 227 reply
*/
a1 = ntohl(ip->ip_src.s_addr);
a2 = (a1 >> 16) & 0xff;
a3 = (a1 >> 8) & 0xff;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf;
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
#if SOLARIS
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
mblk_t *nm;
/* alloc enough to keep same trailer space for lower driver */
nm = allocb(nlen, BPRI_MED);
PANIC((!nm),("ippr_ftp_out: allocb failed"));
nm->b_band = m1->b_band;
nm->b_wptr += nlen;
m1->b_wptr -= olen;
PANIC((m1->b_wptr < m1->b_rptr),
("ippr_ftp_out: cannot handle fragmented data block"));
linkb(m1, nm);
} else {
m1->b_wptr += inc;
}
copyin_mblk(m, off, nlen, newbuf);
#else
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
#endif
if (inc != 0) {
#if SOLARIS || defined(__sgi)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
sum2 = ip->ip_len + inc;
/* Because ~1 == -2, We really need ~1 == -1 */
if (sum1 > sum2)
sum2--;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2);
#endif
ip->ip_len += inc;
}
/*
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
sp = 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);
if (ipn == NULL) {
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 */
fi.fin_data[0] = a5 << 8 | a6;
tcp2->th_dport = htons(fi.fin_data[0]);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
swip = ip->ip_src;
swip2 = ip->ip_dst;
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,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_SPORT);
}
ip->ip_src = swip;
ip->ip_dst = swip2;
}
return inc;
}
int ippr_ftp_in(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
return ippr_ftp_pasvmsg(fin, ip, nat);
}

View File

@ -1,25 +1,17 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.0.2.1.2.5 1997/12/02 13:55:57 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.1 1999/08/04 17:29:57 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#ifndef _KERNEL
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
#else
# include <linux/module.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -29,6 +21,14 @@ static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.0.2.1.2.5 1997/12/02 13:55:5
#include <sys/uio.h>
#include <sys/dir.h>
#include <sys/socket.h>
#ifndef _KERNEL
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
#else
# include <linux/module.h>
#endif
#include <net/if.h>
#include <net/route.h>
@ -67,7 +67,6 @@ int ipl_inited = 0;
int ipl_unreach = ICMP_UNREACH_FILTER;
u_long ipl_frouteok[2] = {0, 0};
static void fixskip __P((frentry_t **, frentry_t *, int));
static int frzerostats __P((caddr_t));
static void frsync __P((void));
#if defined(__NetBSD__) || defined(__OpenBSD__)
@ -146,7 +145,7 @@ int ipldetach()
}
fr_checkp = fr_savep;
frflush(IPL_LOGIPF, &i);
i = frflush(IPL_LOGIPF, i);
ipl_inited = 0;
ipfr_unload();
@ -310,7 +309,7 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
error = EPERM;
else {
IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
frflush(unit, &tmp);
tmp = frflush(unit, tmp);
IWCOPY((caddr_t)&tmp, data, sizeof(tmp));
}
break;
@ -363,25 +362,6 @@ static void frsync()
}
static void fixskip(listp, rp, addremove)
frentry_t **listp, *rp;
int addremove;
{
frentry_t *fp;
int rules = 0, rn = 0;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
;
if (!fp)
return;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
if (fp->fr_skip && (rn + fp->fr_skip >= rules))
fp->fr_skip += addremove;
}
static int frrequest(unit, req, data, set)
int unit;
u_long req;
@ -393,7 +373,8 @@ caddr_t data;
frentry_t frd;
frdest_t *fdp;
frgroup_t *fg = NULL;
int error = 0, in, group;
int error = 0, in;
u_int group;
fp = &frd;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
@ -405,10 +386,10 @@ caddr_t data;
* has been specified, doesn't exist.
*/
if (fp->fr_grhead &&
fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL))
return EEXIST;
if (fp->fr_group &&
!fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
!fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL))
return ESRCH;
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
@ -498,8 +479,8 @@ caddr_t data;
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
if (f->fr_grhead)
fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
set);
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
unit, set);
fixskip(fprev, f, -1);
*ftail = f->fr_next;
KFREE(f);
@ -510,7 +491,7 @@ caddr_t data;
else {
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
KMALLOC(f, frentry_t *, sizeof(*f));
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
fg->fg_head->fr_ref++;
@ -540,7 +521,7 @@ int iplopen(struct inode *inode, struct file *file)
{
u_int min = GET_MINOR(inode->i_rdev);
if (2 < min)
if (IPL_LOGMAX < min)
min = ENXIO;
else {
MOD_INC_USE_COUNT;
@ -554,7 +535,7 @@ void iplclose(struct inode *inode, struct file *file)
{
u_int min = GET_MINOR(inode->i_rdev);
if (2 >= min) {
if (IPL_LOGMAX >= min) {
MOD_DEC_USE_COUNT;
}
}
@ -628,7 +609,7 @@ struct ifnet *ifp;
ip->ip_sum = 0;
ip->ip_sum = ipf_cksum((u_short *)ip, sizeof(ip_t));
tcp->th_sum = fr_tcpsum(m, ip, tcp, sizeof(tcpiphdr_t));
tcp->th_sum = fr_tcpsum(m, ip, tcp);
return ip_forward(m, NULL, IPFWD_NOTTLDEC, ip->ip_dst.s_addr);
}

View File

@ -1,27 +1,33 @@
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_log.c,v 2.0.2.13.2.3 1997/11/20 12:41:40 darrenr Exp $
* $Id: ip_log.c,v 2.1.2.2 1999/09/21 11:55:44 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM)
# include "opt_ipfilter_log.h"
#endif
#ifdef __FreeBSD__
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include "opt_ipfilter.h"
# endif
# else
# include <osreldate.h>
# endif
#endif
#ifdef IPFILTER_LOG
# ifndef SOLARIS
# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
# endif
# if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
# endif
# ifdef __FreeBSD__
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
# else
# include <osreldate.h>
# endif
# endif
# ifndef _KERNEL
# include <stdio.h>
# include <string.h>
@ -30,7 +36,6 @@
# endif
# include <sys/errno.h>
# include <sys/types.h>
# include <sys/param.h>
# include <sys/file.h>
# if __FreeBSD_version >= 220000 && defined(_KERNEL)
# include <sys/fcntl.h>
@ -44,7 +49,7 @@
# endif
# include <sys/uio.h>
# if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603)
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
# else
# include <sys/dir.h>
@ -105,6 +110,10 @@
# include "netinet/ip_frag.h"
# include "netinet/ip_state.h"
# include "netinet/ip_auth.h"
# if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# endif
# ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
# endif
@ -117,13 +126,12 @@ extern kcondvar_t iplwait;
# endif
# endif
iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
int iplused[IPL_LOGMAX+1];
u_long iplcrc[IPL_LOGMAX+1];
u_long iplcrcinit;
#ifdef linux
iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1], *ipll[IPL_LOGMAX+1];
size_t iplused[IPL_LOGMAX+1];
fr_info_t iplcrc[IPL_LOGMAX+1];
# ifdef linux
static struct wait_queue *iplwait[IPL_LOGMAX+1];
#endif
# endif
/*
@ -132,20 +140,15 @@ static struct wait_queue *iplwait[IPL_LOGMAX+1];
*/
void ipflog_init()
{
struct timeval tv;
int i;
for (i = IPL_LOGMAX; i >= 0; i--) {
iplt[i] = NULL;
ipll[i] = NULL;
iplh[i] = &iplt[i];
iplused[i] = 0;
bzero((char *)&iplcrc[i], sizeof(iplcrc[i]));
}
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
microtime(&tv);
# else
uniqtime(&tv);
# endif
iplcrcinit = tv.tv_sec ^ (tv.tv_usec << 8) ^ tv.tv_usec;
}
@ -164,8 +167,7 @@ fr_info_t *fin;
mb_t *m;
{
ipflog_t ipfl;
register int mlen, hlen;
u_long crc;
register size_t mlen, hlen;
size_t sizes[2];
void *ptrs[2];
int types[2];
@ -179,29 +181,36 @@ mb_t *m;
* calculate header size.
*/
hlen = fin->fin_hlen;
if (ip->ip_p == IPPROTO_TCP)
hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_UDP)
hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_ICMP) {
struct icmp *icmp = (struct icmp *)((char *)ip + hlen);
/*
* For ICMP, if the packet is an error packet, also include
* the information about the packet which caused the error.
*/
switch (icmp->icmp_type)
{
case ICMP_UNREACH :
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
hlen += MIN(sizeof(struct icmp) + 8, fin->fin_dlen);
break;
default :
hlen += MIN(sizeof(struct icmp), fin->fin_dlen);
break;
if ((ip->ip_off & IP_OFFMASK) == 0) {
if (ip->ip_p == IPPROTO_TCP)
hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_UDP)
hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_ICMP) {
struct icmp *icmp;
icmp = (struct icmp *)((char *)ip + hlen);
/*
* For ICMP, if the packet is an error packet, also
* include the information about the packet which
* caused the error.
*/
switch (icmp->icmp_type)
{
case ICMP_UNREACH :
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
hlen += MIN(sizeof(struct icmp) + 8,
fin->fin_dlen);
break;
default :
hlen += MIN(sizeof(struct icmp),
fin->fin_dlen);
break;
}
}
}
/*
@ -231,11 +240,15 @@ mb_t *m;
ipfl.fl_hlen = (u_char)hlen;
ipfl.fl_rule = fin->fin_rule;
ipfl.fl_group = fin->fin_group;
if (fin->fin_fr != NULL)
ipfl.fl_loglevel = fin->fin_fr->fr_loglevel;
else
ipfl.fl_loglevel = 0xffff;
ipfl.fl_flags = flags;
ptrs[0] = (void *)&ipfl;
sizes[0] = sizeof(ipfl);
types[0] = 0;
#if SOLARIS
# if SOLARIS
/*
* Are we copied from the mblk or an aligned array ?
*/
@ -248,45 +261,47 @@ mb_t *m;
sizes[1] = hlen + mlen;
types[1] = 0;
}
#else
# else
ptrs[1] = m;
sizes[1] = hlen + mlen;
types[1] = 1;
#endif
crc = (ipf_cksum((u_short *)fin, FI_CSIZE) << 8) + iplcrcinit;
return ipllog(IPL_LOGIPF, crc, ptrs, sizes, types, 2);
# endif
return ipllog(IPL_LOGIPF, fin, ptrs, sizes, types, 2);
}
/*
* ipllog
*/
int ipllog(dev, crc, items, itemsz, types, cnt)
int ipllog(dev, fin, items, itemsz, types, cnt)
int dev;
u_long crc;
fr_info_t *fin;
void **items;
size_t *itemsz;
int *types, cnt;
{
iplog_t *ipl;
caddr_t buf, s;
int len, i;
iplog_t *ipl;
size_t len;
int i;
/*
* Check to see if this log record has a CRC which matches the last
* record logged. If it does, just up the count on the previous one
* rather than create a new one.
*/
if (crc) {
MUTEX_ENTER(&ipl_mutex);
if ((iplcrc[dev] == crc) && *iplh[dev]) {
(*iplh[dev])->ipl_count++;
MUTEX_ENTER(&ipl_mutex);
if (fin != NULL) {
if ((ipll[dev] != NULL) &&
bcmp((char *)fin, (char *)&iplcrc[dev], FI_CSIZE) == 0) {
ipll[dev]->ipl_count++;
MUTEX_EXIT(&ipl_mutex);
return 1;
}
iplcrc[dev] = crc;
MUTEX_EXIT(&ipl_mutex);
}
bcopy((char *)fin, (char *)&iplcrc[dev], FI_CSIZE);
} else
bzero((char *)&iplcrc[dev], FI_CSIZE);
MUTEX_EXIT(&ipl_mutex);
/*
* Get the total amount of data to be logged.
@ -298,7 +313,7 @@ int *types, cnt;
* check that we have space to record this information and can
* allocate that much.
*/
KMALLOC(buf, caddr_t, len);
KMALLOCS(buf, caddr_t, len);
if (!buf)
return 0;
MUTEX_ENTER(&ipl_mutex);
@ -344,6 +359,7 @@ int *types, cnt;
s += itemsz[i];
}
MUTEX_ENTER(&ipl_mutex);
ipll[dev] = ipl;
*iplh[dev] = ipl;
iplh[dev] = &ipl->ipl_next;
# if SOLARIS
@ -362,11 +378,12 @@ int *types, cnt;
int ipflog_read(unit, uio)
int unit;
minor_t unit;
struct uio *uio;
{
size_t dlen, copied;
int error = 0;
iplog_t *ipl;
int error = 0, dlen, copied;
# if defined(_KERNEL) && !SOLARIS
int s;
# endif
@ -375,7 +392,7 @@ struct uio *uio;
* Sanity checks. Make sure the minor # is valid and we're copying
* a valid chunk of data.
*/
if ((IPL_LOGMAX < unit) || (unit < 0))
if (IPL_LOGMAX < unit)
return ENXIO;
if (!uio->uio_resid)
return 0;
@ -419,55 +436,63 @@ struct uio *uio;
for (copied = 0; (ipl = iplt[unit]); copied += dlen) {
dlen = ipl->ipl_dsize;
if (dlen + sizeof(iplog_t) > uio->uio_resid)
if (dlen > uio->uio_resid)
break;
/*
* Don't hold the mutex over the uiomove call.
*/
iplt[unit] = ipl->ipl_next;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
error = UIOMOVE((caddr_t)ipl, ipl->ipl_dsize, UIO_READ, uio);
KFREES((caddr_t)ipl, ipl->ipl_dsize);
if (error)
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
if (error) {
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
iplused[unit] += dlen;
break;
}
KFREES((caddr_t)ipl, dlen);
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
iplused[unit] -= dlen;
}
if (!ipl) {
if (!iplt[unit]) {
iplused[unit] = 0;
iplh[unit] = &iplt[unit];
ipll[unit] = NULL;
}
if (!error) {
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
}
#ifdef linux
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
# ifdef linux
if (!error)
return copied;
return (int)copied;
return -error;
#else
# else
return error;
#endif
# endif
}
int ipflog_clear(unit)
int unit;
minor_t unit;
{
iplog_t *ipl;
int used;
MUTEX_ENTER(&ipl_mutex);
while ((ipl = iplt[unit])) {
iplt[unit] = ipl->ipl_next;
KFREES((caddr_t)ipl, ipl->ipl_dsize);
}
iplh[unit] = &iplt[unit];
ipll[unit] = NULL;
used = iplused[unit];
iplused[unit] = 0;
iplcrc[unit] = 0;
bzero((char *)&iplcrc[unit], FI_CSIZE);
MUTEX_EXIT(&ipl_mutex);
return used;
}
#endif /* IPFILTER_LOG */

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
* $Id: ip_nat.h,v 2.0.2.23.2.3 1998/05/23 18:52:44 darrenr Exp $
* $Id: ip_nat.h,v 2.1.2.1 1999/08/14 04:47:54 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -36,28 +36,50 @@
#define SIOCCNATL _IOWR(r, 87, int)
#endif
#define NAT_SIZE 367
#undef LARGE_NAT /* define this if you're setting up a system to NAT
* LARGE numbers of networks/hosts - i.e. in the
* hundreds or thousands. In such a case, you should
* also change the RDR_SIZE and NAT_SIZE below to more
* appropriate sizes. The figures below were used for
* a setup with 1000-2000 networks to NAT.
*/
#define NAT_SIZE 127
#define RDR_SIZE 127
#define NAT_TABLE_SZ 127
#ifdef LARGE_NAT
#undef NAT_SIZE
#undef RDR_SIZE
#undef NAT_TABLE_SZ
#define NAT_SIZE 2047
#define RDR_SIZE 2047
#define NAT_TABLE_SZ 16383
#endif
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
#endif
#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */
typedef struct nat {
u_long nat_age;
int nat_flags;
u_32_t nat_sumd;
u_32_t nat_ipsumd;
void *nat_data;
void *nat_aps; /* proxy session */
frentry_t *nat_fr; /* filter rule ptr if appropriate */
struct in_addr nat_inip;
struct in_addr nat_outip;
struct in_addr nat_oip; /* other ip */
U_QUAD_T nat_pkts;
U_QUAD_T nat_bytes;
u_short nat_oport; /* other port */
u_short nat_oport; /* other port */
u_short nat_inport;
u_short nat_outport;
u_short nat_use;
u_char nat_state[2];
struct ipnat *nat_ptr;
u_char nat_tcpstate[2];
u_char nat_p; /* protocol for NAT */
struct ipnat *nat_ptr; /* pointer back to the rule */
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_hstart[2];
@ -67,16 +89,22 @@ typedef struct nat {
typedef struct ipnat {
struct ipnat *in_next;
struct ipnat *in_rnext;
struct ipnat *in_mnext;
void *in_ifp;
void *in_apr;
u_int in_space;
u_long in_space;
u_int in_use;
u_int in_hits;
struct in_addr in_nextip;
u_short in_pnext;
u_short in_flags;
u_short in_port[2];
u_short in_ppip; /* ports per IP */
u_short in_ippip; /* IP #'s per IP# */
u_short in_flags; /* From here to in_dport must be reflected */
u_short in_port[2]; /* correctly in IPN_CMPSIZ */
struct in_addr in_in[2];
struct in_addr in_out[2];
struct in_addr in_src[2];
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 */
@ -91,6 +119,8 @@ typedef struct ipnat {
#define in_inmsk in_in[1].s_addr
#define in_outip in_out[0].s_addr
#define in_outmsk in_out[1].s_addr
#define in_srcip in_src[0].s_addr
#define in_srcmsk in_src[1].s_addr
#define NAT_OUTBOUND 0
#define NAT_INBOUND 1
@ -98,9 +128,12 @@ typedef struct ipnat {
#define NAT_MAP 0x01
#define NAT_REDIRECT 0x02
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
#define NAT_MAPBLK 0x04
#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \
sizeof(int) + IFNAMSIZ + APR_LABELLEN + sizeof(char))
#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */
#define USABLE_PORTS (65536 - MAPBLK_MINPORT)
#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
typedef struct natlookup {
struct in_addr nl_inip;
@ -122,14 +155,23 @@ typedef struct natstat {
u_long ns_logfail;
nat_t **ns_table[2];
ipnat_t *ns_list;
void *ns_apslist;
u_int ns_nattab_sz;
u_int ns_rultab_sz;
u_int ns_rdrtab_sz;
nat_t *ns_instances;
} natstat_t;
#define IPN_ANY 0x00
#define IPN_TCP 0x01
#define IPN_UDP 0x02
#define IPN_TCPUDP 0x03
#define IPN_TCPUDP (IPN_TCP|IPN_UDP)
#define IPN_DELETE 0x04
#define IPN_ICMPERR 0x08
#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
#define IPN_AUTOPORTMAP 0x10
#define IPN_RANGE 0x20
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_RANGE)
typedef struct natlog {
@ -150,31 +192,54 @@ typedef struct natlog {
#define NL_NEWRDR NAT_REDIRECT
#define NL_EXPIRE 0xffff
#define NAT_HASH_FN(k,m) (((k) + ((k) >> 12)) % (m))
#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
#define CALC_SUMD(s1, s2, sd) { \
(s1) = ((s1) & 0xffff) + ((s1) >> 16); \
(s2) = ((s2) & 0xffff) + ((s2) >> 16); \
/* Do it twice */ \
(s1) = ((s1) & 0xffff) + ((s1) >> 16); \
(s2) = ((s2) & 0xffff) + ((s2) >> 16); \
/* Because ~1 == -2, We really need ~1 == -1 */ \
if ((s1) > (s2)) (s2)--; \
(sd) = (s2) - (s1); \
(sd) = ((sd) & 0xffff) + ((sd) >> 16); }
extern u_int ipf_nattable_sz;
extern u_int ipf_natrules_sz;
extern u_int ipf_rdrrules_sz;
extern void ip_natsync __P((void *));
extern u_long fr_defnatage;
extern u_long fr_defnaticmpage;
extern nat_t *nat_table[2][NAT_SIZE];
extern nat_t **nat_table[2];
extern nat_t *nat_instances;
extern ipnat_t **nat_rules;
extern ipnat_t **rdr_rules;
extern natstat_t nat_stats;
#if defined(__NetBSD__) || defined(__OpenBSD__)
extern int nat_ioctl __P((caddr_t, u_long, int));
#else
extern int nat_ioctl __P((caddr_t, int, int));
#endif
extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
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));
extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
struct in_addr, u_32_t));
extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
struct in_addr));
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *));
extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, int *));
extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, u_int *));
extern int ip_natout __P((ip_t *, int, fr_info_t *));
extern int ip_natin __P((ip_t *, int, fr_info_t *));
extern int ip_natout __P((ip_t *, fr_info_t *));
extern int ip_natin __P((ip_t *, fr_info_t *));
extern void ip_natunload __P((void)), ip_natexpire __P((void));
extern void nat_log __P((struct nat *, u_short));
extern void nat_log __P((struct nat *, u_int));
extern void fix_incksum __P((u_short *, u_32_t));
extern void fix_outcksum __P((u_short *, u_32_t));

View File

@ -1,31 +1,33 @@
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15:22 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.2.2.1 1999/09/19 12:18:19 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#if !defined(__FreeBSD_version)
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
#include <sys/uio.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#ifndef linux
# include <sys/protosw.h>
#endif
@ -43,7 +45,9 @@ static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15
# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# ifdef _KERNEL
# include <sys/dditypes.h>
# endif
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
@ -70,31 +74,48 @@ static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
static ap_session_t *ap_find __P((ip_t *, tcphdr_t *));
static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *,
fr_info_t *, nat_t *));
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)
#include "netinet/ip_ftp_pxy.c"
#include "netinet/ip_rcmd_pxy.c"
#include "netinet/ip_raudio_pxy.c"
#endif
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_in, ippr_ftp_out },
{ "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
ippr_ftp_in, ippr_ftp_out },
#endif
#ifdef IPF_RCMD_PROXY
{ "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_new,
NULL, ippr_rcmd_out },
#endif
#ifdef IPF_RAUDIO_PROXY
{ "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init,
ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
#endif
{ "", '\0', 0, 0, NULL, NULL }
};
int ap_ok(ip, tcp, nat)
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
ipnat_t *nat;
@ -102,7 +123,7 @@ ipnat_t *nat;
aproxy_t *apr = nat->in_apr;
u_short dport = nat->in_dport;
if (!apr || (apr && (apr->apr_flags & APR_DELETE)) ||
if (!apr || (apr->apr_flags & APR_DELETE) ||
(ip->ip_p != apr->apr_p))
return 0;
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
@ -111,108 +132,36 @@ ipnat_t *nat;
}
static int
ap_matchsrcdst(aps, src, dst, tcp, sport, dport)
ap_session_t *aps;
struct in_addr src, dst;
void *tcp;
u_short sport, dport;
{
if (aps->aps_dst.s_addr == dst.s_addr) {
if ((aps->aps_src.s_addr == src.s_addr) &&
(!tcp || (sport == aps->aps_sport) &&
(dport == aps->aps_dport)))
return 1;
} else if (aps->aps_dst.s_addr == src.s_addr) {
if ((aps->aps_src.s_addr == dst.s_addr) &&
(!tcp || (sport == aps->aps_dport) &&
(dport == aps->aps_sport)))
return 1;
}
return 0;
}
static ap_session_t *ap_find(ip, tcp)
ip_t *ip;
tcphdr_t *tcp;
{
register u_char p = ip->ip_p;
register ap_session_t *aps;
register u_short sp, dp;
register u_long hv;
struct in_addr src, dst;
src = ip->ip_src, dst = ip->ip_dst;
sp = dp = 0; /* XXX gcc -Wunitialized */
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
hv *= 651733;
if (tcp) {
sp = tcp->th_sport;
dp = tcp->th_dport;
hv ^= (sp + dp);
hv *= 5;
}
hv %= AP_SESS_SIZE;
for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next)
if ((aps->aps_p == p) &&
ap_matchsrcdst(aps, src, dst, tcp, sp, dp))
break;
return aps;
}
/*
* 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 *ap_new_session(apr, ip, tcp, fin, nat)
static ap_session_t *appr_new_session(apr, ip, fin, nat)
aproxy_t *apr;
ip_t *ip;
tcphdr_t *tcp;
fr_info_t *fin;
nat_t *nat;
{
register ap_session_t *aps;
u_short dport;
u_long hv;
if (!apr || (apr && (apr->apr_flags & APR_DELETE)) ||
(ip->ip_p != apr->apr_p))
return NULL;
dport = nat->nat_ptr->in_dport;
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p))
return NULL;
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
hv *= 651733;
if (tcp) {
hv ^= (tcp->th_sport + tcp->th_dport);
hv *= 5;
}
hv %= AP_SESS_SIZE;
KMALLOC(aps, ap_session_t *, sizeof(*aps));
KMALLOC(aps, ap_session_t *);
if (!aps)
return NULL;
bzero((char *)aps, sizeof(*aps));
aps->aps_apr = apr;
aps->aps_src = ip->ip_src;
aps->aps_dst = ip->ip_dst;
aps->aps_next = ap_sess_list;
aps->aps_p = ip->ip_p;
aps->aps_tout = 1200; /* XXX */
if (tcp) {
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
}
aps->aps_data = NULL;
aps->aps_apr = apr;
aps->aps_psiz = 0;
aps->aps_next = ap_sess_tab[hv];
ap_sess_tab[hv] = aps;
(void) (*apr->apr_init)(fin, ip, tcp, aps, nat);
ap_sess_list = aps;
aps->aps_nat = nat;
nat->nat_aps = aps;
if (apr->apr_new != NULL)
(void) (*apr->apr_new)(fin, ip, aps, nat);
return aps;
}
@ -221,59 +170,67 @@ nat_t *nat;
* check to see if a packet should be passed through an active proxy routine
* if one has been setup for it.
*/
int ap_check(ip, tcp, fin, nat)
int appr_check(ip, fin, nat)
ip_t *ip;
tcphdr_t *tcp;
fr_info_t *fin;
nat_t *nat;
{
ap_session_t *aps;
aproxy_t *apr;
tcphdr_t *tcp = NULL;
u_32_t sum;
int err;
if (!(fin->fin_fi.fi_fl & FI_TCPUDP))
tcp = NULL;
if ((aps = ap_find(ip, tcp)) ||
(aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) {
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) {
tcp = (tcphdr_t *)fin->fin_dp;
/*
* verify that the checksum is correct. If not, then
* don't do anything with this packet.
*/
if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp,
ip, tcp, ip->ip_len)) {
#if SOLARIS && defined(_KERNEL)
sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
if (sum != tcp->th_sum) {
frstats[fin->fin_out].fr_tcpbad++;
return -1;
}
fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin,
tcp->th_sport == aps->aps_sport);
}
apr = aps->aps_apr;
err = 0;
if (fin->fin_out) {
if (apr->apr_outpkt)
err = (*apr->apr_outpkt)(fin, ip, tcp,
aps, nat);
if (fin->fin_out != 0) {
if (apr->apr_outpkt != NULL)
err = (*apr->apr_outpkt)(fin, ip, aps, nat);
} else {
if (apr->apr_inpkt)
err = (*apr->apr_inpkt)(fin, ip, tcp,
aps, nat);
if (apr->apr_inpkt != NULL)
err = (*apr->apr_inpkt)(fin, ip, aps, nat);
}
if (err == 2) {
tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip,
tcp, ip->ip_len);
err = 0;
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, err);
#if SOLARIS && defined(_KERNEL)
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
}
return err;
aps->aps_bytes += ip->ip_len;
aps->aps_pkts++;
return 2;
}
return -1;
}
aproxy_t *ap_match(pr, name)
u_char pr;
aproxy_t *appr_match(pr, name)
u_int pr;
char *name;
{
aproxy_t *ap;
@ -288,7 +245,7 @@ char *name;
}
void ap_free(ap)
void appr_free(ap)
aproxy_t *ap;
{
ap->apr_ref--;
@ -298,38 +255,133 @@ aproxy_t *ap;
void aps_free(aps)
ap_session_t *aps;
{
if (aps->aps_data && aps->aps_psiz)
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
ap_session_t *a, **ap;
if (!aps)
return;
void ap_unload()
{
ap_session_t *aps;
int i;
for (i = 0; i < AP_SESS_SIZE; i++)
while ((aps = ap_sess_tab[i])) {
ap_sess_tab[i] = aps->aps_next;
aps_free(aps);
for (ap = &ap_sess_list; (a = *ap); ap = &a->aps_next)
if (a == aps) {
*ap = a->aps_next;
break;
}
if (a) {
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
}
void ap_expire()
static int appr_fixseqack(fin, ip, aps, inc)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
int inc;
{
ap_session_t *aps, **apsp;
int i;
int sel, ch = 0, out, nlen;
u_32_t seq1, seq2;
tcphdr_t *tcp;
for (i = 0; i < AP_SESS_SIZE; i++)
for (apsp = &ap_sess_tab[i]; (aps = *apsp); ) {
aps->aps_tout--;
if (!aps->aps_tout) {
ap_sess_tab[i] = aps->aps_next;
aps_free(aps);
*apsp = aps->aps_next;
} else
apsp = &aps->aps_next;
tcp = (tcphdr_t *)fin->fin_dp;
out = fin->fin_out;
nlen = ip->ip_len;
nlen -= (ip->ip_hl << 2) + (tcp->th_off << 2);
if (out != 0) {
seq1 = (u_32_t)ntohl(tcp->th_seq);
sel = aps->aps_sel[out];
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel]))
sel = aps->aps_sel[out] = !sel;
if (aps->aps_seqoff[sel]) {
seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
if (seq1 > seq2) {
seq2 = aps->aps_seqoff[sel];
seq1 += seq2;
tcp->th_seq = htonl(seq1);
ch = 1;
}
}
if (inc && (seq1 > aps->aps_seqmin[!sel])) {
aps->aps_seqmin[!sel] = seq1 + nlen - 1;
aps->aps_seqoff[!sel] = aps->aps_seqoff[sel] + inc;
}
/***/
seq1 = ntohl(tcp->th_ack);
sel = aps->aps_sel[1 - out];
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel]))
sel = aps->aps_sel[1 - out] = !sel;
if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
seq2 = aps->aps_ackoff[sel];
tcp->th_ack = htonl(seq1 - seq2);
ch = 1;
}
} else {
seq1 = ntohl(tcp->th_seq);
sel = aps->aps_sel[out];
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel]))
sel = aps->aps_sel[out] = !sel;
if (aps->aps_ackoff[sel]) {
seq2 = aps->aps_ackmin[sel] -
aps->aps_ackoff[sel];
if (seq1 > seq2) {
seq2 = aps->aps_ackoff[sel];
seq1 += seq2;
tcp->th_seq = htonl(seq1);
ch = 1;
}
}
if (inc && (seq1 > aps->aps_ackmin[!sel])) {
aps->aps_ackmin[!sel] = seq1 + nlen - 1;
aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc;
}
/***/
seq1 = ntohl(tcp->th_ack);
sel = aps->aps_sel[1 - out];
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel]))
sel = aps->aps_sel[1 - out] = !sel;
if (aps->aps_seqoff[sel] && (seq1 > aps->aps_seqmin[sel])) {
seq2 = aps->aps_seqoff[sel];
tcp->th_ack = htonl(seq1 - seq2);
ch = 1;
}
}
return ch ? 2 : 0;
}
int appr_init()
{
aproxy_t *ap;
int err = 0;
for (ap = ap_proxies; ap->apr_p; ap++) {
err = (*ap->apr_init)();
if (err != 0)
break;
}
return err;
}

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_proxy.h,v 2.0.2.10.2.1 1997/11/27 09:33:27 darrenr Exp $
* $Id: ip_proxy.h,v 2.1.2.1 1999/09/19 12:18:20 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@ -26,9 +26,11 @@ struct ipnat;
typedef struct ap_tcp {
u_short apt_sport; /* source port */
u_short apt_dport; /* destination port */
short apt_sel; /* seqoff/after set selector */
short apt_sel[2]; /* {seq,ack}{off,min} set selector */
short apt_seqoff[2]; /* sequence # difference */
tcp_seq apt_after[2]; /* don't change seq-off until after this */
tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
short apt_ackoff[2]; /* sequence # difference */
tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
u_char apt_state[2]; /* connection state */
} ap_tcp_t;
@ -39,19 +41,18 @@ typedef struct ap_udp {
typedef struct ap_session {
struct aproxy *aps_apr;
struct in_addr aps_src; /* source IP# */
struct in_addr aps_dst; /* destination IP# */
u_char aps_p; /* protocol */
union {
struct ap_tcp apu_tcp;
struct ap_udp apu_udp;
} aps_un;
u_int aps_flags;
QUAD_T aps_bytes; /* bytes sent */
QUAD_T aps_pkts; /* packets sent */
u_long aps_tout; /* time left before expiring */
U_QUAD_T aps_bytes; /* bytes sent */
U_QUAD_T aps_pkts; /* packets sent */
void *aps_nat; /* pointer back to nat struct */
void *aps_data; /* private data */
int aps_p; /* protocol */
int aps_psiz; /* size of private data */
struct ap_session *aps_hnext;
struct ap_session *aps_next;
} ap_session_t ;
@ -59,8 +60,10 @@ typedef struct ap_session {
#define aps_dport aps_un.apu_tcp.apt_dport
#define aps_sel aps_un.apu_tcp.apt_sel
#define aps_seqoff aps_un.apu_tcp.apt_seqoff
#define aps_after aps_un.apu_tcp.apt_after
#define aps_seqmin aps_un.apu_tcp.apt_seqmin
#define aps_state aps_un.apu_tcp.apt_state
#define aps_ackoff aps_un.apu_tcp.apt_ackoff
#define aps_ackmin aps_un.apu_tcp.apt_ackmin
typedef struct aproxy {
@ -68,26 +71,59 @@ typedef struct aproxy {
u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((fr_info_t *, ip_t *, tcphdr_t *,
int (* apr_init) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, struct nat *));
int (* apr_outpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
int (* apr_outpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
} aproxy_t;
#define APR_DELETE 1
/*
* Real audio proxy structure and #defines
*/
typedef struct {
int rap_seenpna;
int rap_seenver;
int rap_version;
int rap_eos; /* End Of Startup */
int rap_gotid;
int rap_gotlen;
int rap_mode;
int rap_sdone;
u_short rap_plport;
u_short rap_prport;
u_short rap_srport;
char rap_svr[19];
u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have
* been filled
*/
tcp_seq rap_sseq;
} raudio_t;
#define RA_ID_END 0
#define RA_ID_UDP 1
#define RA_ID_ROBUST 7
#define RAP_M_UDP 1
#define RAP_M_ROBUST 2
#define RAP_M_TCP 4
#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
extern aproxy_t ap_proxies[];
extern int ap_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern void ap_unload __P((void));
extern void ap_free __P((aproxy_t *));
extern int appr_init __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
extern aproxy_t *ap_match __P((u_char, char *));
extern void ap_expire __P((void));
extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
extern aproxy_t *appr_match __P((u_int, char *));
#endif /* __IP_PROXY_H__ */

View File

@ -0,0 +1,270 @@
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
#define IPF_RAUDIO_PROXY
int ippr_raudio_init __P((void));
int ippr_raudio_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_raudio_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_raudio_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
static frentry_t raudiofr;
/*
* Real Audio application proxy initialization.
*/
int ippr_raudio_init()
{
bzero((char *)&raudiofr, sizeof(raudiofr));
raudiofr.fr_ref = 1;
raudiofr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
/*
* Setup for a new proxy to handle Real Audio.
*/
int ippr_raudio_new(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
raudio_t *rap;
KMALLOCS(aps->aps_data, void *, sizeof(raudio_t));
if (aps->aps_data != NULL) {
bzero(aps->aps_data, sizeof(raudio_t));
rap = aps->aps_data;
aps->aps_psiz = sizeof(raudio_t);
rap->rap_mode = RAP_M_TCP; /* default is for TCP */
}
return 0;
}
int ippr_raudio_out(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
char membuf[512 + 1], *s;
int off, dlen, inc = 0;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
u_short sp, dp, id = 0;
struct in_addr swip;
fr_info_t fi;
int len = 0;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
/*
* If we've already processed the start messages, then nothing left
* for the proxy to do.
*/
if (rap->rap_eos == 1)
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
bzero(membuf, sizeof(membuf));
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
if (dlen <= 0)
return 0;
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf);
#else
m = *(mb_t **)fin->fin_mp;
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf);
#endif
/*
* In all the startup parsing, ensure that we don't go outside
* the packet buffer boundary.
*/
/*
* Look for the start of connection "PNA" string if not seen yet.
*/
if (rap->rap_seenpna == 0) {
s = memstr("PNA", membuf, 3, dlen);
if (s == NULL)
return 0;
s += 3;
rap->rap_seenpna = 1;
} else
s = membuf;
/*
* Directly after the PNA will be the version number of this
* connection.
*/
if (rap->rap_seenpna == 1 && rap->rap_seenver == 0) {
if ((s + 1) - membuf < dlen) {
rap->rap_version = (*s << 8) | *(s + 1);
s += 2;
rap->rap_seenver = 1;
} else
return 0;
}
/*
* Now that we've been past the PNA and version number, we're into the
* startup messages block. This ends when a message with an ID of 0.
*/
while ((rap->rap_eos == 0) && ((s + 1) - membuf < dlen)) {
if (rap->rap_gotid == 0) {
id = (*s << 8) | *(s + 1);
s += 2;
rap->rap_gotid = 1;
if (id == RA_ID_END) {
rap->rap_eos = 1;
break;
}
} else if (rap->rap_gotlen == 0) {
len = (*s << 8) | *(s + 1);
s += 2;
rap->rap_gotlen = 1;
}
if (rap->rap_gotid == 1 && rap->rap_gotlen == 1) {
if (id == RA_ID_UDP) {
rap->rap_mode &= ~RAP_M_TCP;
rap->rap_mode |= RAP_M_UDP;
rap->rap_plport = (*s << 8) | *(s + 1);
} else if (id == RA_ID_ROBUST) {
rap->rap_mode |= RAP_M_ROBUST;
rap->rap_prport = (*s << 8) | *(s + 1);
}
s += len;
rap->rap_gotlen = 0;
rap->rap_gotid = 0;
}
}
/*
* Wait until we've seen the end of the start messages and even then
* only proceed further if we're using UDP.
*/
if ((rap->rap_eos == 0) || ((rap->rap_mode & RAP_M_UDP) != RAP_M_UDP))
return 0;
sp = rap->rap_plport;
dp = 0;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_win = htons(8192);
fi.fin_dp = (char *)tcp2;
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
fi.fin_fr = &raudiofr;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT, NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
ip->ip_src = swip;
if ((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) {
sp = rap->rap_prport;
}
return inc;
}
int ippr_raudio_in(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
char membuf[IPF_MAXPORTLEN + 1], *s;
int off, dlen;
raudio_t *rap = aps->aps_data;
u_int a1, a2, a3, a4;
tcphdr_t *tcp;
tcp_seq seq;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
if ((rap->rap_sdone != 0) ||
((rap->rap_mode & RAP_M_UDP_ROBUST) != RAP_M_UDP_ROBUST))
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf);
#else
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf);
#endif
seq = ntohl(tcp->th_seq);
/*
* Check to see if the data in this packet is of interest to us.
* We only care for the first 19 bytes coming back from the server.
*/
if (rap->rap_sseq == 0) {
s = memstr("PNA", membuf, 3, dlen);
if (s == NULL)
return 0;
a1 = s - membuf;
dlen -= a1;
a1 = 0;
rap->rap_sseq = seq;
a2 = MIN(dlen, sizeof(rap->rap_svr));
} else if (seq <= rap->rap_sseq + sizeof(rap->rap_svr)) {
/*
* seq # which is the start of data and from that the offset
* into the buffer array.
*/
a1 = seq - rap->rap_sseq;
a2 = MIN(dlen, sizeof(rap->rap_svr));
a2 -= a1;
s = membuf;
} else
return 0;
for (a3 = a1, a4 = a2; a4 > 0; a4--, a3++) {
rap->rap_sbf |= (1 << a3);
rap->rap_svr[a3] = *s++;
}
if (rap->rap_sbf == 0x7ffff) { /* 19 bits */
s = rap->rap_svr + 13;
rap->rap_srport = (*s << 8) | *(s + 1);
}
return 0;
}

View File

@ -0,0 +1,156 @@
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code.
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
#define isdigit(x) ((x) >= '0' && (x) <= '9')
#define IPF_RCMD_PROXY
int ippr_rcmd_init __P((void));
int ippr_rcmd_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_rcmd_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
u_short ipf_rcmd_atoi __P((char *));
int ippr_rcmd_portmsg __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
static frentry_t rcmdfr;
/*
* RCMD application proxy initialization.
*/
int ippr_rcmd_init()
{
bzero((char *)&rcmdfr, sizeof(rcmdfr));
rcmdfr.fr_ref = 1;
rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
/*
* Setup for a new RCMD proxy.
*/
int ippr_rcmd_new(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
aps->aps_psiz = sizeof(u_32_t);
KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t));
if (aps->aps_data == NULL)
return -1;
*(u_32_t *)aps->aps_data = 0;
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
return 0;
}
/*
* ipf_rcmd_atoi - implement a simple version of atoi
*/
u_short ipf_rcmd_atoi(ptr)
char *ptr;
{
register char *s = ptr, c;
register u_short i = 0;
while ((c = *s++) && isdigit(c)) {
i *= 10;
i += c - '0';
}
return i;
}
int ippr_rcmd_portmsg(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
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;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
dlen = mbufchainlen(m) - off;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
if ((*(u_32_t *)aps->aps_data != 0) &&
(tcp->th_seq != *(u_32_t *)aps->aps_data))
return 0;
portbuf[sizeof(portbuf) - 1] = '\0';
s = portbuf;
sp = ipf_rcmd_atoi(s);
if (!sp)
return 0;
/*
* 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);
if (ipn == NULL) {
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = sp;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, 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);
}
ip->ip_src = swip;
}
return 0;
}
int ippr_rcmd_out(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
return ippr_rcmd_portmsg(fin, ip, aps, nat);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.0.2.25.2.5 1997/12/02 13:55:39 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.2 1999/10/05 12:59:08 darrenr Exp $";
#endif
#include <sys/types.h>
@ -52,16 +52,18 @@ static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.0.2.25.2.5 1997/12/02 13:55:
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
extern fr_flags, fr_active;
int ipfr_timer_id = 0;
int fr_running = 0;
int ipl_unreach = ICMP_UNREACH_HOST;
u_long ipl_frouteok[2] = {0, 0};
static void frzerostats __P((caddr_t));
static int frrequest __P((int, int, caddr_t, int));
kmutex_t ipl_mutex, ipf_mutex, ipfs_mutex;
kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
static int frrequest __P((minor_t, int, caddr_t, int));
kmutex_t ipl_mutex, ipf_authmx, ipf_rw;
KRWLOCK_T ipf_mutex, ipfs_mutex, ipf_solaris;
KRWLOCK_T ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
kcondvar_t iplwait, ipfauthwait;
@ -72,49 +74,62 @@ int ipldetach()
#ifdef IPFDEBUG
cmn_err(CE_CONT, "ipldetach()\n");
#endif
#ifdef IPFILTER_LOG
for (i = IPL_LOGMAX; i >= 0; i--)
ipflog_clear(i);
untimeout(ipfr_timer_id);
#endif
i = FR_INQUE|FR_OUTQUE;
frflush(IPL_LOGIPF, &i);
(void) frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE);
ipfr_unload();
fr_stateunload();
ip_natunload();
cv_destroy(&iplwait);
cv_destroy(&ipfauthwait);
mutex_destroy(&ipf_authmx);
mutex_destroy(&ipl_mutex);
mutex_destroy(&ipf_mutex);
mutex_destroy(&ipfs_mutex);
mutex_destroy(&ipf_frag);
mutex_destroy(&ipf_state);
mutex_destroy(&ipf_natfrag);
mutex_destroy(&ipf_nat);
mutex_destroy(&ipf_auth);
mutex_destroy(&ipf_rw);
RW_DESTROY(&ipf_mutex);
RW_DESTROY(&ipf_frag);
RW_DESTROY(&ipf_state);
RW_DESTROY(&ipf_natfrag);
RW_DESTROY(&ipf_nat);
RW_DESTROY(&ipf_auth);
RW_DESTROY(&ipfs_mutex);
/* NOTE: This lock is acquired in ipf_detach */
RWLOCK_EXIT(&ipf_solaris);
RW_DESTROY(&ipf_solaris);
return 0;
}
int iplattach __P((void))
{
int i;
#ifdef IPFDEBUG
cmn_err(CE_CONT, "iplattach()\n");
#endif
bzero((char *)nat_table, sizeof(nat_table));
bzero((char *)frcache, sizeof(frcache));
mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_mutex, "ipf filter mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipfs_mutex, "ipf solaris mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_frag, "ipf fragment mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_state, "ipf IP state mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_nat, "ipf IP NAT mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_natfrag, "ipf IP NAT-Frag mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_auth, "ipf IP User-Auth mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_rw, "ipf rw mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_authmx, "ipf auth log mutex", MUTEX_DRIVER, NULL);
RWLOCK_INIT(&ipf_solaris, "ipf filter load/unload mutex", NULL);
RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock", NULL);
RWLOCK_INIT(&ipfs_mutex, "ipf solaris mutex", NULL);
RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock", NULL);
RWLOCK_INIT(&ipf_state, "ipf IP state rwlock", NULL);
RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock", NULL);
RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock", NULL);
RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock", NULL);
cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL);
cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL);
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
#ifdef IPFILTER_LOG
ipflog_init();
#endif
if (nat_init() == -1)
return -1;
if (fr_stateinit() == -1)
return -1;
if (appr_init() == -1)
return -1;
return 0;
}
@ -122,7 +137,7 @@ int iplattach __P((void))
static void frzerostats(data)
caddr_t data;
{
struct friostat fio;
friostat_t fio;
bcopy((char *)frstats, (char *)fio.f_st,
sizeof(struct filterstats) * 2);
@ -148,27 +163,38 @@ caddr_t data;
int iplioctl(dev, cmd, data, mode, cp, rp)
dev_t dev;
int cmd;
int data;
#if SOLARIS2 >= 7
intptr_t data;
#else
int *data;
#endif
int mode;
cred_t *cp;
int *rp;
{
int error = 0, unit, tmp;
int error = 0, tmp;
minor_t unit;
#ifdef IPFDEBUG
cmn_err(CE_CONT, "iplioctl(%x,%x,%x,%d,%x,%d)\n",
dev, cmd, data, mode, cp, rp);
#endif
unit = getminor(dev);
if ((IPL_LOGMAX < unit) || (unit < 0))
if (IPL_LOGMAX < unit)
return ENXIO;
if (fr_running <= 0)
return 0;
READ_ENTER(&ipf_solaris);
if (unit == IPL_LOGNAT) {
error = nat_ioctl((caddr_t)data, cmd, mode);
RWLOCK_EXIT(&ipf_solaris);
return error;
}
if (unit == IPL_LOGSTATE) {
error = fr_state_ioctl((caddr_t)data, cmd, mode);
RWLOCK_EXIT(&ipf_solaris);
return error;
}
@ -178,16 +204,20 @@ int *rp;
u_int enable;
if (!(mode & FWRITE))
return EPERM;
IRCOPY((caddr_t)data, (caddr_t)&enable, sizeof(enable));
error = EPERM;
else
IRCOPY((caddr_t)data, (caddr_t)&enable, sizeof(enable));
break;
}
case SIOCSETFF :
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
IRCOPY((caddr_t)data, (caddr_t)&fr_flags, sizeof(fr_flags));
mutex_exit(&ipf_mutex);
error = EPERM;
else {
WRITE_ENTER(&ipf_mutex);
IRCOPY((caddr_t)data, (caddr_t)&fr_flags,
sizeof(fr_flags));
RWLOCK_EXIT(&ipf_mutex);
}
break;
case SIOCGETFF :
IWCOPY((caddr_t)&fr_flags, (caddr_t)data, sizeof(fr_flags));
@ -197,34 +227,36 @@ int *rp;
case SIOCADAFR :
case SIOCZRLST :
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
error = frrequest(unit, cmd, (caddr_t)data, fr_active);
mutex_exit(&ipf_mutex);
error = EPERM;
else
error = frrequest(unit, cmd, (caddr_t)data, fr_active);
break;
case SIOCINIFR :
case SIOCRMIFR :
case SIOCADIFR :
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
error = frrequest(unit, cmd, (caddr_t)data, 1 - fr_active);
mutex_exit(&ipf_mutex);
error = EPERM;
else
error = frrequest(unit, cmd, (caddr_t)data,
1 - fr_active);
break;
case SIOCSWAPA :
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
IWCOPY((caddr_t)&fr_active, (caddr_t)data, sizeof(fr_active));
fr_active = 1 - fr_active;
mutex_exit(&ipf_mutex);
error = EPERM;
else {
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
IWCOPY((caddr_t)&fr_active, (caddr_t)data,
sizeof(fr_active));
fr_active = 1 - fr_active;
RWLOCK_EXIT(&ipf_mutex);
}
break;
case SIOCGETFS :
{
struct friostat fio;
mutex_enter(&ipf_mutex);
READ_ENTER(&ipf_mutex);
bcopy((char *)frstats, (char *)fio.f_st,
sizeof(struct filterstats) * 2);
fio.f_fin[0] = ipfilter[0][0];
@ -238,51 +270,75 @@ int *rp;
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
mutex_exit(&ipf_mutex);
fio.f_running = fr_running;
fio.f_groups[0][0] = ipfgroups[0][0];
fio.f_groups[0][1] = ipfgroups[0][1];
fio.f_groups[1][0] = ipfgroups[1][0];
fio.f_groups[1][1] = ipfgroups[1][1];
fio.f_groups[2][0] = ipfgroups[2][0];
fio.f_groups[2][1] = ipfgroups[2][1];
#ifdef IPFILTER_LOG
fio.f_logging = 1;
#else
fio.f_logging = 0;
#endif
fio.f_defpass = fr_pass;
strncpy(fio.f_version, fio.f_version,
sizeof(fio.f_version));
RWLOCK_EXIT(&ipf_mutex);
IWCOPY((caddr_t)&fio, (caddr_t)data, sizeof(fio));
break;
}
case SIOCFRZST :
if (!(mode & FWRITE))
return EPERM;
frzerostats((caddr_t)data);
error = EPERM;
else
frzerostats((caddr_t)data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
return EPERM;
IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
mutex_enter(&ipf_mutex);
frflush(unit, &tmp);
mutex_exit(&ipf_mutex);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
error = EPERM;
else {
IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
tmp = frflush(unit, tmp);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
}
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
return EPERM;
tmp = ipflog_clear(unit);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
error = EPERM;
else {
tmp = ipflog_clear(unit);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
}
break;
#endif /* IPFILTER_LOG */
case SIOCFRSYN :
if (!(mode & FWRITE))
return EPERM;
error = ipfsync();
error = EPERM;
else
error = ipfsync();
break;
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), (caddr_t)data,
sizeof(ipfrstat_t));
break;
case FIONREAD :
{
#ifdef IPFILTER_LOG
IWCOPY((caddr_t)&iplused[IPL_LOGIPF], (caddr_t)data,
sizeof(iplused[IPL_LOGIPF]));
int copy = (int)iplused[IPL_LOGIPF];
IWCOPY((caddr_t)&copy, (caddr_t)data, sizeof(copy));
#endif
break;
}
case SIOCAUTHW :
case SIOCAUTHR :
if (!(mode & FWRITE))
return EPERM;
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
case SIOCATHST :
error = fr_auth_ioctl((caddr_t)data, cmd, NULL, NULL);
break;
@ -290,6 +346,7 @@ int *rp;
error = EINVAL;
break;
}
RWLOCK_EXIT(&ipf_solaris);
return error;
}
@ -297,8 +354,8 @@ int *rp;
ill_t *get_unit(name)
char *name;
{
size_t len = strlen(name) + 1; /* includes \0 */
ill_t *il;
int len = strlen(name) + 1; /* includes \0 */
for (il = ill_g_head; il; il = il->ill_next)
if ((len == il->ill_name_length) &&
@ -308,27 +365,8 @@ char *name;
}
static void fixskip(listp, rp, addremove)
frentry_t **listp, *rp;
int addremove;
{
frentry_t *fp;
int rules = 0, rn = 0;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
;
if (!fp)
return;
for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
if (fp->fr_skip && (rn + fp->fr_skip >= rules))
fp->fr_skip += addremove;
}
static int frrequest(unit, req, data, set)
int unit;
minor_t unit;
int req, set;
caddr_t data;
{
@ -337,24 +375,31 @@ caddr_t data;
frentry_t fr;
frdest_t *fdp;
frgroup_t *fg = NULL;
int error = 0, in, group;
int error = 0, in;
u_int group;
ill_t *ill;
ipif_t *ipif;
ire_t *ire;
fp = &fr;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
fp->fr_ref = 0;
WRITE_ENTER(&ipf_mutex);
/*
* Check that the group number does exist and that if a head group
* has been specified, doesn't exist.
*/
if (fp->fr_grhead &&
fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
return EEXIST;
if (fp->fr_group &&
!fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
return ESRCH;
if ((req != SIOCZRLST) && fp->fr_grhead &&
fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL)) {
error = EEXIST;
goto out;
}
if ((req != SIOCZRLST) && fp->fr_group &&
!fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL)) {
error = ESRCH;
goto out;
}
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
@ -364,12 +409,18 @@ caddr_t data;
ftail = fprev = &ipacct[in][set];
else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
ftail = fprev = &ipfilter[in][set];
else
return ESRCH;
else {
error = ESRCH;
goto out;
}
if ((group = fp->fr_group)) {
if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
return ESRCH;
group = fp->fr_group;
if (group != NULL) {
fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL);
if (fg == NULL) {
error = ESRCH;
goto out;
}
ftail = fprev = fg->fg_start;
}
@ -435,12 +486,15 @@ caddr_t data;
* If zero'ing statistics, copy current to caller and zero.
*/
if (req == SIOCZRLST) {
if (!f)
return ESRCH;
if (!f) {
error = ESRCH;
goto out;
}
MUTEX_DOWNGRADE(&ipf_mutex);
IWCOPY((caddr_t)f, data, sizeof(*f));
f->fr_hits = 0;
f->fr_bytes = 0;
return 0;
goto out;
}
if (!f) {
@ -458,26 +512,32 @@ caddr_t data;
if (!f)
error = ESRCH;
else {
if (f->fr_ref > 1)
return EBUSY;
if (f->fr_ref > 1) {
error = EBUSY;
goto out;
}
if (fg && fg->fg_head)
fg->fg_head->fr_ref--;
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
if (unit == IPL_LOGAUTH) {
error = fr_auth_ioctl(data, req, f, ftail);
goto out;
}
if (f->fr_grhead)
fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
set);
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
unit, set);
fixskip(fprev, f, -1);
*ftail = f->fr_next;
KFREE(f);
}
} else {
if (f)
if (f) {
error = EEXIST;
else {
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
KMALLOC(f, frentry_t *, sizeof(*f));
} else {
if (unit == IPL_LOGAUTH) {
error = fr_auth_ioctl(data, req, f, ftail);
goto out;
}
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
fg->fg_head->fr_ref++;
@ -489,12 +549,15 @@ caddr_t data;
if (req == SIOCINIFR || req == SIOCINAFR)
fixskip(fprev, f, 1);
f->fr_grp = NULL;
if ((group = f->fr_grhead))
group = f->fr_grhead;
if (group != NULL)
fg = fr_addgroup(group, f, unit, set);
} else
error = ENOMEM;
}
}
out:
RWLOCK_EXIT(&ipf_mutex);
return (error);
}
@ -507,14 +570,14 @@ dev_t *devp;
int flags, otype;
cred_t *cred;
{
u_int min = getminor(*devp);
minor_t min = getminor(*devp);
#ifdef IPFDEBUG
cmn_err(CE_CONT, "iplopen(%x,%x,%x,%x)\n", devp, flags, otype, cred);
#endif
if (!(otype & OTYP_CHR))
if ((fr_running <= 0) || !(otype & OTYP_CHR))
return ENXIO;
min = (2 < min || min < 0) ? ENXIO : 0;
min = (IPL_LOGMAX < min) ? ENXIO : 0;
return min;
}
@ -524,12 +587,12 @@ dev_t dev;
int flags, otype;
cred_t *cred;
{
u_int min = getminor(dev);
minor_t min = getminor(dev);
#ifdef IPFDEBUG
cmn_err(CE_CONT, "iplclose(%x,%x,%x,%x)\n", dev, flags, otype, cred);
#endif
min = (2 < min || min < 0) ? ENXIO : 0;
min = (IPL_LOGMAX < min) ? ENXIO : 0;
return min;
}
@ -557,72 +620,76 @@ cred_t *cp;
* send_reset - this could conceivably be a call to tcp_respond(), but that
* requires a large amount of setting up and isn't any more efficient.
*/
int send_reset(iphdr, qif)
int send_reset(fin, iphdr, qif)
fr_info_t *fin;
ip_t *iphdr;
qif_t *qif;
{
struct tcpiphdr *ti = (struct tcpiphdr *)iphdr;
struct ip *ip;
struct tcphdr *tcp;
queue_t *q = qif->qf_q;
mblk_t *m;
tcphdr_t *tcp, *tcp2;
int tlen = 0;
mblk_t *m;
ip_t *ip;
if (ti->ti_flags & TH_RST)
tcp = (struct tcphdr *)fin->fin_dp;
if (tcp->th_flags & TH_RST)
return -1;
if (ti->ti_flags & TH_SYN)
if (tcp->th_flags & TH_SYN)
tlen = 1;
if ((m = (mblk_t *)allocb(sizeof(struct tcpiphdr), BPRI_HI)) == NULL)
if ((m = (mblk_t *)allocb(sizeof(*ip) + sizeof(*tcp),BPRI_HI)) == NULL)
return -1;
MTYPE(m) = M_DATA;
m->b_wptr += sizeof(struct tcpiphdr);
bzero((char *)m->b_rptr, sizeof(struct tcpiphdr));
m->b_wptr += sizeof(*ip) + sizeof(*tcp);
bzero((char *)m->b_rptr, sizeof(*ip) + sizeof(*tcp));
ip = (ip_t *)m->b_rptr;
tcp = (struct tcphdr *)(m->b_rptr + sizeof(*ip));
tcp2 = (struct tcphdr *)(m->b_rptr + sizeof(*ip));
ip->ip_src.s_addr = ti->ti_dst.s_addr;
ip->ip_dst.s_addr = ti->ti_src.s_addr;
tcp->th_dport = ti->ti_sport;
tcp->th_sport = ti->ti_dport;
tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen);
tcp->th_off = sizeof(struct tcphdr) >> 2;
tcp->th_flags = TH_RST|TH_ACK;
ip->ip_src.s_addr = iphdr->ip_dst.s_addr;
ip->ip_dst.s_addr = iphdr->ip_src.s_addr;
tcp2->th_dport = tcp->th_sport;
tcp2->th_sport = tcp->th_dport;
tcp2->th_ack = htonl(ntohl(tcp->th_seq) + tlen);
tcp2->th_seq = tcp->th_ack;
tcp2->th_off = sizeof(struct tcphdr) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
/*
* This is to get around a bug in the Solaris 2.4/2.5 TCP checksum
* computation that is done by their put routine.
*/
tcp->th_sum = htons(0x14);
tcp2->th_sum = htons(0x14);
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
ip->ip_p = IPPROTO_TCP;
ip->ip_len = htons(sizeof(struct tcpiphdr));
ip->ip_tos = ((struct ip *)ti)->ip_tos;
ip->ip_len = htons(sizeof(*ip) + sizeof(*tcp));
ip->ip_tos = iphdr->ip_tos;
ip->ip_off = 0;
ip->ip_ttl = 60;
ip->ip_sum = 0;
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
ip_wput(qif->qf_ill->ill_wq, m);
READ_ENTER(&ipf_solaris);
READ_ENTER(&ipfs_mutex);
return 0;
}
int icmp_error(ip, type, code, qif, src)
int icmp_error(ip, type, code, qif, dst)
ip_t *ip;
int type, code;
qif_t *qif;
struct in_addr src;
struct in_addr dst;
{
queue_t *q = qif->qf_q;
mblk_t *mb;
struct icmp *icmp;
ip_t *nip;
int sz = sizeof(*nip) + sizeof(*icmp) + 8;
u_short sz = sizeof(*nip) + sizeof(*icmp) + 8;
if ((mb = (mblk_t *)allocb(sz, BPRI_HI)) == NULL)
if ((mb = (mblk_t *)allocb((size_t)sz, BPRI_HI)) == NULL)
return -1;
MTYPE(mb) = M_DATA;
mb->b_wptr += sz;
bzero((char *)mb->b_rptr, sz);
bzero((char *)mb->b_rptr, (size_t)sz);
nip = (ip_t *)mb->b_rptr;
icmp = (struct icmp *)(nip + 1);
@ -633,9 +700,13 @@ struct in_addr src;
nip->ip_sum = 0;
nip->ip_ttl = 60;
nip->ip_tos = ip->ip_tos;
nip->ip_len = htons(sz);
nip->ip_src.s_addr = ip->ip_dst.s_addr;
nip->ip_dst.s_addr = ip->ip_src.s_addr;
nip->ip_len = (u_short)htons(sz);
if (dst.s_addr == 0) {
if (fr_ifpaddr(qif->qf_ill, &dst) == -1)
return -1;
}
nip->ip_src = dst;
nip->ip_dst = ip->ip_src;
icmp->icmp_type = type;
icmp->icmp_code = code;
@ -643,7 +714,26 @@ struct in_addr src;
bcopy((char *)ip, (char *)&icmp->icmp_ip, sizeof(*ip));
bcopy((char *)ip + (ip->ip_hl << 2),
(char *)&icmp->icmp_ip + sizeof(*ip), 8); /* 64 bits */
#ifndef sparc
ip = &icmp->icmp_ip;
{
u_short __iplen, __ipoff;
__iplen = ip->ip_len;
__ipoff = ip->ip_len;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
}
#endif
icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8);
/*
* Need to exit out of these so we don't recursively call rw_enter
* from fr_qout.
*/
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
ip_wput(qif->qf_ill->ill_wq, mb);
READ_ENTER(&ipf_solaris);
READ_ENTER(&ipfs_mutex);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* $Id: ip_state.h,v 2.0.2.14.2.6 1998/05/24 05:18:04 darrenr Exp $
* $Id: ip_state.h,v 2.1 1999/08/04 17:30:00 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@ -31,13 +31,16 @@ typedef struct icmpstate {
u_char ics_type;
} icmpstate_t;
typedef struct tcpdata {
u_32_t td_end;
u_32_t td_maxend;
u_short td_maxwin;
} tcpdata_t;
typedef struct tcpstate {
u_short ts_sport;
u_short ts_dport;
u_long ts_seq;
u_long ts_ack;
u_short ts_swin;
u_short ts_dwin;
tcpdata_t ts_data[2];
u_char ts_state[2];
} tcpstate_t;
@ -49,16 +52,18 @@ typedef struct ipstate {
U_QUAD_T is_bytes;
void *is_ifpin;
void *is_ifpout;
frentry_t *is_rule;
struct in_addr is_src;
struct in_addr is_dst;
u_char is_p;
u_char is_flags;
u_32_t is_opt;
u_32_t is_optmsk;
u_short is_sec;
u_short is_secmsk;
u_short is_auth;
u_short is_authmsk;
u_char is_p; /* Protocol */
u_char is_rout; /* Is rule in/out ? */
u_32_t is_flags;
u_32_t is_opt; /* packet options set */
u_32_t is_optmsk; /* " " mask */
u_short is_sec; /* security options set */
u_short is_secmsk; /* " " mask */
u_short is_auth; /* authentication options set */
u_short is_authmsk; /* " " mask */
union {
icmpstate_t is_ics;
tcpstate_t is_ts;
@ -67,17 +72,29 @@ typedef struct ipstate {
} ipstate_t;
#define is_icmp is_ps.is_ics
#define is_type is_icmp.ics_type
#define is_code is_icmp.ics_code
#define is_tcp is_ps.is_ts
#define is_udp is_ps.is_us
#define is_seq is_tcp.ts_seq
#define is_ack is_tcp.ts_ack
#define is_dwin is_tcp.ts_dwin
#define is_swin is_tcp.ts_swin
#define is_send is_tcp.ts_data[0].td_end
#define is_dend is_tcp.ts_data[1].td_end
#define is_maxswin is_tcp.ts_data[0].td_maxwin
#define is_maxdwin is_tcp.ts_data[1].td_maxwin
#define is_maxsend is_tcp.ts_data[0].td_maxend
#define is_maxdend is_tcp.ts_data[1].td_maxend
#define is_sport is_tcp.ts_sport
#define is_dport is_tcp.ts_dport
#define is_state is_tcp.ts_state
#define TH_OPENING (TH_SYN|TH_ACK)
/*
* is_flags:
* Bits 0 - 3 are use as a mask with the current packet's bits to check for
* whether it is short, tcp/udp, a fragment or the presence of IP options.
* Bits 4 - 7 are set from the initial packet and contain what the packet
* anded with bits 0-3 must match.
* Bits 8,9 are used to indicate wildcard source/destination port matching.
*/
typedef struct ipslog {
@ -87,6 +104,7 @@ typedef struct ipslog {
struct in_addr isl_dst;
u_char isl_p;
u_char isl_flags;
u_char isl_state[2];
u_short isl_type;
union {
u_short isl_filler[2];
@ -117,6 +135,7 @@ typedef struct ips_stat {
u_long iss_active;
u_long iss_logged;
u_long iss_logfail;
u_long iss_inuse;
ipstate_t **iss_table;
} ips_stat_t;
@ -128,13 +147,14 @@ extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_udptimeout;
extern u_long fr_icmptimeout;
extern int fr_stateinit __P((void));
extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
extern int fr_addstate __P((ip_t *, fr_info_t *, u_int));
extern int fr_checkstate __P((ip_t *, fr_info_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 void fr_timeoutstate __P((void));
extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
extern void fr_stateunload __P((void));
extern void ipstate_log __P((struct ipstate *, u_short));
extern void ipstate_log __P((struct ipstate *, u_int));
#if defined(__NetBSD__) || defined(__OpenBSD__)
extern int fr_state_ioctl __P((caddr_t, u_long, int));
#else

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -36,14 +36,16 @@
#include <resolv.h>
#include "ip_compat.h"
#include "ip_fil.h"
#include "ip_nat.h"
#include "ip_state.h"
#include "ipf.h"
#include "ipl.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.0.2.13.2.4 1998/05/23 14:29:44 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.2 1999/08/06 15:26:08 darrenr Exp $";
#endif
static void frsync __P((void));
#if SOLARIS
static void blockunknown __P((void));
#endif
@ -53,6 +55,7 @@ extern char *index __P((const char *, int));
extern char *optarg;
void frsync __P((void));
void zerostats __P((void));
int main __P((int, char *[]));
@ -67,6 +70,18 @@ static int opendevice __P((char *));
static void closedevice __P((void));
static char *getline __P((char *, size_t, FILE *));
static char *ipfname = IPL_NAME;
static void usage __P((void));
static void showversion __P((void));
static int get_flags __P((void));
static void usage()
{
fprintf(stderr, "usage: ipf [-AdDEInoPrsUvVyzZ] %s %s %s\n",
"[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");
exit(1);
}
int main(argc,argv)
int argc;
@ -74,9 +89,11 @@ char *argv[];
{
int c;
while ((c = getopt(argc, argv, "AdDEf:F:Il:noPrsUvyzZ")) != -1) {
while ((c = getopt(argc, argv, "AdDEf:F:Il:noPrsUvVyzZ")) != -1) {
switch (c)
{
case '?' :
usage();
case 'A' :
opts &= ~OPT_INACTIVE;
break;
@ -124,6 +141,9 @@ char *argv[];
case 'v' :
opts |= OPT_VERBOSE;
break;
case 'V' :
showversion();
break;
case 'y' :
frsync();
break;
@ -168,6 +188,18 @@ static void closedevice()
}
static int get_flags()
{
int i;
if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) {
perror("SIOCFRENB");
return 0;
}
return i;
}
static void set_state(enable)
u_int enable;
{
@ -183,13 +215,17 @@ char *name, *file;
FILE *fp;
char line[513], *s;
struct frentry *fr;
u_int add = SIOCADAFR, del = SIOCRMAFR;
u_int add, del;
int linenum = 0;
(void) opendevice(ipfname);
if (opts & OPT_INACTIVE) {
add = SIOCADIFR;
del = SIOCRMIFR;
} else {
add = SIOCADAFR;
del = SIOCRMAFR;
}
if (opts & OPT_DEBUG)
printf("add %x del %x\n", add, del);
@ -205,6 +241,7 @@ char *name, *file;
}
while (getline(line, sizeof(line), fp)) {
linenum++;
/*
* treat CR as EOL. LF is converted to NUL by getline().
*/
@ -222,7 +259,7 @@ char *name, *file;
if (opts & OPT_VERBOSE)
(void)fprintf(stderr, "[%s]\n", line);
fr = parse(line);
fr = parse(line, linenum);
(void)fflush(stdout);
if (fr) {
@ -309,13 +346,12 @@ FILE *file;
static void packetlogon(opt)
char *opt;
{
int err, flag = 0;
int flag, err;
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if ((err = ioctl(fd, SIOCGETFF, &flag)))
perror("ioctl(SIOCGETFF)");
printf("log flag is currently %#x\n", flag);
err = get_flags();
if (err != 0) {
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
printf("log flag is currently %#x\n", flag);
}
flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK);
@ -340,9 +376,7 @@ char *opt;
perror("ioctl(SIOCSETFF)");
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if ((err = ioctl(fd, SIOCGETFF, &flag)))
perror("ioctl(SIOCGETFF)");
flag = get_flags();
printf("log flag is now %#x\n", flag);
}
}
@ -404,7 +438,7 @@ static void swapactive()
}
static void frsync()
void frsync()
{
int frsyn = 0;
@ -465,17 +499,14 @@ friostat_t *fp;
#if SOLARIS
static void blockunknown()
{
int flag;
u_32_t flag;
if (opendevice(ipfname) == -1)
return;
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if (ioctl(fd, SIOCGETFF, &flag))
perror("ioctl(SIOCGETFF)");
flag = get_flags();
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
printf("log flag is currently %#x\n", flag);
}
flag ^= FF_BLOCKNONIP;
@ -490,3 +521,54 @@ static void blockunknown()
}
}
#endif
static void showversion()
{
struct friostat fio;
u_32_t flags;
char *s;
printf("ipf: %s (%d)\n", IPL_VERSION, sizeof(frentry_t));
if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fio)) {
perror("ioctl(SIOCGETFS");
return;
}
flags = get_flags();
printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
(int)sizeof(fio.f_version), fio.f_version);
printf("Running: %s\n", fio.f_running ? "yes" : "no");
printf("Log Flags: %#x = ", flags);
s = "";
if (flags & FF_LOGPASS) {
printf("pass");
s = ", ";
}
if (flags & FF_LOGBLOCK) {
printf("%sblock", s);
s = ", ";
}
if (flags & FF_LOGNOMATCH) {
printf("%snomatch", s);
s = ", ";
}
if (flags & FF_BLOCKNONIP) {
printf("%snonip", s);
s = ", ";
}
if (!*s)
printf("none set");
putchar('\n');
printf("Default: ");
if (fio.f_defpass & FR_PASS)
s = "pass";
else if (fio.f_defpass & FR_BLOCK)
s = "block";
else
s = "nomatch -> block";
printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un");
printf("Active list: %d\n", fio.f_active);
}

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ipf.h 1.12 6/5/96
* $Id: ipf.h,v 2.0.2.12 1997/09/28 07:11:50 darrenr Exp $
* $Id: ipf.h,v 2.1.2.1 1999/10/05 12:59:25 darrenr Exp $
*/
#ifndef __IPF_H__
@ -15,26 +15,28 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#define OPT_REMOVE 0x00001
#define OPT_DEBUG 0x00002
#define OPT_OUTQUE FR_OUTQUE /* 0x0004 */
#define OPT_INQUE FR_INQUE /* 0x0008 */
#define OPT_LOG FR_LOG /* 0x0010 */
#define OPT_SHOWLIST 0x00020
#define OPT_VERBOSE 0x00040
#define OPT_DONOTHING 0x00080
#define OPT_HITS 0x00100
#define OPT_BRIEF 0x00200
#define OPT_REMOVE 0x000001
#define OPT_DEBUG 0x000002
#define OPT_OUTQUE FR_OUTQUE /* 0x00004 */
#define OPT_INQUE FR_INQUE /* 0x00008 */
#define OPT_LOG FR_LOG /* 0x00010 */
#define OPT_SHOWLIST 0x000020
#define OPT_VERBOSE 0x000040
#define OPT_DONOTHING 0x000080
#define OPT_HITS 0x000100
#define OPT_BRIEF 0x000200
#define OPT_ACCNT FR_ACCOUNT /* 0x0400 */
#define OPT_FRSTATES FR_KEEPFRAG /* 0x0800 */
#define OPT_IPSTATES FR_KEEPSTATE /* 0x1000 */
#define OPT_INACTIVE FR_INACTIVE /* 0x2000 */
#define OPT_SHOWLINENO 0x04000
#define OPT_PRINTFR 0x08000
#define OPT_ZERORULEST 0x10000
#define OPT_SAVEOUT 0x20000
#define OPT_AUTHSTATS 0x40000
#define OPT_RAW 0x80000
#define OPT_SHOWLINENO 0x004000
#define OPT_PRINTFR 0x008000
#define OPT_ZERORULEST 0x010000
#define OPT_SAVEOUT 0x020000
#define OPT_AUTHSTATS 0x040000
#define OPT_RAW 0x080000
#define OPT_NAT 0x100000
#define OPT_GROUPS 0x200000
#ifndef __P
# ifdef __STDC__
@ -48,11 +50,11 @@
extern char *strdup __P((char *));
#endif
extern struct frentry *parse __P((char *));
extern struct frentry *parse __P((char *, int));
extern void printfr __P((struct frentry *));
extern void binprint __P((struct frentry *)), initparse __P((void));
extern u_short portnum __P((char *));
extern int portnum __P((char *, u_short *, int));
struct ipopt_names {
@ -64,18 +66,20 @@ struct ipopt_names {
extern u_32_t buildopts __P((char *, char *, int));
extern u_32_t hostnum __P((char *, int *));
extern u_32_t optname __P((char ***, u_short *));
extern u_32_t hostnum __P((char *, int *, int));
extern u_32_t optname __P((char ***, u_short *, int));
extern void printpacket __P((ip_t *));
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
extern int gethostname __P((char *, int ));
extern void sync __P((void));
#endif
#ifdef sun
#define STRERROR(x) sys_errlist[x]
#if defined(sun) && !SOLARIS
# define STRERROR(x) sys_errlist[x]
extern char *sys_errlist[];
#else
#define STRERROR(x) strerror(x)
# define STRERROR(x) strerror(x)
#endif
#ifndef MIN

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -51,7 +51,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.0.2.7.2.1 1997/11/12 10:56:06 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.1 1999/08/04 17:30:02 darrenr Exp $";
#endif
static int etherf_open __P((char *));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -42,7 +42,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.0.2.8.2.1 1997/11/12 10:56:07 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.1 1999/08/04 17:30:03 darrenr Exp $";
#endif
extern int opts;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -29,11 +29,11 @@
#include "ip_compat.h"
#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "pcap.h"
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.0.2.6.2.1 1997/11/12 10:56:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.1 1999/08/04 17:30:03 darrenr Exp $";
#endif
struct llc {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -33,11 +33,11 @@
#include "ip_compat.h"
#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "snoop.h"
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.0.2.6.2.1 1997/11/12 10:56:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.1 1999/08/04 17:30:04 darrenr Exp $";
#endif
struct llc {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -60,7 +60,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.0.2.6.2.1 1997/11/12 10:56:10 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.1 1999/08/04 17:30:04 darrenr Exp $";
#endif
static int tcpd_open __P((char *));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -43,7 +43,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.0.2.11.2.3 1998/05/23 19:20:32 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.1 1999/08/04 17:30:05 darrenr Exp $";
#endif
extern int opts;
@ -196,7 +196,7 @@ int cnt, *dir;
*dir = 0;
if (!parseline(line, (ip_t *)buf, ifn, dir))
#if 0
return sizeof(struct tcpiphdr);
return sizeof(*ip) + sizeof(tcphdr_t);
#else
return sizeof(ip_t);
#endif
@ -263,6 +263,9 @@ int *out;
tx_proto = "icmp";
}
cpp++;
} else if (isdigit(**cpp) && !index(*cpp, '.')) {
ip->ip_p = atoi(*cpp);
cpp++;
} else
ip->ip_p = IPPROTO_IP;
@ -308,6 +311,8 @@ int *out;
if (tcp->th_flags)
cpp++;
assert(tcp->th_flags != 0);
tcp->th_win = htons(4096);
tcp->th_off = sizeof(*tcp) >> 2;
} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {
extern char *tx_icmptypes[];
char **s, *t;
@ -340,5 +345,6 @@ int *out;
else if (ip->ip_p == IPPROTO_ICMP)
bcopy((char *)ic, ((char *)ip) + (ip->ip_hl << 2),
sizeof(*ic));
ip->ip_len = htons(ip->ip_len);
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1999 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -11,6 +11,6 @@
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter v3.2.7"
#define IPL_VERSION "IP Filter: v3.3.3"
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -49,3 +49,6 @@ typedef struct aniphdr {
#define ah_tcp ah_un.ahu_tcp
#define ah_udp ah_un.ahu_udp
#define ah_icmp ah_un.ahu_icmp
extern int get_arpipv4 __P((char *, char *));

View File

@ -1,12 +1,12 @@
%{
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_l.l,v 2.0.2.15.2.5 1997/12/28 01:32:13 darrenr Exp $
* $Id: iplang_l.l,v 2.1 1999/08/04 17:30:53 darrenr Exp $
*/
#include <stdio.h>
#include <string.h>
@ -310,7 +310,9 @@ int nstate, fornext;
void swallow()
{
int c = input();
int c;
c = input();
if (c == '#') {
while ((c != '\n') && (c != EOF))

View File

@ -1,14 +1,14 @@
%{
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_y.y,v 2.0.2.18.2.7 1998/05/23 14:29:53 darrenr Exp $
* $Id: iplang_y.y,v 2.1 1999/08/04 17:30:53 darrenr Exp $
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@ -1431,6 +1431,21 @@ char **arg;
}
int arp_getipv4(ip, addr)
char *ip;
char *addr;
{
arp_t *a;
for (a = arplist; a; a = a->arp_next)
if (!bcmp(ip, (char *)&a->arp_addr, 4)) {
bcopy((char *)&a->arp_eaddr, addr, 6);
return 0;
}
return -1;
}
void reset_send()
{
sending.snd_if = iflist;

View File

@ -1,41 +1,51 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1997 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.0.2.29.2.9 1998/05/23 14:29:45 darrenr Exp $";
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1998 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.3.2.1 1999/08/14 04:46:07 darrenr Exp $";
#endif
#ifndef SOLARIS
#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun)
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
# if (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
# else
# include <sys/dir.h>
# endif
#else
# include <sys/filio.h>
# include <sys/byteorder.h>
#endif
#include <strings.h>
#include <signal.h>
#include <sys/dir.h>
#else
#include <sys/filio.h>
#include <sys/byteorder.h>
#endif
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/tcp_fsm.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@ -44,7 +54,6 @@ static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.0.2.29.2.9 1998/05/23 14:29:45
#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
# include <sys/user.h>
# include <netinet/ip_var.h>
#endif
@ -85,6 +94,15 @@ struct flags tcpfl[] = {
{ 0, '\0' }
};
#if SOLARIS
static char *pidfile = "/etc/opt/ipf/ipmon.pid";
#else
# if BSD >= 199306
static char *pidfile = "/var/run/ipmon.pid";
# else
static char *pidfile = "/etc/ipmon.pid";
# endif
#endif
static char line[2048];
static int opts = 0;
@ -92,19 +110,27 @@ static FILE *newlog = NULL;
static char *logfile = NULL;
static int donehup = 0;
static void usage __P((char *));
static void handlehup __P((void));
static void handlehup __P((int));
static void flushlogs __P((char *, FILE *));
static void print_log __P((int, FILE *, char *, int));
static void print_ipflog __P((FILE *, char *, int));
static void print_natlog __P((FILE *, char *, int));
static void print_statelog __P((FILE *, char *, int));
static void dumphex __P((FILE *, u_char *, int));
static int read_log __P((int, int *, char *, int, FILE *));
static int read_log __P((int, int *, char *, int));
static void write_pid __P((char *));
char *hostname __P((int, struct in_addr));
char *portname __P((int, char *, u_short));
char *portname __P((int, char *, u_int));
int main __P((int, char *[]));
static void logopts __P((int, char *));
static void init_tabs __P((void));
static char *getproto __P((u_int));
static char **protocols = NULL;
static char **udp_ports = NULL;
static char **tcp_ports = NULL;
#define OPT_SYSLOG 0x001
@ -117,28 +143,106 @@ static void logopts __P((int, char *));
#define OPT_STATE 0x100
#define OPT_FILTER 0x200
#define OPT_PORTNUM 0x400
#define OPT_ALL (OPT_NAT|OPT_STATE|OPT_FILTER)
#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER)
#ifndef LOGFAC
#define LOGFAC LOG_LOCAL0
#endif
static void handlehup()
void handlehup(sig)
int sig;
{
FILE *fp;
signal(SIGHUP, handlehup);
if (logfile && (fp = fopen(logfile, "a")))
newlog = fp;
init_tabs();
donehup = 1;
}
static int read_log(fd, lenp, buf, bufsize, log)
static void init_tabs()
{
struct protoent *p;
struct servent *s;
char *name, **tab;
u_int port;
if (protocols != NULL) {
free(protocols);
protocols = NULL;
}
protocols = (char **)malloc(256 * sizeof(*protocols));
if (protocols != NULL) {
bzero((char *)protocols, 256 * sizeof(*protocols));
setprotoent(1);
while ((p = getprotoent()) != NULL)
if (p->p_proto >= 0 && p->p_proto <= 255 &&
p->p_name != NULL)
protocols[p->p_proto] = strdup(p->p_name);
endprotoent();
}
if (udp_ports != NULL) {
free(udp_ports);
udp_ports = NULL;
}
udp_ports = (char **)malloc(65536 * sizeof(*udp_ports));
if (udp_ports != NULL)
bzero((char *)udp_ports, 65536 * sizeof(*udp_ports));
if (tcp_ports != NULL) {
free(tcp_ports);
tcp_ports = NULL;
}
tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports));
if (tcp_ports != NULL)
bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports));
setservent(1);
while ((s = getservent()) != NULL) {
if (s->s_proto == NULL)
continue;
else if (!strcmp(s->s_proto, "tcp")) {
port = (u_int)s->s_port;
name = s->s_name;
tab = tcp_ports;
} else if (!strcmp(s->s_proto, "udp")) {
port = (u_int)s->s_port;
name = s->s_name;
tab = udp_ports;
} else
continue;
if ((port < 0 || port > 65535) || (name == NULL))
continue;
tab[port] = strdup(name);
}
endservent();
}
static char *getproto(p)
u_int p;
{
static char pnum[4];
char *s;
p &= 0xff;
s = protocols ? protocols[p] : NULL;
if (s == NULL) {
sprintf(pnum, "%u", p);
s = pnum;
}
return s;
}
static int read_log(fd, lenp, buf, bufsize)
int fd, bufsize, *lenp;
char *buf;
FILE *log;
{
int nr;
@ -170,18 +274,24 @@ struct in_addr ip;
char *portname(res, proto, port)
int res;
char *proto;
u_short port;
u_int port;
{
static char pname[8];
struct servent *serv;
char *s;
(void) sprintf(pname, "%hu", htons(port));
port = ntohs(port);
port &= 0xffff;
(void) sprintf(pname, "%u", port);
if (!res || (opts & OPT_PORTNUM))
return pname;
serv = getservbyport((int)port, proto);
if (!serv)
return pname;
return serv->s_name;
s = NULL;
if (!strcmp(proto, "tcp"))
s = tcp_ports[port];
else if (!strcmp(proto, "udp"))
s = udp_ports[port];
if (s == NULL)
s = pname;
return s;
}
@ -271,20 +381,20 @@ int blen;
strcpy(t, "NAT:MAP ");
else if (nl->nl_type == NL_NEWRDR)
strcpy(t, "NAT:RDR ");
else if (nl->nl_type == ISL_EXPIRE)
else if (nl->nl_type == NL_EXPIRE)
strcpy(t, "NAT:EXPIRE ");
else
sprintf(t, "Type: %d ", nl->nl_type);
t += strlen(t);
(void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nl_inip),
portname(res, NULL, nl->nl_inport));
portname(res, NULL, (u_int)nl->nl_inport));
t += strlen(t);
(void) sprintf(t, "%s,%s ", hostname(res, nl->nl_outip),
portname(res, NULL, nl->nl_outport));
portname(res, NULL, (u_int)nl->nl_outport));
t += strlen(t);
(void) sprintf(t, "[%s,%s]", hostname(res, nl->nl_origip),
portname(res, NULL, nl->nl_origport));
portname(res, NULL, (u_int)nl->nl_origport));
t += strlen(t);
if (nl->nl_type == NL_EXPIRE) {
#ifdef USE_QUAD_T
@ -312,8 +422,7 @@ int blen;
{
struct ipslog *sl;
iplog_t *ipl = (iplog_t *)buf;
struct protoent *pr;
char *t = line, *proto, pname[6];
char *t = line, *proto;
struct tm *tm;
int res, i, len;
@ -334,27 +443,29 @@ int blen;
if (sl->isl_type == ISL_NEW)
strcpy(t, "STATE:NEW ");
else if (sl->isl_type == ISL_EXPIRE)
strcpy(t, "STATE:EXPIRE ");
else if (sl->isl_type == ISL_EXPIRE) {
if ((sl->isl_p == IPPROTO_TCP) &&
(sl->isl_state[0] > TCPS_ESTABLISHED ||
sl->isl_state[1] > TCPS_ESTABLISHED))
strcpy(t, "STATE:CLOSE ");
else
strcpy(t, "STATE:EXPIRE ");
} else if (sl->isl_type == ISL_FLUSH)
strcpy(t, "STATE:FLUSH ");
else
sprintf(t, "Type: %d ", sl->isl_type);
t += strlen(t);
pr = getprotobynumber((int)sl->isl_p);
if (!pr) {
proto = pname;
sprintf(proto, "%d", (u_int)sl->isl_p);
} else
proto = pr->p_name;
proto = getproto(sl->isl_p);
if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) {
(void) sprintf(t, "%s,%s -> ",
hostname(res, sl->isl_src),
portname(res, proto, sl->isl_sport));
portname(res, proto, (u_int)sl->isl_sport));
t += strlen(t);
(void) sprintf(t, "%s,%s PR %s",
hostname(res, sl->isl_dst),
portname(res, proto, sl->isl_dport), proto);
portname(res, proto, (u_int)sl->isl_dport), proto);
} else if (sl->isl_p == IPPROTO_ICMP) {
(void) sprintf(t, "%s -> ", hostname(res, sl->isl_src));
t += strlen(t);
@ -436,11 +547,10 @@ FILE *log;
char *buf;
int blen;
{
struct protoent *pr;
struct tcphdr *tp;
tcphdr_t *tp;
struct icmp *ic;
struct tm *tm;
char c[3], pname[8], *t, *proto;
char *t, *proto;
u_short hl, p;
int i, lvl, res, len;
ip_t *ipc, *ip;
@ -480,60 +590,62 @@ int blen;
(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
len = (int)sizeof(ipf->fl_ifname);
(void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
t += strlen(t);
# if SOLARIS
if (isalpha(*(t - 1)))
*t++ = '0' + ipf->fl_unit;
# endif
#else
for (len = 0; len < 3; len++)
if (!ipf->fl_ifname[len])
if (ipf->fl_ifname[len] == '\0')
break;
if (ipf->fl_ifname[len])
len++;
(void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
#endif
t += strlen(t);
#endif
(void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
pr = getprotobynumber((int)p);
if (!pr) {
proto = pname;
sprintf(proto, "%d", (u_int)p);
} else
proto = pr->p_name;
t += strlen(t);
proto = getproto(p);
if (ipf->fl_flags & FF_SHORT) {
c[0] = 'S';
*t++ = 'S';
lvl = LOG_ERR;
} else if (ipf->fl_flags & FR_PASS) {
if (ipf->fl_flags & FR_LOGP)
c[0] = 'p';
*t++ = 'p';
else
c[0] = 'P';
*t++ = 'P';
lvl = LOG_NOTICE;
} else if (ipf->fl_flags & FR_BLOCK) {
if (ipf->fl_flags & FR_LOGB)
c[0] = 'b';
*t++ = 'b';
else
c[0] = 'B';
*t++ = 'B';
lvl = LOG_WARNING;
} else if (ipf->fl_flags & FF_LOGNOMATCH) {
c[0] = 'n';
*t++ = 'n';
lvl = LOG_NOTICE;
} else {
c[0] = 'L';
*t++ = 'L';
lvl = LOG_INFO;
}
c[1] = ' ';
c[2] = '\0';
(void) strcat(line, c);
t = line + strlen(line);
if (ipf->fl_loglevel != 0xffff)
lvl = ipf->fl_loglevel;
*t++ = ' ';
*t = '\0';
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !(ip->ip_off & 0x1fff)) {
tp = (struct tcphdr *)((char *)ip + hl);
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) &&
!(ip->ip_off & IP_OFFMASK)) {
tp = (tcphdr_t *)((char *)ip + hl);
if (!(ipf->fl_flags & (FI_SHORT << 16))) {
(void) sprintf(t, "%s,%s -> ",
hostname(res, ip->ip_src),
portname(res, proto, tp->th_sport));
portname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
(void) sprintf(t, "%s,%s PR %s len %hu %hu ",
hostname(res, ip->ip_dst),
portname(res, proto, tp->th_dport),
portname(res, proto, (u_int)tp->th_dport),
proto, hl, ip->ip_len);
t += strlen(t);
@ -542,12 +654,13 @@ int blen;
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
*t++ = tcpfl[i].flag;
}
if (opts & OPT_VERBOSE) {
(void) sprintf(t, " %lu %lu %hu",
(u_long)tp->th_seq,
(u_long)tp->th_ack, tp->th_win);
t += strlen(t);
if (opts & OPT_VERBOSE) {
(void) sprintf(t, " %lu %lu %hu",
(u_long)(ntohl(tp->th_seq)),
(u_long)(ntohl(tp->th_ack)),
ntohs(tp->th_win));
t += strlen(t);
}
}
*t = '\0';
} else {
@ -570,24 +683,18 @@ int blen;
ic->icmp_type == ICMP_REDIRECT ||
ic->icmp_type == ICMP_TIMXCEED) {
ipc = &ic->icmp_ip;
tp = (struct tcphdr *)((char *)ipc + hl);
tp = (tcphdr_t *)((char *)ipc + hl);
p = (u_short)ipc->ip_p;
pr = getprotobynumber((int)p);
if (!pr) {
proto = pname;
(void) sprintf(proto, "%d", (int)p);
} else
proto = pr->p_name;
proto = getproto(ipc->ip_p);
t += strlen(t);
(void) sprintf(t, " for %s,%s -",
hostname(res, ipc->ip_src),
portname(res, proto, tp->th_sport));
portname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
(void) sprintf(t, " %s,%s PR %s len %hu %hu",
hostname(res, ipc->ip_dst),
portname(res, proto, tp->th_dport),
portname(res, proto, (u_int)tp->th_dport),
proto, ipc->ip_hl << 2, ipc->ip_len);
}
} else {
@ -596,11 +703,12 @@ int blen;
(void) sprintf(t, "%s PR %s len %hu (%hu)",
hostname(res, ip->ip_dst), proto, hl, ip->ip_len);
t += strlen(t);
if (ip->ip_off & 0x1fff)
if (ip->ip_off & IP_OFFMASK)
(void) sprintf(t, " frag %s%s%hu@%hu",
ip->ip_off & IP_MF ? "+" : "",
ip->ip_off & IP_DF ? "-" : "",
ip->ip_len - hl, (ip->ip_off & 0x1fff) << 3);
ip->ip_len - hl,
(ip->ip_off & IP_OFFMASK) << 3);
}
t += strlen(t);
@ -614,6 +722,11 @@ int blen;
t += strlen(t);
}
if (ipf->fl_flags & FR_INQUE)
strcpy(t, " IN");
else if (ipf->fl_flags & FR_OUTQUE)
strcpy(t, " OUT");
t += strlen(t);
*t++ = '\n';
*t++ = '\0';
if (opts & OPT_SYSLOG)
@ -621,7 +734,7 @@ int blen;
else
(void) fprintf(log, "%s", line);
if (opts & OPT_HEXHDR)
dumphex(log, (u_char *)buf, sizeof(iplog_t));
dumphex(log, (u_char *)buf, sizeof(iplog_t) + sizeof(*ipf));
if (opts & OPT_HEXBODY)
dumphex(log, (u_char *)ip, ipf->fl_plen + ipf->fl_hlen);
}
@ -635,6 +748,25 @@ char *prog;
}
static void write_pid(file)
char *file;
{
FILE *fp = NULL;
int fd;
if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0)
fp = fdopen(fd, "w");
if (!fp) {
close(fd);
fprintf(stderr, "unable to open/create pid file: %s\n", file);
return;
}
fprintf(fp, "%d", getpid());
fclose(fp);
close(fd);
}
static void flushlogs(file, log)
char *file;
FILE *log;
@ -706,7 +838,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[512], *iplfile[3], *s;
extern int optind;
extern char *optarg;
@ -716,11 +848,14 @@ char *argv[];
iplfile[1] = IPNAT_NAME;
iplfile[2] = IPSTATE_NAME;
while ((c = getopt(argc, argv, "?aDf:FhI:nN:o:O:sS:tvxX")) != -1)
while ((c = getopt(argc, argv, "?aDf:FhnN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
case 'a' :
opts |= OPT_ALL;
opts |= OPT_LOGALL;
fdt[0] = IPL_LOGIPF;
fdt[1] = IPL_LOGNAT;
fdt[2] = IPL_LOGSTATE;
break;
case 'D' :
make_daemon = 1;
@ -756,8 +891,17 @@ char *argv[];
case 'p' :
opts |= OPT_PORTNUM;
break;
case 'P' :
pidfile = optarg;
break;
case 's' :
openlog(argv[0], LOG_NDELAY|LOG_PID, LOGFAC);
s = strrchr(argv[0], '/');
if (s == NULL)
s = argv[0];
else
s++;
openlog(s, LOG_NDELAY|LOG_PID, LOGFAC);
s = NULL;
opts |= OPT_SYSLOG;
break;
case 'S' :
@ -783,6 +927,8 @@ char *argv[];
usage(argv[0]);
}
init_tabs();
/*
* Default action is to only open the filter log file.
*/
@ -822,16 +968,19 @@ char *argv[];
exit(-1);
}
setvbuf(log, NULL, _IONBF, 0);
}
} else
log = NULL;
if (make_daemon && (log != stdout)) {
if (fork() > 0)
exit(0);
write_pid(pidfile);
close(0);
close(1);
close(2);
setsid();
}
} else
write_pid(pidfile);
signal(SIGHUP, handlehup);
@ -856,7 +1005,7 @@ char *argv[];
continue;
nr += tr;
tr = read_log(fd[i], &n, buf, sizeof(buf), log);
tr = read_log(fd[i], &n, buf, sizeof(buf));
if (donehup) {
donehup = 0;
if (newlog) {

View File

@ -1,20 +1,11 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
*
* Broken still:
* Displaying the nat with redirect entries is way confusing
*
* Example redirection line:
* rdr le1 0.0.0.0/0 port 79 -> 199.165.219.129 port 9901
*
* Will redirect all incoming packets on le1 to any machine, port 79 to
* host 199.165.219.129, port 9901
*/
#include <stdio.h>
#include <string.h>
@ -42,6 +33,9 @@
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include <netdb.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
@ -62,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: ipnat.c,v 2.0.2.21.2.6 1998/05/23 19:07:02 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.1 1999/08/04 17:30:07 darrenr Exp $";
#endif
@ -71,18 +65,18 @@ static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.0.2.21.2.6 1998/05/23 19:07:02
#endif
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 *));
ipnat_t *parse __P((char *));
u_32_t hostnum __P((char *, int *));
u_32_t hostnum __P((char *, int *, int));
u_32_t hostmask __P((char *));
u_short portnum __P((char *, char *));
void dostats __P((int, int)), flushtable __P((int, int));
void printnat __P((ipnat_t *, int, void *));
void parsefile __P((int, char *, 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));
#define OPT_REM 1
#define OPT_NODO 2
@ -91,12 +85,13 @@ int main __P((int, char*[]));
#define OPT_VERBOSE 16
#define OPT_FLUSH 32
#define OPT_CLEAR 64
#define OPT_HITS 128
void usage(name)
char *name;
{
fprintf(stderr, "%s: [-CFlnrsv] [-f filename]\n", name);
fprintf(stderr, "%s: [-CFhlnrsv] [-f filename]\n", name);
exit(1);
}
@ -106,9 +101,9 @@ int argc;
char *argv[];
{
char *file = NULL;
int fd = -1, opts = 1, c;
int fd = -1, opts = 0, c;
while ((c = getopt(argc, argv, "CFf:lnrsv")) != -1)
while ((c = getopt(argc, argv, "CFf:hlnrsv")) != -1)
switch (c)
{
case 'C' :
@ -120,6 +115,9 @@ char *argv[];
case 'F' :
opts |= OPT_FLUSH;
break;
case 'h' :
opts |=OPT_HITS;
break;
case 'l' :
opts |= OPT_LIST;
break;
@ -127,7 +125,7 @@ char *argv[];
opts |= OPT_NODO;
break;
case 'r' :
opts &= ~OPT_REM;
opts |= OPT_REM;
break;
case 's' :
opts |= OPT_STAT;
@ -149,7 +147,7 @@ char *argv[];
if (opts & (OPT_FLUSH|OPT_CLEAR))
flushtable(fd, opts);
if (file)
parsefile(fd, file, opts);
natparsefile(fd, file, opts);
if (opts & (OPT_LIST|OPT_STAT))
dostats(fd, opts);
return 0;
@ -185,94 +183,58 @@ u_32_t ip;
}
void printnat(np, verbose, ptr)
ipnat_t *np;
int verbose;
void *ptr;
void printaps(aps, opts)
ap_session_t *aps;
int opts;
{
int bits;
struct protoent *pr;
ap_session_t ap;
aproxy_t apr;
raudio_t ra;
switch (np->in_redir)
{
case NAT_REDIRECT :
printf("rdr ");
break;
case NAT_MAP :
printf("map ");
break;
case NAT_BIMAP :
printf("bimap ");
break;
default :
fprintf(stderr, "unknown value for in_redir: %#x\n",
np->in_redir);
break;
if (kmemcpy((char *)&ap, (long)aps, sizeof(ap)))
return;
if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr)))
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", ap.aps_bytes, 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 (np->in_redir == NAT_REDIRECT) {
printf("%s %s", np->in_ifname, 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));
printf("-> %s", inet_ntoa(np->in_in[0]));
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");
printf("\n");
if (verbose)
printf("\t%p %u %x %u %p %d\n", np->in_ifp,
np->in_space, np->in_flags, np->in_pnext, np,
np->in_use);
} else {
np->in_nextip.s_addr = htonl(np->in_nextip.s_addr);
printf("%s %s/", np->in_ifname, 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(" -> %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) {
printf(" proxy port");
if (np->in_dport)
printf(" %hu", ntohs(np->in_dport));
printf(" %.*s/", (int)sizeof(np->in_plabel),
np->in_plabel);
if ((pr = getprotobynumber(np->in_p)))
fputs(pr->p_name, stdout);
else
printf("%d", np->in_p);
} else if (np->in_pmin || np->in_pmax) {
printf(" portmap");
if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
printf(" tcp/udp");
else if (np->in_flags & IPN_TCP)
printf(" tcp");
else if (np->in_flags & IPN_UDP)
printf(" udp");
printf(" %d:%d", ntohs(np->in_pmin),
ntohs(np->in_pmax));
}
printf("\n");
if (verbose)
printf("\t%p %u %s %d %x\n", np->in_ifp,
np->in_space, inet_ntoa(np->in_nextip),
np->in_pnext, np->in_flags);
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);
}
}
@ -286,8 +248,8 @@ ipnat_t *ipnat;
char *which;
ipnat_t ipnatbuff;
if (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat,
sizeof(ipnatbuff)))
if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat,
sizeof(ipnatbuff))))
return "???";
switch (ipnatbuff.in_redir)
@ -295,6 +257,9 @@ ipnat_t *ipnat;
case NAT_MAP :
which = "MAP";
break;
case NAT_MAPBLK :
which = "MAP-BLOCK";
break;
case NAT_REDIRECT :
which = "RDR";
break;
@ -341,6 +306,8 @@ int fd, opts;
perror("kmemcpy");
break;
}
if (opts & OPT_HITS)
printf("%d ", ipn.in_hits);
printnat(&ipn, opts & OPT_VERBOSE, (void *)ns.ns_list);
ns.ns_list = ipn.in_next;
}
@ -354,69 +321,42 @@ int fd, opts;
printf("\nList of active sessions:\n");
for (i = 0; i < NAT_SIZE; i++)
for (np = nt[0][i]; np; np = nat.nat_hnext[0]) {
if (kmemcpy((char *)&nat, (long)np,
sizeof(nat)))
break;
for (np = ns.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));
printf(" %ld %hu %lx", nat.nat_age,
nat.nat_use, nat.nat_sumd);
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 %x pr %u",
nat.nat_age, nat.nat_use, nat.nat_sumd,
nat.nat_p);
printf(" bkt %d flags %x ", i, nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
nat.nat_bytes, 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');
}
putchar('\n');
if (nat.nat_aps)
printaps(nat.nat_aps, opts);
}
free(nt[0]);
}
}
u_short portnum(name, proto)
char *name, *proto;
{
struct servent *sp, *sp2;
u_short p1 = 0;
if (isdigit(*name))
return htons((u_short)atoi(name));
if (!proto)
proto = "tcp/udp";
if (strcasecmp(proto, "tcp/udp")) {
sp = getservbyname(name, proto);
if (sp)
return sp->s_port;
(void) fprintf(stderr, "unknown service \"%s\".\n", name);
return 0;
}
sp = getservbyname(name, "tcp");
if (sp)
p1 = sp->s_port;
sp2 = getservbyname(name, "udp");
if (!sp || !sp2) {
(void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n",
name);
return 0;
}
if (p1 != sp2->s_port) {
(void) fprintf(stderr, "%s %d/tcp is a different port to ",
name, p1);
(void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port);
return 0;
}
return p1;
}
u_32_t hostmask(msk)
char *msk;
{
@ -445,9 +385,10 @@ char *msk;
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
u_32_t hostnum(host, resolved)
u_32_t hostnum(host, resolved, linenum)
char *host;
int *resolved;
int linenum;
{
struct hostent *hp;
struct netent *np;
@ -461,7 +402,7 @@ int *resolved;
if (!(hp = gethostbyname(host))) {
if (!(np = getnetbyname(host))) {
*resolved = -1;
fprintf(stderr, "can't resolve hostname: %s\n", host);
fprintf(stderr, "Line %d: can't resolve hostname: %s\n", linenum, host);
return 0;
}
return htonl(np->n_net);
@ -470,336 +411,6 @@ int *resolved;
}
ipnat_t *parse(line)
char *line;
{
struct protoent *pr;
static ipnat_t ipn;
char *s, *t;
char *shost, *snetm, *dhost, *proto;
char *dnetm = NULL, *dport = NULL, *tport = NULL;
int resolved;
bzero((char *)&ipn, sizeof(ipn));
if ((s = strchr(line, '\n')))
*s = '\0';
if ((s = strchr(line, '#')))
*s = '\0';
if (!*line)
return NULL;
if (!(s = strtok(line, " \t")))
return NULL;
if (!strcasecmp(s, "map"))
ipn.in_redir = NAT_MAP;
else if (!strcasecmp(s, "rdr"))
ipn.in_redir = NAT_REDIRECT;
else if (!strcasecmp(s, "bimap"))
ipn.in_redir = NAT_BIMAP;
else {
(void)fprintf(stderr,
"expected map/rdr/bimap, got \"%s\"\n", s);
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (interface)\n");
return NULL;
}
strncpy(ipn.in_ifname, s, sizeof(ipn.in_ifname) - 1);
ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0';
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (%s)\n",
ipn.in_redir ? "destination": "source");
return NULL;
}
shost = s;
if (ipn.in_redir == NAT_REDIRECT) {
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (destination port)\n");
return NULL;
}
if (strcasecmp(s, "port")) {
fprintf(stderr, "missing fields (port)\n");
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (destination port)\n");
return NULL;
}
dport = s;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (->)\n");
return NULL;
}
if (!strcmp(s, "->")) {
snetm = strrchr(shost, '/');
if (!snetm) {
fprintf(stderr, "missing fields (%s netmask)\n",
ipn.in_redir ? "destination":"source");
return NULL;
}
} else {
if (strcasecmp(s, "netmask")) {
fprintf(stderr, "missing fields (netmask)\n");
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (%s netmask)\n",
ipn.in_redir ? "destination":"source");
return NULL;
}
snetm = s;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (%s)\n",
ipn.in_redir ? "destination":"target");
return NULL;
}
dhost = s;
if (ipn.in_redir & NAT_MAP) {
if (!(s = strtok(NULL, " \t"))) {
dnetm = strrchr(dhost, '/');
if (!dnetm) {
fprintf(stderr,
"missing fields (dest netmask)\n");
return NULL;
}
}
if (!s || !strcasecmp(s, "portmap") ||
!strcasecmp(s, "proxy")) {
dnetm = strrchr(dhost, '/');
if (!dnetm) {
fprintf(stderr,
"missing fields (dest netmask)\n");
return NULL;
}
} else {
if (strcasecmp(s, "netmask")) {
fprintf(stderr,
"missing fields (dest netmask)\n");
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"missing fields (dest netmask)\n");
return NULL;
}
dnetm = s;
}
if (*dnetm == '/')
*dnetm++ = '\0';
} else {
/* If it's a in_redir, expect target port */
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (destination port)\n");
return NULL;
}
if (strcasecmp(s, "port")) {
fprintf(stderr, "missing fields (port)\n");
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (destination port)\n");
return NULL;
}
tport = s;
}
if (*snetm == '/')
*snetm++ = '\0';
if (ipn.in_redir & NAT_MAP) {
ipn.in_inip = hostnum(shost, &resolved);
if (resolved == -1)
return NULL;
ipn.in_inmsk = hostmask(snetm);
ipn.in_outip = hostnum(dhost, &resolved);
if (resolved == -1)
return NULL;
ipn.in_outmsk = hostmask(dnetm);
} else {
ipn.in_inip = hostnum(dhost, &resolved); /* Inside is target */
if (resolved == -1)
return NULL;
ipn.in_inmsk = hostmask("255.255.255.255");
ipn.in_outip = hostnum(shost, &resolved);
if (resolved == -1)
return NULL;
ipn.in_outmsk = hostmask(snetm);
if (!(s = strtok(NULL, " \t"))) {
ipn.in_flags = IPN_TCP; /* XXX- TCP only by default */
proto = "tcp";
} else {
if (!strcasecmp(s, "tcp"))
ipn.in_flags = IPN_TCP;
else if (!strcasecmp(s, "udp"))
ipn.in_flags = IPN_UDP;
else if (!strcasecmp(s, "tcp/udp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "tcpudp"))
ipn.in_flags = IPN_TCPUDP;
else {
fprintf(stderr,
"expected protocol - got \"%s\"\n", s);
return NULL;
}
proto = s;
if ((s = strtok(NULL, " \t"))) {
fprintf(stderr,
"extra junk at the end of rdr: %s\n",
s);
return NULL;
}
}
ipn.in_pmin = portnum(dport, proto); /* dest port */
ipn.in_pmax = ipn.in_pmin; /* NECESSARY of removing nats */
ipn.in_pnext = portnum(tport, proto); /* target port */
s = NULL; /* That's all she wrote! */
}
ipn.in_inip &= ipn.in_inmsk;
ipn.in_outip &= ipn.in_outmsk;
if (!s)
return &ipn;
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr, "extra words at the end of bimap line: %s\n",
s);
return NULL;
}
if (!strcasecmp(s, "proxy")) {
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing parameter for \"proxy\"\n");
return NULL;
}
dport = NULL;
if (!strcasecmp(s, "port")) {
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"missing parameter for \"port\"\n");
return NULL;
}
dport = s;
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"missing parameter for \"proxy\"\n");
return NULL;
}
}
if ((proto = index(s, '/'))) {
*proto++ = '\0';
if ((pr = getprotobyname(proto)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(proto);
if (dport)
ipn.in_dport = portnum(dport, proto);
} else {
ipn.in_p = 0;
if (dport)
ipn.in_dport = portnum(dport, NULL);
}
(void) strncpy(ipn.in_plabel, s, sizeof(ipn.in_plabel));
if ((s = strtok(NULL, " \t"))) {
fprintf(stderr, "too many parameters for \"proxy\"\n");
return NULL;
}
return &ipn;
}
if (strcasecmp(s, "portmap")) {
fprintf(stderr, "expected \"portmap\" - got \"%s\"\n", s);
return NULL;
}
if (!(s = strtok(NULL, " \t")))
return NULL;
if (!strcasecmp(s, "tcp"))
ipn.in_flags = IPN_TCP;
else if (!strcasecmp(s, "udp"))
ipn.in_flags = IPN_UDP;
else if (!strcasecmp(s, "tcpudp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "tcp/udp"))
ipn.in_flags = IPN_TCPUDP;
else {
fprintf(stderr, "expected protocol name - got \"%s\"\n", s);
return NULL;
}
proto = s;
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "no port range found\n");
return NULL;
}
if (!(t = strchr(s, ':'))) {
fprintf(stderr, "no port range in \"%s\"\n", s);
return NULL;
}
*t++ = '\0';
ipn.in_pmin = portnum(s, proto);
ipn.in_pmax = portnum(t, proto);
return &ipn;
}
void parsefile(fd, file, opts)
int fd;
char *file;
int opts;
{
char line[512], *s;
ipnat_t *np;
FILE *fp;
int linenum = 1;
if (strcmp(file, "-")) {
if (!(fp = fopen(file, "r"))) {
(void) fprintf(stderr, "%s: open: %s\n", file,
STRERROR(errno));
exit(1);
}
} else
fp = stdin;
while (fgets(line, sizeof(line) - 1, fp)) {
line[sizeof(line) - 1] = '\0';
if ((s = strchr(line, '\n')))
*s = '\0';
if (!(np = parse(line))) {
if (*line)
fprintf(stderr, "%d: syntax error in \"%s\"\n",
linenum, line);
} else if (!(opts & OPT_NODO)) {
if ((opts & OPT_VERBOSE) && np)
printnat(np, opts & OPT_VERBOSE, NULL);
if (opts & OPT_REM) {
if (ioctl(fd, SIOCADNAT, np) == -1)
perror("ioctl(SIOCADNAT)");
} else if (ioctl(fd, SIOCRMNAT, np) == -1)
perror("ioctl(SIOCRMNAT)");
}
linenum++;
}
if (fp != stdin)
fclose(fp);
}
void flushtable(fd, opts)
int fd, opts;
{

View File

@ -0,0 +1,201 @@
/*
* (C)opyright 1995 by Darren Reed.
*
* This code may be freely distributed as long as it retains this notice
* and is not changed in any way. The author accepts no responsibility
* for the use of this software. I hate legaleese, don't you ?
*
* @(#)ip_compat.h 1.1 9/14/95
*/
/*
* 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
* of these will turn up there too.
*/
#ifndef ICMP_UNREACH
# define ICMP_UNREACH ICMP_DEST_UNREACH
#endif
#ifndef ICMP_SOURCEQUENCH
# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
#endif
#ifndef ICMP_TIMXCEED
# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
#endif
#ifndef ICMP_PARAMPROB
# define ICMP_PARAMPROB ICMP_PARAMETERPROB
#endif
#ifndef IPVERSION
# define IPVERSION 4
#endif
#ifndef IPOPT_MINOFF
# define IPOPT_MINOFF 4
#endif
#ifndef IPOPT_COPIED
# define IPOPT_COPIED(x) ((x)&0x80)
#endif
#ifndef IPOPT_EOL
# define IPOPT_EOL 0
#endif
#ifndef IPOPT_NOP
# define IPOPT_NOP 1
#endif
#ifndef IP_MF
# define IP_MF ((u_short)0x2000)
#endif
#ifndef ETHERTYPE_IP
# define ETHERTYPE_IP ((u_short)0x0800)
#endif
#ifndef TH_FIN
# define TH_FIN 0x01
#endif
#ifndef TH_SYN
# define TH_SYN 0x02
#endif
#ifndef TH_RST
# define TH_RST 0x04
#endif
#ifndef TH_PUSH
# define TH_PUSH 0x08
#endif
#ifndef TH_ACK
# define TH_ACK 0x10
#endif
#ifndef TH_URG
# define TH_URG 0x20
#endif
#ifndef IPOPT_EOL
# define IPOPT_EOL 0
#endif
#ifndef IPOPT_NOP
# define IPOPT_NOP 1
#endif
#ifndef IPOPT_RR
# define IPOPT_RR 7
#endif
#ifndef IPOPT_TS
# define IPOPT_TS 68
#endif
#ifndef IPOPT_SECURITY
# define IPOPT_SECURITY 130
#endif
#ifndef IPOPT_LSRR
# define IPOPT_LSRR 131
#endif
#ifndef IPOPT_SATID
# define IPOPT_SATID 136
#endif
#ifndef IPOPT_SSRR
# define IPOPT_SSRR 137
#endif
#ifndef IPOPT_SECUR_UNCLASS
# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
#endif
#ifndef IPOPT_SECUR_CONFID
# define IPOPT_SECUR_CONFID ((u_short)0xf135)
#endif
#ifndef IPOPT_SECUR_EFTO
# define IPOPT_SECUR_EFTO ((u_short)0x789a)
#endif
#ifndef IPOPT_SECUR_MMMM
# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
#endif
#ifndef IPOPT_SECUR_RESTR
# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
#endif
#ifndef IPOPT_SECUR_SECRET
# define IPOPT_SECUR_SECRET ((u_short)0xd788)
#endif
#ifndef IPOPT_SECUR_TOPSECRET
# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
#endif
#ifdef linux
# define icmp icmphdr
# define icmp_type type
# define icmp_code code
/*
* From /usr/include/netinet/ip_var.h
* !%@#!$@# linux...
*/
struct ipovly {
caddr_t ih_next, ih_prev; /* for protocol sequence q's */
u_char ih_x1; /* (unused) */
u_char ih_pr; /* protocol */
short ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
};
typedef struct {
__u16 th_sport;
__u16 th_dport;
__u32 th_seq;
__u32 th_ack;
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
defined(vax)
__u8 th_res:4;
__u8 th_off:4;
#else
__u8 th_off:4;
__u8 th_res:4;
#endif
__u8 th_flags;
__u16 th_win;
__u16 th_sum;
__u16 th_urp;
} tcphdr_t;
typedef struct {
__u16 uh_sport;
__u16 uh_dport;
__s16 uh_ulen;
__u16 uh_sum;
} udphdr_t;
typedef struct {
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
defined(vax)
__u8 ip_hl:4;
__u8 ip_v:4;
# else
__u8 ip_hl:4;
__u8 ip_v:4;
# endif
__u8 ip_tos;
__u16 ip_len;
__u16 ip_id;
__u16 ip_off;
__u8 ip_ttl;
__u8 ip_p;
__u16 ip_sum;
struct in_addr ip_src;
struct in_addr ip_dst;
} ip_t;
typedef struct {
__u8 ether_dhost[6];
__u8 ether_shost[6];
__u16 ether_type;
} ether_header_t;
# define bcopy(a,b,c) memmove(b,a,c)
# define bcmp(a,b,c) memcmp(a,b,c)
# define ifnet device
#else
typedef struct udphdr udphdr_t;
typedef struct tcphdr tcphdr_t;
typedef struct ip ip_t;
typedef struct ether_header ether_header_t;
#endif
#ifdef solaris
# define bcopy(a,b,c) memmove(b,a,c)
# define bcmp(a,b,c) memcmp(a,b,c)
# define bzero(a,b) memset(a,0,b)
#endif

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 1993-1997 by Darren Reed.
# Copyright (C) 1993-1998 by Darren Reed.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1995-1997 Darren Reed.
* (C)opyright 1995-1998 Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -37,7 +37,7 @@
#ifndef lint
static const char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.0.2.4 1997/09/28 07:13:17 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.1 1999/08/04 17:30:56 darrenr Exp $";
#endif
extern char *optarg;

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1995-1997 Darren Reed.
* (C)opyright 1995-1998 Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1995-1997 Darren Reed.
* (C)opyright 1995-1998 Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -38,7 +38,7 @@
#ifndef lint
static const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.0.2.3 1997/09/28 07:13:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.1 1999/08/04 17:30:57 darrenr Exp $";
#endif
extern char *optarg;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1995-1997 Darren Reed. (from tcplog)
* (C)opyright 1995-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1992-1997 Darren Reed. (from tcplog)
* (C)opyright 1992-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1992-1997 Darren Reed. (from tcplog)
* (C)opyright 1992-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1992-1997 Darren Reed. (from tcplog)
* (C)opyright 1992-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -0,0 +1,242 @@
/*
* (C)opyright 1995 by Darren Reed.
*
* This code may be freely distributed as long as it retains this notice
* and is not changed in any way. The author accepts no responsibility
* for the use of this software. I hate legaleese, don't you ?
*
* @(#)ip_compat.h 1.2 12/7/95
*/
/*
* 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
* of these will turn up there too.
*/
#ifndef ICMP_UNREACH
# define ICMP_UNREACH ICMP_DEST_UNREACH
#endif
#ifndef ICMP_SOURCEQUENCH
# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
#endif
#ifndef ICMP_TIMXCEED
# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
#endif
#ifndef ICMP_PARAMPROB
# define ICMP_PARAMPROB ICMP_PARAMETERPROB
#endif
#ifndef IPVERSION
# define IPVERSION 4
#endif
#ifndef IPOPT_MINOFF
# define IPOPT_MINOFF 4
#endif
#ifndef IPOPT_COPIED
# define IPOPT_COPIED(x) ((x)&0x80)
#endif
#ifndef IPOPT_EOL
# define IPOPT_EOL 0
#endif
#ifndef IPOPT_NOP
# define IPOPT_NOP 1
#endif
#ifndef IP_MF
# define IP_MF ((u_short)0x2000)
#endif
#ifndef ETHERTYPE_IP
# define ETHERTYPE_IP ((u_short)0x0800)
#endif
#ifndef TH_FIN
# define TH_FIN 0x01
#endif
#ifndef TH_SYN
# define TH_SYN 0x02
#endif
#ifndef TH_RST
# define TH_RST 0x04
#endif
#ifndef TH_PUSH
# define TH_PUSH 0x08
#endif
#ifndef TH_ACK
# define TH_ACK 0x10
#endif
#ifndef TH_URG
# define TH_URG 0x20
#endif
#ifndef IPOPT_EOL
# define IPOPT_EOL 0
#endif
#ifndef IPOPT_NOP
# define IPOPT_NOP 1
#endif
#ifndef IPOPT_RR
# define IPOPT_RR 7
#endif
#ifndef IPOPT_TS
# define IPOPT_TS 68
#endif
#ifndef IPOPT_SECURITY
# define IPOPT_SECURITY 130
#endif
#ifndef IPOPT_LSRR
# define IPOPT_LSRR 131
#endif
#ifndef IPOPT_SATID
# define IPOPT_SATID 136
#endif
#ifndef IPOPT_SSRR
# define IPOPT_SSRR 137
#endif
#ifndef IPOPT_SECUR_UNCLASS
# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
#endif
#ifndef IPOPT_SECUR_CONFID
# define IPOPT_SECUR_CONFID ((u_short)0xf135)
#endif
#ifndef IPOPT_SECUR_EFTO
# define IPOPT_SECUR_EFTO ((u_short)0x789a)
#endif
#ifndef IPOPT_SECUR_MMMM
# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
#endif
#ifndef IPOPT_SECUR_RESTR
# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
#endif
#ifndef IPOPT_SECUR_SECRET
# define IPOPT_SECUR_SECRET ((u_short)0xd788)
#endif
#ifndef IPOPT_SECUR_TOPSECRET
# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
#endif
#ifdef linux
# if LINUX < 0200
# define icmp icmphdr
# define icmp_type type
# define icmp_code code
# endif
/*
* From /usr/include/netinet/ip_var.h
* !%@#!$@# linux...
*/
struct ipovly {
caddr_t ih_next, ih_prev; /* for protocol sequence q's */
u_char ih_x1; /* (unused) */
u_char ih_pr; /* protocol */
short ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
};
typedef struct {
__u16 th_sport;
__u16 th_dport;
__u32 th_seq;
__u32 th_ack;
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
defined(vax)
__u8 th_res:4;
__u8 th_off:4;
#else
__u8 th_off:4;
__u8 th_res:4;
#endif
__u8 th_flags;
__u16 th_win;
__u16 th_sum;
__u16 th_urp;
} tcphdr_t;
typedef struct {
__u16 uh_sport;
__u16 uh_dport;
__s16 uh_ulen;
__u16 uh_sum;
} udphdr_t;
typedef struct {
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
defined(vax)
__u8 ip_hl:4;
__u8 ip_v:4;
# else
__u8 ip_hl:4;
__u8 ip_v:4;
# endif
__u8 ip_tos;
__u16 ip_len;
__u16 ip_id;
__u16 ip_off;
__u8 ip_ttl;
__u8 ip_p;
__u16 ip_sum;
struct in_addr ip_src;
struct in_addr ip_dst;
} ip_t;
typedef struct {
__u8 ether_dhost[6];
__u8 ether_shost[6];
__u16 ether_type;
} ether_header_t;
typedef struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */
union {
u_char ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
n_short icd_id;
n_short icd_seq;
} ih_idseq;
int ih_void;
} icmp_hun;
#define icmp_pptr icmp_hun.ih_pptr
#define icmp_gwaddr icmp_hun.ih_gwaddr
#define icmp_id icmp_hun.ih_idseq.icd_id
#define icmp_seq icmp_hun.ih_idseq.icd_seq
#define icmp_void icmp_hun.ih_void
union {
struct id_ts {
n_time its_otime;
n_time its_rtime;
n_time its_ttime;
} id_ts;
struct id_ip {
ip_t idi_ip;
/* options and then 64 bits of data */
} id_ip;
u_long id_mask;
char id_data[1];
} icmp_dun;
#define icmp_otime icmp_dun.id_ts.its_otime
#define icmp_rtime icmp_dun.id_ts.its_rtime
#define icmp_ttime icmp_dun.id_ts.its_ttime
#define icmp_ip icmp_dun.id_ip.idi_ip
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data
} icmphdr_t;
# define bcopy(a,b,c) memmove(b,a,c)
# define bcmp(a,b,c) memcmp(a,b,c)
# define ifnet device
#else
typedef struct udphdr udphdr_t;
typedef struct tcphdr tcphdr_t;
typedef struct ip ip_t;
typedef struct ether_header ether_header_t;
#endif
#if defined(__SVR4) || defined(__svr4__)
# define bcopy(a,b,c) memmove(b,a,c)
# define bcmp(a,b,c) memcmp(a,b,c)
# define bzero(a,b) memset(a,0,b)
#endif

View File

@ -26,6 +26,7 @@
# include <net/if_var.h>
#endif
#include "ipsend.h"
#include "iplang/iplang.h"
/*
@ -65,6 +66,11 @@ char *addr, *eaddr;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
#ifdef IPSEND
if (arp_getipv4(ip, ether) == 0)
return 0;
#endif
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 1993-1997 by Darren Reed.
# Copyright (C) 1993-1998 by Darren Reed.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and due credit is given
@ -67,7 +67,7 @@ install:
bpf sunos4-bpf :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
"CFLAGS=$(CFLAGS) -DDOSOCKET -DIPSEND" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
@ -75,7 +75,7 @@ bpf sunos4-bpf :
nit sunos4 sunos4-nit :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
"CFLAGS=$(CFLAGS) -DDOSOCKET -DIPSEND" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
@ -83,7 +83,8 @@ nit sunos4 sunos4-nit :
dlpi sunos5 :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl" "LLIB=-ll"
CFLAGS="$(CFLAGS) -Dsolaris -DIPSEND" "LIBS=-lsocket -lnsl" \
"LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
@ -91,7 +92,7 @@ dlpi sunos5 :
bsd-bpf :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
"CFLAGS=$(CFLAGS) -DDOSOCKET -DIPSEND" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
@ -99,7 +100,7 @@ bsd-bpf :
linuxrev :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET" $(LINUXK)
CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET -DIPSEND" $(LINUXK)
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET" $(LINUXK)
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
@ -119,7 +120,7 @@ linux20:
ultrix :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS)" "LIBS=" "LLIB=-ll"
CFLAGS="$(CFLAGS) -DIPSEND" "LIBS=" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS)" "LIBS="
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
@ -127,7 +128,7 @@ ultrix :
hpux9 :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS)" "LIBS="
CFLAGS="$(CFLAGS) -DIPSEND" "LIBS="
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \
CFLAGS="$(CFLAGS)" "LIBS="
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \

View File

@ -1,5 +1,5 @@
/*
* arp.c (C) 1995-1997 Darren Reed
* arp.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,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.0.2.6 1997/09/28 07:13:25 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: arp.c,v 2.1 1999/08/04 17:31:03 darrenr Exp $";
#endif
#include <stdio.h>
#include <errno.h>
@ -20,6 +20,7 @@ static const char rcsid[] = "@(#)$Id: arp.c,v 2.0.2.6 1997/09/28 07:13:25 darren
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#ifndef ultrix
#include <net/if_arp.h>
#endif
@ -27,6 +28,7 @@ static const char rcsid[] = "@(#)$Id: arp.c,v 2.0.2.6 1997/09/28 07:13:25 darren
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include "ipsend.h"
#include "iplang/iplang.h"
/*
@ -71,6 +73,10 @@ char *ether;
struct hostent *hp;
int fd;
#ifdef IPSEND
if (arp_getipv4(ip, ether) == 0)
return 0;
#endif
if (!bcmp(ipsave, ip, 4)) {
bcopy(ethersave, ether, 6);
return 0;

View File

@ -1,5 +1,5 @@
/*
* (C)opyright 1997 Darren Reed. (from tcplog)
* (C)opyright 1997-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given

View File

@ -1,5 +1,5 @@
/*
* ip.c (C) 1995-1997 Darren Reed
* ip.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995";
static const char rcsid[] = "@(#)$Id: ip.c,v 2.0.2.11.2.3 1997/12/21 12:17:37 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip.c,v 2.1 1999/08/04 17:31:04 darrenr Exp $";
#endif
#include <errno.h>
#include <stdio.h>

View File

@ -44,6 +44,7 @@ MTU's without setting them so.
.TP
.BR \-r \0<filename>
Specify the filename from which to take input. Default is stdin.
.TP
.B \-E
The input file is to be text output from etherfind. The text formats which
are currently supported are those which result from the following etherfind
@ -91,7 +92,7 @@ option combinations:
.TP
.B \-X
The input file is composed of text descriptions of IP packets.
.TP
.DT
.SH SEE ALSO
snoop(1m), tcpdump(8), etherfind(8c), ipftest(1), ipresend(1), iptest(1), bpf(4), dlpi(7p)
.SH DIAGNOSTICS

View File

@ -1,5 +1,5 @@
/*
* ipresend.c (C) 1995-1997 Darren Reed
* ipresend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -12,7 +12,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.0.2.9 1997/10/12 09:48:37 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1 1999/08/04 17:31:05 darrenr Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,5 +1,5 @@
/*
* ipsend.c (C) 1995-1997 Darren Reed
* ipsend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -12,7 +12,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.0.2.19.2.1 1998/05/14 14:01:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.1 1999/08/04 17:31:06 darrenr Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,5 +1,5 @@
/*
* ipsend.h (C) 1997 Darren Reed
* ipsend.h (C) 1997-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -64,4 +64,6 @@ extern int kmemcpy __P((char *, void *, int));
#define KMCPY(a,b,c) kmemcpy((char *)(a), (void *)(b), (int)(c))
#ifndef OPT_RAW
#define OPT_RAW 0x80000
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,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.0.2.10 1997/09/28 07:13:28 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1 1999/08/04 17:31:07 darrenr Exp $";
#endif
#include <stdio.h>
#include <string.h>

View File

@ -1,5 +1,5 @@
/*
* ipsend.c (C) 1995-1997 Darren Reed
* ipsend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -12,7 +12,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.0.2.8.2.1 1997/11/28 03:36:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.1 1999/08/04 17:31:08 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptests.c,v 2.0.2.13.2.2 1997/12/21 12:17:38 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptests.c,v 2.1 1999/08/04 17:31:09 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>
@ -16,12 +16,18 @@ static const char rcsid[] = "@(#)$Id: iptests.c,v 2.0.2.13.2.2 1997/12/21 12:17:
#include <sys/types.h>
#include <sys/time.h>
#include <sys/param.h>
#define _KERNEL
#define KERNEL
#if !defined(solaris) && !defined(linux) && !defined(__sgi)
# define _KERNEL
# define KERNEL
# include <sys/file.h>
# undef _KERNEL
# undef KERNEL
#else
# ifdef solaris
# include <sys/dditypes.h>
# endif
#endif
#undef _KERNEL
#undef KERNEL
#if !defined(solaris) && !defined(linux) && !defined(__sgi)
# include <nlist.h>
# include <sys/user.h>
# include <sys/proc.h>

View File

@ -1,5 +1,5 @@
/*
* larp.c (C) 1995-1997 Darren Reed
* larp.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: larp.c,v 2.0.2.3 1997/09/28 07:13:31 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: larp.c,v 2.1 1999/08/04 17:31:10 darrenr Exp $";
#endif
#include <stdio.h>
#include <errno.h>
@ -19,6 +19,9 @@ static const char rcsid[] = "@(#)$Id: larp.c,v 2.0.2.3 1997/09/28 07:13:31 darre
#include <net/if.h>
#include <net/if_arp.h>
#include "ip_compat.h"
#include "iplang/iplang.h"
/*
* lookup host and return
* its IP address in address
@ -59,6 +62,10 @@ char *ether;
struct sockaddr_in *sin;
char *inet_ntoa();
#ifdef IP_SEND
if (arp_getipv4(ip, ether) == 0)
return 0;
#endif
bzero((char *)&ar, sizeof(ar));
sin = (struct sockaddr_in *)&ar.arp_pa;
sin->sin_family = AF_INET;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* This code may be freely distributed as long as it retains this notice
* and is not changed in any way. The author accepts no responsibility

View File

@ -1,5 +1,5 @@
/*
* lsock.c (C) 1995-1997 Darren Reed
* lsock.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -7,7 +7,7 @@
*/
#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.0.2.7 1997/09/28 07:13:32 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1 1999/08/04 17:31:11 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>

View File

@ -1,5 +1,5 @@
/*
* resend.c (C) 1995-1997 Darren Reed
* resend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -12,7 +12,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.0.2.12 1997/10/23 11:42:46 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: resend.c,v 2.1 1999/08/04 17:31:12 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>
@ -41,7 +41,7 @@ static const char rcsid[] = "@(#)$Id: resend.c,v 2.0.2.12 1997/10/23 11:42:46 da
extern int opts;
static u_char buf[65536]; /* 1 big packet */
static u_char pbuf[65536]; /* 1 big packet */
void printpacket __P((ip_t *));
@ -95,7 +95,7 @@ char *datain;
if (fd < 0)
exit(-1);
ip = (struct ip *)buf;
ip = (struct ip *)pbuf;
eh = (ether_header_t *)malloc(sizeof(*eh));
bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
@ -105,7 +105,7 @@ char *datain;
return -2;
}
while ((i = (*r->r_readip)(buf, sizeof(buf), NULL, NULL)) > 0)
while ((i = (*r->r_readip)((char *)pbuf, sizeof(pbuf), NULL, NULL)) > 0)
{
if (!(opts & OPT_RAW)) {
len = ntohs(ip->ip_len);
@ -127,7 +127,7 @@ char *datain;
len += sizeof(*eh);
printpacket(ip);
} else {
eh = (ether_header_t *)buf;
eh = (ether_header_t *)pbuf;
len = i;
}

Some files were not shown because too many files have changed in this diff Show More