Import IPFilter 3.4.25

This commit is contained in:
Darren Reed 2002-03-19 11:45:20 +00:00
parent dba82da1c8
commit d564cc784f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/ipfilter/dist/; revision=92686
84 changed files with 4920 additions and 2289 deletions

View File

@ -2,27 +2,29 @@ filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
[ proto ] [ ip ] [ group ].
insert = "@" decnumber .
action = block | "pass" | log | "count" | skip | auth | call .
action = block | "no-match" | "pass" | log | "count" | skip | auth | call .
in-out = "in" | "out" .
options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ]
[ via ] ] .
tos = "tos" decnumber | "tos" hexnumber .
ttl = "ttl" decnumber .
proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
group = [ "head" decnumber ] [ "group" decnumber ] .
block = "block" [ reutrn-icmp[return-code] | "return-rst" ] .
block = "block" [ return-icmp[return-code] | "return-rst" ] .
auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
call = "call" [ "now" ] function-name .
skip = "skip" decnumber .
dup = "dup-to" interface-name[":"ipaddr] .
via = "in-via" interface-name | "out-via" interface-name .
froute = "fastroute" | "to" interface-name [ ":" ipaddr ] .
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
reutrn-icmp = "return-icmp" | "return-icmp-as-dest" .
return-icmp = "return-icmp" | "return-icmp-as-dest" .
loglevel = facility"."priority | priority .
object = addr [ port-comp | port-range ] .
addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
@ -32,7 +34,8 @@ flags = "flags" flag { flag } [ "/" flag { flag } ] .
with = "with" | "and" .
icmp = "icmp-type" icmp-type [ "code" decnumber ] .
return-code = "("icmp-code")" .
keep = "keep" "state" | "keep" "frags" .
keep = "keep" "state" | "keep" "frags" | "keep" "state-age" state-age .
state-age = decnmber [ "/" decnumber ] .
nummask = host-name [ "/" decnumber ] .
host-name = ipaddr | hostname | "any" .

View File

@ -8,7 +8,7 @@
BINDEST=/usr/sbin
SBINDEST=/sbin
MANDIR=/usr/share/man
CC=cc -Wall -Wuninitialized -Wstrict-prototypes -Werror -O
CC=cc -Wall -Wstrict-prototypes -Wuninitialized -O
CFLAGS=-g -I$(TOP)
#
# For NetBSD/FreeBSD
@ -39,22 +39,23 @@ INSTALL=install
#
MODOBJS=ip_fil.o fil_k.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \
ip_auth.o ip_log.o
DFLAGS=$(IPFLKM) $(IPFLOG) $(DEF) $(DLKM)
DFLAGS=$(IPFLKM) $(DEF) $(DLKM)
IPF=ipf.o parse.o common.o opt.o facpri.o
IPT=ipt.o parse.o common.o fil.o ipft_sn.o ipft_ef.o ipft_td.o ipft_pc.o \
opt.o ipft_tx.o misc.o ip_frag_u.o ip_state_u.o ip_nat_u.o ip_proxy_u.o \
ip_auth_u.o ipft_hx.o ip_fil_u.o natparse.o facpri.o
IPNAT=ipnat.o kmem.o natparse.o common.o
FILS=fils.o parse.o kmem.o opt.o facpri.o common.o
ip_auth_u.o ipft_hx.o ip_fil_u.o ip_log_u.o natparse.o facpri.o \
printnat.o printstate.o
IPNAT=ipnat.o kmem.o natparse.o common.o printnat.o
FILS=fils.o parse.o kmem.o opt.o facpri.o common.o printstate.o
build all: ipf ipfs ipfstat ipftest ipmon ipnat $(LKM)
ipfstat: $(FILS)
$(CC) $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) $(FILS) \
-o $@ $(LIBS) $(STATETOP_LIB)
$(CC) -static $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
$(FILS) -o $@ $(LIBS) $(STATETOP_LIB) -lkvm
ipf: $(IPF)
$(CC) $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
$(CC) -static $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
/bin/rm -f $(TOP)/ipf
ln -s `pwd`/ipf $(TOP)
@ -64,10 +65,10 @@ ipftest: $(IPT)
ln -s `pwd`/ipftest $(TOP)
ipnat: $(IPNAT)
$(CC) $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS)
$(CC) -static $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS) -lkvm
ipfs: ipfs.o
$(CC) $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
$(CC) -static $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
tests:
(cd test; make )
@ -107,6 +108,14 @@ natparse.o: $(TOP)/natparse.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
$(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/natparse.c -o $@
printnat.o: $(TOP)/printnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
$(TOP)/ip_compat.h $(TOP)/ip_proxy.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printnat.c -o $@
printstate.o: $(TOP)/printstate.c $(TOP)/ip_fil.h $(TOP)/ipf.h \
$(TOP)/ip_state.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printstate.c -o $@
ipft_sn.o: $(TOP)/ipft_sn.c $(TOP)/ipt.h $(TOP)/ipf.h $(TOP)/ip_fil.h \
$(TOP)/snoop.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_sn.c -o $@
@ -130,7 +139,8 @@ ip_nat_u.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_nat.c -o $@
ip_proxy_u.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_nat.h
$(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_rcmd_pxy.c \
$(TOP)/ip_raudio_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_proxy.c -o $@
ip_frag_u.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h \
@ -148,6 +158,9 @@ ip_auth_u.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
ip_fil_u.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/$(IPFILC) -o $@
ip_log_u.o: $(TOP)/ip_log.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_log.c -o $@
if_ipl.o: $(MODOBJS)
ld -r $(MODOBJS) -o $(LKM)
${RM} -f if_ipl
@ -170,7 +183,7 @@ ip_state.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
ip_proxy.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_raudio_pxy.c \
$(TOP)/ip_nat.h
$(TOP)/ip_rcmd_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_proxy.c -o $@
ip_auth.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
@ -207,6 +220,8 @@ facpri.o: $(TOP)/facpri.c $(TOP)/facpri.h
ipmon: $(TOP)/ipmon.c
$(CC) $(DEBUG) $(CFLAGS) $(LOGFAC) $(TOP)/ipmon.c -o $@ $(LIBS)
/bin/rm -f $(TOP)/ipmon
ln -s `pwd`/ipmon $(TOP)
clean:
${RM} -f *.core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipnat \
@ -231,10 +246,20 @@ install:
-if [ -d /modules -a -f ipf.ko ] ; then \
cp ipf.ko /modules; \
fi
-$(INSTALL) -cs -g wheel -m 755 -o root ipf $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipfs $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipnat $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipfstat $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipmon $(BINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipftest $(BINDEST)
@for i in ipf:$(SBINDEST) ipfs:$(SBINDEST) ipnat:$(SBINDEST) \
ipfstat:$(SBINDEST) ipftest:$(SBINDEST) ipmon:$(BINDEST); do \
def="`expr $$i : '[^:]*:\(.*\)'`"; \
p="`expr $$i : '\([^:]*\):.*'`"; \
for d in $(BINDEST) $(SBINDEST); do \
if [ -f $$d/$$i ] ; then \
echo "$(INSTALL) -cs -g wheel -m 755 -o root $$p $$d"; \
$(INSTALL) -cs -g wheel -m 755 -o root $$p $$d; \
dd=$$d; \
fi; \
done; \
if [ -z "$$dd" ] ; then \
echo $(INSTALL) -cs -g wheel -m 755 -o root $$p $$def; \
$(INSTALL) -cs -g wheel -m 755 -o root $$p $$def; \
fi \
done
(cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP))

View File

@ -9,13 +9,17 @@ argv0=`basename $0`
dir=`pwd`
karch=`uname -m`
archdir="/sys/arch/$karch"
ipfdir=/sys/netinet
if [ -d /sys/contrib/ipfilter ] ; then
ipfdir=/sys/contrib/ipfilter/netinet
fi
confdir="$archdir/conf"
echo -n "Installing "
for i in ip_fil.[ch] fil.c ip_nat.[ch] ip_frag.[ch] ip_state.[ch] ip_proxy.[ch] ip_auth.[ch] ip_log.c ip_compat.h ipl.h ip_ftp_pxy.c ip_rcmd_pxy.c ip_raudio_pxy.c ; do
for i in ip_fil.[ch] fil.c ip_nat.[ch] ip_frag.[ch] ip_state.[ch] ip_proxy.[ch] ip_auth.[ch] ip_log.c ip_compat.h ipl.h ip_*_pxy.c ; do
echo -n "$i "
cp $i /sys/netinet/
chmod 644 /sys/netinet/$i
cp $i $ipfdir
chmod 644 $ipfdir/$i
done
echo ""
if [ -f /sys/netinet/ip_fil_compat.h ] ; then

View File

@ -9,11 +9,17 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_proxy.[ch] ip_{ftp,rcmd}_pxy.c mlf_ipl.c ipl.h ip_compat.h \
ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c ipl.h ip_compat.h \
ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
switch ( $i )
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
breaksw
endsw
end
echo ""
echo "Copying /usr/include/osreldate.h to /sys/sys"

View File

@ -9,11 +9,17 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c ipl.h \
ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c ipl.h \
ip_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
switch ( $i )
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
breaksw
endsw
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"

View File

@ -2,27 +2,38 @@
#
set dir=`pwd`
set karch=`uname -m`
set ipfdir=/sys/netinet
set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
if ( -d /sys/contrib/ipfilter ) set ipfdir=/sys/contrib/ipfilter/netinet
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c mlfk_ipl.c \
ip_proxy.[ch] ip_*_pxy.c mlf_ipl.c mlfk_ipl.c \
ipl.h ip_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
cp $i $ipfdir
chmod 644 $ipfdir/$i
switch ( $i )
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
breaksw
endsw
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
ln -s /usr/include/osreldate.h /sys/sys/osreldate.h
echo ""
echo "Patching ip6_input.c and ip6_output.c"
cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch)
patchfile=FreeBSd-4.0/ipv6-patch-$krev
if ( -f $patchfile ) then
echo ""
echo "Patching ip6_input.c and ip6_output.c"
cat $patchfile | (cd /sys/netinet6; patch)
endif
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "

View File

@ -9,10 +9,16 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_proxy.[ch] ip_auth.[ch] ip_{ftp,rcmd}_pxy.c ip_compat.h ip_log.c)
ip_proxy.[ch] ip_auth.[ch] ip_*_pxy.c ip_compat.h ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
switch ( $i )
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
breaksw
endsw
end
echo ""
grep iplopen $archdir/$karch/conf.c >& /dev/null

View File

@ -22,6 +22,219 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.4.25 13/03/2002 - Released
retain rule # in state information
log the direction of a packet so ipmon gets it right rather than incorrectly
deriving it from the rule flags
add #ifdef for IPFILTER_LOGSIZE (put options IPFILTER_LOGSIZE=16384 in BSD
kernel config files to increase that buffer size)
recognise return-* rules differently to block in ipftest
fix bug in ipmon output for solaris
add regression testing for skip rules, logging and using head/group
fix output of ipmon: was displaying large unsigned ints rather than -1
when no rules matched.
make logging code compile into ipftest and add -l command line option to
dump binary log file (read with ipmon -f) when it finishes.
protect rule # and group # from interference when checking accounting rules
add regression testing for log output (text) from ipmon.
document -b command line option for ipmon
fix double-quick in Solaris startup script
3.4.24 01/03/2002 - Released
fix how files are installed on SunOS5
fix some minor problems in SunOS5 ipfboot script
by default, compile all OpenBSD tools in 3.0 for IPv6
fix NULL-pointer dereference in NAT code
make a better attempt at replacing the appropriate binaries on BSD systems
always print IPv6 icmp-types as a number
impose some rules about what "skip" can be used with
fix parsing problems with "keep state" and "keep state-age"
Try to read as much data as is in the log device in ipmon
remove some redundant checks when searching for rdr/nat rules
fix bug in handling of ACCT with FTP proxy
increase array size for interface names, using LIFNAMSIZ
include H.323 proxy from QNX
3.4.23 16/01/2002 - Released
Include patches to install IPFilter into OpenBSD 3.0, both for just kernel
compiles and complete system builds.
Fix bug in automatic flushing of state table which would cause it to hang
in an infinite loop bug introduced in 3.4.20.
Modify the sample proxy (samples/proxy.c) so that it ads a NAT mapping for
the outgoing connection to make it look like it comes from the real source.
Only support ICMPv6 with IPv6.
Move ipnat.1 to ipnat.8
Enhance ipmon to print textual ICMP[v6] types and subtypes where possible.
Make it possible to do IPv6 regression testing with ipftest.
Use kvm library for kmem access, rather than trying to do it manually with
open/lseek/read.
Fix diffs for ip_input.c on BSDOS so it doesn't crash with fastroute.
Remove Berkeley advertising licence clause. Reference:
ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
Add more regression tests: ICMPv6 neighbour discovery, ICMP time exceeded
and fragmentation required.
Fix ipfboot script on Solaris to deal with no nameservers or no route to
them in a clean manner.
Support per-rule set timeouts for non-TCP NAT and state
Add netbios proxy
Add ICMPv6 stateful checking, including handling multicast destination
addresses for neighbour discovery.
Fix problems with internals of ICMP messages for MTU discovery and
unreachables not being correctly adjust on little endian boxes.
Add "in-via" and "out-via" to filtering rules grammar. It is now possible
to bind a rule to both incoming and outgoing interfaces, in both forward
and reverse directions (4 directions in total). allows for asymetric flows
through a firewall.
Fix ipfstat and ipnat for working on crash dumps.
Don't let USE_INET6 stay defined for SunOS4
Count things we see for each interface on solaris.
Include <netinet/icmp6.h> when compiling with USE_INET6 defined and
also include a whole bunch of #define's to make sure the symbols expected
can be used.
Fix up fastroute on BSD systems.
Make fastrouting work for IPv6 just a bit better. doesn't split up big
packets into fragments like the IPv4 one does. You can now do a
"to <if>:<ipv6_addr>"
Remove some of the differences between user-space and kernel-space code
that is internal to ipfilter.
Call ipfr_slowtimer() after each packet is processed in ipftest to artificially
create the illusion of passing time and include the expire functions in the
code compiled for user-space.
Fix issues with the IPSec proxy not working or leading to a system crash.
Junk all processing of SPIs and special handling for ESP.
Add "no-match" as a filter rule action (resets _LAST_ match)
Add hack to workaround problems with Cassini interface cards on
Solaris and VLANs
Add some protocols to etc/protocols
3.4.22 03/12/2001 - Released
various openbsd changes
sorting based on IP numbers for ipfstat top output
fix various IPv6 code & compile problems
modify ip_fil.c to be more netbsd friendly
fix fastroute bug where it modified a packet post-sending
fix get_unit() - don't understand why it was broken.
add FI_IGNOREPKT and don't count so marked packets when doing stats or
state/nat.
extend the interface name saved to log output
make proxies capable of extending the matching done on a packet with a
particular nat session
change interfaces inside NAT & state code to accomodate redesign to allow
IPsec proxy to work.
fix bug when free'ing loaded rules that results in a memory leak
(only an issue with "ipf -rf -", not flush)
make ipftest capable of loading > 1 file or rules, making it now possible
to load both NAT & filter rules
fix hex input for ipftest to allow interface name & direction to work
show ipsec proxy details in ipnat output
if OPT_HEX is set in opts, print a packet out as hex
don't modify b_next or preseve it or preserve b_prev for solaris
fix up kinstall scripts to install all the files everywhere they need to
fix overflowing of bits in ip_off inside iptest
make userauth and proxy in samples directory compile
fix minimum size when doing a pullup for ESP & ICMPv6
3.4.21 24/10/2001 - Released
include ipsec proxy
make state work for non-tcp/udp/icmp in a very simple way
include diffs for ipv6 firewall on openbsd-2.9
add compatibility filter wrapper for NetBSD-current
fix command line option problems with ipfs
if we fill the state table and a automated flush doesn't purge any
expiring entries, remove all entries idle for more than half a day
fix bug with sending resets/icmp errors where the pointer to the data
section of the packet was not being set (BSD only)
split out validating ftp commands and responses into different halves,
one for each of server & client.
do not compile in STATETOP support for specific architectures
fix INSTALL.FreeBSD to no longer provide directions and properly direct
people to the right file for the right version of FreeBSD.
3.4.20 24/07/2001 - Released
adjust NAT hashing to give a better spread across the table

View File

@ -1,51 +1,7 @@
*** IF you are using FreeBSD 2.2.x, see the file "INST.FreeBSD-2.2" ***
*** IF you are using FreeBSD 3 or later, see the file "INST.FreeBSD-3" ***
*** in the "FreeBSD-3" directory ***
To build a kernel for use with the loadable kernel module, follow these
steps:
1. do "make freebsd"
2. do "make install-bsd"
(probably has to be done as root)
3. run "FreeBSD/minstall" as root
4. build a new kernel
5. install and reboot with the new kernel
6. use modload(8) to load the packet filter with:
modload if_ipl.o
7. do "modstat" to confirm that it has been loaded successfully.
There is no need to use mknod to create the device in /dev;
- upon loading the module, it will create itself with the correct values,
under the name (IPL_NAME) from the Makefile. It will also remove itself
from /dev when it is modunload'd.
To build a kernel with the IP filter, follow these steps:
1. do "make freebsd"
2. do "make install-bsd"
(probably has to be done as root)
3. run "FreeBSD/kinstall" as root
4. build a new kernel
5. create devices for IP Filter as follows (assuming it was
installed into the device table as char dev 20):
mknod /dev/ipl c 20 0
mknod /dev/ipnat c 20 1
mknod /dev/ipstate c 20 2
mknod /dev/ipauth c 20 3
6. install and reboot with the new kernel
*** IF you are using FreeBSD 2.2.x, see the file "INST.FreeBSD-2.2" ***
*** IF you are using FreeBSD 3.x, see the file "FreeBSD-3/INST.FreeBSD-3" ***
*** IF you are using FreeBSD 4.x, see the file "FreeBSD-4.0/INST.FreeBSD-4" ***
Darren Reed
darrenr@pobox.com

View File

@ -1,4 +1,4 @@
Copyright (C) 1993-2001 by Darren Reed.
Copyright (C) 1993-2002 by Darren Reed.
The author accepts no responsibility for the use of this software and
provides it on an ``as is'' basis without express or implied warranty.

View File

@ -3,7 +3,7 @@
#
# See the IPFILTER.LICENCE file for details on licencing.
#
# $Id: Makefile,v 2.11.2.8 2001/06/26 10:43:10 darrenr Exp $
# $Id: Makefile,v 2.11.2.13 2002/03/06 09:43:15 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@ -34,7 +34,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
# Uncomment the next 3 lines if you want to view the state table a la top(1)
# (requires that you have installed ncurses).
#STATETOP_CFLAGS=-DSTATETOP
STATETOP_CFLAGS=-DSTATETOP
#
# Where to find the ncurses include files (if not in default path),
#
@ -43,7 +43,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
# How to link the ncurses library
#
#STATETOP_LIB=-lncurses
STATETOP_LIB=-lcurses
#STATETOP_LIB=-L/usr/local/lib -lncurses
#
@ -59,7 +59,7 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6)' \
MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6) $(IPFLOG)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \
@ -100,7 +100,7 @@ tests:
include:
if [ ! -f netinet/done ] ; then \
(cd netinet; ln -s ../*.h .; ln -s ../ip_ftp_pxy.c .; ln -s ../ip_rcmd_pxy.c .; ln -s ../ip_raudio_pxy.c .); \
(cd netinet; ln -s ../*.h .; ln -s ../ip_*_pxy.c .; ); \
(cd netinet; ln -s ../ipsend/tcpip.h tcpip.h); \
touch netinet/done; \
fi
@ -168,8 +168,8 @@ bsdi bsdos: include
irix IRIX: include
make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
-(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.std build TOP=../.. $(DEST) $(MFLAGS); else smake build TOP=../.. $(DEST) $(MFLAGS); fi;)
-(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.ipsend.std TOP=../.. $(DEST) $(MFLAGS); else smake -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); fi)
-(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.std build TOP=../.. $(DEST) SGI=`../getrev` $(MFLAGS); else smake build SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi;)
-(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.ipsend.std SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); else smake -f Makefile.ipsend SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi)
linux: include
make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
@ -258,7 +258,7 @@ install-bsd:
(cd BSD/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
install-sunos4: solaris
(cd SunOS4; $(MAKE) "CPU=$(CPU) TOP=.." install)
(cd SunOS4; $(MAKE) "CPU=$(CPU)" "TOP=.." install)
install-sunos5: solaris
(cd SunOS5; $(MAKE) "CPUDIR=`uname -p`-`uname -r`" "CPU=$(CPU) TOP=.." install)

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
@ -44,9 +47,7 @@ static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 da
extern struct ipopt_names ionames[], secclass[];
extern int opts;
#ifdef USE_INET6
extern int use_inet6;
#endif
char *proto = NULL;
@ -54,10 +55,8 @@ char flagset[] = "FSRPAUEC";
u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
TH_ECN, TH_CWR };
#ifdef USE_INET6
void fill6bits __P((int, u_32_t *));
int count6bits __P((u_32_t *));
#endif
static char thishost[MAXHOSTNAMELEN];
@ -95,30 +94,24 @@ u_32_t *mskp;
* set x most significant bits
*/
bits = (int)strtol(msk, &endptr, 0);
#ifdef USE_INET6
if ((*endptr != '\0') ||
((bits > 32) && !use_inet6) || (bits < 0) ||
((bits > 128) && use_inet6))
#else
if (*endptr != '\0' || bits > 32 || bits < 0)
#endif
return -1;
#ifdef USE_INET6
if (use_inet6)
fill6bits(bits, mskp);
else
#endif
if (bits == 0)
*mskp = 0;
else
*mskp = htonl(0xffffffff << (32 - bits));
else {
if (bits == 0)
*mskp = 0;
else
*mskp = htonl(0xffffffff << (32 - bits));
}
}
return 0;
}
#ifdef USE_INET6
void fill6bits(bits, msk)
int bits;
u_32_t *msk;
@ -134,7 +127,6 @@ u_32_t *msk;
while (i < 4)
msk[i++] = 0;
}
#endif
/*
@ -197,7 +189,6 @@ int linenum;
return -1;
}
(*seg)++;
#ifdef USE_INET6
if (use_inet6) {
u_32_t k = 0;
if (sa[0] || sa[1] || sa[2] || sa[3])
@ -205,8 +196,7 @@ int linenum;
msk[0] = msk[1] = msk[2] = msk[3] = k;
}
else
#endif
*msk = *sa ? 0xffffffff : 0;
*msk = *sa ? 0xffffffff : 0;
return ports(seg, pp, cp, tp, linenum);
}
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
@ -448,7 +438,6 @@ u_32_t ip;
}
#ifdef USE_INET6
int count6bits(msk)
u_32_t *msk;
{
@ -465,7 +454,6 @@ u_32_t *msk;
}
return i;
}
#endif
char *portname(pr, port)
@ -596,3 +584,27 @@ int len, zend;
break;
}
}
char *hostname(v, ip)
int v;
void *ip;
{
#ifdef USE_INET6
static char hostbuf[MAXHOSTNAMELEN+1];
#endif
struct in_addr ipa;
if (v == 4) {
ipa.s_addr = *(u_32_t *)ip;
return inet_ntoa(ipa);
}
#ifdef USE_INET6
(void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
hostbuf[MAXHOSTNAMELEN] = '\0';
return hostbuf;
#else
return "IPv6";
#endif
}

View File

@ -47,11 +47,15 @@ rsvp 46 RSVP # Reservation Protocol
gre 47 GRE # General Routing Encapsulation
mhrp 48 MHRP # Mobile Host Routing Protocol
bna 49 BNA # BNA
sipp-esp 50 SIPP-ESP # SIPP Encap Security Payload
sipp-ah 51 SIPP-AH # SIPP Authentication Header
esp 50 esp # Encap Security Payload
ah 51 AH # Authentication Header
i-nlsp 52 I-NLSP # Integrated Net Layer Security TUBA
swipe 53 SWIPE # IP with Encryption
nhrp 54 NHRP # NBMA Next Hop Resolution Protocol
mobile 55 MOBILE # IP Mobility (IP tunneling)
ipv6-icmp 58 icmpv6 IPv6-ICMP ICMPv6 # ICMP version 6
ipv6-nonxt 59 IPv6-Nonxt # No Next Header for IPv6
ipv6-opts 60 IPv6-Opts # Destination Options for IPv6
any 61 any # host internal protocol
cftp 62 CFTP # CFTP
any 63 any # local network
@ -92,4 +96,6 @@ etherip 97 ETHERIP # Ethernet-within-IP Encapsulation
encap 98 ENCAP # Encapsulation Header
any 99 any # private encryption scheme
gmtp 100 GMTP # GMTP
pim 103 PIM # Protocol Independant Multicast
ipcomp 108 IPCOMP # IP Payload Compression Protocol
reserved 255 Reserved #

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -34,7 +37,6 @@
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/uio.h>
#if !defined(__SVR4) && !defined(__svr4__)
# ifndef linux
# include <sys/mbuf.h>
@ -77,10 +79,10 @@
#endif
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@ -95,7 +97,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $";
#endif
#ifndef _KERNEL
@ -105,7 +107,7 @@ extern int opts;
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
# define IPLLOG(a, c, d, e) ipllog()
# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
#else /* #ifndef _KERNEL */
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
@ -260,7 +262,7 @@ fr_info_t *fin;
fin->fin_off = off;
fin->fin_plen = plen;
fin->fin_dp = (void *)tcp;
fin->fin_dp = (char *)tcp;
off <<= 3;
switch (p)
@ -280,7 +282,7 @@ fr_info_t *fin;
{
case ICMP6_ECHO_REPLY :
case ICMP6_ECHO_REQUEST :
minicmpsz = ICMP6ERR_MINPKTLEN;
minicmpsz = ICMP6_MINLEN;
break;
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
@ -380,6 +382,19 @@ fr_info_t *fin;
fin->fin_data[1] = ntohs(tcp->th_dport);
}
break;
case IPPROTO_ESP :
#ifdef USE_INET6
if (v == 6) {
if (plen < 8)
fi->fi_fl |= FI_SHORT;
} else
#endif
if (v == 4) {
if (((ip->ip_len < hlen + 8) && !off) ||
(off && off < 8))
fi->fi_fl |= FI_SHORT;
}
break;
default :
break;
}
@ -545,8 +560,8 @@ fr_info_t *fin;
* Could be per interface, but this gets real nasty when you don't have
* kernel sauce.
*/
int fr_scanlist(pass, ip, fin, m)
u_32_t pass;
int fr_scanlist(passin, ip, fin, m)
u_32_t passin;
ip_t *ip;
register fr_info_t *fin;
void *m;
@ -554,20 +569,21 @@ void *m;
register struct frentry *fr;
register fr_ip_t *fi = &fin->fin_fi;
int rulen, portcmp = 0, off, skip = 0, logged = 0;
u_32_t passt;
u_32_t pass, passt, passl;
frentry_t *frl;
frl = NULL;
pass = passin;
fr = fin->fin_fr;
fin->fin_fr = NULL;
fin->fin_rule = 0;
fin->fin_group = 0;
off = fin->fin_off;
pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
portcmp = 1;
for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
if (skip) {
FR_VERBOSE(("%d (%#x)\n", skip, fr->fr_flags));
skip--;
continue;
}
@ -578,25 +594,28 @@ void *m;
* check that we are working for the right interface
*/
#ifdef _KERNEL
# if BSD >= 199306
# if (BSD >= 199306)
if (fin->fin_out != 0) {
if ((fr->fr_oifa &&
fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif) ||
(fr->fr_ifa && fr->fr_ifa != fin->fin_ifp))
(fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif)))
continue;
} else
}
# endif
if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
continue;
#else
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
(pass & FR_AUTH) ? 'a' : 'b'));
#endif
FR_VERBOSE(("%c", fr->fr_skip ? 's' :
(pass & FR_PASS) ? 'p' :
(pass & FR_AUTH) ? 'a' :
(pass & FR_ACCOUNT) ? 'A' :
(pass & FR_NOMATCH) ? 'n' : 'b'));
if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
continue;
FR_VERBOSE((":i"));
#endif
{
register u_32_t *ld, *lm, *lip;
register int i;
@ -618,22 +637,19 @@ void *m;
/*
* Unrolled loops (4 each, for 32 bits).
*/
i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
i |= ((*lip++ & *lm++) != *ld++) << 5;
if (fi->fi_v == 6) {
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 19;
i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 19;
i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
i |= ((*lip++ & *lm++) != *ld++) << 5;
} else {
lip += 3;
lm += 3;
@ -642,23 +658,19 @@ void *m;
i ^= (fr->fr_flags & FR_NOTSRCIP);
if (i)
continue;
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
i |= ((*lip++ & *lm++) != *ld++) << 6;
if (fi->fi_v == 6) {
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 20;
i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld) << 20;
i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
i |= ((*lip++ & *lm++) != *ld++) << 6;
} else {
lip += 3;
lm += 3;
@ -667,14 +679,12 @@ void *m;
i ^= (fr->fr_flags & FR_NOTDSTIP);
if (i)
continue;
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld);
FR_DEBUG(("3. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
lip++, lm++, ld++;
i |= ((*lip & *lm) != *ld);
i |= ((*lip++ & *lm++) != *ld++);
FR_DEBUG(("4. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
i |= ((*lip & *lm) != *ld);
if (i)
continue;
}
@ -701,17 +711,30 @@ void *m;
}
}
FR_VERBOSE(("*"));
/*
* Just log this packet...
*/
if (fr->fr_flags & FR_NOMATCH) {
passt = passl;
passl = passin;
fin->fin_fr = frl;
frl = NULL;
if (fr->fr_flags & FR_QUICK)
break;
continue;
}
passl = passt;
passt = fr->fr_flags;
frl = fin->fin_fr;
fin->fin_fr = fr;
#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
if (securelevel <= 0)
#endif
if ((passt & FR_CALLNOW) && fr->fr_func)
passt = (*fr->fr_func)(passt, ip, fin);
fin->fin_fr = fr;
#ifdef IPFILTER_LOG
/*
* Just log this packet...
*/
if ((passt & FR_LOGMASK) == FR_LOG) {
if (!IPLLOG(passt, ip, fin, m)) {
if (passt & FR_LOGORBLOCK)
@ -722,32 +745,33 @@ void *m;
logged = 1;
}
#endif /* IPFILTER_LOG */
if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
pass = passt;
FR_DEBUG(("pass %#x\n", pass));
ATOMIC_INCL(fr->fr_hits);
if (pass & FR_ACCOUNT)
if (passt & FR_ACCOUNT)
fr->fr_bytes += (U_QUAD_T)ip->ip_len;
else
fin->fin_icode = fr->fr_icode;
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
if (fr->fr_grp) {
if (fr->fr_grp != NULL) {
fin->fin_fr = fr->fr_grp;
pass = fr_scanlist(pass, ip, fin, m);
passt = fr_scanlist(passt, ip, fin, m);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
fin->fin_fr = fr;
}
if (pass & FR_DONTCACHE)
if (passt & FR_DONTCACHE)
logged = 1;
}
if (pass & FR_QUICK)
if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
pass = passt;
FR_DEBUG(("pass %#x\n", pass));
if (passt & FR_QUICK)
break;
}
if (logged)
pass |= FR_DONTCACHE;
pass |= (fi->fi_fl << 24);
return pass;
}
@ -803,7 +827,7 @@ int out;
/*
* disable delayed checksums.
*/
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
if ((out != 0) && (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
@ -844,6 +868,9 @@ int out;
case IPPROTO_ICMP:
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
case IPPROTO_ESP:
plen = 8;
break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
@ -906,20 +933,26 @@ int out;
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
logit = -2;
if (fr_minttllog & 1)
logit = -3;
if (fr_minttllog & 2)
drop = 1;
}
} else
# endif
if (!out) {
if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
if (fr_chksrc == 2)
if (fr_chksrc & 1)
drop = 1;
if (fr_chksrc & 2)
logit = -2;
} else if (ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
if (fr_minttllog & 1)
logit = -3;
if (fr_minttllog & 2)
drop = 1;
}
}
if (drop) {
@ -1010,6 +1043,7 @@ int out;
FI_COPYSIZE);
if (pass & FR_NOMATCH) {
ATOMIC_INCL(frstats[out].fr_nom);
fin->fin_fr = NULL;
}
}
} else
@ -1023,11 +1057,7 @@ int out;
*/
if ((pass & FR_AUTH)) {
if (fr_newauth((mb_t *)m, fin, ip) != 0) {
#ifdef _KERNEL
m = *mp = NULL;
#else
;
#endif
error = 0;
} else
error = ENOSPC;
@ -1057,7 +1087,7 @@ int out;
}
}
if (pass & FR_KEEPSTATE) {
if (fr_addstate(ip, fin, 0) == NULL) {
if (fr_addstate(ip, fin, NULL, 0) == NULL) {
ATOMIC_INCL(frstats[out].fr_bads);
} else {
ATOMIC_INCL(frstats[out].fr_ads);
@ -1086,11 +1116,19 @@ int out;
else
#endif
list = ipacct[1][fr_active];
if ((fin->fin_fr = list) &&
(fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
ATOMIC_INCL(frstats[1].fr_acct);
if (list != NULL) {
u_32_t sg, sr;
fin->fin_fr = list;
sg = fin->fin_group;
sr = fin->fin_rule;
if (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT) {
ATOMIC_INCL(frstats[1].fr_acct);
}
fin->fin_group = sg;
fin->fin_rule = sr;
fin->fin_fr = fr;
}
fin->fin_fr = fr;
changed = ip_natout(ip, fin);
} else
fin->fin_fr = fr;
@ -1134,10 +1172,10 @@ int out;
# if SOLARIS
mc = dupmsg(m);
# else
# ifndef linux
mc = m_copy(m, 0, M_COPYALL);
# if defined(__OpenBSD__) && (OpenBSD >= 199905)
mc = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
# else
;
mc = m_copy(m, 0, M_COPYALL);
# endif
# endif
#endif
@ -1154,7 +1192,6 @@ int out;
* some operating systems.
*/
if (!out) {
#ifdef _KERNEL
if (pass & FR_RETICMP) {
int dst;
@ -1170,19 +1207,6 @@ int out;
ATOMIC_INCL(frstats[1].fr_ret);
}
}
#else
if ((pass & FR_RETMASK) == FR_RETICMP) {
verbose("- ICMP unreachable sent\n");
ATOMIC_INCL(frstats[0].fr_ret);
} else if ((pass & FR_RETMASK) == FR_FAKEICMP) {
verbose("- forged ICMP unreachable sent\n");
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
!(fin->fin_fl & FI_SHORT)) {
verbose("- TCP RST sent\n");
ATOMIC_INCL(frstats[1].fr_ret);
}
#endif
} else {
if (pass & FR_RETRST)
error = ECONNRESET;
@ -1207,8 +1231,10 @@ int out;
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
(fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
(fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
(void) ipfr_fastroute(m, mp, fin, fdp);
m = *mp;
}
if (mc != NULL)
(void) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
@ -1243,6 +1269,12 @@ int out;
return 0;
if (pass & FR_AUTH)
return -2;
if ((pass & FR_RETMASK) == FR_RETRST)
return -3;
if ((pass & FR_RETMASK) == FR_RETICMP)
return -4;
if ((pass & FR_RETMASK) == FR_FAKEICMP)
return -5;
return -1;
#endif /* _KERNEL */
}
@ -1464,7 +1496,7 @@ tcphdr_t *tcp;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $
* $Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,

View File

@ -12,6 +12,9 @@
# endif
# endif
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__svr4__)
@ -21,8 +24,24 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/file.h>
#if defined(STATETOP) && defined(sun) && !defined(__svr4__) && !defined(__SVR4)
#include <sys/select.h>
#if defined(STATETOP)
# if defined(_BSDI_VERSION)
# undef STATETOP)
# endif
# if defined(__FreeBSD__) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 430000))
# undef STATETOP
# endif
# if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000)
# undef STATETOP
# endif
# if defined(sun)
# if defined(__svr4__) || defined(__SVR4)
# include <sys/select.h>
# else
# undef STATETOP /* NOT supported on SunOS4 */
# endif
# endif
#endif
#include <stdlib.h>
#include <unistd.h>
@ -50,15 +69,16 @@
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "ipf.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
#ifdef STATETOP
# include "netinet/ipl.h"
# include <ctype.h>
# if SOLARIS
# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \
defined(__sgi)
# ifdef ERR
# undef ERR
# endif
@ -74,7 +94,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.17 2001/07/19 12:24:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.34 2002/02/22 15:32:45 darrenr Exp $";
#endif
extern char *optarg;
@ -89,9 +109,8 @@ static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
"ipacct(in)", "ipacct(out)" };
int opts = 0;
#ifdef USE_INET6
int use_inet6 = 0;
#endif
int live_kernel = 1;
#ifdef STATETOP
#define STSTRSIZE 80
@ -102,7 +121,9 @@ int use_inet6 = 0;
#define STSORT_PKTS 1
#define STSORT_BYTES 2
#define STSORT_TTL 3
#define STSORT_MAX STSORT_TTL
#define STSORT_SRCIP 4
#define STSORT_DSTIP 5
#define STSORT_MAX STSORT_DSTIP
#define STSORT_DEFAULT STSORT_BYTES
@ -120,51 +141,33 @@ typedef struct statetop {
#endif
extern int main __P((int, char *[]));
static void showstats __P((int, friostat_t *));
static void showfrstates __P((int, ipfrstat_t *));
static void showstats __P((friostat_t *, u_32_t));
static void showfrstates __P((ipfrstat_t *));
static void showlist __P((friostat_t *));
static void showipstates __P((int, ips_stat_t *));
static void showauthstates __P((int, fr_authstat_t *));
static void showipstates __P((ips_stat_t *));
static void showauthstates __P((fr_authstat_t *));
static void showgroups __P((friostat_t *));
static void Usage __P((char *));
static void printlist __P((frentry_t *));
static char *get_ifname __P((void *));
static char *hostname __P((int, void *));
static void parse_ipportstr __P((const char *, struct in_addr *, int *));
static int ipfstate_live __P((char *, friostat_t **, ips_stat_t **,
ipfrstat_t **, fr_authstat_t **, u_32_t *));
static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **,
ipfrstat_t **, fr_authstat_t **, u_32_t *));
#ifdef STATETOP
static void topipstates __P((int, struct in_addr, struct in_addr, int, int, int, int, int));
static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int));
static char *ttl_to_string __P((long));
static int sort_p __P((const void *, const void *));
static int sort_pkts __P((const void *, const void *));
static int sort_bytes __P((const void *, const void *));
static int sort_ttl __P((const void *, const void *));
static int sort_srcip __P((const void *, const void *));
static int sort_dstip __P((const void *, const void *));
#endif
#if SOLARIS
void showqiflist __P((char *));
#endif
static char *hostname(v, ip)
int v;
void *ip;
{
#ifdef USE_INET6
static char hostbuf[MAXHOSTNAMELEN+1];
#endif
struct in_addr ipa;
if (v == 4) {
ipa.s_addr = *(u_32_t *)ip;
return inet_ntoa(ipa);
}
#ifdef USE_INET6
(void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
hostbuf[MAXHOSTNAMELEN] = '\0';
return hostbuf;
#else
return "IPv6";
#endif
}
static void Usage(name)
char *name;
@ -174,11 +177,8 @@ char *name;
#else
fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
#endif
fprintf(stderr, "\t\t[-M corefile]");
#if SOLARIS
fprintf(stderr, " [-N symbol-list]");
#endif
fprintf(stderr, "\n %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
fprintf(stderr, "\t\t[-M corefile] [-N symbol-list]\n");
fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
exit(1);
}
@ -190,15 +190,13 @@ char *argv[];
fr_authstat_t frauthst;
fr_authstat_t *frauthstp = &frauthst;
friostat_t fio;
friostat_t *fiop=&fio;
friostat_t *fiop = &fio;
ips_stat_t ipsst;
ips_stat_t *ipsstp = &ipsst;
ipfrstat_t ifrst;
ipfrstat_t *ifrstp = &ifrst;
char *name = NULL, *device = IPL_NAME, *memf = NULL;
#if SOLARIS
char *device = IPL_NAME, *memf = NULL;
char *kern = NULL;
#endif
int c, fd, myoptind;
struct protoent *proto;
@ -208,6 +206,8 @@ char *argv[];
int dport = -1; /* -1 = wild card for any dest port */
int topclosed = 0; /* do not show closed tcp sessions */
struct in_addr saddr, daddr;
u_32_t frf;
saddr.s_addr = INADDR_ANY; /* default any source addr */
daddr.s_addr = INADDR_ANY; /* default any dest addr */
@ -216,45 +216,33 @@ char *argv[];
* in the parsing of the rest.
*/
myoptind = optind;
#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
#else
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:P:S:T:")) != -1)
#endif
switch (c)
{
case 'M' :
memf = optarg;
live_kernel = 0;
break;
#if SOLARIS
case 'N' :
kern = optarg;
live_kernel = 0;
break;
#endif
}
optind = myoptind;
#if SOLARIS
if (kern != NULL || memf != NULL)
#else
if (memf != NULL)
#endif
{
(void)setuid(getuid());
(void)setgid(getgid());
}
if (openkmem(memf) == -1)
if (openkmem(kern, memf) == -1)
exit(-1);
(void)setuid(getuid());
(void)setgid(getgid());
#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
#else
while ((c = getopt(argc, argv, "6aACfghIilnostvd:D:M:P:S:T:")) != -1)
#endif
{
switch (c)
{
@ -265,7 +253,8 @@ char *argv[];
#endif
case 'a' :
opts |= OPT_ACCNT|OPT_SHOWLIST;
break; case 'A' :
break;
case 'A' :
device = IPAUTH_NAME;
opts |= OPT_AUTHSTATS;
break;
@ -316,11 +305,15 @@ char *argv[];
exit(-2);
}
break;
#if SOLARIS
case 'q' :
#if SOLARIS
showqiflist(kern);
exit(0);
break;
#else
fprintf(stderr, "-q only availble on Solaris\n");
exit(1);
break;
#endif
case 's' :
opts |= OPT_IPSTATES;
@ -356,19 +349,67 @@ char *argv[];
}
}
if (live_kernel == 1) {
bzero((char *)&fio, sizeof(fio));
bzero((char *)&ipsst, sizeof(ipsst));
bzero((char *)&ifrst, sizeof(ifrst));
fd = ipfstate_live(device, &fiop, &ipsstp, &ifrstp,
&frauthstp, &frf);
} else
ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf);
if (opts & OPT_IPSTATES) {
showipstates(ipsstp);
} else if (opts & OPT_SHOWLIST) {
showlist(fiop);
if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
opts &= ~OPT_OUTQUE;
showlist(fiop);
}
} else {
if (opts & OPT_FRSTATES)
showfrstates(ifrstp);
#ifdef STATETOP
else if (opts & OPT_STATETOP)
topipstates(saddr, daddr, sport, dport,
protocol, refreshtime, topclosed);
#endif
else if (opts & OPT_AUTHSTATS)
showauthstates(frauthstp);
else if (opts & OPT_GROUPS)
showgroups(fiop);
else
showstats(fiop, frf);
}
return 0;
}
/*
* Fill in the stats structures from the live kernel, using a combination
* of ioctl's and copying directly from kernel memory.
*/
int ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
char *device;
friostat_t **fiopp;
ips_stat_t **ipsstpp;
ipfrstat_t **ifrstpp;
fr_authstat_t **frauthstpp;
u_32_t *frfp;
{
int fd;
if ((fd = open(device, O_RDONLY)) < 0) {
perror("open");
exit(-1);
}
bzero((char *)&fio, sizeof(fio));
bzero((char *)&ipsst, sizeof(ipsst));
bzero((char *)&ifrst, sizeof(ifrst));
if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) {
if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, fiopp) == -1) {
perror("ioctl(ipf:SIOCGETFS)");
exit(-1);
}
if ((opts & OPT_IPSTATES)) {
int sfd = open(IPL_STATE, O_RDONLY);
@ -376,64 +417,237 @@ char *argv[];
perror("open");
exit(-1);
}
if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
if ((ioctl(sfd, SIOCGETFS, ipsstpp) == -1)) {
perror("ioctl(state:SIOCGETFS)");
exit(-1);
}
close(sfd);
}
if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrstp) == -1)) {
if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, ifrstpp) == -1)) {
perror("ioctl(SIOCGFRST)");
exit(-1);
}
if (opts & OPT_VERBOSE)
PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
PRINTF("opts %#x name %s\n", opts, device);
if ((opts & OPT_AUTHSTATS) &&
(ioctl(fd, SIOCATHST, &frauthstp) == -1)) {
(ioctl(fd, SIOCATHST, frauthstpp) == -1)) {
perror("ioctl(SIOCATHST)");
exit(-1);
}
if (opts & OPT_IPSTATES) {
showipstates(fd, ipsstp);
} else if (opts & OPT_SHOWLIST) {
showlist(&fio);
if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
opts &= ~OPT_OUTQUE;
showlist(&fio);
}
} else {
if (opts & OPT_FRSTATES)
showfrstates(fd, ifrstp);
#ifdef STATETOP
else if (opts & OPT_STATETOP)
topipstates(fd, saddr, daddr, sport, dport,
protocol, refreshtime, topclosed);
#endif
else if (opts & OPT_AUTHSTATS)
showauthstates(fd, frauthstp);
else if (opts & OPT_GROUPS)
showgroups(&fio);
else
showstats(fd, &fio);
}
return 0;
if (ioctl(fd, SIOCGETFF, frfp) == -1)
perror("ioctl(SIOCGETFF)");
return fd;
}
/*
* read the kernel stats for packets blocked and passed
* Build up the stats structures from data held in the "core" memory.
* This is mainly useful when looking at data in crash dumps and ioctl's
* just won't work any more.
*/
static void showstats(fd, fp)
int fd;
struct friostat *fp;
void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
char *kernel;
friostat_t **fiopp;
ips_stat_t **ipsstpp;
ipfrstat_t **ifrstpp;
fr_authstat_t **frauthstpp;
u_32_t *frfp;
{
u_32_t frf = 0;
static fr_authstat_t frauthst, *frauthstp;
static ips_stat_t ipsst, *ipsstp;
static ipfrstat_t ifrst, *ifrstp;
static friostat_t fio, *fiop;
if (ioctl(fd, SIOCGETFF, &frf) == -1)
perror("ioctl(SIOCGETFF)");
void *rules[2][2];
struct nlist deadlist[42] = {
{ "fr_authstats" }, /* 0 */
{ "fae_list" },
{ "ipauth" },
{ "fr_authlist" },
{ "fr_authstart" },
{ "fr_authend" }, /* 5 */
{ "fr_authnext" },
{ "fr_auth" },
{ "fr_authused" },
{ "fr_authsize" },
{ "fr_defaultauthage" }, /* 10 */
{ "fr_authpkts" },
{ "fr_auth_lock" },
{ "frstats" },
{ "ips_stats" },
{ "ips_num" }, /* 15 */
{ "ips_wild" },
{ "ips_list" },
{ "ips_table" },
{ "fr_statemax" },
{ "fr_statesize" }, /* 20 */
{ "fr_state_doflush" },
{ "fr_state_lock" },
{ "ipfr_heads" },
{ "ipfr_nattab" },
{ "ipfr_stats" }, /* 25 */
{ "ipfr_inuse" },
{ "fr_ipfrttl" },
{ "fr_frag_lock" },
{ "ipfr_timer_id" },
{ "fr_nat_lock" }, /* 30 */
{ "ipfilter" },
{ "ipfilter6" },
{ "ipacct" },
{ "ipacct6" },
{ "ipl_frouteok" }, /* 35 */
{ "fr_running" },
{ "ipfgroups" },
{ "fr_active" },
{ "fr_pass" },
{ "fr_flags" }, /* 40 */
{ NULL }
};
frauthstp = &frauthst;
ipsstp = &ipsst;
ifrstp = &ifrst;
fiop = &fio;
*frfp = 0;
*fiopp = fiop;
*ipsstpp = ipsstp;
*ifrstpp = ifrstp;
*frauthstpp = frauthstp;
bzero((char *)fiop, sizeof(*fiop));
bzero((char *)ipsstp, sizeof(*ipsstp));
bzero((char *)ifrstp, sizeof(*ifrstp));
bzero((char *)frauthstp, sizeof(*frauthstp));
if (nlist(kernel, deadlist) == -1) {
fprintf(stderr, "nlist error\n");
return;
}
/*
* This is for SIOCGETFF.
*/
kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp));
/*
* f_locks is a combination of the lock variable from each part of
* ipfilter (state, auth, nat, fragments).
*/
kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop));
kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value,
sizeof(fiop->f_locks[0]));
kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value,
sizeof(fiop->f_locks[1]));
kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value,
sizeof(fiop->f_locks[2]));
kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value,
sizeof(fiop->f_locks[3]));
/*
* Get pointers to each list of rules (active, inactive, in, out)
*/
kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules));
fiop->f_fin[0] = rules[0][0];
fiop->f_fin[1] = rules[0][1];
fiop->f_fout[0] = rules[1][0];
fiop->f_fout[1] = rules[1][1];
/*
* Same for IPv6, except make them null if support for it is not
* being compiled in.
*/
#ifdef USE_INET6
kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules));
fiop->f_fin6[0] = rules[0][0];
fiop->f_fin6[1] = rules[0][1];
fiop->f_fout6[0] = rules[1][0];
fiop->f_fout6[1] = rules[1][1];
#else
fiop->f_fin6[0] = NULL;
fiop->f_fin6[1] = NULL;
fiop->f_fout6[0] = NULL;
fiop->f_fout6[1] = NULL;
#endif
/*
* Now get accounting rules pointers.
*/
kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules));
fiop->f_acctin[0] = rules[0][0];
fiop->f_acctin[1] = rules[0][1];
fiop->f_acctout[0] = rules[1][0];
fiop->f_acctout[1] = rules[1][1];
#ifdef USE_INET6
kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules));
fiop->f_acctin6[0] = rules[0][0];
fiop->f_acctin6[1] = rules[0][1];
fiop->f_acctout6[0] = rules[1][0];
fiop->f_acctout6[1] = rules[1][1];
#else
fiop->f_acctin6[0] = NULL;
fiop->f_acctin6[1] = NULL;
fiop->f_acctout6[0] = NULL;
fiop->f_acctout6[1] = NULL;
#endif
/*
* A collection of "global" variables used inside the kernel which
* are all collected in friostat_t via ioctl.
*/
kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value,
sizeof(fiop->f_froute));
kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value,
sizeof(fiop->f_running));
kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value,
sizeof(fiop->f_groups));
kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value,
sizeof(fiop->f_active));
kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value,
sizeof(fiop->f_defpass));
/*
* Build up the state information stats structure.
*/
kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp));
kmemcpy((char *)&ipsstp->iss_active, (u_long)deadlist[15].n_value,
sizeof(ipsstp->iss_active));
ipsstp->iss_table = (void *)deadlist[18].n_value;
ipsstp->iss_list = (void *)deadlist[17].n_value;
/*
* Build up the authentiation information stats structure.
*/
kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value,
sizeof(*frauthstp));
frauthstp->fas_faelist = (void *)deadlist[1].n_value;
/*
* Build up the fragment information stats structure.
*/
kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value,
sizeof(*ifrstp));
ifrstp->ifs_table = (void *)deadlist[23].n_value;
ifrstp->ifs_nattab = (void *)deadlist[24].n_value;
kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value,
sizeof(ifrstp->ifs_inuse));
}
/*
* Display the kernel stats for packets blocked and passed and other
* associated running totals which are kept.
*/
static void showstats(fp, frf)
struct friostat *fp;
u_32_t frf;
{
#if SOLARIS
PRINTF("dropped packets:\tin %lu\tout %lu\n",
@ -505,6 +719,9 @@ struct friostat *fp;
}
/*
* Print out a list of rules from the kernel, starting at the one passed.
*/
static void printlist(fp)
frentry_t *fp;
{
@ -543,7 +760,8 @@ frentry_t *fp;
}
/*
* print out filter rule list
* print out all of the asked for rule sets, using the stats struct as
* the base from which to get the pointers.
*/
static void showlist(fiop)
struct friostat *fiop;
@ -598,12 +816,17 @@ struct friostat *fiop;
}
static void showipstates(fd, ipsp)
int fd;
/*
* Display ipfilter stateful filtering information
*/
static void showipstates(ipsp)
ips_stat_t *ipsp;
{
ipstate_t *istab[IPSTATE_SIZE], ips;
ipstate_t *istab[IPSTATE_SIZE];
/*
* If a list of states hasn't been asked for, only print out stats
*/
if (!(opts & OPT_SHOWLIST)) {
PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n",
ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp);
@ -619,116 +842,20 @@ ips_stat_t *ipsp;
if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
return;
while (ipsp->iss_list) {
if (kmemcpy((char *)&ips, (u_long)ipsp->iss_list, sizeof(ips)))
break;
ipsp->iss_list = ips.is_next;
PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4));
PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n",
hostname(ips.is_v, &ips.is_dst.in4),
ips.is_age, ips.is_pass, ips.is_p,
ips.is_state[0], ips.is_state[1]);
#ifdef USE_QUAD_T
PRINTF("\tpkts %qu bytes %qu",
(unsigned long long) ips.is_pkts,
(unsigned long long) ips.is_bytes);
#else
PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes);
#endif
if (ips.is_p == IPPROTO_TCP)
#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
(__FreeBSD_version >= 220000) || defined(__OpenBSD__)
PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
ntohs(ips.is_sport), ntohs(ips.is_dport),
ips.is_send, ips.is_dend,
ips.is_maxswin, ips.is_maxdwin);
#else
PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
ntohs(ips.is_sport), ntohs(ips.is_dport),
ips.is_send, ips.is_dend,
ips.is_maxswin, ips.is_maxdwin);
#endif
else if (ips.is_p == IPPROTO_UDP)
PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
ntohs(ips.is_dport));
else if (ips.is_p == IPPROTO_ICMP
#ifdef USE_INET6
|| ips.is_p == IPPROTO_ICMPV6
#endif
)
PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
ips.is_icmp.ics_seq, ips.is_icmp.ics_type);
PRINTF("\n\t");
if (ips.is_pass & FR_PASS) {
PRINTF("pass");
} else if (ips.is_pass & FR_BLOCK) {
PRINTF("block");
switch (ips.is_pass & FR_RETMASK)
{
case FR_RETICMP :
PRINTF(" return-icmp");
break;
case FR_FAKEICMP :
PRINTF(" return-icmp-as-dest");
break;
case FR_RETRST :
PRINTF(" return-rst");
break;
default :
break;
}
} else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
PRINTF("log");
if (ips.is_pass & FR_LOGBODY)
PRINTF(" body");
if (ips.is_pass & FR_LOGFIRST)
PRINTF(" first");
} else if (ips.is_pass & FR_ACCOUNT)
PRINTF("count");
if (ips.is_pass & FR_OUTQUE)
PRINTF(" out");
else
PRINTF(" in");
if ((ips.is_pass & FR_LOG) != 0) {
PRINTF(" log");
if (ips.is_pass & FR_LOGBODY)
PRINTF(" body");
if (ips.is_pass & FR_LOGFIRST)
PRINTF(" first");
if (ips.is_pass & FR_LOGORBLOCK)
PRINTF(" or-block");
}
if (ips.is_pass & FR_QUICK)
PRINTF(" quick");
if (ips.is_pass & FR_KEEPFRAG)
PRINTF(" keep frags");
/* a given; no? */
if (ips.is_pass & FR_KEEPSTATE)
PRINTF(" keep state");
PRINTF("\tIPv%d", ips.is_v);
PRINTF("\n");
PRINTF("\tpkt_flags & %x(%x) = %x,\t",
ips.is_flags & 0xf, ips.is_flags,
ips.is_flags >> 4);
PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk,
ips.is_opt);
PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n",
ips.is_secmsk, ips.is_sec, ips.is_authmsk,
ips.is_auth);
PRINTF("\tinterfaces: in %s[%p] ",
get_ifname(ips.is_ifpin), ips.is_ifpin);
PRINTF("out %s[%p]\n",
get_ifname(ips.is_ifpout), ips.is_ifpout);
/*
* Print out all the state information currently held in the kernel.
*/
while (ipsp->iss_list != NULL) {
ipsp->iss_list = printstate(ipsp->iss_list, opts);
}
}
#if SOLARIS
/*
* Displays the list of interfaces of which IPFilter has taken control in
* Solaris.
*/
void showqiflist(kern)
char *kern;
{
@ -737,6 +864,7 @@ char *kern;
{ NULL }
};
qif_t qif, *qf;
ill_t ill;
if (kern == NULL)
kern = "/dev/ksyms";
@ -752,24 +880,27 @@ char *kern;
while (qf) {
if (kmemcpy((char *)&qif, (u_long)qf, sizeof(qif)))
break;
printf("\tName: %-8s Header Length: %2d SAP: %s (%04x)\n",
if (kmemcpy((char *)&ill, (u_long)qif.qf_ill, sizeof(ill)))
ill.ill_ppa = -1;
printf("Name: %-8s Header Length: %2d SAP: %s (%04x) PPA %d",
qif.qf_name, qif.qf_hl,
#ifdef IP6_DL_SAP
(qif.qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
, qif.qf_sap);
, qif.qf_sap, ill.ill_ppa);
printf(" %ld %ld", qif.qf_incnt, qif.qf_outcnt);
qf = qif.qf_next;
putchar('\n');
}
}
#endif
#ifdef STATETOP
static void topipstates(fd, saddr, daddr, sport, dport, protocol,
static void topipstates(saddr, daddr, sport, dport, protocol,
refreshtime, topclosed)
int fd;
struct in_addr saddr;
struct in_addr daddr;
int sport;
@ -841,8 +972,8 @@ int topclosed;
((dport < 0) ||
(htons(dport) == ips.is_dport)))) &&
(topclosed || (ips.is_p != IPPROTO_TCP) ||
(ips.is_state[0] < TCPS_CLOSE_WAIT) ||
(ips.is_state[1] < TCPS_CLOSE_WAIT))) {
(ips.is_state[0] < TCPS_LAST_ACK) ||
(ips.is_state[1] < TCPS_LAST_ACK))) {
/*
* if necessary make room for this state
* entry
@ -899,6 +1030,14 @@ int topclosed;
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_ttl);
break;
case STSORT_SRCIP:
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_srcip);
break;
case STSORT_DSTIP:
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_dstip);
break;
default:
break;
}
@ -957,6 +1096,12 @@ int topclosed;
case STSORT_TTL:
sprintf(str4, "ttl");
break;
case STSORT_SRCIP:
sprintf(str4, "srcip");
break;
case STSORT_DSTIP:
sprintf(str4, "dstip");
break;
default:
sprintf(str4, "unknown");
break;
@ -1079,14 +1224,20 @@ int topclosed;
}
#endif
static void showfrstates(fd, ifsp)
int fd;
/*
* Show fragment cache information that's held in the kernel.
*/
static void showfrstates(ifsp)
ipfrstat_t *ifsp;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
frentry_t fr;
int i;
/*
* print out the numeric statistics
*/
PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits);
PRINTF("\t%lu no memory\n\t%lu already exist\n",
@ -1094,6 +1245,10 @@ ipfrstat_t *ifsp;
PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab)))
return;
/*
* Print out the contents (if any) of the fragment cache table.
*/
for (i = 0; i < IPFT_SIZE; i++)
while (ipfrtab[i]) {
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
@ -1129,8 +1284,10 @@ ipfrstat_t *ifsp;
}
static void showauthstates(fd, asp)
int fd;
/*
* Show stats on how auth within IPFilter has been used
*/
static void showauthstates(asp)
fr_authstat_t *asp;
{
frauthent_t *frap, fra;
@ -1161,63 +1318,10 @@ fr_authstat_t *asp;
}
static char *get_ifname(ptr)
void *ptr;
{
#if SOLARIS
char *ifname;
ill_t ill;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
return "X";
ifname = malloc(ill.ill_name_length + 1);
if (kmemcpy(ifname, (u_long)ill.ill_name,
ill.ill_name_length) == -1)
return "X";
return ifname;
#else
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
#else
char buf[32];
int len;
# endif
struct ifnet netif;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
return "X";
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
return strdup(netif.if_xname);
# else
if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
return "X";
if (netif.if_unit < 10)
len = 2;
else if (netif.if_unit < 1000)
len = 3;
else if (netif.if_unit < 10000)
len = 4;
else
len = 5;
buf[sizeof(buf) - len] = '\0';
sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
return strdup(buf);
# endif
#endif
}
/*
* Display groups used for each of filter rules, accounting rules and
* authentication, separately.
*/
static void showgroups(fiop)
struct friostat *fiop;
{
@ -1370,4 +1474,32 @@ const void *b;
return 1;
return -1;
}
static int sort_srcip(a, b)
const void *a;
const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr))
return 0;
else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr))
return 1;
return -1;
}
static int sort_dstip(a, b)
const void *a;
const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr))
return 0;
else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr))
return 1;
return -1;
}
#endif

View File

@ -65,7 +65,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.1.4.1 2001/07/15 22:06:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.1.4.2 2002/02/22 15:32:46 darrenr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -182,7 +182,8 @@ inet_aton(cp, addr)
* Ascii internet address interpretation routine.
* The value returned is in network order.
*/
#if defined(SOLARIS2) && (SOLARIS2 > 5)
#if (defined(SOLARIS2) && (SOLARIS2 > 5)) || \
(defined(IRIX) && (IRIX >= 605))
in_addr_t
#else
u_long

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -19,7 +22,6 @@
#else
# include <sys/ioctl.h>
#endif
#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@ -102,7 +104,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#endif
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.12 2001/07/18 14:57:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.17 2002/03/06 09:44:10 darrenr Exp $";
#endif
@ -305,7 +307,7 @@ ip_t *ip;
int fr_auth_ioctl(data, mode, cmd, fr, frptr)
caddr_t data;
int mode;
#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
u_long cmd;
#else
int cmd;
@ -377,9 +379,7 @@ frentry_t *fr, **frptr;
error = EINVAL;
break;
case SIOCATHST:
READ_ENTER(&ipf_auth);
fr_authstats.fas_faelist = fae_list;
RWLOCK_EXIT(&ipf_auth);
error = IWCOPYPTR((char *)&fr_authstats, data,
sizeof(fr_authstats));
break;
@ -453,7 +453,7 @@ frentry_t *fr, **frptr;
bzero((char *)&ro, sizeof(ro));
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
defined(__OpenBSD__)
defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605))
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
# else
@ -478,7 +478,9 @@ frentry_t *fr, **frptr;
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
# if IRIX < 605
schednetisr(NETISR_IP);
# endif
}
# endif /* SOLARIS */
if (error)
@ -526,7 +528,6 @@ frentry_t *fr, **frptr;
}
#ifdef _KERNEL
/*
* Free all network buffer memory used to keep saved packets.
*/
@ -587,7 +588,7 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
#if !SOLARIS
#if !SOLARIS && defined(_KERNEL)
int s;
#endif
@ -626,4 +627,3 @@ void fr_authexpire()
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
#endif

View File

@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_auth.h,v 2.3.2.4 2001/07/18 14:57:08 darrenr Exp $
* $Id: ip_auth.h,v 2.3.2.5 2001/11/04 13:15:51 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@ -52,7 +52,8 @@ extern void fr_authexpire __P((void));
extern void fr_authunload __P((void));
extern mb_t *fr_authpkts[];
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__) || \
(__FreeBSD_version >= 300003)
extern int fr_auth_ioctl __P((caddr_t, int, u_long, frentry_t *, frentry_t **));
#else
extern int fr_auth_ioctl __P((caddr_t, int, int, frentry_t *, frentry_t **));

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.26.2.17 2001/07/23 04:22:48 darrenr Exp $
* $Id: ip_compat.h,v 2.26.2.39 2002/03/13 03:54:34 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -25,13 +25,20 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#if SOLARIS && !defined(SOLARIS2)
# define SOLARIS2 4 /* Pick an old version */
#endif
#if SOLARIS2 >= 8
# ifndef USE_INET6
# define USE_INET6
#if SOLARIS
# if !defined(SOLARIS2)
# define SOLARIS2 3 /* Pick an old version */
# endif
# if SOLARIS2 >= 8
# ifndef USE_INET6
# define USE_INET6
# endif
# else
# undef USE_INET6
# endif
#endif
#if defined(sun) && !(defined(__svr4__) || defined(__SVR4))
# undef USE_INET6
#endif
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
@ -62,6 +69,18 @@ struct ether_addr {
};
#endif
#ifndef LIFNAMSIZ
# ifdef IF_NAMESIZE
# define LIFNAMSIZ IF_NAMESIZE
# else
# ifdef IFNAMSIZ
# define LIFNAMSIZ IFNAMSIZ
# else
# define LIFNAMSIZ 16
# endif
# endif
#endif
#if defined(__sgi) && !defined(IPFILTER_LKM)
# ifdef __STDC__
# define IPL_EXTERN(ep) ipfilter##ep
@ -76,12 +95,37 @@ struct ether_addr {
# endif
#endif
#ifdef __sgi
# include <sys/debug.h>
#endif
#ifdef linux
# include <sys/sysmacros.h>
#endif
/*
* This is a workaround for <sys/uio.h> troubles on FreeBSD and OpenBSD.
*/
#ifndef _KERNEL
# define ADD_KERNEL
# define _KERNEL
# define KERNEL
#endif
#ifdef __OpenBSD__
struct file;
#endif
#include <sys/uio.h>
#ifdef ADD_KERNEL
# undef _KERNEL
# undef KERNEL
#endif
#if SOLARIS
# define MTYPE(m) ((m)->b_datap->db_type)
# include <sys/isa_defs.h>
# if SOLARIS2 >= 4
# include <sys/isa_defs.h>
# endif
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
# include <sys/kmem.h>
@ -137,12 +181,14 @@ typedef struct qif {
queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
size_t qf_off;
size_t qf_len; /* this field is used for in ipfr_fastroute */
char qf_name[8];
char qf_name[LIFNAMSIZ];
/*
* in case the ILL has disappeared...
*/
size_t qf_hl; /* header length */
int qf_sap;
size_t qf_incnt;
size_t qf_outcnt;
} qif_t;
#else /* SOLARIS */
# if !defined(__sgi)
@ -210,6 +256,7 @@ typedef unsigned int u_32_t;
# endif
typedef struct ip6_hdr ip6_t;
# endif
# include <netinet/icmp6.h>
union i6addr {
u_32_t i6[4];
struct in_addr in4;
@ -225,6 +272,14 @@ union i6addr {
#define IP6CMP(a,b) bcmp((char *)&(a), (char *)&(b), sizeof(a))
#define IP6EQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) == 0)
#define IP6NEQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) != 0)
#define IP6_ISZERO(a) ((((union i6addr *)(a))->i6[0] | \
((union i6addr *)(a))->i6[1] | \
((union i6addr *)(a))->i6[2] | \
((union i6addr *)(a))->i6[3]) == 0)
#define IP6_NOTZERO(a) ((((union i6addr *)(a))->i6[0] | \
((union i6addr *)(a))->i6[1] | \
((union i6addr *)(a))->i6[2] | \
((union i6addr *)(a))->i6[3]) != 0)
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@ -325,6 +380,21 @@ union i6addr {
* Build some macros and #defines to enable the same code to compile anywhere
* Well, that's the idea, anyway :-)
*/
#if SOLARIS
typedef mblk_t mb_t;
# if SOLARIS2 >= 7
# ifdef lint
# define ALIGN32(ptr) (ptr ? 0L : 0L)
# define ALIGN16(ptr) (ptr ? 0L : 0L)
# else
# define ALIGN32(ptr) (ptr)
# define ALIGN16(ptr) (ptr)
# endif
# endif
#else
typedef struct mbuf mb_t;
#endif /* SOLARIS */
#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
# define ATOMIC_INCL ATOMIC_INC
# define ATOMIC_INC64 ATOMIC_INC
@ -506,11 +576,19 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# define GET_MINOR(x) minor(x)
# endif
# if (BSD >= 199306) || defined(__FreeBSD__)
# include <vm/vm.h>
# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \
defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_BSDI_VERSION)
# include <vm/vm.h>
# endif
# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
# include <vm/vm_extern.h>
# include <sys/proc.h>
# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \
(defined(OpenBSD) && (OpenBSD >= 200111))
# include <uvm/uvm_extern.h>
# else
# include <vm/vm_extern.h>
extern vm_map_t kmem_map;
# endif
# include <sys/proc.h>
# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# include <vm/vm_kern.h>
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
@ -542,7 +620,7 @@ extern vm_map_t kmem_map;
# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
# define PANIC(x,y) if (x) panic y
#else /* KERNEL */
# define SLEEP(x,y) ;
# define SLEEP(x,y) 1
# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define ATOMIC_INC(x) (x)++
@ -564,40 +642,18 @@ extern vm_map_t kmem_map;
# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
# define FREE_MB_T(x) ;
# define GETUNIT(x, v) get_unit(x,v)
# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
# define IFNAME(x) get_ifname((struct ifnet *)x)
# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
#endif /* KERNEL */
#if SOLARIS
typedef mblk_t mb_t;
# if SOLARIS2 >= 7
# ifdef lint
# define ALIGN32(ptr) (ptr ? 0L : 0L)
# define ALIGN16(ptr) (ptr ? 0L : 0L)
# else
# define ALIGN32(ptr) (ptr)
# define ALIGN16(ptr) (ptr)
# endif
# endif
#else
# ifdef linux
# ifndef kernel
typedef struct mb {
struct mb *next;
u_int len;
u_char *data;
} mb_t;
# else
typedef struct sk_buff mb_t;
# endif
# else
typedef struct mbuf mb_t;
# endif
#endif /* SOLARIS */
/*
* These #ifdef's are here mainly for linux, but who knows, they may
* not be in other places or maybe one day linux will grow up and some
@ -606,39 +662,153 @@ typedef struct mbuf mb_t;
#ifndef ICMP_MINLEN
# define ICMP_MINLEN 8
#endif
#ifndef ICMP_ECHOREPLY
# define ICMP_ECHOREPLY 0
#endif
#ifndef ICMP_UNREACH
# define ICMP_UNREACH ICMP_DEST_UNREACH
# define ICMP_UNREACH 3
#endif
#ifndef ICMP_UNREACH_NET
# define ICMP_UNREACH_NET 0
#endif
#ifndef ICMP_UNREACH_HOST
# define ICMP_UNREACH_HOST 1
#endif
#ifndef ICMP_UNREACH_PROTOCOL
# define ICMP_UNREACH_PROTOCOL 2
#endif
#ifndef ICMP_UNREACH_PORT
# define ICMP_UNREACH_PORT 3
#endif
#ifndef ICMP_UNREACH_NEEDFRAG
# define ICMP_UNREACH_NEEDFRAG 4
#endif
#ifndef ICMP_UNREACH_SRCFAIL
# define ICMP_UNREACH_SRCFAIL 5
#endif
#ifndef ICMP_UNREACH_NET_UNKNOWN
# define ICMP_UNREACH_NET_UNKNOWN 6
#endif
#ifndef ICMP_UNREACH_HOST_UNKNOWN
# define ICMP_UNREACH_HOST_UNKNOWN 7
#endif
#ifndef ICMP_UNREACH_ISOLATED
# define ICMP_UNREACH_ISOLATED 8
#endif
#ifndef ICMP_UNREACH_NET_PROHIB
# define ICMP_UNREACH_NET_PROHIB 9
#endif
#ifndef ICMP_UNREACH_HOST_PROHIB
# define ICMP_UNREACH_HOST_PROHIB 10
#endif
#ifndef ICMP_UNREACH_TOSNET
# define ICMP_UNREACH_TOSNET 11
#endif
#ifndef ICMP_UNREACH_TOSHOST
# define ICMP_UNREACH_TOSHOST 12
#endif
#ifndef ICMP_UNREACH_ADMIN_PROHIBIT
# define ICMP_UNREACH_ADMIN_PROHIBIT 13
#endif
#ifndef ICMP_UNREACH_HOST_PRECEDENCE
# define ICMP_UNREACH_HOST_PRECEDENCE 14
#endif
#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
#endif
#ifndef ICMP_SOURCEQUENCH
# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
# define ICMP_SOURCEQUENCH 4
#endif
#ifndef ICMP_REDIRECT_NET
# define ICMP_REDIRECT_NET 0
#endif
#ifndef ICMP_REDIRECT_HOST
# define ICMP_REDIRECT_HOST 1
#endif
#ifndef ICMP_REDIRECT_TOSNET
# define ICMP_REDIRECT_TOSNET 2
#endif
#ifndef ICMP_REDIRECT_TOSHOST
# define ICMP_REDIRECT_TOSHOST 3
#endif
#ifndef ICMP_ALTHOSTADDR
# define ICMP_ALTHOSTADDR 6
#endif
#ifndef ICMP_TIMXCEED
# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
# define ICMP_TIMXCEED 11
#endif
#ifndef ICMP_TIMXCEED_INTRANS
# define ICMP_TIMXCEED_INTRANS 0
#endif
#ifndef ICMP_TIMXCEED_REASS
# define ICMP_TIMXCEED_REASS 1
#endif
#ifndef ICMP_PARAMPROB
# define ICMP_PARAMPROB ICMP_PARAMETERPROB
# define ICMP_PARAMPROB 12
#endif
#ifndef ICMP_TSTAMP
# define ICMP_TSTAMP ICMP_TIMESTAMP
#endif
#ifndef ICMP_TSTAMPREPLY
# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
#endif
#ifndef ICMP_IREQ
# define ICMP_IREQ ICMP_INFO_REQUEST
#endif
#ifndef ICMP_IREQREPLY
# define ICMP_IREQREPLY ICMP_INFO_REPLY
#endif
#ifndef ICMP_MASKREQ
# define ICMP_MASKREQ ICMP_ADDRESS
#endif
#ifndef ICMP_MASKREPLY
# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
#ifndef ICMP_PARAMPROB_ERRATPTR
# define ICMP_PARAMPROB_ERRATPTR 0
#endif
#ifndef ICMP_PARAMPROB_OPTABSENT
# define ICMP_PARAMPROB_OPTABSENT 1
#endif
#ifndef ICMP_PARAMPROB_LENGTH
# define ICMP_PARAMPROB_LENGTH 2
#endif
#ifndef ICMP_TSTAMP
# define ICMP_TSTAMP 13
#endif
#ifndef ICMP_TSTAMPREPLY
# define ICMP_TSTAMPREPLY 14
#endif
#ifndef ICMP_IREQ
# define ICMP_IREQ 15
#endif
#ifndef ICMP_IREQREPLY
# define ICMP_IREQREPLY 16
#endif
#ifndef ICMP_MASKREQ
# define ICMP_MASKREQ 17
#endif
#ifndef ICMP_MASKREPLY
# define ICMP_MASKREPLY 18
#endif
#ifndef ICMP_TRACEROUTE
# define ICMP_TRACEROUTE 30
#endif
#ifndef ICMP_DATACONVERR
# define ICMP_DATACONVERR 31
#endif
#ifndef ICMP_MOBILE_REDIRECT
# define ICMP_MOBILE_REDIRECT 32
#endif
#ifndef ICMP_IPV6_WHEREAREYOU
# define ICMP_IPV6_WHEREAREYOU 33
#endif
#ifndef ICMP_IPV6_IAMHERE
# define ICMP_IPV6_IAMHERE 34
#endif
#ifndef ICMP_MOBILE_REGREQUEST
# define ICMP_MOBILE_REGREQUEST 35
#endif
#ifndef ICMP_MOBILE_REGREPLY
# define ICMP_MOBILE_REGREPLY 36
#endif
#ifndef ICMP_SKIP
# define ICMP_SKIP 39
#endif
#ifndef ICMP_PHOTURIS
# define ICMP_PHOTURIS 40
#endif
#ifndef ICMP_PHOTURIS_UNKNOWN_INDEX
# define ICMP_PHOTURIS_UNKNOWN_INDEX 1
#endif
#ifndef ICMP_PHOTURIS_AUTH_FAILED
# define ICMP_PHOTURIS_AUTH_FAILED 2
#endif
#ifndef ICMP_PHOTURIS_DECRYPT_FAILED
# define ICMP_PHOTURIS_DECRYPT_FAILED 3
#endif
#ifndef IPVERSION
# define IPVERSION 4
#endif
@ -726,6 +896,15 @@ typedef struct mbuf mb_t;
#ifndef IPOPT_OLEN
# define IPOPT_OLEN 1
#endif
#ifndef IPPROTO_GRE
# define IPPROTO_GRE 47 /* GRE encaps RFC 1701 */
#endif
#ifndef IPPROTO_ESP
# define IPPROTO_ESP 50
#endif
#ifndef IPPROTO_ICMPV6
# define IPPROTO_ICMPV6 58
#endif
#ifdef linux
#include <linux/in_systm.h>
@ -997,6 +1176,10 @@ struct ether_addr {
#define A_A &
#endif
#if (BSD >= 199306) && !defined(m_act)
# define m_act m_nextpkt
#endif
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
@ -1016,9 +1199,170 @@ struct ether_addr {
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
#define ICMP6_MINLEN 8
#define ICMP6ERR_MINPKTLEN (40 + 8)
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
#ifndef ICMP6_DST_UNREACH
# define ICMP6_DST_UNREACH 1
#endif
#ifndef ICMP6_PACKET_TOO_BIG
# define ICMP6_PACKET_TOO_BIG 2
#endif
#ifndef ICMP6_TIME_EXCEEDED
# define ICMP6_TIME_EXCEEDED 3
#endif
#ifndef ICMP6_PARAM_PROB
# define ICMP6_PARAM_PROB 4
#endif
#ifndef ICMP6_ECHO_REQUEST
# define ICMP6_ECHO_REQUEST 128
#endif
#ifndef ICMP6_ECHO_REPLY
# define ICMP6_ECHO_REPLY 129
#endif
#ifndef ICMP6_MEMBERSHIP_QUERY
# define ICMP6_MEMBERSHIP_QUERY 130
#endif
#ifndef MLD6_LISTENER_QUERY
# define MLD6_LISTENER_QUERY 130
#endif
#ifndef ICMP6_MEMBERSHIP_REPORT
# define ICMP6_MEMBERSHIP_REPORT 131
#endif
#ifndef MLD6_LISTENER_REPORT
# define MLD6_LISTENER_REPORT 131
#endif
#ifndef ICMP6_MEMBERSHIP_REDUCTION
# define ICMP6_MEMBERSHIP_REDUCTION 132
#endif
#ifndef MLD6_LISTENER_DONE
# define MLD6_LISTENER_DONE 132
#endif
#ifndef ND_ROUTER_SOLICIT
# define ND_ROUTER_SOLICIT 133
#endif
#ifndef ND_ROUTER_ADVERT
# define ND_ROUTER_ADVERT 134
#endif
#ifndef ND_NEIGHBOR_SOLICIT
# define ND_NEIGHBOR_SOLICIT 135
#endif
#ifndef ND_NEIGHBOR_ADVERT
# define ND_NEIGHBOR_ADVERT 136
#endif
#ifndef ND_REDIRECT
# define ND_REDIRECT 137
#endif
#ifndef ICMP6_ROUTER_RENUMBERING
# define ICMP6_ROUTER_RENUMBERING 138
#endif
#ifndef ICMP6_WRUREQUEST
# define ICMP6_WRUREQUEST 139
#endif
#ifndef ICMP6_WRUREPLY
# define ICMP6_WRUREPLY 140
#endif
#ifndef ICMP6_FQDN_QUERY
# define ICMP6_FQDN_QUERY 139
#endif
#ifndef ICMP6_FQDN_REPLY
# define ICMP6_FQDN_REPLY 140
#endif
#ifndef ICMP6_NI_QUERY
# define ICMP6_NI_QUERY 139
#endif
#ifndef ICMP6_NI_REPLY
# define ICMP6_NI_REPLY 140
#endif
#ifndef MLD6_MTRACE_RESP
# define MLD6_MTRACE_RESP 200
#endif
#ifndef MLD6_MTRACE
# define MLD6_MTRACE 201
#endif
#ifndef ICMP6_HADISCOV_REQUEST
# define ICMP6_HADISCOV_REQUEST 202
#endif
#ifndef ICMP6_HADISCOV_REPLY
# define ICMP6_HADISCOV_REPLY 203
#endif
#ifndef ICMP6_MOBILEPREFIX_SOLICIT
# define ICMP6_MOBILEPREFIX_SOLICIT 204
#endif
#ifndef ICMP6_MOBILEPREFIX_ADVERT
# define ICMP6_MOBILEPREFIX_ADVERT 205
#endif
#ifndef ICMP6_MAXTYPE
# define ICMP6_MAXTYPE 205
#endif
#ifndef ICMP6_DST_UNREACH_NOROUTE
# define ICMP6_DST_UNREACH_NOROUTE 0
#endif
#ifndef ICMP6_DST_UNREACH_ADMIN
# define ICMP6_DST_UNREACH_ADMIN 1
#endif
#ifndef ICMP6_DST_UNREACH_NOTNEIGHBOR
# define ICMP6_DST_UNREACH_NOTNEIGHBOR 2
#endif
#ifndef ICMP6_DST_UNREACH_BEYONDSCOPE
# define ICMP6_DST_UNREACH_BEYONDSCOPE 2
#endif
#ifndef ICMP6_DST_UNREACH_ADDR
# define ICMP6_DST_UNREACH_ADDR 3
#endif
#ifndef ICMP6_DST_UNREACH_NOPORT
# define ICMP6_DST_UNREACH_NOPORT 4
#endif
#ifndef ICMP6_TIME_EXCEED_TRANSIT
# define ICMP6_TIME_EXCEED_TRANSIT 0
#endif
#ifndef ICMP6_TIME_EXCEED_REASSEMBLY
# define ICMP6_TIME_EXCEED_REASSEMBLY 1
#endif
#ifndef ICMP6_NI_SUCCESS
# define ICMP6_NI_SUCCESS 0
#endif
#ifndef ICMP6_NI_REFUSED
# define ICMP6_NI_REFUSED 1
#endif
#ifndef ICMP6_NI_UNKNOWN
# define ICMP6_NI_UNKNOWN 2
#endif
#ifndef ICMP6_ROUTER_RENUMBERING_COMMAND
# define ICMP6_ROUTER_RENUMBERING_COMMAND 0
#endif
#ifndef ICMP6_ROUTER_RENUMBERING_RESULT
# define ICMP6_ROUTER_RENUMBERING_RESULT 1
#endif
#ifndef ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET
# define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255
#endif
#ifndef ICMP6_PARAMPROB_HEADER
# define ICMP6_PARAMPROB_HEADER 0
#endif
#ifndef ICMP6_PARAMPROB_NEXTHEADER
# define ICMP6_PARAMPROB_NEXTHEADER 1
#endif
#ifndef ICMP6_PARAMPROB_OPTION
# define ICMP6_PARAMPROB_OPTION 2
#endif
#ifndef ICMP6_NI_SUBJ_IPV6
# define ICMP6_NI_SUBJ_IPV6 0
#endif
#ifndef ICMP6_NI_SUBJ_FQDN
# define ICMP6_NI_SUBJ_FQDN 1
#endif
#ifndef ICMP6_NI_SUBJ_IPV4
# define ICMP6_NI_SUBJ_IPV4 2
#endif
/*
* ECN is a new addition to TCP - RFC 2481
*/

View File

@ -16,7 +16,7 @@
#endif
#include <sys/param.h>
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
defined(_KERNEL)
defined(_KERNEL) && !defined(_LKM)
# include "opt_ipfilter_log.h"
#endif
#if defined(__FreeBSD__) && !defined(__FreeBSD_version)
@ -24,6 +24,9 @@
# include <osreldate.h>
# endif
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#ifndef _KERNEL
# include <stdio.h>
# include <string.h>
@ -44,7 +47,6 @@
#ifdef _KERNEL
# include <sys/systm.h>
#endif
#include <sys/uio.h>
#if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@ -93,12 +95,16 @@
#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
# if !SOLARIS
# include <netinet6/ip6protosw.h>
# include <netinet6/nd6.h>
# endif
#endif
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@ -113,7 +119,7 @@ extern int ip_optcopy __P((struct ip *, struct ip *));
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.34 2001/07/23 13:49:57 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.53 2002/03/13 02:29:08 darrenr Exp $";
#endif
@ -144,15 +150,18 @@ static int frrequest __P((int, int, caddr_t, int));
#endif
#ifdef _KERNEL
static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
static int send_ip __P((ip_t *, fr_info_t *, struct mbuf *));
static int send_ip __P((ip_t *, fr_info_t *, struct mbuf **));
# ifdef USE_INET6
static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **,
fr_info_t *, frdest_t *));
# endif
# ifdef __sgi
extern kmutex_t ipf_rw;
extern KRWLOCK_T ipf_mutex;
# endif
#else
int ipllog __P((void));
void init_ifp __P((void));
# ifdef __sgi
# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *));
static int write_output __P((struct ifnet *, struct mbuf *,
@ -208,6 +217,77 @@ int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
# endif /* NETBSD_PF */
#endif /* __NetBSD__ */
#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000) && \
defined(_KERNEL)
# include <net/pfil.h>
static int fr_check_wrapper(void *, struct mbuf **, struct ifnet *, int );
static int fr_check_wrapper(arg, mp, ifp, dir)
void *arg;
struct mbuf **mp;
struct ifnet *ifp;
int dir;
{
struct ip *ip = mtod(*mp, struct ip *);
int rv, hlen = ip->ip_hl << 2;
#if defined(M_CSUM_TCPv4)
/*
* If the packet is out-bound, we can't delay checksums
* here. For in-bound, the checksum has already been
* validated.
*/
if (dir == PFIL_OUT) {
if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
in_delayed_cksum(*mp);
(*mp)->m_pkthdr.csum_flags &=
~(M_CSUM_TCPv4|M_CSUM_UDPv4);
}
}
#endif /* M_CSUM_TCPv4 */
/*
* We get the packet with all fields in network byte
* order. We expect ip_len and ip_off to be in host
* order. We frob them, call the filter, then frob
* them back.
*
* Note, we don't need to update the checksum, because
* it has already been verified.
*/
NTOHS(ip->ip_len);
NTOHS(ip->ip_off);
rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
if (rv == 0 && *mp != NULL) {
ip = mtod(*mp, struct ip *);
HTONS(ip->ip_len);
HTONS(ip->ip_off);
}
return (rv);
}
# ifdef USE_INET6
# include <netinet/ip6.h>
static int fr_check_wrapper6(void *, struct mbuf **, struct ifnet *, int );
static int fr_check_wrapper6(arg, mp, ifp, dir)
void *arg;
struct mbuf **mp;
struct ifnet *ifp;
int dir;
{
return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
ifp, (dir == PFIL_OUT), mp));
}
# endif
#endif /* __NetBSD_Version >= 105110000 && _KERNEL */
#ifdef _KERNEL
# if defined(IPFILTER_LKM) && !defined(__sgi)
int iplidentify(s)
@ -228,19 +308,32 @@ void
ipfilterattach(count)
int count;
{
if (iplattach() != 0)
printf("IP Filter failed to attach\n");
/*
* Do nothing here, really. The filter will be enabled
* by the SIOCFRENB ioctl.
*/
}
# endif
# if defined(__NetBSD__)
int ipl_enable()
# else
int iplattach()
# endif
{
char *defpass;
int s;
# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000))
int error = 0;
# endif
#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000)
struct pfil_head *ph_inet;
# ifdef USE_INET6
struct pfil_head *ph_inet6;
# endif
#endif
SPL_NET(s);
if (fr_running || (fr_checkp == fr_check)) {
@ -267,8 +360,24 @@ int iplattach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
# if __NetBSD_Version__ >= 105110000
if (
!(ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET))
# ifdef USE_INET6
&& !(ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6))
# endif
)
return ENODEV;
if (ph_inet != NULL)
error = pfil_add_hook((void *)fr_check_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet);
else
error = 0;
# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
# endif
if (error) {
# ifdef USE_INET6
goto pfil_error;
@ -284,11 +393,22 @@ int iplattach()
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
# if __NetBSD_Version__ >= 105110000
if (ph_inet6 != NULL)
error = pfil_add_hook((void *)fr_check_wrapper6, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
else
error = 0;
if (error) {
pfil_remove_hook((void *)fr_check_wrapper6, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
&inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
if (error) {
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
# endif
pfil_error:
SPL_X(s);
appr_unload();
@ -355,11 +475,21 @@ int iplattach()
* Disable the filter by removing the hooks from the IP input/output
* stream.
*/
# if defined(__NetBSD__)
int ipl_disable()
# else
int ipldetach()
# endif
{
int s, i = FR_INQUE|FR_OUTQUE;
#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
int error = 0;
# if __NetBSD_Version__ >= 105150000
struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
# ifdef USE_INET6
struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
# endif
# endif
#endif
#ifdef _KERNEL
@ -397,8 +527,16 @@ int ipldetach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
# if __NetBSD_Version__ >= 105110000
if (ph_inet != NULL)
error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet);
else
error = 0;
# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
# endif
if (error) {
SPL_X(s);
return error;
@ -407,8 +545,16 @@ int ipldetach()
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
# if __NetBSD_Version__ >= 105110000
if (ph_inet6 != NULL)
error = pfil_remove_hook((void *)fr_check_wrapper6, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
else
error = 0;
# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
&inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
# endif
if (error) {
SPL_X(s);
return error;
@ -530,7 +676,7 @@ int mode;
sizeof(iplused[IPL_LOGIPF]));
#endif
break;
#if !defined(IPFILTER_LKM) && defined(_KERNEL)
#if (!defined(IPFILTER_LKM) || defined(__NetBSD__)) && defined(_KERNEL)
case SIOCFRENB :
{
u_int enable;
@ -542,9 +688,17 @@ int mode;
if (error)
break;
if (enable)
# if defined(__NetBSD__)
error = ipl_enable();
# else
error = iplattach();
# endif
else
# if defined(__NetBSD__)
error = ipl_disable();
# else
error = ipldetach();
# endif
}
break;
}
@ -711,11 +865,11 @@ caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
frgroup_t *fg = NULL;
int error = 0, in, i;
u_int *p, *pp;
frentry_t frd;
frdest_t *fdp;
frgroup_t *fg = NULL;
u_int *p, *pp;
int error = 0, in;
u_int group;
fp = &frd;
@ -764,18 +918,17 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (*fp->fr_ifname) {
fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_v);
if (!fp->fr_ifa)
fp->fr_ifa = (void *)-1;
for (i = 0; i < 4; i++) {
if ((fp->fr_ifnames[i][1] == '\0') &&
((fp->fr_ifnames[i][0] == '-') ||
(fp->fr_ifnames[i][0] == '*'))) {
fp->fr_ifas[i] = NULL;
} else if (*fp->fr_ifnames[i]) {
fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v);
if (!fp->fr_ifas[i])
fp->fr_ifas[i] = (void *)-1;
}
}
#if BSD >= 199306
if (*fp->fr_oifname) {
fp->fr_oifa = GETUNIT(fp->fr_oifname, fp->fr_v);
if (!fp->fr_oifa)
fp->fr_oifa = (void *)-1;
}
#endif
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
@ -854,6 +1007,7 @@ caddr_t data;
fixskip(fprev, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
f->fr_ref--;
if (f->fr_ref == 0)
KFREE(f);
}
@ -1002,7 +1156,7 @@ fr_info_t *fin;
if (m == NULL)
return -1;
tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
tlen = fin->fin_dlen - (tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
@ -1044,7 +1198,7 @@ fr_info_t *fin;
ip6->ip6_dst = oip6->ip6_src;
tcp2->th_sum = in6_cksum(m, IPPROTO_TCP,
sizeof(*ip6), sizeof(*tcp2));
return send_ip(oip, fin, m);
return send_ip(oip, fin, &m);
}
# endif
ip->ip_p = IPPROTO_TCP;
@ -1053,17 +1207,25 @@ fr_info_t *fin;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2));
ip->ip_len = hlen + sizeof(*tcp2);
return send_ip(oip, fin, m);
return send_ip(oip, fin, &m);
}
static int send_ip(oip, fin, m)
/*
* Send an IP(v4/v6) datagram out into the network
*/
static int send_ip(oip, fin, mp)
ip_t *oip;
fr_info_t *fin;
struct mbuf *m;
struct mbuf **mp;
{
struct mbuf *m = *mp;
char *dpsave;
int error;
ip_t *ip;
dpsave = fin->fin_dp;
ip = mtod(m, ip_t *);
ip->ip_v = fin->fin_v;
@ -1079,20 +1241,22 @@ struct mbuf *m;
ip->ip_ttl = ip_defttl;
# endif
ip->ip_sum = 0;
fin->fin_dp = (char *)(ip + 1);
}
# ifdef USE_INET6
else if (ip->ip_v == 6) {
ip6_t *ip6 = (ip6_t *)ip;
ip6->ip6_hlim = 127;
return ip6_output(m, NULL, NULL, 0, NULL, NULL);
fin->fin_dp = (char *)(ip6 + 1);
}
# endif
# ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
# endif
return ipfr_fastroute(m, fin->fin_mp, fin, NULL);
error = ipfr_fastroute(m, mp, fin, NULL);
fin->fin_dp = dpsave;
return error;
}
@ -1266,7 +1430,7 @@ int dst;
shlen = fin->fin_hlen;
fin->fin_hlen = hlen;
err = send_ip(oip, fin, m);
err = send_ip(oip, fin, &m);
fin->fin_hlen = shlen;
#ifdef USE_INET6
if (fin->fin_v == 4)
@ -1279,7 +1443,8 @@ int dst;
}
# if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
# if !defined(IPFILTER_LKM) && !defined(__sgi) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 300000))
# if (BSD < 199306)
int iplinit __P((void));
@ -1291,21 +1456,35 @@ void
# endif
iplinit()
{
# if defined(__NetBSD__)
if (ipl_enable() != 0)
# else
if (iplattach() != 0)
# endif
{
printf("IP Filter failed to attach\n");
}
ip_init();
}
# endif /* ! __NetBSD__ */
/*
* Return the length of the entire mbuf.
*/
size_t mbufchainlen(m0)
register struct mbuf *m0;
{
#if BSD >= 199306
return m0->m_pkthdr.len;
#else
register size_t len = 0;
for (; m0; m0 = m0->m_next)
len += m0->m_len;
return len;
#endif
}
@ -1323,6 +1502,24 @@ frdest_t *fdp;
struct route iproute;
frentry_t *fr;
ip = NULL;
ro = NULL;
ifp = NULL;
ro = &iproute;
ro->ro_rt = NULL;
#ifdef USE_INET6
if (fin->fin_v == 6) {
error = ipfr_fastroute6(m0, mpp, fin, fdp);
if (error != 0)
goto bad;
goto done;
}
#else
if (fin->fin_v == 6)
goto bad;
#endif
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@ -1336,13 +1533,14 @@ frdest_t *fdp;
* problem.
*/
if (M_WRITABLE(m) == 0) {
if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
m_freem(m);
if ((m0 = m_dup(m, M_DONTWAIT)) != NULL) {
m_freem(*mpp);
*mpp = m0;
m = m0;
} else {
error = ENOBUFS;
m_freem(m);
ipl_frouteok[1]++;
m_freem(*mpp);
goto done;
}
}
#endif
@ -1354,35 +1552,26 @@ frdest_t *fdp;
/*
* Clear any in-bound checksum flags for this packet.
*/
# if (__NetBSD_Version__ > 105009999)
m0->m_pkthdr.csum_flags = 0;
# else
m0->m_pkthdr.csuminfo = 0;
# endif
#endif /* __NetBSD__ && M_CSUM_IPv4 */
#ifdef USE_INET6
if (ip->ip_v == 6) {
/*
* currently "to <if>" and "to <if>:ip#" are not supported
* for IPv6
*/
error = ip6_output(m0, NULL, NULL, 0, NULL, NULL);
*mpp = NULL;
return error;
}
#endif
/*
* Route packet.
*/
ro = &iproute;
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
dst->sin_addr = ip->ip_dst;
fr = fin->fin_fr;
if (fdp)
if (fdp != NULL)
ifp = fdp->fd_ifp;
else {
else
ifp = fin->fin_ifp;
dst->sin_addr = ip->ip_dst;
}
/*
* In case we're here due to "to <if>" being used with "keep state",
@ -1391,13 +1580,9 @@ frdest_t *fdp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return 0;
dst->sin_addr = ip->ip_dst;
} else if (fdp) {
if (fdp->fd_ip.s_addr) {
} else if (fdp != NULL) {
if (fdp->fd_ip.s_addr != 0)
dst->sin_addr = fdp->fd_ip;
ip->ip_dst = fdp->fd_ip;
} else
dst->sin_addr = ip->ip_dst;
}
# if BSD >= 199306
@ -1418,26 +1603,36 @@ frdest_t *fdp;
error = -2;
goto bad;
}
if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
if (in_localaddr(ip->ip_dst))
error = EHOSTUNREACH;
else
error = ENETUNREACH;
goto bad;
}
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
}
if (ro->ro_rt)
ro->ro_rt->rt_use++;
if ((ifp == NULL) && (ro->ro_rt != NULL))
ifp = ro->ro_rt->rt_ifp;
if ((ro->ro_rt == NULL) || (ifp == NULL)) {
if (in_localaddr(ip->ip_dst))
error = EHOSTUNREACH;
else
error = ENETUNREACH;
goto bad;
}
if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
#if BSD >= 199306
dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
#else
dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
#endif
}
ro->ro_rt->rt_use++;
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
* NAT'd and counted.
*/
fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
sifp = fin->fin_ifp;
fin->fin_ifp = ifp;
fin->fin_out = 1;
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
@ -1447,44 +1642,39 @@ frdest_t *fdp;
if (!fr || !(fr->fr_flags & FR_RETMASK))
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
fin->fin_ifp = sifp;
} else
ip->ip_sum = 0;
/*
* If small enough for interface, can just send directly.
*/
if (ip->ip_len <= ifp->if_mtu) {
# if defined(MCLISREFERENCED) && !defined(sparc)
int i = 0;
if ((m->m_flags & M_EXT) && MCLISREFERENCED(m))
i = 1;
# endif
# ifndef sparc
# if !(_BSDI_VERSION >= 199510)
# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510))
ip->ip_id = htons(ip->ip_id);
# endif
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
# endif
# if defined(__NetBSD__) && defined(M_CSUM_IPv4)
# if (__NetBSD_Version__ > 105009999)
if (ifp->if_csum_flags_tx & IFCAP_CSUM_IPv4)
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
else if (ip->ip_sum == 0)
ip->ip_sum = in_cksum(m, hlen);
# else
if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
else if (ip->ip_sum == 0)
ip->ip_sum = in_cksum(m, hlen);
# endif
# else
if (!ip->ip_sum)
ip->ip_sum = in_cksum(m, hlen);
# endif /* __NetBSD__ && M_CSUM_IPv4 */
# if BSD >= 199306
# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
ro->ro_rt);
# if defined(MCLISREFERENCED) && !defined(sparc)
if (i) {
ip->ip_id = ntohs(ip->ip_id);
ip->ip_len = ntohs(ip->ip_len);
ip->ip_off = ntohs(ip->ip_off);
}
# endif
# else
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
# endif
@ -1554,9 +1744,7 @@ frdest_t *fdp;
m->m_pkthdr.len = mhlen + len;
m->m_pkthdr.rcvif = NULL;
# endif
# ifndef sparc
mhip->ip_off = htons((u_short)mhip->ip_off);
# endif
mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen);
*mnext = m;
@ -1576,7 +1764,7 @@ frdest_t *fdp;
m0 = m->m_act;
m->m_act = 0;
if (error == 0)
# if BSD >= 199306
# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
# else
@ -1593,13 +1781,13 @@ frdest_t *fdp;
else
ipl_frouteok[1]++;
if (ro->ro_rt) {
if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
}
*mpp = NULL;
return error;
bad:
if (error == EMSGSIZE) {
if ((error == EMSGSIZE) && (fin->fin_v == 4)) {
sifp = fin->fin_ifp;
code = fin->fin_icode;
fin->fin_icode = ICMP_UNREACH_NEEDFRAG;
@ -1613,6 +1801,10 @@ frdest_t *fdp;
}
/*
* Return true or false depending on whether the route to the
* given IP address uses the same interface as the one passed.
*/
int fr_verifysrc(ipa, ifp)
struct in_addr ipa;
void *ifp;
@ -1622,6 +1814,9 @@ void *ifp;
bzero((char *)&iproute, sizeof(iproute));
dst = (struct sockaddr_in *)&iproute.ro_dst;
# if (BSD >= 199306)
dst->sin_len = sizeof(*dst);
# endif
dst->sin_family = AF_INET;
dst->sin_addr = ipa;
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
@ -1651,10 +1846,78 @@ struct ifnet *ifp;
return workbuf;
}
# endif
# if defined(USE_INET6)
/*
* This is the IPv6 specific fastroute code. It doesn't clean up the mbuf's
* or ensure that it is an IPv6 packet that is being forwarded, those are
* expected to be done by the called (ipfr_fastroute).
*/
static int ipfr_fastroute6(m0, mpp, fin, fdp)
struct mbuf *m0, **mpp;
fr_info_t *fin;
frdest_t *fdp;
{
struct route_in6 ip6route;
struct sockaddr_in6 *dst6;
struct route_in6 *ro;
struct ifnet *ifp;
frentry_t *fr;
int error;
ifp = NULL;
ro = &ip6route;
fr = fin->fin_fr;
bzero((caddr_t)ro, sizeof(*ro));
dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(struct sockaddr_in6);
dst6->sin6_addr = fin->fin_fi.fi_src.in6;
if (fdp != NULL)
ifp = fdp->fd_ifp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return 0;
} else if (fdp != NULL) {
if (IP6_NOTZERO(&fdp->fd_ip6))
dst6->sin6_addr = fdp->fd_ip6.in6;
}
if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
return -2;
rtalloc((struct route *)ro);
if ((ifp == NULL) && (ro->ro_rt != NULL))
ifp = ro->ro_rt->rt_ifp;
if ((ro->ro_rt == NULL) || (ifp == NULL) ||
(ifp != ro->ro_rt->rt_ifp)) {
error = EHOSTUNREACH;
} else {
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst6 = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
ro->ro_rt->rt_use++;
if (m0->m_pkthdr.len <= nd_ifinfo[ifp->if_index].linkmtu)
error = nd6_output(ifp, fin->fin_ifp, m0, dst6,
ro->ro_rt);
else
error = EMSGSIZE;
}
if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
}
return error;
}
# endif
#else /* #ifdef _KERNEL */
# ifdef __sgi
# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@ -1667,7 +1930,7 @@ static int no_output __P((struct ifnet *ifp, struct mbuf *m,
# ifdef __STDC__
# ifdef __sgi
# if defined(__sgi) && (IRIX < 605)
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@ -1702,26 +1965,39 @@ ip_t *ip;
}
struct ifnet *get_unit(name, v)
char *name;
char *get_ifname(ifp)
struct ifnet *ifp;
{
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
return ifp->if_xname;
# else
static char fullifname[LIFNAMSIZ];
sprintf(fullifname, "%s%d", ifp->if_name, ifp->if_unit);
return fullifname;
# endif
}
struct ifnet *get_unit(ifname, v)
char *ifname;
int v;
{
struct ifnet *ifp, **ifa, **old_ifneta;
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
if (!strcmp(name, ifp->if_xname))
return ifp;
}
# else
char ifname[32], *s;
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
(void) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
if (!strcmp(name, ifname))
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
if (!strncmp(ifname, ifp->if_xname, sizeof(ifp->if_xname)))
# else
char fullname[LIFNAMSIZ];
sprintf(fullname, "%s%d", ifp->if_name, ifp->if_unit);
if (!strcmp(ifname, fullname))
# endif
return ifp;
}
# endif
if (!ifneta) {
ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
@ -1754,20 +2030,19 @@ int v;
ifp = ifneta[nifs - 1];
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
(defined(OpenBSD) && (OpenBSD >= 199603))
strncpy(ifp->if_xname, ifname, sizeof(ifp->if_xname));
# else
for (s = name; *s && !isdigit(*s); s++)
;
if (*s && isdigit(*s)) {
ifp->if_unit = atoi(s);
ifp->if_name = (char *)malloc(s - name + 1);
strncpy(ifp->if_name, name, s - name);
ifp->if_name[s - name] = '\0';
} else {
ifp->if_name = strdup(name);
ifp->if_name = strdup(ifname);
ifname = ifp->if_name;
while (*ifname && !isdigit(*ifname))
ifname++;
if (*ifname && isdigit(*ifname)) {
ifp->if_unit = atoi(ifname);
*ifname = '\0';
} else
ifp->if_unit = -1;
}
# endif
ifp->if_output = no_output;
return ifp;
@ -1807,27 +2082,22 @@ void init_ifp()
}
int ipllog __P((void))
{
verbose("l");
return 0;
}
int send_reset(ip, ifp)
int send_reset(ip, fin)
ip_t *ip;
struct ifnet *ifp;
fr_info_t *fin;
{
verbose("- TCP RST sent\n");
return 0;
}
int icmp_error(ip, ifp)
int send_icmp_err(ip, code, fin, dst)
ip_t *ip;
struct ifnet *ifp;
int code;
fr_info_t *fin;
int dst;
{
verbose("- TCP RST sent\n");
verbose("- ICMP UNREACHABLE RST sent\n");
return 0;
}
@ -1836,4 +2106,52 @@ void frsync()
{
return;
}
void m_copydata(m, off, len, cp)
mb_t *m;
int off, len;
caddr_t cp;
{
bcopy((char *)m + off, cp, len);
}
int ipfuiomove(buf, len, rwflag, uio)
caddr_t buf;
int len, rwflag;
struct uio *uio;
{
int left, ioc, num, offset;
struct iovec *io;
char *start;
if (rwflag == UIO_READ) {
left = len;
ioc = 0;
offset = uio->uio_offset;
while ((left > 0) && (ioc < uio->uio_iovcnt)) {
io = uio->uio_iov + ioc;
num = io->iov_len;
if (num > left)
num = left;
start = io->iov_base + offset;
if (start > io->iov_base + io->iov_len) {
offset -= io->iov_len;
ioc++;
continue;
}
bcopy(buf, start, num);
uio->uio_resid -= num;
uio->uio_offset += num;
left -= num;
if (left > 0)
ioc++;
}
if (left > 0)
return EFAULT;
}
return 0;
}
#endif /* _KERNEL */

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_fil.h,v 2.29.2.10 2001/07/15 13:51:42 darrenr Exp $
* $Id: ip_fil.h,v 2.29.2.29 2002/03/13 03:56:46 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -34,6 +34,10 @@
# endif
#endif
#ifndef offsetof
# define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#if defined(__STDC__) || defined(__GNUC__)
# define SIOCADAFR _IOW('r', 60, struct frentry *)
# define SIOCRMAFR _IOW('r', 61, struct frentry *)
@ -51,8 +55,8 @@
# define SIOCFRSYN _IOW('r', 73, u_int)
# define SIOCFRZST _IOWR('r', 74, struct friostat *)
# define SIOCZRLST _IOWR('r', 75, struct frentry *)
# define SIOCAUTHW _IOWR('r', 76, struct fr_info *)
# define SIOCAUTHR _IOWR('r', 77, struct fr_info *)
# define SIOCAUTHW _IOWR('r', 76, struct frauth_t *)
# define SIOCAUTHR _IOWR('r', 77, struct frauth_t *)
# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR('r', 79, u_int)
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
@ -76,8 +80,8 @@
# define SIOCFRSYN _IOW(r, 73, u_int)
# define SIOCFRZST _IOWR(r, 74, struct friostat *)
# define SIOCZRLST _IOWR(r, 75, struct frentry *)
# define SIOCAUTHW _IOWR(r, 76, struct fr_info *)
# define SIOCAUTHR _IOWR(r, 77, struct fr_info *)
# define SIOCAUTHW _IOWR(r, 76, struct frauth_t *)
# define SIOCAUTHR _IOWR(r, 77, struct frauth_t *)
# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR(r, 79, u_int)
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
@ -123,7 +127,9 @@ typedef struct fr_ip {
#define FI_W_SADDR 0x00000400
#define FI_W_DADDR 0x00000800
#define FI_WILDA (FI_W_SADDR|FI_W_DADDR)
#define FI_NEWFR 0x00001000
#define FI_NEWFR 0x00001000 /* Create a filter rule */
#define FI_IGNOREPKT 0x00002000 /* Do not treat as a real packet */
#define FI_NORULE 0x00004000 /* Not direct a result of a rule */
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
@ -135,10 +141,12 @@ typedef struct fr_info {
u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
/* From here on is packet specific */
u_char fin_icode; /* ICMP error to return */
u_short fin_rule; /* rule # last matched */
u_32_t fin_rule; /* rule # last matched */
u_32_t fin_group; /* group number, -1 for none */
struct frentry *fin_fr; /* last matching rule */
char *fin_dp; /* start of data past IP header */
u_short fin_plen;
u_short fin_off;
u_short fin_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
void *fin_mp; /* pointer to pointer to mbuf */
@ -146,19 +154,21 @@ typedef struct fr_info {
void *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qif;
#endif
u_short fin_plen;
u_short fin_off;
} fr_info_t;
#define fin_v fin_fi.fi_v
#define fin_p fin_fi.fi_p
#define fin_saddr fin_fi.fi_saddr
#define fin_src fin_fi.fi_src.in4
#define fin_daddr fin_fi.fi_daddr
#define fin_dst fin_fi.fi_dst.in4
#define fin_fl fin_fi.fi_fl
/*
* Size for compares on fr_info structures
*/
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
#define FI_LCSIZE offsetof(fr_info_t, fin_dp)
/*
* Size for copying cache fr_info structure
@ -167,13 +177,16 @@ typedef struct fr_info {
typedef struct frdest {
void *fd_ifp;
struct in_addr fd_ip;
char fd_ifname[IFNAMSIZ];
union i6addr fd_ip6;
char fd_ifname[LIFNAMSIZ];
#if SOLARIS
mb_t *fd_mp; /* cache resolver for to/dup-to */
#endif
} frdest_t;
#define fd_ip fd_ip6.in4
typedef struct frpcmp {
int frp_cmp; /* data for port comparisons */
u_short frp_port; /* top port for <> and >< */
@ -198,10 +211,7 @@ typedef struct frentry {
struct frentry *fr_next;
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
void *fr_ifa;
#if BSD >= 199306
void *fr_oifa;
#endif
void *fr_ifas[4];
/*
* These are only incremented when a packet matches this rule and
* it is the last match
@ -218,6 +228,7 @@ typedef struct frentry {
u_short fr_icmpm; /* data for ICMP packets (mask) */
u_short fr_icmp;
u_int fr_age[2]; /* aging for state */
frtuc_t fr_tuc;
u_32_t fr_group; /* group to which this rule belongs */
u_32_t fr_grhead; /* group # which this rule starts */
@ -227,10 +238,7 @@ typedef struct frentry {
int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
int fr_sap; /* For solaris only */
u_char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
#if BSD >= 199306
char fr_oifname[IFNAMSIZ];
#endif
char fr_ifnames[4][LIFNAMSIZ];
struct frdest fr_tif; /* "to" interface */
struct frdest fr_dif; /* duplicate packet interfaces */
u_int fr_cksum; /* checksum on filter rules for performance */
@ -252,10 +260,11 @@ typedef struct frentry {
#define fr_src fr_ip.fi_src.in4
#define fr_dmsk fr_mip.fi_dst.in4
#define fr_smsk fr_mip.fi_src.in4
#define fr_ifname fr_ifnames[0]
#define fr_oifname fr_ifnames[2]
#define fr_ifa fr_ifas[0]
#define fr_oifa fr_ifas[2]
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#define FR_CMPSIZ (sizeof(struct frentry) - offsetof(frentry_t, fr_ip))
/*
@ -268,8 +277,8 @@ typedef struct frentry {
#define FR_LOG 0x00010 /* Log */
#define FR_LOGB 0x00011 /* Log-fail */
#define FR_LOGP 0x00012 /* Log-pass */
#define FR_LOGBODY 0x00020 /* Log the body */
#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
#define FR_NOTSRCIP 0x00020 /* not the src IP# */
#define FR_NOTDSTIP 0x00040 /* not the dst IP# */
#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
#define FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
@ -283,8 +292,8 @@ typedef struct frentry {
#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
#define FR_DUP 0x20000 /* duplicate packet */
#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
#define FR_NOTSRCIP 0x80000 /* not the src IP# */
#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
#define FR_LOGBODY 0x80000 /* Log the body */
#define FR_LOGFIRST 0x100000 /* Log the first byte if state held */
#define FR_AUTH 0x200000 /* use authentication */
#define FR_PREAUTH 0x400000 /* require preauthentication */
#define FR_DONTCACHE 0x800000 /* don't cache the result */
@ -406,15 +415,16 @@ typedef struct iplog {
struct iplog *ipl_next;
} iplog_t;
#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
#define IPLOG_SIZE sizeof(iplog_t)
typedef struct ipflog {
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
u_char fl_ifname[IFNAMSIZ];
u_char fl_ifname[LIFNAMSIZ];
#else
u_int fl_unit;
u_char fl_ifname[4];
u_char fl_ifname[LIFNAMSIZ];
#endif
u_char fl_plen; /* extra data after hlen */
u_char fl_hlen; /* length of IP headers saved */
@ -422,7 +432,8 @@ typedef struct ipflog {
u_32_t fl_rule;
u_32_t fl_group;
u_32_t fl_flags;
u_32_t fl_lflags;
u_char fl_dir;
u_char fl_pad[3];
} ipflog_t;
@ -485,10 +496,11 @@ typedef struct ipflog {
#ifndef _KERNEL
extern char *get_ifname __P((struct ifnet *));
extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
extern int send_reset __P((ip_t *, struct ifnet *));
extern int icmp_error __P((ip_t *, struct ifnet *));
extern int send_reset __P((ip_t *, fr_info_t *));
extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int ipf_log __P((void));
extern struct ifnet *get_unit __P((char *, int));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
@ -506,11 +518,6 @@ extern void ipfilterattach __P((int));
extern int iplattach __P((void));
extern int ipl_enable __P((void));
extern int ipl_disable __P((void));
extern void ipflog_init __P((void));
extern int ipflog_clear __P((minor_t));
extern int ipflog_read __P((minor_t, struct uio *));
extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int send_reset __P((ip_t *, fr_info_t *));
# if SOLARIS
@ -593,6 +600,12 @@ extern u_short ipf_cksum __P((u_short *, int));
extern int ircopyptr __P((void *, void *, size_t));
extern int iwcopyptr __P((void *, void *, size_t));
extern void ipflog_init __P((void));
extern int ipflog_clear __P((minor_t));
extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern int ipflog_read __P((minor_t, struct uio *));
extern int frflush __P((minor_t, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));

View File

@ -7,6 +7,9 @@
# define _KERNEL
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -23,7 +26,6 @@
#else
# include <sys/ioctl.h>
#endif
#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@ -63,7 +65,6 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
@ -89,7 +90,7 @@ extern struct timeout ipfr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.14 2001/07/15 22:06:15 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.20 2002/03/06 09:44:11 darrenr Exp $";
#endif
@ -494,7 +495,6 @@ void ipfr_unload()
}
#ifdef _KERNEL
void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
@ -565,6 +565,7 @@ void ipfr_fragexpire()
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
#ifdef _KERNEL
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
@ -574,6 +575,9 @@ void ipfr_slowtimer __P((void *ptr))
# else
int ipfr_slowtimer()
# endif
#else
void ipfr_slowtimer()
#endif
{
#if defined(_KERNEL) && SOLARIS
extern int fr_running;
@ -583,7 +587,7 @@ int ipfr_slowtimer()
#endif
READ_ENTER(&ipf_solaris);
#ifdef __sgi
#if defined(__sgi) && defined(_KERNEL)
ipfilter_sgi_intfsync();
#endif
@ -591,6 +595,7 @@ int ipfr_slowtimer()
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
#if defined(_KERNEL)
# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
RWLOCK_EXIT(&ipf_solaris);
@ -601,8 +606,8 @@ int ipfr_slowtimer()
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
# if defined(__OpenBSD_)
timeout_add(&ipfr_slowtimer_ch, hz/2, ipfr_slowtimer, NULL);
# if defined(__OpenBSD__)
timeout_add(&ipfr_slowtimer_ch, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
@ -612,5 +617,5 @@ int ipfr_slowtimer()
# endif /* FreeBSD */
# endif /* NetBSD */
# endif /* SOLARIS */
}
#endif /* defined(_KERNEL) */
}

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.4.2.5 2001/06/26 10:43:13 darrenr Exp $
* $Id: ip_frag.h,v 2.4.2.6 2002/01/01 15:09:38 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@ -56,14 +56,18 @@ extern void ipfr_forget __P((void *));
extern void ipfr_unload __P((void));
extern void ipfr_fragexpire __P((void));
#if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
#ifdef _KERNEL
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
extern void ipfr_slowtimer __P((void));
# else
# else
extern void ipfr_slowtimer __P((void *));
# endif
#else
# endif
# else
extern int ipfr_slowtimer __P((void));
#endif /* (BSD >= 199306) || SOLARIS */
# endif /* (BSD >= 199306) || SOLARIS */
#else
extern void ipfr_slowtimer __P((void));
#endif /* _KERNEL */
#endif /* __IP_FIL_H__ */

View File

@ -2,7 +2,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_ftp_pxy.c,v 2.7.2.26 2001/07/15 13:50:54 darrenr Exp $
* $Id: ip_ftp_pxy.c,v 2.7.2.33 2002/02/15 14:48:38 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@ -49,10 +49,12 @@ int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_valid __P((char *, size_t));
int ippr_ftp_valid __P((int, char *, size_t));
int ippr_ftp_server_valid __P((char *, size_t));
int ippr_ftp_client_valid __P((char *, size_t));
u_short ippr_ftp_atoi __P((char **));
static frentry_t natfr;
static frentry_t ftppxyfr;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0;
@ -62,9 +64,9 @@ int ippr_ftp_insecure = 0;
*/
int ippr_ftp_init()
{
bzero((char *)&natfr, sizeof(natfr));
natfr.fr_ref = 1;
natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
bzero((char *)&ftppxyfr, sizeof(ftppxyfr));
ftppxyfr.fr_ref = 1;
ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
@ -105,9 +107,9 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
char newbuf[IPF_FTPBUFSZ], *s;
u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
struct in_addr swip;
u_short a5, a6, sp;
size_t nlen, olen;
fr_info_t fi;
int inc, off;
@ -173,7 +175,7 @@ int dlen;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - f->ftps_rptr;
/* DO NOT change this to sprintf! */
/* DO NOT change this to snprintf! */
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
@ -241,46 +243,47 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
sp = htons(a5 << 8 | a6);
sp = (a5 << 8 | a6);
/*
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
if (ntohs(sp) < 1024)
if (sp < 1024)
return 0;
/*
* The server may not make the connection back from port 20, but
* it is the most likely so use it here to check for a conflicting
* mapping.
*/
dp = htons(fin->fin_data[1] - 1);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp, 0);
bcopy((char *)fin, (char *)&fi, sizeof(fi));
fi.fin_data[0] = sp;
fi.fin_data[1] = fin->fin_data[1] - 1;
ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = sp;
tcp2->th_sport = htons(sp);
tcp2->th_off = 5;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dlen = sizeof(*tcp2);
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
(void) fr_addstate(ip, &fi, NULL,
FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@ -340,7 +343,8 @@ int dlen;
!strncmp(cmd, "ADAT ", 5)) {
ftp->ftp_passok = FTPXY_ADAT_1;
ftp->ftp_incok = 1;
} else if ((ftp->ftp_passok == FTPXY_PAOK_2) &&
} else if ((ftp->ftp_passok == FTPXY_PAOK_1 ||
ftp->ftp_passok == FTPXY_PAOK_2) &&
!strncmp(cmd, "ACCT ", 5)) {
ftp->ftp_passok = FTPXY_ACCT_1;
ftp->ftp_incok = 1;
@ -368,8 +372,8 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
struct in_addr swip, swip2;
u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
u_short a5, a6, dp;
fr_info_t fi;
nat_t *ipn;
int inc;
@ -501,26 +505,27 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
sp = 0;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
fi.fin_data[0] = 0;
dp = htons(fin->fin_data[1] - 1);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp, 0);
fi.fin_data[1] = ntohs(dp);
ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = 0; /* XXX - fake it for nat_new */
tcp2->th_off = 5;
fi.fin_data[0] = a5 << 8 | a6;
fi.fin_data[1] = a5 << 8 | a6;
fi.fin_dlen = sizeof(*tcp2);
tcp2->th_dport = htons(fi.fin_data[0]);
fi.fin_data[1] = 0;
tcp2->th_dport = htons(fi.fin_data[1]);
fi.fin_data[0] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
swip2 = ip->ip_dst;
@ -528,11 +533,12 @@ int dlen;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_dst = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_SPORT,
ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_SPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_SPORT);
(void) fr_addstate(ip, &fi, NULL,
FI_W_SPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@ -601,7 +607,7 @@ int dlen;
* Look to see if the buffer starts with something which we recognise as
* being the correct syntax for the FTP protocol.
*/
int ippr_ftp_valid(buf, len)
int ippr_ftp_client_valid(buf, len)
char *buf;
size_t len;
{
@ -614,22 +620,7 @@ size_t len;
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if ((c != '-') && (c != ' '))
return 1;
} else
return 1;
} else
return 1;
} else if (isalpha(c)) {
if (isalpha(c)) {
c = *s++;
i--;
if (isalpha(c)) {
@ -660,6 +651,60 @@ size_t len;
}
int ippr_ftp_server_valid(buf, len)
char *buf;
size_t len;
{
register char *s, c;
register size_t i = len;
if (i < 5)
return 2;
s = buf;
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if (isdigit(c)) {
c = *s++;
i--;
if ((c != '-') && (c != ' '))
return 1;
} else
return 1;
} else
return 1;
} else
return 1;
for (; i; i--) {
c = *s++;
if (c == '\n')
return 0;
}
return 2;
}
int ippr_ftp_valid(side, buf, len)
int side;
char *buf;
size_t len;
{
int ret;
if (side == 0)
ret = ippr_ftp_client_valid(buf, len);
else
ret = ippr_ftp_server_valid(buf, len);
return ret;
}
int ippr_ftp_process(fin, ip, nat, ftp, rv)
fr_info_t *fin;
ip_t *ip;
@ -715,7 +760,7 @@ int rv;
if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq))
f->ftps_seq = ntohl(tcp->th_seq);
else if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
return APR_ERR(-1);
return APR_ERR(1);
}
f->ftps_len = mlen;
@ -732,11 +777,12 @@ int rv;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
if (f->ftps_junk == 0) {
f->ftps_cmds++;
len = wptr - rptr;
f->ftps_rptr = rptr;
if (rv)
@ -746,9 +792,17 @@ int rv;
inc += ippr_ftp_client(fin, ip, nat,
ftp, len);
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
}
}
/*
* Off to a bad start so lets just forget about using the
* ftp proxy for this connection.
*/
if ((f->ftps_cmds == 0) && (f->ftps_junk == 1))
return APR_ERR(2);
while ((f->ftps_junk == 1) && (rptr < wptr)) {
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.4 2002/03/06 09:44:11 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@ -16,7 +16,6 @@ static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 da
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/dir.h>
#include <sys/socket.h>
#ifndef _KERNEL
@ -42,8 +41,8 @@ static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.2 2001/07/18 14:57:09 da
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
#include "netinet/ip_auth.h"

View File

@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_log.c,v 2.5.2.5 2001/06/26 10:43:14 darrenr Exp $
* $Id: ip_log.c,v 2.5.2.17 2002/03/13 03:57:05 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@ -52,7 +52,6 @@
# if defined(_KERNEL)
# include <sys/systm.h>
# endif
# include <sys/uio.h>
# if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@ -63,13 +62,14 @@
# else
# include <sys/filio.h>
# include <sys/cred.h>
# include <sys/ddi.h>
# include <sys/sunddi.h>
# include <sys/ksynch.h>
# include <sys/kmem.h>
# include <sys/mkdev.h>
# include <sys/dditypes.h>
# include <sys/cmn_err.h>
# ifdef _KERNEL
# include <sys/ddi.h>
# include <sys/sunddi.h>
# include <sys/ksynch.h>
# include <sys/dditypes.h>
# include <sys/cmn_err.h>
# endif
# endif
# include <sys/protosw.h>
# include <sys/socket.h>
@ -104,11 +104,6 @@
# include "netinet/ip_compat.h"
# include <netinet/tcpip.h>
# include "netinet/ip_fil.h"
# include "netinet/ip_proxy.h"
# include "netinet/ip_nat.h"
# include "netinet/ip_frag.h"
# include "netinet/ip_state.h"
# include "netinet/ip_auth.h"
# if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# endif
@ -116,6 +111,10 @@
# ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
# endif
# ifdef IPFILTER_LOGSIZE
# undef IPLLOGSIZE
# define IPLLOGSIZE IPFILTER_LOGSIZE
# endif
# if SOLARIS || defined(__sgi)
@ -168,7 +167,7 @@ mb_t *m;
void *ptrs[2];
int types[2];
u_char p;
# if SOLARIS
# if SOLARIS && defined(_KERNEL)
ill_t *ifp = fin->fin_ifp;
# else
struct ifnet *ifp = fin->fin_ifp;
@ -215,9 +214,11 @@ mb_t *m;
* Get the interface number and name to which this packet is
* currently associated.
*/
# if SOLARIS
bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
# if SOLARIS && defined(_KERNEL)
ipfl.fl_unit = (u_char)ifp->ill_ppa;
bcopy(ifp->ill_name, ipfl.fl_ifname, MIN(ifp->ill_name_length, 4));
bcopy(ifp->ill_name, ipfl.fl_ifname,
MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
# else
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
@ -225,10 +226,8 @@ mb_t *m;
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
# else
ipfl.fl_unit = (u_char)ifp->if_unit;
if ((ipfl.fl_ifname[0] = ifp->if_name[0]))
if ((ipfl.fl_ifname[1] = ifp->if_name[1]))
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
ipfl.fl_ifname[3] = ifp->if_name[3];
strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
sizeof(ifp->if_name)));
# endif
mlen = (flags & FR_LOGBODY) ? MIN(fin->fin_plen - hlen, 128) : 0;
# endif
@ -241,10 +240,11 @@ mb_t *m;
else
ipfl.fl_loglevel = 0xffff;
ipfl.fl_flags = flags;
ipfl.fl_dir = fin->fin_out;
ptrs[0] = (void *)&ipfl;
sizes[0] = sizeof(ipfl);
types[0] = 0;
# if SOLARIS
# if SOLARIS && defined(_KERNEL)
/*
* Are we copied from the mblk or an aligned array ?
*/
@ -289,20 +289,20 @@ int *types, cnt;
MUTEX_ENTER(&ipl_mutex);
if (fin != NULL) {
if ((ipll[dev] != NULL) &&
bcmp((char *)fin, (char *)&iplcrc[dev], FI_CSIZE) == 0) {
bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
ipll[dev]->ipl_count++;
MUTEX_EXIT(&ipl_mutex);
return 1;
}
bcopy((char *)fin, (char *)&iplcrc[dev], FI_CSIZE);
bcopy((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE);
} else
bzero((char *)&iplcrc[dev], FI_CSIZE);
bzero((char *)&iplcrc[dev], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
/*
* Get the total amount of data to be logged.
*/
for (i = 0, len = sizeof(iplog_t); i < cnt; i++)
for (i = 0, len = IPLOG_SIZE; i < cnt; i++)
len += itemsz[i];
/*
@ -330,23 +330,28 @@ int *types, cnt;
ipl->ipl_count = 1;
ipl->ipl_next = NULL;
ipl->ipl_dsize = len;
# if SOLARIS || defined(sun)
# ifdef _KERNEL
# if SOLARIS || defined(sun)
uniqtime((struct timeval *)&ipl->ipl_sec);
# else
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
# else
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
microtime((struct timeval *)&ipl->ipl_sec);
# endif
# endif
# else
ipl->ipl_sec = 0;
ipl->ipl_usec = 0;
# endif
/*
* Loop through all the items to be logged, copying each one to the
* buffer. Use bcopy for normal data or the mb_t copyout routine.
*/
for (i = 0, s = buf + sizeof(*ipl); i < cnt; i++) {
for (i = 0, s = buf + IPLOG_SIZE; i < cnt; i++) {
if (types[i] == 0)
bcopy(items[i], s, itemsz[i]);
else if (types[i] == 1) {
# if SOLARIS
# if SOLARIS && defined(_KERNEL)
copyout_mblk(items[i], 0, itemsz[i], s);
# else
m_copydata(items[i], 0, itemsz[i], s);
@ -358,12 +363,12 @@ int *types, cnt;
ipll[dev] = ipl;
*iplh[dev] = ipl;
iplh[dev] = &ipl->ipl_next;
# if SOLARIS
# if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait);
mutex_exit(&ipl_mutex);
# else
MUTEX_EXIT(&ipl_mutex);
wakeup(&iplh[dev]);
WAKEUP(&iplh[dev]);
# endif
return 1;
}
@ -388,7 +393,7 @@ struct uio *uio;
return ENXIO;
if (!uio->uio_resid)
return 0;
if (uio->uio_resid < sizeof(iplog_t))
if (uio->uio_resid < IPLOG_SIZE)
return EINVAL;
/*
@ -430,15 +435,14 @@ struct uio *uio;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
MUTEX_ENTER(&ipl_mutex);
if (error) {
MUTEX_ENTER(&ipl_mutex);
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
iplused[unit] += dlen;
break;
}
KFREES((caddr_t)ipl, dlen);
MUTEX_ENTER(&ipl_mutex);
}
if (!iplt[unit]) {
iplused[unit] = 0;
@ -467,7 +471,7 @@ minor_t unit;
ipll[unit] = NULL;
used = iplused[unit];
iplused[unit] = 0;
bzero((char *)&iplcrc[unit], FI_CSIZE);
bzero((char *)&iplcrc[unit], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
return used;
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
* $Id: ip_nat.h,v 2.17.2.20 2001/06/26 10:43:15 darrenr Exp $
* $Id: ip_nat.h,v 2.17.2.25 2002/01/01 15:10:49 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -88,6 +88,7 @@ typedef struct nat {
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_phnext[2];
struct nat **nat_me;
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
@ -118,6 +119,7 @@ typedef struct ipnat {
struct in_addr in_out[2];
struct in_addr in_src[2];
struct frtuc in_tuc;
u_int in_age[2]; /* Aging for NAT entries. Not for TCP */
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
char in_ifname[IFNAMSIZ];
char in_plabel[APR_LABELLEN]; /* proxy label */
@ -286,23 +288,27 @@ extern nat_t **nat_table[2];
extern nat_t *nat_instances;
extern ipnat_t **nat_rules;
extern ipnat_t **rdr_rules;
extern ipnat_t *nat_list;
extern natstat_t nat_stats;
#if defined(__OpenBSD__)
extern void nat_ifdetach __P((void *));
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
extern int nat_ioctl __P((caddr_t, u_long, int));
#else
extern int nat_ioctl __P((caddr_t, int, int));
#endif
extern int nat_init __P((void));
extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
struct in_addr, u_32_t, int));
extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
struct in_addr, u_32_t, int));
extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
struct in_addr));
extern nat_t *nat_new __P((fr_info_t *, ip_t *, ipnat_t *, nat_t **,
u_int, int));
extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
struct in_addr, int));
extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
struct in_addr, int));
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmplookup __P((ip_t *, fr_info_t *, int));
extern nat_t *nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
extern int nat_clearlist __P((void));
extern void nat_insert __P((nat_t *));
extern int ip_natout __P((ip_t *, fr_info_t *));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2001 by Darren Reed.
* Copyright (C) 1997-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@ -7,6 +7,9 @@
# define _KERNEL
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -16,7 +19,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
#include <sys/uio.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
@ -65,34 +67,38 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.6 2001/07/15 22:06:15 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.21 2002/03/06 09:44:14 darrenr Exp $";
#endif
#if defined(_KERNEL) && (SOLARIS || defined(__sgi))
extern KRWLOCK_T ipf_nat, ipf_state;
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
static ap_session_t *appr_new_session __P((aproxy_t *, ip_t *,
fr_info_t *, nat_t *));
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
#define AP_SESS_SIZE 53
#if defined(_KERNEL) && !defined(linux)
#if defined(_KERNEL)
#include "netinet/ip_ftp_pxy.c"
#include "netinet/ip_rcmd_pxy.c"
#include "netinet/ip_raudio_pxy.c"
#include "netinet/ip_netbios_pxy.c"
#include "netinet/ip_h323_pxy.c"
#endif
#include "netinet/ip_ipsec_pxy.c"
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
@ -100,20 +106,39 @@ aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL },
#endif
#ifdef IPF_RCMD_PROXY
{ NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
ippr_rcmd_new, NULL, ippr_rcmd_out },
ippr_rcmd_new, NULL, NULL, ippr_rcmd_out, NULL },
#endif
#ifdef IPF_RAUDIO_PROXY
{ NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL },
#endif
{ NULL, "", '\0', 0, 0, NULL, NULL }
#ifdef IPF_IPSEC_PROXY
{ NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, ippr_ipsec_init, NULL,
ippr_ipsec_new, ippr_ipsec_del, NULL, ippr_ipsec_out,
ippr_ipsec_match },
#endif
#ifdef IPF_NETBIOS_PROXY
{ NULL, "netbios", (char)IPPROTO_TCP, 0, 0, ippr_netbios_init, NULL,
NULL, NULL, NULL, ippr_netbios_out, NULL },
#endif
#ifdef IPF_H323_PROXY
{ NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, NULL,
ippr_h323_new, ippr_h323_del, ippr_h323_in, ippr_h323_out, NULL },
{ NULL, "h245", (char)IPPROTO_TCP, 0, 0, ippr_h245_init, NULL,
ippr_h245_new, NULL, NULL, ippr_h245_out, NULL },
#endif
{ NULL, "", '\0', 0, 0, NULL, NULL, NULL }
};
/*
* Dynamically add a new kernel proxy. Ensure that it is unique in the
* collection compiled in and dynamically added.
*/
int appr_add(ap)
aproxy_t *ap;
{
@ -125,7 +150,7 @@ aproxy_t *ap;
sizeof(ap->apr_label)))
return -1;
for (a = ap_proxylist; a->apr_p; a = a->apr_next)
for (a = ap_proxylist; a && a->apr_p; a = a->apr_next)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
sizeof(ap->apr_label)))
@ -136,6 +161,11 @@ aproxy_t *ap;
}
/*
* Delete a proxy that has been added dynamically from those available.
* If it is in use, return 1 (do not destroy NOW), not in use 0 or -1
* if it cannot be matched.
*/
int appr_del(ap)
aproxy_t *ap;
{
@ -143,15 +173,19 @@ aproxy_t *ap;
for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
if (a == ap) {
a->apr_flags |= APR_DELETE;
*app = a->apr_next;
if (ap->apr_ref != 0)
return 1;
*app = a->apr_next;
return 0;
}
return -1;
}
/*
* Return 1 if the packet is a good match against a proxy, else 0.
*/
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@ -160,34 +194,64 @@ ipnat_t *nat;
aproxy_t *apr = nat->in_apr;
u_short dport = nat->in_dport;
if (!apr || (apr->apr_flags & APR_DELETE) ||
if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
(ip->ip_p != apr->apr_p))
return 0;
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
if (((tcp != NULL) && (tcp->th_dport != dport)) || (!tcp && dport))
return 0;
return 1;
}
/*
* If a proxy has a match function, call that to do extended packet
* matching.
*/
int appr_match(fin, nat)
fr_info_t *fin;
nat_t *nat;
{
aproxy_t *apr;
ipnat_t *ipn;
ipn = nat->nat_ptr;
if (ipn == NULL)
return -1;
apr = ipn->in_apr;
if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
(nat->nat_aps == NULL))
return -1;
if (apr->apr_match != NULL)
if ((*apr->apr_match)(fin, nat->nat_aps, nat) != 0)
return -1;
return 0;
}
/*
* Allocate a new application proxy structure and fill it in with the
* relevant details. call the init function once complete, prior to
* returning.
*/
static ap_session_t *appr_new_session(apr, ip, fin, nat)
aproxy_t *apr;
ip_t *ip;
int appr_new(fin, ip, nat)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
{
register ap_session_t *aps;
aproxy_t *apr;
if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL))
return -1;
apr = nat->nat_ptr->in_apr;
if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p))
return NULL;
return -1;
KMALLOC(aps, ap_session_t *);
if (!aps)
return NULL;
return -1;
bzero((char *)aps, sizeof(*aps));
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
@ -195,13 +259,18 @@ nat_t *nat;
aps->aps_psiz = 0;
if (apr->apr_new != NULL)
if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) {
KFREES(aps->aps_data, aps->aps_psiz);
}
KFREE(aps);
return NULL;
return -1;
}
aps->aps_nat = nat;
aps->aps_next = ap_sess_list;
ap_sess_list = aps;
return aps;
nat->nat_aps = aps;
return 0;
}
@ -225,9 +294,6 @@ nat_t *nat;
short rv;
int err;
if (nat->nat_aps == NULL)
nat->nat_aps = appr_new_session(nat->nat_ptr->in_apr, ip,
fin, nat);
aps = nat->nat_aps;
if ((aps != NULL) && (aps->aps_p == ip->ip_p)) {
if (ip->ip_p == IPPROTO_TCP) {
@ -263,8 +329,13 @@ nat_t *nat;
}
rv = APR_EXIT(err);
if (rv == -1)
return rv;
if (rv == 1)
return -1;
if (rv == 2) {
appr_free(apr);
nat->nat_aps = NULL;
return -1;
}
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, APR_INC(err));
@ -283,7 +354,10 @@ nat_t *nat;
}
aproxy_t *appr_match(pr, name)
/*
* Search for an proxy by the protocol it is being used with and its name.
*/
aproxy_t *appr_lookup(pr, name)
u_int pr;
char *name;
{
@ -317,6 +391,7 @@ void aps_free(aps)
ap_session_t *aps;
{
ap_session_t *a, **ap;
aproxy_t *apr;
if (!aps)
return;
@ -327,6 +402,10 @@ ap_session_t *aps;
break;
}
apr = aps->aps_apr;
if ((apr != NULL) && (apr->apr_del != NULL))
(*apr->apr_del)(aps);
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
@ -432,6 +511,10 @@ int inc;
}
/*
* Initialise hook for kernel application proxies.
* Call the initialise routine for all the compiled in kernel proxies.
*/
int appr_init()
{
aproxy_t *ap;
@ -446,6 +529,10 @@ int appr_init()
}
/*
* Unload hook for kernel application proxies.
* Call the finialise routine for all the compiled in kernel proxies.
*/
void appr_unload()
{
aproxy_t *ap;

View File

@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_proxy.h,v 2.8.2.7 2001/06/26 10:43:16 darrenr Exp $
* $Id: ip_proxy.h,v 2.8.2.12 2002/01/01 13:41:43 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@ -74,10 +74,12 @@ typedef struct aproxy {
void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
void (* apr_del) __P((ap_session_t *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_outpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *));
} aproxy_t;
#define APR_DELETE 1
@ -96,6 +98,7 @@ typedef struct ftpside {
u_32_t ftps_seq;
u_32_t ftps_len;
int ftps_junk;
int ftps_cmds;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
@ -108,7 +111,7 @@ typedef struct ftpinfo {
/*
* Real audio proxy structure and #defines
*/
typedef struct {
typedef struct raudio_s {
int rap_seenpna;
int rap_seenver;
int rap_version;
@ -136,6 +139,19 @@ typedef struct {
#define RAP_M_TCP 4
#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
/*
* IPSec proxy
*/
typedef u_32_t ipsec_cookie_t[2];
typedef struct ipsec_pxy {
ipsec_cookie_t ipsc_icookie;
ipsec_cookie_t ipsc_rcookie;
int ipsc_rckset;
ipnat_t ipsc_rule;
nat_t *ipsc_nat;
ipstate_t *ipsc_state;
} ipsec_pxy_t;
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
@ -147,9 +163,11 @@ extern int appr_del __P((aproxy_t *));
extern int appr_init __P((void));
extern void appr_unload __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern int appr_match __P((fr_info_t *, struct nat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
extern aproxy_t *appr_match __P((u_int, char *));
extern aproxy_t *appr_lookup __P((u_int, char *));
extern int appr_new __P((fr_info_t *, ip_t *, struct nat *));
#endif /* __IP_PROXY_H__ */

View File

@ -1,5 +1,5 @@
/*
* $Id: ip_raudio_pxy.c,v 1.7.2.6 2001/07/23 04:17:56 darrenr Exp $
* $Id: ip_raudio_pxy.c,v 1.7.2.8 2002/01/13 04:58:29 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@ -78,7 +78,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
off = fin->fin_hlen + (tcp->th_off << 2);
bzero(membuf, sizeof(membuf));
#if SOLARIS
m = fin->fin_qfm;
@ -194,7 +194,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
off = fin->fin_hlen + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
@ -283,11 +283,13 @@ nat_t *nat;
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
fi.fin_out = 0;
ipn = nat_new(nat->nat_ptr, ip, &fi,
ipn = nat_new(&fi, ip, nat->nat_ptr, NULL,
IPN_UDP | (sp ? 0 : FI_W_SPORT), NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT);
(void) fr_addstate(ip, &fi, NULL,
FI_IGNOREPKT|FI_NORULE|
(sp ? 0 : FI_W_SPORT));
}
}
@ -298,11 +300,12 @@ nat_t *nat;
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
fi.fin_out = 1;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP|FI_W_DPORT,
ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_UDP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
(void) fr_addstate(ip, &fi, NULL,
FI_W_DPORT|FI_IGNOREPKT|FI_NORULE);
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: ip_rcmd_pxy.c,v 1.4.2.4 2000/11/01 14:34:20 darrenr Exp $
* $Id: ip_rcmd_pxy.c,v 1.4.2.5 2001/10/30 16:38:14 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@ -82,10 +82,10 @@ nat_t *nat;
{
char portbuf[8], *s;
struct in_addr swip;
u_short sp, dp;
int off, dlen;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
fr_info_t fi;
u_short sp;
nat_t *ipn;
mb_t *m;
#if SOLARIS
@ -103,7 +103,7 @@ nat_t *nat;
(tcp->th_seq != *(u_32_t *)aps->aps_data))
return 0;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
off = fin->fin_hlen + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
@ -128,33 +128,33 @@ nat_t *nat;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
sp = htons(sp);
dp = htons(fin->fin_data[1]);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp, 0);
bcopy((char *)fin, (char *)&fi, sizeof(fi));
fi.fin_data[0] = sp;
fi.fin_data[1] = fin->fin_data[1];
ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp);
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = sp;
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_off = 5;
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_dlen = sizeof(*tcp2);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
fi.fin_fr = &rcmdfr;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
(void) fr_addstate(ip, &fi, NULL,
FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.12 2001/07/18 14:57:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.15 2001/12/26 22:28:51 darrenr Exp $";
#endif
#include <sys/types.h>
@ -375,14 +375,14 @@ caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
frentry_t fr;
frdest_t *fdp;
frgroup_t *fg = NULL;
u_int *p, *pp;
int error = 0, in;
int error = 0, in, i;
u_int *p, *pp;
frdest_t *fdp;
frentry_t fr;
u_32_t group;
ill_t *ill;
ipif_t *ipif;
ill_t *ill;
ire_t *ire;
fp = &fr;
@ -448,11 +448,16 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (*fp->fr_ifname) {
fp->fr_ifa = (void *)get_unit((char *)fp->fr_ifname,
(int)fp->fr_v);
if (!fp->fr_ifa)
fp->fr_ifa = (struct ifnet *)-1;
for (i = 0; i < 4; i++) {
if ((fp->fr_ifnames[i][1] == '\0') &&
((fp->fr_ifnames[i][0] == '-') ||
(fp->fr_ifnames[i][0] == '*'))) {
fp->fr_ifas[i] = NULL;
} else if (*fp->fr_ifnames[i]) {
fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v);
if (!fp->fr_ifas[i])
fp->fr_ifas[i] = (void *)-1;
}
}
fdp = &fp->fr_dif;
@ -583,6 +588,7 @@ caddr_t data;
fixskip(fprev, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
f->fr_ref--;
if (f->fr_ref == 0)
KFREE(f);
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* $Id: ip_state.h,v 2.13.2.4 2001/06/26 10:43:17 darrenr Exp $
* $Id: ip_state.h,v 2.13.2.10 2002/03/06 14:07:38 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@ -57,17 +57,20 @@ typedef struct ipstate {
struct ipstate **is_pnext;
struct ipstate *is_hnext;
struct ipstate **is_phnext;
struct ipstate **is_me;
u_long is_age;
u_int is_frage[2]; /* age from filter rule, forward & reverse */
u_int is_pass;
U_QUAD_T is_pkts;
U_QUAD_T is_bytes;
void *is_ifp[2];
void *is_ifp[4];
frentry_t *is_rule;
union i6addr is_src;
union i6addr is_dst;
u_char is_p; /* Protocol */
u_char is_v;
u_int is_hv;
u_32_t is_rulen; /* rule number */
u_32_t is_flags;
u_32_t is_opt; /* packet options set */
u_32_t is_optmsk; /* " " mask */
@ -80,7 +83,7 @@ typedef struct ipstate {
tcpstate_t is_ts;
udpstate_t is_us;
} is_ps;
char is_ifname[2][IFNAMSIZ];
char is_ifname[4][IFNAMSIZ];
#if SOLARIS || defined(__sgi)
kmutex_t is_lock;
#endif
@ -103,7 +106,7 @@ typedef struct ipstate {
#define is_dport is_tcp.ts_dport
#define is_state is_tcp.ts_state
#define is_ifpin is_ifp[0]
#define is_ifpout is_ifp[1]
#define is_ifpout is_ifp[2]
#define TH_OPENING (TH_SYN|TH_ACK)
/*
@ -177,12 +180,15 @@ extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_tcphalfclosed;
extern u_long fr_udptimeout;
extern u_long fr_udpacktimeout;
extern u_long fr_icmptimeout;
extern u_long fr_icmpacktimeout;
extern ipstate_t *ips_list;
extern int fr_state_lock;
extern int fr_stateinit __P((void));
extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int));
extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, ipstate_t **, u_int));
extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
extern void ip_statesync __P((void *));
extern void fr_timeoutstate __P((void));
extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));

View File

@ -12,6 +12,9 @@
# endif
# endif
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@ -47,7 +50,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.10 2001/07/18 11:34:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.13 2002/02/22 15:32:53 darrenr Exp $";
#endif
#if SOLARIS
@ -64,9 +67,7 @@ void zerostats __P((void));
int main __P((int, char *[]));
int opts = 0;
#ifdef USE_INET6
int use_inet6 = 0;
#endif
static int fd = -1;
@ -105,11 +106,9 @@ char *argv[];
while ((c = getopt(argc, argv, OPTS)) != -1) {
switch (c)
{
#ifdef USE_INET6
case '6' :
use_inet6 = 1;
break;
#endif
case 'A' :
opts &= ~OPT_INACTIVE;
break;

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipf.h 1.12 6/5/96
* $Id: ipf.h,v 2.9.2.3 2001/06/26 10:43:18 darrenr Exp $
* $Id: ipf.h,v 2.9.2.6 2002/01/03 08:00:12 darrenr Exp $
*/
#ifndef __IPF_H__
@ -38,6 +38,7 @@
#define OPT_STATETOP 0x400000
#define OPT_FLUSH 0x800000
#define OPT_CLEAR 0x1000000
#define OPT_HEX 0x2000000
#define OPT_NODO 0x80000000
#define OPT_STAT OPT_FRSTATES
@ -52,7 +53,10 @@
# endif
#endif
struct ipstate;
struct frpcmp;
struct ipnat;
struct nat;
#ifdef ultrix
extern char *strdup __P((char *));
@ -90,9 +94,15 @@ extern int genmask __P((char *, u_32_t *));
extern int hostnum __P((u_32_t *, char *, int));
extern u_32_t optname __P((char ***, u_short *, int));
extern void printpacket __P((ip_t *));
extern void printpacket6 __P((ip_t *));
extern void printportcmp __P((int, struct frpcmp *));
extern void printhostmask __P((int, u_32_t *, u_32_t *));
extern void printbuf __P((char *, int, int));
extern char *hostname __P((int, void *));
extern struct ipstate *printstate __P((struct ipstate *, int));
extern void printnat __P((struct ipnat *, int));
extern void printactivenat __P((struct nat *, int));
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
extern int gethostname __P((char *, int ));

View File

@ -45,7 +45,7 @@
#include "ipf.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.7 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.8 2001/09/14 18:52:21 darrenr Exp $";
#endif
#ifndef IPF_SAVEDIR
@ -237,13 +237,13 @@ char *argv[];
opts |= OPT_DONOTHING;
break;
case 'N' :
if ((ns > 0) || dirname || (rw != -1) || set)
if ((ns >= 0) || dirname || (rw != -1) || set)
usage();
ns = 0;
set = 1;
break;
case 'r' :
if ((ns > 0) || dirname || (rw != -1))
if ((ns >= 0) || dirname || (rw != -1))
usage();
rw = 0;
set = 1;
@ -253,7 +253,7 @@ char *argv[];
set = 1;
break;
case 'S' :
if ((ns > 0) || dirname || (rw != -1) || set)
if ((ns >= 0) || dirname || (rw != -1) || set)
usage();
ns = 1;
set = 1;
@ -268,7 +268,7 @@ char *argv[];
opts |= OPT_VERBOSE;
break;
case 'w' :
if ((ns > 0) || dirname || (rw != -1) || (ns == -1))
if (dirname || (rw != -1) || (ns == -1))
usage();
rw = 1;
set = 1;
@ -283,7 +283,7 @@ char *argv[];
}
if (ifs) {
if (!filename || ns<0)
if (!filename || ns < 0)
usage();
if (ns == 0)
return changenatif(ifs, filename);

View File

@ -17,6 +17,9 @@ etherfind -n -t
0.32 91 04 131.170.1.10 128.250.133.13
0.33 566 udp 128.250.37.155 128.250.133.3 901 901
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@ -49,7 +52,7 @@ etherfind -n -t
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.2 2002/02/22 15:32:53 darrenr Exp $";
#endif
static int etherf_open __P((char *));

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
@ -40,7 +43,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.2.2.5 2002/02/22 15:32:54 darrenr Exp $";
#endif
extern int opts;
@ -91,6 +94,14 @@ int cnt, *dir;
char line[513];
ip_t *ip;
/*
* interpret start of line as possibly "[ifname]" or
* "[in/out,ifname]".
*/
if (ifn)
*ifn = NULL;
if (dir)
*dir = 0;
ip = (ip_t *)buf;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n'))) {
@ -107,21 +118,14 @@ int cnt, *dir;
fflush(stdout);
}
/*
* interpret start of line as possibly "[ifname]" or
* "[in/out,ifname]".
*/
if (ifn)
*ifn = NULL;
if (dir)
*dir = 0;
if ((*buf == '[') && (s = index(line, ']'))) {
t = buf + 1;
if (t - s > 0) {
if ((*line == '[') && (s = index(line, ']'))) {
t = line + 1;
if (s - t > 0) {
*s++ = '\0';
if ((u = index(t, ',')) && (u < s)) {
u++;
if (ifn)
*ifn = u;
*ifn = strdup(u);
if (dir) {
if (*t == 'i')
*dir = 0;
@ -130,7 +134,6 @@ int cnt, *dir;
}
} else if (ifn)
*ifn = t;
*s++ = '\0';
}
} else
s = line;

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@ -31,7 +34,7 @@
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2.2.2 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2.2.3 2002/02/22 15:32:54 darrenr Exp $";
#endif
struct llc {

View File

@ -7,6 +7,9 @@
/*
* Written to comply with the recent RFC 1761 from Sun.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@ -35,7 +38,7 @@
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2.2.2 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2.2.3 2002/02/22 15:32:54 darrenr Exp $";
#endif
struct llc {

View File

@ -26,6 +26,9 @@ tcpdump -nqte
8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__GNUC__)
@ -58,7 +61,7 @@ tcpdump -nqte
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.1 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.2 2002/02/22 15:32:54 darrenr Exp $";
#endif
static int tcpd_open __P((char *));

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
@ -41,7 +44,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.3.2.4 2001/06/26 10:43:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.3.2.6 2002/03/13 03:55:15 darrenr Exp $";
#endif
extern int opts;
@ -261,7 +264,7 @@ int *out;
tx_proto = "udp";
} else {
ip->ip_p = IPPROTO_ICMP;
ip->ip_len += sizeof(struct icmp);
ip->ip_len += ICMPERR_IPICMPHLEN;
tx_proto = "icmp";
}
cpp++;

View File

@ -1,15 +1,15 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
* $Id: ipl.h,v 2.15.2.23 2001/07/23 13:52:10 darrenr Exp $
* $Id: ipl.h,v 2.15.2.31 2002/03/13 03:57:42 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.4.20"
#define IPL_VERSION "IP Filter: v3.4.25"
#endif

View File

@ -6,9 +6,12 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_y.y,v 2.2.2.1 2000/08/05 14:43:39 darrenr Exp $
* $Id: iplang_y.y,v 2.2.2.2 2002/02/22 15:32:57 darrenr Exp $
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@ -7,6 +7,9 @@
#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun)
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
@ -46,7 +49,6 @@
#include <arpa/nameser.h>
#include <resolv.h>
#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
# include <netinet/ip_var.h>
@ -61,13 +63,12 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.13 2001/07/19 12:24:59 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.32 2002/03/13 03:30:18 darrenr Exp $";
#endif
@ -84,6 +85,23 @@ struct flags {
char flag;
};
typedef struct icmp_subtype {
int ist_val;
char *ist_name;
} icmp_subtype_t;
typedef struct icmp_type {
int it_val;
struct icmp_subtype *it_subtable;
size_t it_stsize;
char *it_name;
} icmp_type_t;
#define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t))
struct flags tcpfl[] = {
{ TH_ACK, 'A' },
{ TH_RST, 'R' },
@ -122,6 +140,9 @@ static void dumphex __P((FILE *, u_char *, int));
static int read_log __P((int, int *, char *, int));
static void write_pid __P((char *));
static char *icmpname __P((u_int, u_int));
static char *icmpname6 __P((u_int, u_int));
static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t));
static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t));
char *hostname __P((int, int, u_32_t *));
char *portname __P((int, char *, u_int));
@ -134,7 +155,6 @@ static char *getproto __P((u_int));
static char **protocols = NULL;
static char **udp_ports = NULL;
static char **tcp_ports = NULL;
static char *argv0 = "ipmon";
#define OPT_SYSLOG 0x001
#define OPT_RESOLVE 0x002
@ -156,47 +176,198 @@ static char *argv0 = "ipmon";
#endif
#define ICMPUNREACHNAMES 14
static char *icmpunreachnames[ICMPUNREACHNAMES] = {
"net",
"host",
"protocol",
"port",
"needfrag",
"srcfail",
"net_unknown",
"host_unknown",
"isolated",
"net_prohib",
"host_prohib",
"tosnet",
"toshost",
"admin_prohibit"
static icmp_subtype_t icmpunreachnames[] = {
{ ICMP_UNREACH_NET, "net" },
{ ICMP_UNREACH_HOST, "host" },
{ ICMP_UNREACH_PROTOCOL, "protocol" },
{ ICMP_UNREACH_PORT, "port" },
{ ICMP_UNREACH_NEEDFRAG, "needfrag" },
{ ICMP_UNREACH_SRCFAIL, "srcfail" },
{ ICMP_UNREACH_NET_UNKNOWN, "net_unknown" },
{ ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" },
{ ICMP_UNREACH_NET, "isolated" },
{ ICMP_UNREACH_NET_PROHIB, "net_prohib" },
{ ICMP_UNREACH_NET_PROHIB, "host_prohib" },
{ ICMP_UNREACH_TOSNET, "tosnet" },
{ ICMP_UNREACH_TOSHOST, "toshost" },
{ ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" },
{ -2, NULL }
};
#define ICMPTYPES 19
static char *icmptypes[ICMPTYPES] = {
"echoreply",
NULL,
NULL,
"unreach",
"sourcequench",
"redirect",
NULL,
NULL,
"echo",
"routeradvert",
"routersolicit",
"timxceed",
"paramprob",
"timestamp",
"timestampreply",
"inforeq",
"inforeply",
"maskreq",
"maskreply"
static icmp_subtype_t redirectnames[] = {
{ ICMP_REDIRECT_NET, "net" },
{ ICMP_REDIRECT_HOST, "host" },
{ ICMP_REDIRECT_TOSNET, "tosnet" },
{ ICMP_REDIRECT_TOSHOST, "toshost" },
{ -2, NULL }
};
static icmp_subtype_t timxceednames[] = {
{ ICMP_TIMXCEED_INTRANS, "transit" },
{ ICMP_TIMXCEED_REASS, "reassem" },
{ -2, NULL }
};
static icmp_subtype_t paramnames[] = {
{ ICMP_PARAMPROB_ERRATPTR, "errata_pointer" },
{ ICMP_PARAMPROB_OPTABSENT, "optmissing" },
{ ICMP_PARAMPROB_LENGTH, "length" },
{ -2, NULL }
};
static icmp_type_t icmptypes[] = {
{ ICMP_ECHOREPLY, NULL, 0, "echoreply" },
{ -1, NULL, 0, NULL },
{ -1, NULL, 0, NULL },
{ ICMP_UNREACH, icmpunreachnames,
IST_SZ(icmpunreachnames),"unreach" },
{ ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" },
{ ICMP_REDIRECT, redirectnames,
IST_SZ(redirectnames), "redirect" },
{ -1, NULL, 0, NULL },
{ -1, NULL, 0, NULL },
{ ICMP_ECHO, NULL, 0, "echo" },
{ ICMP_ROUTERADVERT, NULL, 0, "routeradvert" },
{ ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" },
{ ICMP_TIMXCEED, timxceednames,
IST_SZ(timxceednames), "timxceed" },
{ ICMP_PARAMPROB, paramnames,
IST_SZ(paramnames), "paramprob" },
{ ICMP_TSTAMP, NULL, 0, "timestamp" },
{ ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" },
{ ICMP_IREQ, NULL, 0, "inforeq" },
{ ICMP_IREQREPLY, NULL, 0, "inforeply" },
{ ICMP_MASKREQ, NULL, 0, "maskreq" },
{ ICMP_MASKREPLY, NULL, 0, "maskreply" },
{ -2, NULL, 0, NULL }
};
static icmp_subtype_t icmpredirect6[] = {
{ ICMP6_DST_UNREACH_NOROUTE, "noroute" },
{ ICMP6_DST_UNREACH_ADMIN, "admin" },
{ ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" },
{ ICMP6_DST_UNREACH_ADDR, "address" },
{ ICMP6_DST_UNREACH_NOPORT, "noport" },
{ -2, NULL }
};
static icmp_subtype_t icmptimexceed6[] = {
{ ICMP6_TIME_EXCEED_TRANSIT, "intransit" },
{ ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" },
{ -2, NULL }
};
static icmp_subtype_t icmpparamprob6[] = {
{ ICMP6_PARAMPROB_HEADER, "header" },
{ ICMP6_PARAMPROB_NEXTHEADER, "nextheader" },
{ ICMP6_PARAMPROB_OPTION, "option" },
{ -2, NULL }
};
static icmp_subtype_t icmpquerysubject6[] = {
{ ICMP6_NI_SUBJ_IPV6, "ipv6" },
{ ICMP6_NI_SUBJ_FQDN, "fqdn" },
{ ICMP6_NI_SUBJ_IPV4, "ipv4" },
{ -2, NULL },
};
static icmp_subtype_t icmpnodeinfo6[] = {
{ ICMP6_NI_SUCCESS, "success" },
{ ICMP6_NI_REFUSED, "refused" },
{ ICMP6_NI_UNKNOWN, "unknown" },
{ -2, NULL }
};
static icmp_subtype_t icmprenumber6[] = {
{ ICMP6_ROUTER_RENUMBERING_COMMAND, "command" },
{ ICMP6_ROUTER_RENUMBERING_RESULT, "result" },
{ ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" },
{ -2, NULL }
};
static icmp_type_t icmptypes6[] = {
{ 0, NULL, 0, NULL },
{ ICMP6_DST_UNREACH, icmpredirect6,
IST_SZ(icmpredirect6), "unreach" },
{ ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" },
{ ICMP6_TIME_EXCEEDED, icmptimexceed6,
IST_SZ(icmptimexceed6), "timxceed" },
{ ICMP6_PARAM_PROB, icmpparamprob6,
IST_SZ(icmpparamprob6), "paramprob" },
{ ICMP6_ECHO_REQUEST, NULL, 0, "echo" },
{ ICMP6_ECHO_REPLY, NULL, 0, "echoreply" },
{ ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6,
IST_SZ(icmpquerysubject6), "groupmemberquery" },
{ ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" },
{ ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" },
{ ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" },
{ ND_ROUTER_ADVERT, NULL, 0, "routeradvert" },
{ ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" },
{ ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" },
{ ND_REDIRECT, NULL, 0, "redirect" },
{ ICMP6_ROUTER_RENUMBERING, icmprenumber6,
IST_SZ(icmprenumber6), "routerrenumber" },
{ ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" },
{ ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" },
{ ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" },
{ ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" },
{ ICMP6_NI_QUERY, icmpnodeinfo6,
IST_SZ(icmpnodeinfo6), "nodeinforequest" },
{ ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" },
{ MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" },
{ MLD6_MTRACE, NULL, 0, "mtracerequest" },
{ -2, NULL, 0, NULL }
};
static icmp_subtype_t *find_icmpsubtype(type, table, tablesz)
int type;
icmp_subtype_t *table;
size_t tablesz;
{
icmp_subtype_t *ist;
int i;
if (tablesz < 2)
return NULL;
if ((type < 0) || (type > table[tablesz - 2].ist_val))
return NULL;
i = type;
if (table[type].ist_val == type)
return table + type;
for (i = 0, ist = table; ist->ist_val != -2; i++, ist++)
if (ist->ist_val == type)
return ist;
return NULL;
}
static icmp_type_t *find_icmptype(type, table, tablesz)
int type;
icmp_type_t *table;
size_t tablesz;
{
icmp_type_t *it;
int i;
if (tablesz < 2)
return NULL;
if ((type < 0) || (type > table[tablesz - 2].it_val))
return NULL;
i = type;
if (table[type].it_val == type)
return table + type;
for (i = 0, it = table; it->it_val != -2; i++, it++)
if (it->it_val == type)
return it;
return NULL;
}
static void handlehup(sig)
int sig;
@ -229,7 +400,7 @@ static void init_tabs()
setprotoent(1);
while ((p = getprotoent()) != NULL)
if (p->p_proto >= 0 && p->p_proto <= 255 &&
p->p_name != NULL)
p->p_name != NULL && protocols[p->p_proto] == NULL)
protocols[p->p_proto] = strdup(p->p_name);
endprotoent();
}
@ -320,10 +491,11 @@ u_32_t *ip;
ipa.s_addr = *ip;
if (!res)
return inet_ntoa(ipa);
hp = gethostbyaddr((char *)ip, sizeof(ip), AF_INET);
hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET);
if (!hp)
return inet_ntoa(ipa);
sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, inet_ntoa(ipa));
sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name,
inet_ntoa(ipa));
return hname;
}
#ifdef USE_INET6
@ -360,62 +532,64 @@ u_int port;
}
#define TYPECODE(x,y) (((x) << 8) | (y))
static char *icmpname(type, code)
u_int type;
u_int code;
{
static char name[80];
char codeval[8], *s;
u_int typecode;
sprintf(codeval, "%d", code);
icmp_subtype_t *ist;
icmp_type_t *it;
char *s;
s = NULL;
if (type < ICMPTYPES)
s = icmptypes[type];
it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it));
if (it != NULL)
s = it->it_name;
if (s == NULL)
sprintf(name, "icmptype(%d)/", type);
else
sprintf(name, "%s/", s);
if (type == ICMP_UNREACH) {
if (code >= ICMPUNREACHNAMES)
sprintf(name + strlen(name), "%d", code);
else
strcat(name, icmpunreachnames[code]);
} else {
typecode = (type << 8) | code;
ist = NULL;
if (it != NULL && it->it_subtable != NULL)
ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize);
switch (typecode)
{
case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_NET) :
strcat(name, "net");
break;
case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_HOST) :
strcat(name, "host");
break;
case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_TOSNET) :
strcat(name, "tosnet");
break;
case TYPECODE(ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST) :
strcat(name, "toshost");
break;
case TYPECODE(ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS) :
strcat(name, "intrans");
break;
case TYPECODE(ICMP_TIMXCEED, ICMP_TIMXCEED_REASS) :
strcat(name, "reass");
break;
case TYPECODE(ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT) :
strcat(name, "optabsent");
break;
default:
strcat(name, codeval);
break;
}
}
if (ist != NULL && ist->ist_name != NULL)
strcat(name, ist->ist_name);
else
sprintf(name + strlen(name), "%d", code);
return name;
}
static char *icmpname6(type, code)
u_int type;
u_int code;
{
static char name[80];
icmp_subtype_t *ist;
icmp_type_t *it;
char *s;
s = NULL;
it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it));
if (it != NULL)
s = it->it_name;
if (s == NULL)
sprintf(name, "icmpv6type(%d)/", type);
else
sprintf(name, "%s/", s);
ist = NULL;
if (it != NULL && it->it_subtable != NULL)
ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize);
if (ist != NULL && ist->ist_name != NULL)
strcat(name, ist->ist_name);
else
sprintf(name + strlen(name), "%d", code);
return name;
}
@ -430,6 +604,10 @@ int len;
int i, j, k;
u_char *s = buf, *t = (u_char *)line;
if (len == 0 || buf == 0)
return;
*line = '\0';
for (i = len, j = 0; i; i--, j++, s++) {
if (j && !(j & 0xf)) {
*t++ = '\n';
@ -445,7 +623,7 @@ int len;
t += 2;
if (!((j + 1) & 0xf)) {
s -= 15;
sprintf((char *)t, " ");
sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
*t++ = (isprint(*s) ? *s : '.');
@ -489,7 +667,7 @@ int blen;
int res, i, len;
char *proto;
nl = (struct natlog *)((char *)ipl + sizeof(*ipl));
nl = (struct natlog *)((char *)ipl + IPLOG_SIZE);
res = (opts & OPT_RESOLVE) ? 1 : 0;
tm = localtime((time_t *)&ipl->ipl_sec);
len = sizeof(line);
@ -563,7 +741,7 @@ int blen;
struct tm *tm;
int res, i, len;
sl = (struct ipslog *)((char *)ipl + sizeof(*ipl));
sl = (struct ipslog *)((char *)ipl + IPLOG_SIZE);
res = (opts & OPT_RESOLVE) ? 1 : 0;
tm = localtime((time_t *)&ipl->ipl_sec);
len = sizeof(line);
@ -612,6 +790,13 @@ int blen;
(void) sprintf(t, "%s PR icmp %d",
hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
} else if (sl->isl_p == IPPROTO_ICMPV6) {
(void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
(u_32_t *)&sl->isl_src));
t += strlen(t);
(void) sprintf(t, "%s PR icmpv6 %d",
hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
}
t += strlen(t);
if (sl->isl_type != ISL_NEW) {
@ -706,7 +891,7 @@ int blen;
#endif
ipl = (iplog_t *)buf;
ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
ipf = (ipflog_t *)((char *)buf + IPLOG_SIZE);
ip = (ip_t *)((char *)ipf + sizeof(*ipf));
v = ip->ip_v;
res = (opts & OPT_RESOLVE) ? 1 : 0;
@ -736,13 +921,20 @@ int blen;
#if (SOLARIS || \
(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
len = (int)sizeof(ipf->fl_ifname);
(void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
{
char ifname[sizeof(ipf->fl_ifname) + 1];
strncpy(ifname, (char *)ipf->fl_ifname, sizeof(ipf->fl_ifname));
ifname[sizeof(ipf->fl_ifname)] = '\0';
(void) sprintf(t, "%s", ifname);
t += strlen(t);
# if SOLARIS
if (isalpha(*(t - 1)))
*t++ = '0' + ipf->fl_unit;
if (isalpha(*(t - 1))) {
sprintf(t, "%d", ipf->fl_unit);
t += strlen(t);
}
# endif
}
#else
for (len = 0; len < 3; len++)
if (ipf->fl_ifname[len] == '\0')
@ -752,7 +944,15 @@ int blen;
(void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
t += strlen(t);
#endif
(void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
if (ipf->fl_group == 0xffffffff)
strcat(t, " @-1:");
else
(void) sprintf(t, " @%u:", ipf->fl_group);
t += strlen(t);
if (ipf->fl_rule == 0xffffffff)
strcat(t, "-1 ");
else
(void) sprintf(t, "%u ", ipf->fl_rule + 1);
t += strlen(t);
if (ipf->fl_flags & FF_SHORT) {
@ -811,17 +1011,18 @@ int blen;
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) {
tp = (tcphdr_t *)((char *)ip + hl);
if (!(ipf->fl_flags & (FI_SHORT << 16))) {
if (!(ipf->fl_flags & FF_SHORT)) {
(void) sprintf(t, "%s,%s -> ", hostname(res, v, s),
portname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
(void) sprintf(t, "%s,%s PR %s len %hu %hu ",
(void) sprintf(t, "%s,%s PR %s len %hu %hu",
hostname(res, v, d),
portname(res, proto, (u_int)tp->th_dport),
proto, hl, plen);
t += strlen(t);
if (p == IPPROTO_TCP) {
*t++ = ' ';
*t++ = '-';
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
@ -841,13 +1042,20 @@ int blen;
(void) sprintf(t, "%s PR %s len %hu %hu",
hostname(res, v, d), proto, hl, plen);
}
} else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) {
ic = (struct icmp *)((char *)ip + hl);
(void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s",
hostname(res, v, d), hl, plen,
icmpname6(ic->icmp_type, ic->icmp_code));
} else if ((p == IPPROTO_ICMP) && !off && (v == 4)) {
ic = (struct icmp *)((char *)ip + hl);
(void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR icmp len %hu %hu icmp %s",
hostname(res, v, d), hl, plen,
icmpname((u_int) ic->icmp_type, (u_int) ic->icmp_code));
icmpname(ic->icmp_type, ic->icmp_code));
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
ic->icmp_type == ICMP_PARAMPROB ||
@ -929,9 +1137,9 @@ int blen;
t += strlen(t);
}
if (ipf->fl_flags & FR_INQUE)
if (ipf->fl_dir == 0)
strcpy(t, " IN");
else if (ipf->fl_flags & FR_OUTQUE)
else if (ipf->fl_dir == 1)
strcpy(t, " OUT");
t += strlen(t);
printipflog:
@ -984,7 +1192,8 @@ FILE *log;
int fd, flushed = 0;
if ((fd = open(file, O_RDWR)) == -1) {
(void) fprintf(stderr, "%s: open: %s\n", file,STRERROR(errno));
(void) fprintf(stderr, "%s: open: %s\n",
file, STRERROR(errno));
exit(1);
}
@ -1048,7 +1257,7 @@ char *argv[];
int fd[3], doread, n, i;
int tr, nr, regular[3], c;
int fdt[3], devices = 0, make_daemon = 0;
char buf[512], *iplfile[3];
char buf[IPLLOGSIZE], *iplfile[3], *s;
extern int optind;
extern char *optarg;
@ -1058,12 +1267,6 @@ char *argv[];
iplfile[1] = IPNAT_NAME;
iplfile[2] = IPSTATE_NAME;
argv0 = strrchr(argv[0], '/');
if (argv0 == NULL)
argv0 = argv[0];
else
argv0++;
while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
@ -1114,7 +1317,12 @@ char *argv[];
pidfile = optarg;
break;
case 's' :
openlog(argv0, LOG_NDELAY|LOG_PID, LOGFAC);
s = strrchr(argv[0], '/');
if (s == NULL)
s = argv[0];
else
s++;
openlog(s, LOG_NDELAY|LOG_PID, LOGFAC);
opts |= OPT_SYSLOG;
log = NULL;
break;
@ -1138,7 +1346,7 @@ char *argv[];
default :
case 'h' :
case '?' :
usage(argv0);
usage(argv[0]);
}
init_tabs();
@ -1163,8 +1371,8 @@ char *argv[];
/* NOTREACHED */
}
if (fstat(fd[i], &sb) == -1) {
(void) fprintf(stderr, "%d: fstat: %s\n",fd[i],
STRERROR(errno));
(void) fprintf(stderr, "%d: fstat: %s\n",
fd[i], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@ -1177,8 +1385,8 @@ char *argv[];
logfile = argv[optind];
log = logfile ? fopen(logfile, "a") : stdout;
if (log == NULL) {
(void) fprintf(stderr, "%s: fopen: %s\n", argv[optind],
STRERROR(errno));
(void) fprintf(stderr, "%s: fopen: %s\n",
argv[optind], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@ -1194,8 +1402,8 @@ char *argv[];
if ((pid = fork()) > 0)
exit(0);
if (pid < 0) {
(void) fprintf(stderr, "%s: fork() failed: %s\n", argv0,
STRERROR(errno));
(void) fprintf(stderr, "%s: fork() failed: %s\n",
argv[0], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
@ -1220,7 +1428,8 @@ char *argv[];
if (!regular[i]) {
if (ioctl(fd[i], FIONREAD, &tr) == -1) {
if (opts & OPT_SYSLOG)
syslog(LOG_CRIT, "ioctl(FIONREAD): %m");
syslog(LOG_CRIT,
"ioctl(FIONREAD): %m");
else
perror("ioctl(FIONREAD)");
exit(1);

View File

@ -1,10 +1,13 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@ -39,10 +42,12 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
#include <nlist.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "ipf.h"
#include "kmem.h"
@ -55,32 +60,32 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.9 2001/07/18 15:06:33 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.20 2002/02/22 15:32:55 darrenr Exp $";
#endif
#if SOLARIS
#define bzero(a,b) memset(a,0,b)
#endif
#ifdef USE_INET6
int use_inet6 = 0;
#endif
static char thishost[MAXHOSTNAMELEN];
char thishost[MAXHOSTNAMELEN];
extern char *optarg;
extern ipnat_t *natparse __P((char *, int));
extern void natparsefile __P((int, char *, int));
extern void printnat __P((ipnat_t *, int, void *));
extern void printnat __P((ipnat_t *, int));
extern void printactivenat __P((nat_t *, int));
extern void printhostmap __P((hostmap_t *, u_int));
extern char *getsumd __P((u_32_t));
void dostats __P((int, int)), flushtable __P((int, int));
void dostats __P((natstat_t *, int)), flushtable __P((int, int));
void usage __P((char *));
int countbits __P((u_32_t));
char *getnattype __P((ipnat_t *));
int main __P((int, char*[]));
void printaps __P((ap_session_t *, int));
char *getsumd __P((u_32_t));
void showhostmap __P((natstat_t *nsp));
void natstat_dead __P((natstat_t *, char *));
void usage(name)
@ -91,27 +96,22 @@ char *name;
}
char *getsumd(sum)
u_32_t sum;
{
static char sumdbuf[17];
if (sum & NAT_HW_CKSUM)
sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff);
else
sprintf(sumdbuf, "%#0x", sum);
return sumdbuf;
}
int main(argc, argv)
int argc;
char *argv[];
{
int fd = -1, opts = 0, c, mode = O_RDWR;
char *file = NULL, *core = NULL;
natstat_t ns, *nsp = &ns;
char *file, *core, *kernel;
int fd, opts, c, mode;
while ((c = getopt(argc, argv, "CdFf:hlM:nrsv")) != -1)
fd = -1;
opts = 0;
file = NULL;
core = NULL;
kernel = NULL;
mode = O_RDWR;
while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1)
switch (c)
{
case 'C' :
@ -136,6 +136,9 @@ char *argv[];
case 'M' :
core = optarg;
break;
case 'N' :
kernel = optarg;
break;
case 'n' :
opts |= OPT_NODO;
mode = O_RDONLY;
@ -154,21 +157,40 @@ char *argv[];
usage(argv[0]);
}
if (core != NULL) {
if (openkmem(core) == -1)
exit(1);
if ((kernel != NULL) || (core != NULL)) {
(void) setgid(getgid());
(void) setuid(getuid());
}
bzero((char *)&ns, sizeof(ns));
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, mode)) == -1) &&
((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
(void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
STRERROR(errno));
exit(-1);
if (!(opts & OPT_NODO) && (kernel == NULL) && (core == NULL)) {
if (openkmem(kernel, core) == -1)
exit(1);
if (((fd = open(IPL_NAT, mode)) == -1) &&
((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
(void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
STRERROR(errno));
exit(1);
}
if (ioctl(fd, SIOCGNATS, &nsp) == -1) {
perror("ioctl(SIOCGNATS)");
exit(1);
}
(void) setgid(getgid());
(void) setuid(getuid());
} else if ((kernel != NULL) || (core != NULL)) {
if (openkmem(kernel, core) == -1)
exit(1);
natstat_dead(nsp, kernel);
if (opts & (OPT_LIST|OPT_STAT))
dostats(nsp, opts);
exit(0);
}
if (opts & (OPT_FLUSH|OPT_CLEAR))
@ -176,172 +198,113 @@ char *argv[];
if (file)
natparsefile(fd, file, opts);
if (opts & (OPT_LIST|OPT_STAT))
dostats(fd, opts);
dostats(nsp, opts);
return 0;
}
void printaps(aps, opts)
ap_session_t *aps;
int opts;
/*
* Read nat statistic information in using a symbol table and memory file
* rather than doing ioctl's.
*/
void natstat_dead(nsp, kernel)
natstat_t *nsp;
char *kernel;
{
ap_session_t ap;
ftpinfo_t ftp;
aproxy_t apr;
raudio_t ra;
struct nlist nat_nlist[10] = {
{ "nat_table" }, /* 0 */
{ "nat_list" },
{ "maptable" },
{ "ipf_nattable_sz" },
{ "ipf_natrules_sz" },
{ "ipf_rdrrules_sz" }, /* 5 */
{ "ipf_hostmap_sz" },
{ "nat_instances" },
{ "ap_sess_list" },
{ NULL }
};
void *tables[2];
if (kmemcpy((char *)&ap, (long)aps, sizeof(ap)))
if (nlist(kernel, nat_nlist) == -1) {
fprintf(stderr, "nlist error\n");
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", (unsigned long long)ap.aps_bytes,
(unsigned long long)ap.aps_pkts);
#else
printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts);
#endif
printf(" data %p psiz %d\n", ap.aps_data, ap.aps_psiz);
if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) {
printf("\t\tstate[%u,%u], sel[%d,%d]\n",
ap.aps_state[0], ap.aps_state[1],
ap.aps_sel[0], ap.aps_sel[1]);
#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \
(__FreeBSD_version >= 300000) || defined(OpenBSD)
printf("\t\tseq: off %hd/%hd min %x/%x\n",
ap.aps_seqoff[0], ap.aps_seqoff[1],
ap.aps_seqmin[0], ap.aps_seqmin[1]);
printf("\t\tack: off %hd/%hd min %x/%x\n",
ap.aps_ackoff[0], ap.aps_ackoff[1],
ap.aps_ackmin[0], ap.aps_ackmin[1]);
#else
printf("\t\tseq: off %hd/%hd min %lx/%lx\n",
ap.aps_seqoff[0], ap.aps_seqoff[1],
ap.aps_seqmin[0], ap.aps_seqmin[1]);
printf("\t\tack: off %hd/%hd min %lx/%lx\n",
ap.aps_ackoff[0], ap.aps_ackoff[1],
ap.aps_ackmin[0], ap.aps_ackmin[1]);
#endif
}
if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) {
if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra)))
return;
printf("\tReal Audio Proxy:\n");
printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n",
ra.rap_seenpna, ra.rap_version, ra.rap_eos);
printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf);
printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n",
ra.rap_plport, ra.rap_prport, ra.rap_srport);
} else if (!strcmp(apr.apr_label, "ftp") &&
(ap.aps_psiz == sizeof(ftp))) {
if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp)))
return;
printf("\tFTP Proxy:\n");
printf("\t\tpassok: %d\n", ftp.ftp_passok);
ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0';
ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0';
printf("\tClient:\n");
printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
ftp.ftp_side[0].ftps_rptr, ftp.ftp_side[0].ftps_wptr,
ftp.ftp_side[0].ftps_seq, ftp.ftp_side[0].ftps_len,
ftp.ftp_side[0].ftps_junk);
printf("\t\tbuf [");
printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1);
printf("]\n\tServer:\n");
printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
ftp.ftp_side[1].ftps_rptr, ftp.ftp_side[1].ftps_wptr,
ftp.ftp_side[1].ftps_seq, ftp.ftp_side[1].ftps_len,
ftp.ftp_side[1].ftps_junk);
printf("\t\tbuf [");
printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1);
printf("]\n");
}
/*
* Normally the ioctl copies all of these values into the structure
* for us, before returning it to useland, so here we must copy each
* one in individually.
*/
kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
nsp->ns_table[0] = tables[0];
nsp->ns_table[1] = tables[1];
kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
sizeof(nsp->ns_list));
kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value,
sizeof(nsp->ns_maptable));
kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value,
sizeof(nsp->ns_nattab_sz));
kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value,
sizeof(nsp->ns_rultab_sz));
kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value,
sizeof(nsp->ns_rdrtab_sz));
kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value,
sizeof(nsp->ns_hostmap_sz));
kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
sizeof(nsp->ns_instances));
kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
sizeof(nsp->ns_apslist));
}
/*
* Get a nat filter type given its kernel address.
* Display NAT statistics.
*/
char *getnattype(ipnat)
ipnat_t *ipnat;
void dostats(nsp, opts)
natstat_t *nsp;
int opts;
{
char *which;
ipnat_t ipnatbuff;
if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat,
sizeof(ipnatbuff))))
return "???";
switch (ipnatbuff.in_redir)
{
case NAT_MAP :
which = "MAP";
break;
case NAT_MAPBLK :
which = "MAP-BLOCK";
break;
case NAT_REDIRECT :
which = "RDR";
break;
case NAT_BIMAP :
which = "BIMAP";
break;
default :
which = "unknown";
break;
}
return which;
}
void dostats(fd, opts)
int fd, opts;
{
hostmap_t hm, *hmp, **maptable;
natstat_t ns, *nsp = &ns;
nat_t **nt[2], *np, nat;
u_int hv, hv1, hv2;
ipnat_t ipn;
bzero((char *)&ns, sizeof(ns));
if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &nsp) == -1) {
perror("ioctl(SIOCGNATS)");
return;
}
/*
* Show statistics ?
*/
if (opts & OPT_STAT) {
printf("mapped\tin\t%lu\tout\t%lu\n",
ns.ns_mapped[0], ns.ns_mapped[1]);
nsp->ns_mapped[0], nsp->ns_mapped[1]);
printf("added\t%lu\texpired\t%lu\n",
ns.ns_added, ns.ns_expire);
nsp->ns_added, nsp->ns_expire);
printf("no memory\t%lu\tbad nat\t%lu\n",
ns.ns_memfail, ns.ns_badnat);
printf("inuse\t%lu\nrules\t%lu\n", ns.ns_inuse, ns.ns_rules);
printf("wilds\t%u\n", ns.ns_wilds);
nsp->ns_memfail, nsp->ns_badnat);
printf("inuse\t%lu\nrules\t%lu\n",
nsp->ns_inuse, nsp->ns_rules);
printf("wilds\t%u\n", nsp->ns_wilds);
if (opts & OPT_VERBOSE)
printf("table %p list %p\n", ns.ns_table, ns.ns_list);
printf("table %p list %p\n",
nsp->ns_table, nsp->ns_list);
}
/*
* Show list of NAT rules and NAT sessions ?
*/
if (opts & OPT_LIST) {
printf("List of active MAP/Redirect filters:\n");
while (ns.ns_list) {
if (kmemcpy((char *)&ipn, (long)ns.ns_list,
while (nsp->ns_list) {
if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
sizeof(ipn))) {
perror("kmemcpy");
break;
}
if (opts & OPT_HITS)
printf("%d ", ipn.in_hits);
printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE),
(void *)ns.ns_list);
ns.ns_list = ipn.in_next;
printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
nsp->ns_list = ipn.in_next;
}
nt[0] = (nat_t **)malloc(sizeof(*nt) * NAT_SIZE);
if (kmemcpy((char *)nt[0], (long)ns.ns_table[0],
if (kmemcpy((char *)nt[0], (long)nsp->ns_table[0],
sizeof(**nt) * NAT_SIZE)) {
perror("kmemcpy");
return;
@ -349,89 +312,59 @@ int fd, opts;
printf("\nList of active sessions:\n");
for (np = ns.ns_instances; np; np = nat.nat_next) {
for (np = nsp->ns_instances; np; np = nat.nat_next) {
if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
break;
printf("%s %-15s %-5hu <- ->", getnattype(nat.nat_ptr),
inet_ntoa(nat.nat_inip), ntohs(nat.nat_inport));
printf(" %-15s %-5hu", inet_ntoa(nat.nat_outip),
ntohs(nat.nat_outport));
printf(" [%s %hu]", inet_ntoa(nat.nat_oip),
ntohs(nat.nat_oport));
if (opts & OPT_VERBOSE) {
printf("\n\tage %lu use %hu sumd %s/",
nat.nat_age, nat.nat_use,
getsumd(nat.nat_sumd[0]));
hv1 = NAT_HASH_FN(nat.nat_inip.s_addr,
nat.nat_inport,
0xffffffff),
hv1 = NAT_HASH_FN(nat.nat_oip.s_addr,
hv1 + nat.nat_oport,
NAT_TABLE_SZ),
hv2 = NAT_HASH_FN(nat.nat_outip.s_addr,
nat.nat_outport,
0xffffffff),
hv2 = NAT_HASH_FN(nat.nat_oip.s_addr,
hv2 + nat.nat_oport,
NAT_TABLE_SZ),
printf("%s pr %u bkt %d/%d flags %x ",
getsumd(nat.nat_sumd[1]), nat.nat_p,
hv1, hv2, nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
(unsigned long long)nat.nat_bytes,
(unsigned long long)nat.nat_pkts);
#else
printf("bytes %lu pkts %lu",
nat.nat_bytes, nat.nat_pkts);
#endif
#if SOLARIS
printf(" %lx", nat.nat_ipsumd);
#endif
}
putchar('\n');
if (nat.nat_aps)
printaps(nat.nat_aps, opts);
printactivenat(&nat, opts);
}
if (opts & OPT_VERBOSE) {
printf("\nList of active host mappings:\n");
maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
ns.ns_hostmap_sz);
if (kmemcpy((char *)maptable, (u_long)ns.ns_maptable,
sizeof(hostmap_t *) * ns.ns_hostmap_sz)) {
perror("kmemcpy (maptable)");
return;
}
for (hv = 0; hv < ns.ns_hostmap_sz; hv++) {
hmp = maptable[hv];
while(hmp) {
if (kmemcpy((char *)&hm, (u_long)hmp,
sizeof(hostmap_t))) {
perror("kmemcpy (hostmap)");
return;
}
printf("%s -> ",
inet_ntoa(hm.hm_realip));
printf("%s ", inet_ntoa(hm.hm_mapip));
printf("(use = %d hv = %u)\n",
hm.hm_ref, hv);
hmp = hm.hm_next;
}
}
free(maptable);
}
if (opts & OPT_VERBOSE)
showhostmap(nsp);
free(nt[0]);
}
}
/*
* display the active host mapping table.
*/
void showhostmap(nsp)
natstat_t *nsp;
{
hostmap_t hm, *hmp, **maptable;
u_int hv;
printf("\nList of active host mappings:\n");
maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
nsp->ns_hostmap_sz);
if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
perror("kmemcpy (maptable)");
return;
}
for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
hmp = maptable[hv];
while (hmp) {
if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
perror("kmemcpy (hostmap)");
return;
}
printhostmap(&hm, hv);
hmp = hm.hm_next;
}
}
free(maptable);
}
/*
* Issue an ioctl to flush either the NAT rules table or the active mapping
* table or both.
*/
void flushtable(fd, opts)
int fd, opts;
{

View File

@ -1,6 +1,9 @@
/*
* Based upon 4.4BSD's /usr/sbin/arp
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
@ -26,7 +29,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: arp.c,v 2.1.4.2 2001/07/15 22:00:13 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: arp.c,v 2.1.4.3 2002/02/22 15:32:57 darrenr Exp $";
#endif

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -29,7 +32,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995";
static const char rcsid[] = "@(#)$Id: ip.c,v 2.1.4.3 2001/07/15 22:00:13 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip.c,v 2.1.4.4 2002/02/22 15:32:57 darrenr Exp $";
#endif
static char *ipbuf = NULL, *ethbuf = NULL;

View File

@ -8,12 +8,16 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -30,7 +34,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1.4.2 2001/07/15 22:00:13 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1.4.3 2002/02/22 15:32:57 darrenr Exp $";
#endif

View File

@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -32,7 +35,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.2.2.3 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.2.2.4 2002/02/22 15:32:57 darrenr Exp $";
#endif

View File

@ -3,6 +3,10 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -21,7 +25,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.2 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.3 2002/02/22 15:32:58 darrenr Exp $";
#endif

View File

@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
@ -34,7 +37,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2.2.2 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2.2.3 2002/02/22 15:32:58 darrenr Exp $";
#endif

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@ -76,7 +79,7 @@
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptests.c,v 2.1.4.2 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptests.c,v 2.1.4.5 2002/02/22 15:32:58 darrenr Exp $";
#endif
@ -299,14 +302,14 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (63 * 1024 + 768); i += 768) {
ip->ip_off = htons(IP_MF | (i >> 3));
ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
fflush(stdout);
PAUSE();
}
ip->ip_len = 896 + 20;
ip->ip_off = htons(i >> 3);
ip->ip_off = htons((i >> 3) & 0x1fff);
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
putchar('\n');
@ -333,7 +336,7 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (63 * 1024 + 768); i += 768) {
ip->ip_off = htons(IP_MF | (i >> 3));
ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
if ((rand() & 0x1f) != 0) {
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
@ -343,7 +346,7 @@ int ptest;
PAUSE();
}
ip->ip_len = 896 + 20;
ip->ip_off = htons(i >> 3);
ip->ip_off = htons((i >> 3) & 0x1fff);
if ((rand() & 0x1f) != 0) {
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
@ -370,14 +373,14 @@ int ptest;
ip->ip_len = MIN(768 + 20, mtu - 68);
i = 512;
for (; i < (32 * 1024 + 768); i += 768) {
ip->ip_off = htons(IP_MF | (i >> 3));
ip->ip_off = htons(IP_MF | ((i >> 3) & 0x1fff));
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
fflush(stdout);
PAUSE();
}
ip->ip_len = 896 + 20;
ip->ip_off = htons(i >> 3);
ip->ip_off = htons((i >> 3) & 0x1fff);
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
putchar('\n');
@ -1030,6 +1033,7 @@ int ptest;
struct sockaddr_in sin;
int fd, slen;
fd = -1;
bzero((char *)&sin, sizeof(sin));
for (i = 1; i < 63; i++) {
@ -1262,7 +1266,7 @@ int ptest;
for (j = 768; j < 3584; j += 768) {
ip->ip_len = sizeof(*ip) + 768;
ip->ip_off = htons(IP_MF|(j>>3));
ip->ip_off = htons(IP_MF|((j>>3) & 0x1fff));
(void) send_ip(nfd, 1500, ip, gwip, 1);
printf("%d %d\r", i, j);
fflush(stdout);
@ -1270,7 +1274,7 @@ int ptest;
ip->ip_len = sizeof(*ip) + 128;
for (k = j - 768; k < j; k += 128) {
ip->ip_off = htons(IP_MF|(k>>3));
ip->ip_off = htons(IP_MF|((k>>3) & 0x1fff));
(void) send_ip(nfd, 1500, ip, gwip, 1);
printf("%d %d\r", i, k);
fflush(stdout);

View File

@ -5,7 +5,10 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.2 2002/02/22 15:32:58 darrenr Exp $";
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <unistd.h>

View File

@ -8,6 +8,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <netdb.h>
#include <string.h>
@ -35,7 +38,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.3 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.4 2002/02/22 15:32:58 darrenr Exp $";
#endif

View File

@ -41,7 +41,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.1.4.2 2001/09/30 04:04:28 darrenr Exp $";
#endif
/*
@ -61,6 +61,8 @@ int sport, tout;
char bpfname[16];
int fd, i;
fd = -1;
for (i = 0; i < 16; i++)
{
(void) sprintf(bpfname, "/dev/bpf%d", i);

View File

@ -4,6 +4,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <string.h>

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@ -62,7 +65,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.3 2001/07/15 22:00:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.5 2002/02/22 15:32:58 darrenr Exp $";
#endif
@ -187,8 +190,6 @@ struct tcpiphdr *ti;
if (!(p = getproc()))
return NULL;
printf("fl %x ty %x cn %d mc %d\n",
f->f_flag, f->f_type, f->f_count, f->f_msgcount);
up = (struct user *)malloc(sizeof(*up));
#ifndef ultrix
if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@ -12,6 +12,9 @@
# endif
# endif
#endif
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <string.h>
@ -54,12 +57,13 @@
#include "ip_fil.h"
#include "ip_nat.h"
#include "ip_state.h"
#include "ip_frag.h"
#include "ipf.h"
#include "ipt.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.2 2001/06/26 10:43:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.19 2002/03/11 03:30:51 darrenr Exp $";
#endif
extern char *optarg;
@ -71,23 +75,42 @@ extern ipnat_t *natparse __P((char *, int));
extern int fr_running;
int opts = 0;
#ifdef USE_INET6
int use_inet6 = 0;
#endif
int main __P((int, char *[]));
int loadrules __P((char *));
int kmemcpy __P((char *, long, int));
void dumpnat __P((void));
void dumpstate __P((void));
char *getifname __P((void *));
void drain_log __P((char *));
int main(argc,argv)
int argc;
char *argv[];
{
struct ipread *r = &iptext;
u_long buf[2048];
char *datain, *iface, *ifname, *packet, *logout;
int fd, i, dir, c, loaded, dump, hlen;
struct ifnet *ifp;
char *rules = NULL, *datain = NULL, *iface = NULL;
struct ipread *r;
u_long buf[2048];
ip_t *ip;
int fd, i, dir = 0, c;
while ((c = getopt(argc, argv, "6bdEHi:I:NoPr:STvX")) != -1)
dir = 0;
dump = 0;
loaded = 0;
r = &iptext;
iface = NULL;
logout = NULL;
ifname = "anon0";
datain = NULL;
nat_init();
fr_stateinit();
initparse();
ipflog_init();
fr_running = 1;
while ((c = getopt(argc, argv, "6bdDEHi:I:l:NoPr:STvxX")) != -1)
switch (c)
{
#ifdef USE_INET6
@ -101,17 +124,25 @@ char *argv[];
case 'd' :
opts |= OPT_DEBUG;
break;
case 'D' :
dump = 1;
break;
case 'i' :
datain = optarg;
break;
case 'I' :
iface = optarg;
ifname = optarg;
break;
case 'l' :
logout = optarg;
break;
case 'o' :
opts |= OPT_SAVEOUT;
break;
case 'r' :
rules = optarg;
if (loadrules(optarg) == -1)
return -1;
loaded = 1;
break;
case 'v' :
opts |= OPT_VERBOSE;
@ -134,80 +165,19 @@ char *argv[];
case 'T' :
r = &tcpd;
break;
case 'x' :
opts |= OPT_HEX;
break;
case 'X' :
r = &iptext;
break;
}
if (!rules) {
(void)fprintf(stderr,"no rule file present\n");
if (loaded == 0) {
(void)fprintf(stderr,"no rules loaded\n");
exit(-1);
}
nat_init();
fr_stateinit();
initparse();
fr_running = 1;
if (rules) {
char line[513], *s;
void *fr;
FILE *fp;
int linenum = 0;
if (!strcmp(rules, "-"))
fp = stdin;
else if (!(fp = fopen(rules, "r"))) {
(void)fprintf(stderr, "couldn't open %s\n", rules);
exit(-1);
}
if (!(opts & OPT_BRIEF))
(void)printf("opening rule file \"%s\"\n", rules);
while (fgets(line, sizeof(line)-1, fp)) {
linenum++;
/*
* treat both CR and LF as EOL
*/
if ((s = index(line, '\n')))
*s = '\0';
if ((s = index(line, '\r')))
*s = '\0';
/*
* # is comment marker, everything after is a ignored
*/
if ((s = index(line, '#')))
*s = '\0';
if (!*line)
continue;
/* fake an `ioctl' call :) */
if ((opts & OPT_NAT) != 0) {
if (!(fr = natparse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT,
(caddr_t)&fr,
FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
"iplioctl(ADNAT,%p,1) = %d\n",
fr, i);
} else {
if (!(fr = parse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(0, SIOCADAFR,
(caddr_t)&fr,
FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
"iplioctl(ADAFR,%p,1) = %d\n",
fr, i);
}
}
(void)fclose(fp);
}
if (opts & OPT_SAVEOUT)
init_ifp();
@ -222,13 +192,34 @@ char *argv[];
ip = (ip_t *)buf;
while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
&iface, &dir)) > 0) {
ifp = iface ? get_unit(iface, ip->ip_v) : NULL;
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
i = fr_check(ip, ip->ip_hl << 2, ifp, dir, (mb_t **)&buf);
if (iface == NULL || *iface == '\0')
iface = ifname;
ifp = get_unit(iface, ip->ip_v);
hlen = 0;
if (!use_inet6) {
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
hlen = ip->ip_hl << 2;
}
#ifdef USE_INET6
else
hlen = sizeof(ip6_t);
#endif
packet = (char *)buf;
/* ipfr_slowtimer(); */
i = fr_check(ip, hlen, ifp, dir, (mb_t **)&packet);
if ((opts & OPT_NAT) == 0)
switch (i)
{
case -5 :
(void)printf("block return-icmp-as-dest");
break;
case -4 :
(void)printf("block return-icmp");
break;
case -3 :
(void)printf("block return-rst");
break;
case -2 :
(void)printf("auth");
break;
@ -242,6 +233,10 @@ char *argv[];
(void)printf("nomatch");
break;
}
if (!use_inet6) {
ip->ip_off = htons(ip->ip_off);
ip->ip_len = htons(ip->ip_len);
}
if (!(opts & OPT_BRIEF)) {
putchar(' ');
@ -250,17 +245,232 @@ char *argv[];
} else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF))
printpacket((ip_t *)buf);
#ifndef linux
if (dir && ifp && ip->ip_v)
# ifdef __sgi
(*ifp->if_output)(ifp, (void *)buf, NULL);
if (dir && (ifp != NULL) && ip->ip_v && (packet != NULL))
# if defined(__sgi) && (IRIX < 605)
(*ifp->if_output)(ifp, (void *)packet, NULL);
# else
(*ifp->if_output)(ifp, (void *)buf, NULL, 0);
(*ifp->if_output)(ifp, (void *)packet, NULL, 0);
# endif
#endif
if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF))
putchar('\n');
dir = 0;
if (iface != ifname) {
free(iface);
iface = ifname;
}
}
(*r->r_close)();
if (logout != NULL) {
drain_log(logout);
}
if (dump == 1) {
dumpnat();
dumpstate();
}
return 0;
}
/*
* Load in either NAT or ipf rules from a file, which is treated as stdin
* if the name is "-". NOTE, stdin can only be used once as the file is
* closed after use.
*/
int loadrules(file)
char *file;
{
char line[513], *s;
int linenum, i;
void *fr;
FILE *fp;
if (!strcmp(file, "-"))
fp = stdin;
else if (!(fp = fopen(file, "r"))) {
(void)fprintf(stderr, "couldn't open %s\n", file);
return (-1);
}
if (!(opts & OPT_BRIEF))
(void)printf("opening rule file \"%s\"\n", file);
linenum = 0;
while (fgets(line, sizeof(line) - 1, fp)) {
linenum++;
/*
* treat both CR and LF as EOL
*/
if ((s = index(line, '\n')))
*s = '\0';
if ((s = index(line, '\r')))
*s = '\0';
/*
* # is comment marker, everything after is a ignored
*/
if ((s = index(line, '#')))
*s = '\0';
if (!*line)
continue;
/* fake an `ioctl' call :) */
if ((opts & OPT_NAT) != 0) {
if (!(fr = natparse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT,
(caddr_t)&fr, FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr, "iplioctl(ADNAT,%p,1) = %d\n",
fr, i);
} else {
if (!(fr = parse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(0, SIOCADAFR, (caddr_t)&fr,
FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr, "iplioctl(ADAFR,%p,1) = %d\n",
fr, i);
}
}
(void)fclose(fp);
return 0;
}
int kmemcpy(addr, offset, size)
char *addr;
long offset;
int size;
{
bcopy((char *)offset, addr, size);
return 0;
}
/*
* Display the built up NAT table rules and mapping entries.
*/
void dumpnat()
{
ipnat_t *ipn;
nat_t *nat;
printf("List of active MAP/Redirect filters:\n");
for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next)
printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
printf("\nList of active sessions:\n");
for (nat = nat_instances; nat; nat = nat->nat_next)
printactivenat(nat, opts);
}
/*
* Display the built up state table rules and mapping entries.
*/
void dumpstate()
{
ipstate_t *ips;
printf("List of active state sessions:\n");
for (ips = ips_list; ips != NULL; )
ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE));
}
/*
* Given a pointer to an interface in the kernel, return a pointer to a
* string which is the interface name.
*/
char *getifname(ptr)
void *ptr;
{
#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
#else
char buf[32], *s;
int len;
#endif
struct ifnet netif;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
return "X";
#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
return strdup(netif.if_xname);
#else
if (kmemcpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
return "X";
if (netif.if_unit < 10)
len = 2;
else if (netif.if_unit < 1000)
len = 3;
else if (netif.if_unit < 10000)
len = 4;
else
len = 5;
buf[sizeof(buf) - len] = '\0';
for (s = buf; *s && !isdigit(*s); s++)
;
if (isdigit(*s))
*s = '\0';
sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
return strdup(buf);
#endif
}
void drain_log(filename)
char *filename;
{
char buffer[IPLLOGSIZE];
struct iovec iov;
struct uio uio;
size_t resid;
int fd;
fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
if (fd == -1) {
perror("drain_log:open");
return;
}
while (1) {
bzero((char *)&iov, sizeof(iov));
iov.iov_base = buffer;
iov.iov_len = sizeof(buffer);
bzero((char *)&uio, sizeof(uio));
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_resid = iov.iov_len;
resid = uio.uio_resid;
if (ipflog_read(0, &uio) == 0) {
/*
* If nothing was read then break out.
*/
if (uio.uio_resid == resid)
break;
write(fd, buffer, resid - uio.uio_resid);
} else
break;
}
close(fd);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@ -8,13 +8,37 @@
* returns 0 on success, -1 on error.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/file.h>
#ifndef __sgi
#include <kvm.h>
#endif
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include "kmem.h"
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "ipf.h"
#ifndef __STDC__
# define const
@ -22,23 +46,68 @@
#if !defined(lint)
static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.3 2001/07/15 22:06:16 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.12 2002/03/06 09:44:16 darrenr Exp $";
#endif
static int kmemfd = -1;
#ifndef __sgi
int openkmem(core)
char *core;
static kvm_t *kvm_f = NULL;
#else
typedef int kvm_t;
static kvm_t kvm_f = -1;
static char *kvm_errstr;
kvm_t kvm_open(kernel, core, swap, mode, errstr)
char *kernel, *core, *swap;
int mode;
char *errstr;
{
if (core == NULL)
core = KMEM;
kvm_t fd;
if ((kmemfd = open(core, O_RDONLY)) == -1)
kvm_errstr = errstr;
fd = open(core, mode);
return fd;
}
int kvm_read(kvm, pos, buffer, size)
kvm_t kvm;
u_long pos;
char *buffer;
size_t size;
{
int r, left;
char *bufp;
if (lseek(kvm, pos, 0) == -1) {
fprintf(stderr, "%s", kvm_errstr);
perror("lseek");
return -1;
}
for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
r = read(kvm, bufp, 1);
if (r <= 0)
return -1;
}
return 0;
}
#endif
int openkmem(kern, core)
char *kern, *core;
{
kvm_f = kvm_open(kern, core, NULL, O_RDONLY, "");
if (kvm_f == NULL)
{
perror("kmeminit:open");
perror("openkmem:open");
return -1;
}
return kmemfd;
return (int)kvm_f;
}
int kmemcpy(buf, pos, n)
@ -50,23 +119,22 @@ register int n;
if (!n)
return 0;
if (kmemfd == -1)
if (openkmem(NULL) == -1)
if (kvm_f == NULL)
if (openkmem(NULL, NULL) == -1)
return -1;
if (lseek(kmemfd, pos, 0) == -1)
{
perror("kmemcpy:lseek");
return -1;
}
while ((r = read(kmemfd, buf, n)) < n)
while ((r = kvm_read(kvm_f, pos, buf, n)) < n)
if (r <= 0)
{
fprintf(stderr, "pos=0x%x ", (u_int)pos);
perror("kmemcpy:read");
return -1;
}
else
{
buf += r;
pos += r;
n -= r;
}
return 0;
@ -81,19 +149,18 @@ register int n;
if (!n)
return 0;
if (kmemfd == -1)
if (openkmem(NULL) == -1)
if (kvm_f == NULL)
if (openkmem(NULL, NULL) == -1)
return -1;
if (lseek(kmemfd, pos, 0) == -1)
while (n > 0)
{
perror("kmemcpy:lseek");
return -1;
}
while (n > 0) {
r = read(kmemfd, buf, 1);
r = kvm_read(kvm_f, pos, buf, 1);
if (r <= 0)
{
perror("kmemcpy:read");
fprintf(stderr, "pos=0x%x ", (u_int)pos);
perror("kstrncpy:read");
return -1;
}
else
@ -101,8 +168,70 @@ register int n;
if (*buf == '\0')
break;
buf++;
pos++;
n--;
}
}
}
return 0;
}
/*
* Given a pointer to an interface in the kernel, return a pointer to a
* string which is the interface name.
*/
char *getifname(ptr)
void *ptr;
{
#if SOLARIS
char *ifname;
ill_t ill;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
return "X";
ifname = malloc(ill.ill_name_length + 1);
if (kmemcpy(ifname, (u_long)ill.ill_name,
ill.ill_name_length) == -1)
return "X";
return ifname;
#else
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
#else
char buf[32];
int len;
# endif
struct ifnet netif;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
return "X";
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__)
return strdup(netif.if_xname);
# else
if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
return "X";
if (netif.if_unit < 10)
len = 2;
else if (netif.if_unit < 1000)
len = 3;
else if (netif.if_unit < 10000)
len = 4;
else
len = 5;
buf[sizeof(buf) - len] = '\0';
sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
return strdup(buf);
# endif
#endif
}

View File

@ -2,7 +2,7 @@
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
* $Id: kmem.h,v 2.2.2.2 2001/06/26 10:43:19 darrenr Exp $
* $Id: kmem.h,v 2.2.2.4 2002/01/01 13:43:48 darrenr Exp $
*/
#ifndef __KMEM_H__
@ -15,9 +15,10 @@
# define __P(x) ()
# endif
#endif
extern int openkmem __P((char *));
extern int openkmem __P((char *, char *));
extern int kmemcpy __P((char *, long, int));
extern int kstrncpy __P((char *, long, int));
extern char *getifname __P((void *));
#if defined(__NetBSD__) || defined(__OpenBSD)
# include <paths.h>

View File

@ -10,7 +10,7 @@ all:
install:
$(INSTALL) -m 0644 -c -o root -g bin ipftest.1 $(MANDIR)/man1
$(INSTALL) -m 0644 -c -o root -g bin ipnat.1 $(MANDIR)/man1
$(INSTALL) -m 0644 -c -o root -g bin ipnat.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipf.4 $(MANDIR)/man4
$(INSTALL) -m 0644 -c -o root -g bin ipl.4 $(MANDIR)/man4
$(INSTALL) -m 0644 -c -o root -g bin ipnat.4 $(MANDIR)/man4

View File

@ -35,8 +35,8 @@ However, the full complement is as follows:
ioctl(fd, SIOCFRSYN, u_int *)
ioctl(fd, SIOCFRZST, struct friostat **)
ioctl(fd, SIOCZRLST, struct frentry **)
ioctl(fd, SIOCAUTHW, struct fr_info **)
ioctl(fd, SIOCAUTHR, struct fr_info **)
ioctl(fd, SIOCAUTHW, struct frauth_t **)
ioctl(fd, SIOCAUTHR, struct frauth_t **)
ioctl(fd, SIOCATHST, struct fr_authstat **)
.fi
.PP
@ -122,7 +122,7 @@ Flags which are recognised in fr_flags:
FR_RETRST 0x000080 /* return a TCP RST packet if blocked */
FR_RETICMP 0x000100 /* return an ICMP packet if blocked */
FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
FR_NOMATCH 0x000200 /* no match occured */
FR_NOMATCH 0x000200 /* No match occurred */
FR_ACCOUNT 0x000400 /* count packet bytes */
FR_KEEPFRAG 0x000800 /* keep fragment information */
FR_KEEPSTATE 0x001000 /* keep `connection' state information */

View File

@ -1,10 +1,10 @@
.TH IPFILTER 1
.SH NAME
IP FIlter
IP Filter
.SH DESCRIPTION
.PP
IP Filter is a package providing packet filtering capabilities for a variety
of operating systems. On a properly setup system, it can be used to build a
firewall.
.SH SEE ALSO
ipf(8), ipf(1), ipf(5), ipnat(1), ipnat(5), mkfilters(1)
ipf(8), ipf(1), ipf(5), ipnat(8), ipnat(5), mkfilters(1)

View File

@ -52,6 +52,7 @@ Change the default directory used with
and
.B \-W
options for saving state information.
.TP
.B \-n
Don't actually take any action that would effect information stored in
the kernel or on disk.
@ -59,6 +60,11 @@ the kernel or on disk.
.B \-v
Provides a verbose description of what's being done.
.TP
.B \-i <ifname1>,<ifname2>
Change all instances of interface name ifname1 in the state save file to
ifname2. Useful if you're restoring state information after a hardware
reconfiguration or change.
.TP
.B \-N
Operate on NAT information.
.TP
@ -69,7 +75,7 @@ Operate on filtering state information.
Unlock state tables in the kernel.
.TP
.B \-l
Unlock state tables in the kernel.
Lock state tables in the kernel.
.TP
.B \-r
Read information in from the specified file and load it into the

View File

@ -49,7 +49,7 @@ When reading from the \fBipl\fP device, it is necessary to call read(2) with
a buffer big enough to hold at least 1 complete log record - reading of partial
log records is not supported.
.PP
If the packet contents is more then 128 bytes when \fBlog body\fP is used,
If the packet contents are more than 128 bytes when \fBlog body\fP is used,
then only 128 bytes of the packet contents is logged.
.PP
Although it is only possible to read from the \fBipl\fP device, opening it

View File

@ -4,7 +4,7 @@ ipmon \- monitors /dev/ipl for logged packets
.SH SYNOPSIS
.B ipmon
[
.B \-aDFhnpstvxX
.B \-abDFhnpstvxX
] [
.B "\-N <device>"
] [
@ -76,6 +76,10 @@ In order for \fBipmon\fP to properly work, the kernel option
Open all of the device logfiles for reading log entries from. All entries
are displayed to the same output 'device' (stderr or syslog).
.TP
.B \-b
For rules which log the body of a packet, generate hex output representing
the packet contents afte the headers.
.TP
.B \-D
Cause ipmon to turn itself into a daemon. Using subshells or backgrounding
of ipmon is not required to turn it into an orphan so it can run indefinately.

View File

@ -10,10 +10,11 @@ ipmap :: = mapblock | redir | map .
map ::= mapit ifname ipmask "->" ipmask [ mapport ] .
map ::= mapit ifname fromto "->" ipmask [ mapport ] .
mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] .
redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] [ ports ] options .
redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport options .
dport ::= "port" portnum [ "-" portnum ] .
ports ::= "ports" numports | "auto" .
rdrport ::= "port" portnum .
mapit ::= "map" | "bimap" .
fromto ::= "from" object "to" object .
ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
@ -199,6 +200,7 @@ own. As opposed to the above use of \fBmap\fP, if for some reason the user
of (say) 172.192.0.2 wanted 260 simultaneous connections going out, they would
be limited to 252 with \fBmap-block\fP but would just \fImove on\fP to the next
IP address with the \fBmap\fP command.
.SH FILES
/dev/ipnat
.br
/etc/services

View File

@ -1,8 +1,11 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#if (SOLARIS2 >= 7)
# define _SYS_VARARGS_H
# define _VARARGS_H
@ -50,7 +53,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: misc.c,v 2.2.2.1 2001/06/26 10:43:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: misc.c,v 2.2.2.7 2002/02/22 15:32:55 darrenr Exp $";
#endif
extern int opts;
@ -60,9 +63,38 @@ void printpacket(ip)
ip_t *ip;
{
tcphdr_t *tcp;
u_short len;
if (ip->ip_v == 4)
len = ntohs(ip->ip_len);
else if (ip->ip_v == 6)
len = ntohs(((u_short *)ip)[2]) + 40;
else
len = 0;
if ((opts & OPT_HEX) == OPT_HEX) {
u_char *s;
int i;
for (s = (u_char *)ip, i = 0; i < len; i++) {
printf("%02x", *s++ & 0xff);
if (len - i > 1) {
i++;
printf("%02x", *s++ & 0xff);
}
putchar(' ');
}
putchar('\n');
return;
}
if (ip->ip_v == 6) {
printpacket6(ip);
return;
}
tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2));
printf("ip %d(%d) %d", ip->ip_len, ip->ip_hl << 2, ip->ip_p);
printf("ip %d(%d) %d", ntohs(ip->ip_len), ip->ip_hl << 2, ip->ip_p);
if (ip->ip_off & IP_OFFMASK)
printf(" @%d", ip->ip_off << 3);
(void)printf(" %s", inet_ntoa(ip->ip_src));
@ -78,6 +110,48 @@ ip_t *ip;
}
/*
* This is meant to work without the IPv6 header files being present or
* the inet_ntop() library.
*/
void printpacket6(ip)
ip_t *ip;
{
u_char *buf, p, hops;
u_short plen, *addrs;
tcphdr_t *tcp;
u_32_t flow;
buf = (u_char *)ip;
tcp = (tcphdr_t *)(buf + 40);
p = buf[6];
hops = buf[7];
flow = ntohl(*(u_32_t *)buf);
flow &= 0xfffff;
plen = ntohs(*((u_short *)buf +2));
addrs = (u_short *)buf + 4;
printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p);
printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]),
ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]),
ntohs(addrs[6]), ntohs(addrs[7]));
if (plen >= 4)
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
(void)printf(",%d", ntohs(tcp->th_sport));
printf(" >");
addrs += 8;
printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]),
ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]),
ntohs(addrs[6]), ntohs(addrs[7]));
if (plen >= 4)
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
(void)printf(",%d", ntohs(tcp->th_dport));
putchar('\n');
}
#if defined(__STDC__)
void verbose(char *fmt, ...)
#else

View File

@ -117,8 +117,12 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
&fr_tcpclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
&fr_udpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
&fr_icmpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
&fr_defnatage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mlfk_ipl.c,v 2.1.2.6 2000/11/18 03:58:29 darrenr Exp $
* $Id: mlfk_ipl.c,v 2.1.2.7 2001/08/27 21:14:04 darrenr Exp $
*/
@ -76,8 +76,12 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
&fr_udpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
&fr_icmpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
&fr_defnatage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,

View File

@ -62,7 +62,12 @@ static __psunsigned_t ipfk_code[4];
typedef struct nif {
struct nif *nf_next;
struct ifnet *nf_ifp;
#if IRIX < 605
int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *);
#else
int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
#endif
char nf_name[IFNAMSIZ];
int nf_unit;
} nif_t;
@ -74,7 +79,12 @@ extern int in_interfaces;
extern ipnat_t *nat_list;
static int
#if IRIX < 605
ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
#else
ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct rtentry *rt)
#endif
{
nif_t *nif;
@ -112,19 +122,19 @@ ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
#if IPFDEBUG >= 4
if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
return (*nif->nf_output)(ifp, m, dst);
goto done;
}
#endif
if (m->m_len < sizeof(char)) {
printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags));
return (*nif->nf_output)(ifp, m, dst);
goto done;
}
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
#if IPFDEBUG >= 4
printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
#endif
return (*nif->nf_output)(ifp, m, dst);
goto done;
}
hlen = ip->ip_hl << 2;
@ -142,7 +152,12 @@ ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
break;
}
}
done:
#if IRIX < 605
return (*nif->nf_output)(ifp, m, dst);
#else
return (*nif->nf_output)(ifp, m, dst, rt);
#endif
}
int

View File

@ -235,7 +235,7 @@ static int ipl_load()
*/
(void)ipl_remove();
error = iplattach();
error = ipl_enable();
if (error)
return error;

View File

@ -1,8 +1,11 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@ -39,8 +42,9 @@
#include <ctype.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "ipf.h"
#if defined(sun) && !SOLARIS2
@ -52,7 +56,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.11 2001/07/17 14:33:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.23 2002/02/22 15:32:55 darrenr Exp $";
#endif
@ -60,191 +64,15 @@ static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.11 2001/07/17 14:33:09
#define bzero(a,b) memset(a,0,b)
#endif
extern void printnat __P((ipnat_t *, int));
extern int countbits __P((u_32_t));
extern char *proto;
ipnat_t *natparse __P((char *, int));
void printnat __P((ipnat_t *, int, void *));
void natparsefile __P((int, char *, int));
void nat_setgroupmap __P((struct ipnat *));
void printnat(np, opts, ptr)
ipnat_t *np;
int opts;
void *ptr;
{
struct protoent *pr;
struct servent *sv;
int bits;
switch (np->in_redir)
{
case NAT_REDIRECT :
printf("rdr");
break;
case NAT_MAP :
printf("map");
break;
case NAT_MAPBLK :
printf("map-block");
break;
case NAT_BIMAP :
printf("bimap");
break;
default :
fprintf(stderr, "unknown value for in_redir: %#x\n",
np->in_redir);
break;
}
printf(" %s ", np->in_ifname);
if (np->in_flags & IPN_FILTER) {
if (np->in_flags & IPN_NOTSRC)
printf("! ");
printf("from ");
if (np->in_redir == NAT_REDIRECT) {
printhostmask(4, (u_32_t *)&np->in_srcip,
(u_32_t *)&np->in_srcmsk);
if (np->in_scmp)
printportcmp(np->in_p, &np->in_tuc.ftu_src);
} else {
printhostmask(4, (u_32_t *)&np->in_inip,
(u_32_t *)&np->in_inmsk);
if (np->in_dcmp)
printportcmp(np->in_p, &np->in_tuc.ftu_dst);
}
if (np->in_flags & IPN_NOTDST)
printf(" !");
printf(" to ");
if (np->in_redir == NAT_REDIRECT) {
printhostmask(4, (u_32_t *)&np->in_outip,
(u_32_t *)&np->in_outmsk);
if (np->in_dcmp)
printportcmp(np->in_p, &np->in_tuc.ftu_dst);
} else {
printhostmask(4, (u_32_t *)&np->in_srcip,
(u_32_t *)&np->in_srcmsk);
if (np->in_scmp)
printportcmp(np->in_p, &np->in_tuc.ftu_src);
}
}
if (np->in_redir == NAT_REDIRECT) {
if (!(np->in_flags & IPN_FILTER)) {
printf("%s", inet_ntoa(np->in_out[0]));
bits = countbits(np->in_out[1].s_addr);
if (bits != -1)
printf("/%d ", bits);
else
printf("/%s ", inet_ntoa(np->in_out[1]));
if (np->in_pmin)
printf("port %d", ntohs(np->in_pmin));
if (np->in_pmax != np->in_pmin)
printf("- %d", ntohs(np->in_pmax));
}
printf(" -> %s", inet_ntoa(np->in_in[0]));
if (np->in_flags & IPN_SPLIT)
printf(",%s", inet_ntoa(np->in_in[1]));
if (np->in_pnext)
printf(" port %d", ntohs(np->in_pnext));
if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
printf(" tcp/udp");
else if ((np->in_flags & IPN_TCP) == IPN_TCP)
printf(" tcp");
else if ((np->in_flags & IPN_UDP) == IPN_UDP)
printf(" udp");
if (np->in_flags & IPN_ROUNDR)
printf(" round-robin");
if (np->in_flags & IPN_FRAG)
printf(" frag");
printf("\n");
if (opts & OPT_DEBUG)
printf("\t%p %lu %#x %u %p %d\n", np->in_ifp,
np->in_space, np->in_flags, np->in_pmax, np,
np->in_use);
} else {
np->in_nextip.s_addr = htonl(np->in_nextip.s_addr);
if (!(np->in_flags & IPN_FILTER)) {
printf("%s/", inet_ntoa(np->in_in[0]));
bits = countbits(np->in_in[1].s_addr);
if (bits != -1)
printf("%d ", bits);
else
printf("%s", inet_ntoa(np->in_in[1]));
}
printf(" -> ");
if (np->in_flags & IPN_IPRANGE) {
printf("range %s-", inet_ntoa(np->in_out[0]));
printf("%s", inet_ntoa(np->in_out[1]));
} else {
printf("%s/", inet_ntoa(np->in_out[0]));
bits = countbits(np->in_out[1].s_addr);
if (bits != -1)
printf("%d ", bits);
else
printf("%s", inet_ntoa(np->in_out[1]));
}
if (*np->in_plabel) {
pr = getprotobynumber(np->in_p);
printf(" proxy port");
if (np->in_dport != 0) {
if (pr != NULL)
sv = getservbyport(np->in_dport,
pr->p_name);
else
sv = getservbyport(np->in_dport, NULL);
if (sv != NULL)
printf(" %s", sv->s_name);
else
printf(" %hu", ntohs(np->in_dport));
}
printf(" %.*s/", (int)sizeof(np->in_plabel),
np->in_plabel);
if (pr != NULL)
fputs(pr->p_name, stdout);
else
printf("%d", np->in_p);
} else if (np->in_redir == NAT_MAPBLK) {
printf(" ports %d", np->in_pmin);
if (opts & OPT_VERBOSE)
printf("\n\tip modulous %d", np->in_pmax);
} else if (np->in_pmin || np->in_pmax) {
printf(" portmap");
if (np->in_flags & IPN_AUTOPORTMAP) {
printf(" auto");
if (opts & OPT_DEBUG)
printf(" [%d:%d %d %d]",
ntohs(np->in_pmin),
ntohs(np->in_pmax),
np->in_ippip, np->in_ppip);
} else {
if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
printf(" tcp/udp");
else if (np->in_flags & IPN_TCP)
printf(" tcp");
else if (np->in_flags & IPN_UDP)
printf(" udp");
printf(" %d:%d", ntohs(np->in_pmin),
ntohs(np->in_pmax));
}
}
if (np->in_flags & IPN_FRAG)
printf(" frag");
printf("\n");
if (opts & OPT_DEBUG) {
printf("\tifp %p space %lu nextip %s pnext %d",
np->in_ifp, np->in_space,
inet_ntoa(np->in_nextip), np->in_pnext);
printf(" flags %x use %u\n",
np->in_flags, np->in_use);
}
}
}
void nat_setgroupmap(n)
ipnat_t *n;
{
@ -268,7 +96,9 @@ ipnat_t *n;
}
/*
* Parse a line of input from the ipnat configuration file
*/
ipnat_t *natparse(line, linenum)
char *line;
int linenum;
@ -278,9 +108,13 @@ int linenum;
char *dnetm = NULL, *dport = NULL;
char *s, *t, *cps[31], **cpp;
int i, cnt;
char *port1a = NULL, *port1b = NULL, *port2a = NULL;
proto = NULL;
/*
* Search for end of line and comment marker, advance of leading spaces
*/
if ((s = strchr(line, '\n')))
*s = '\0';
if ((s = strchr(line, '#')))
@ -293,6 +127,9 @@ int linenum;
bzero((char *)&ipn, sizeof(ipn));
cnt = 0;
/*
* split line upto into segments.
*/
for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++)
cps[++i] = strtok(NULL, " \b\t\r\n");
@ -305,6 +142,9 @@ int linenum;
cpp = cps;
/*
* Check first word is a recognised keyword and then is the interface
*/
if (!strcasecmp(*cpp, "map"))
ipn.in_redir = NAT_MAP;
else if (!strcasecmp(*cpp, "map-block"))
@ -325,6 +165,10 @@ int linenum;
ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0';
cpp++;
/*
* If the first word after the interface is "from" or is a ! then
* the expanded syntax is being used so parse it differently.
*/
if (!strcasecmp(*cpp, "from") || (**cpp == '!')) {
if (!strcmp(*cpp, "!")) {
cpp++;
@ -349,19 +193,17 @@ int linenum;
ipn.in_flags |= IPN_FILTER;
cpp++;
if (ipn.in_redir == NAT_REDIRECT) {
if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
(u_32_t *)&ipn.in_srcmsk,
&ipn.in_sport, &ipn.in_scmp,
&ipn.in_stop, linenum)) {
return NULL;
}
if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
(u_32_t *)&ipn.in_srcmsk, &ipn.in_sport,
&ipn.in_scmp, &ipn.in_stop, linenum)) {
return NULL;
}
} else {
if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
(u_32_t *)&ipn.in_inmsk,
&ipn.in_sport, &ipn.in_scmp,
&ipn.in_stop, linenum)) {
return NULL;
}
if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
(u_32_t *)&ipn.in_inmsk, &ipn.in_sport,
&ipn.in_scmp, &ipn.in_stop, linenum)) {
return NULL;
}
}
if (!strcmp(*cpp, "!")) {
@ -388,28 +230,30 @@ int linenum;
return NULL;
}
if (ipn.in_redir == NAT_REDIRECT) {
if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
(u_32_t *)&ipn.in_outmsk,
&ipn.in_dport, &ipn.in_dcmp,
&ipn.in_dtop, linenum)) {
return NULL;
}
ipn.in_pmin = htons(ipn.in_dport);
if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
(u_32_t *)&ipn.in_outmsk, &ipn.in_dport,
&ipn.in_dcmp, &ipn.in_dtop, linenum)) {
return NULL;
}
ipn.in_pmin = htons(ipn.in_dport);
} else {
if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
(u_32_t *)&ipn.in_srcmsk,
&ipn.in_dport, &ipn.in_dcmp,
&ipn.in_dtop, linenum)) {
return NULL;
}
if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
(u_32_t *)&ipn.in_srcmsk, &ipn.in_dport,
&ipn.in_dcmp, &ipn.in_dtop, linenum)) {
return NULL;
}
}
} else {
s = *cpp;
if (!s)
if (!s) {
fprintf(stderr, "%d: short line\n", linenum);
return NULL;
}
t = strchr(s, '/');
if (!t)
if (!t) {
fprintf(stderr, "%d: no netmask on LHS\n", linenum);
return NULL;
}
*t++ = '\0';
if (ipn.in_redir == NAT_REDIRECT) {
if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1)
@ -425,10 +269,16 @@ int linenum;
}
}
cpp++;
if (!*cpp)
if (!*cpp) {
fprintf(stderr, "%d: short line\n", linenum);
return NULL;
}
}
/*
* If it is a standard redirect then we expect it to have a port
* match after the hostmask.
*/
if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
if (strcasecmp(*cpp, "port")) {
fprintf(stderr, "%d: missing fields - 1st port\n",
@ -450,24 +300,23 @@ int linenum;
else
s = NULL;
if (!portnum(*cpp, &ipn.in_pmin, linenum))
return NULL;
ipn.in_pmin = htons(ipn.in_pmin);
cpp++;
port1a = *cpp++;
if (!strcmp(*cpp, "-")) {
cpp++;
s = *cpp++;
}
if (s) {
if (!portnum(s, &ipn.in_pmax, linenum))
return NULL;
ipn.in_pmax = htons(ipn.in_pmax);
} else
if (s)
port1b = s;
else
ipn.in_pmax = ipn.in_pmin;
}
/*
* In the middle of the NAT rule syntax is -> to indicate the
* direction of translation.
*/
if (!*cpp) {
fprintf(stderr, "%d: missing fields (->)\n", linenum);
return NULL;
@ -537,6 +386,8 @@ int linenum;
if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1)
return NULL;
} else {
if (!strcmp(*cpp, ipn.in_ifname))
*cpp = "0";
if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1)
return NULL;
}
@ -556,11 +407,18 @@ int linenum;
} else
ipn.in_pmin = 0;
} else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
if (!*cpp || strrchr(*cpp, '/') != NULL) {
if (*cpp && (strrchr(*cpp, '/') != NULL)) {
fprintf(stderr, "%d: No netmask supported in %s\n",
linenum, "destination host for redirect");
return NULL;
}
if (!*cpp) {
fprintf(stderr, "%d: Missing destination port %s\n",
linenum, "in redirect");
return NULL;
}
/* If it's a in_redir, expect target port */
if (strcasecmp(*cpp, "port")) {
@ -575,10 +433,8 @@ int linenum;
linenum);
return NULL;
}
if (!portnum(*cpp, &ipn.in_pnext, linenum))
return NULL;
ipn.in_pnext = htons(ipn.in_pnext);
cpp++;
port2a = *cpp++;
}
if (dnetm && *dnetm == '/')
*dnetm++ = '\0';
@ -601,25 +457,32 @@ int linenum;
ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */
proto = "tcp";
} else {
if (!strcasecmp(*cpp, "tcp"))
proto = *cpp++;
if (!strcasecmp(proto, "tcp"))
ipn.in_flags |= IPN_TCP;
else if (!strcasecmp(*cpp, "udp"))
else if (!strcasecmp(proto, "udp"))
ipn.in_flags |= IPN_UDP;
else if (!strcasecmp(*cpp, "tcp/udp"))
else if (!strcasecmp(proto, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "tcpudp"))
else if (!strcasecmp(proto, "tcpudp")) {
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "ip"))
proto = "tcp/udp";
} else if (!strcasecmp(proto, "ip"))
ipn.in_flags |= IPN_ANY;
else {
ipn.in_flags |= IPN_ANY;
if ((pr = getprotobyname(*cpp)))
if ((pr = getprotobyname(proto)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(*cpp);
else {
if (!isdigit(*proto)) {
fprintf(stderr,
"%d: Unknown protocol %s\n",
linenum, proto);
return NULL;
} else
ipn.in_p = atoi(proto);
}
}
proto = *cpp;
cpp++;
if (*cpp && !strcasecmp(*cpp, "round-robin")) {
cpp++;
@ -631,15 +494,51 @@ int linenum;
ipn.in_flags |= IPN_FRAG;
}
if (*cpp && !strcasecmp(*cpp, "age")) {
cpp++;
if (!*cpp) {
fprintf(stderr,
"%d: age with no parameters\n",
linenum);
return NULL;
}
ipn.in_age[0] = atoi(*cpp);
s = index(*cpp, '/');
if (s != NULL)
ipn.in_age[1] = atoi(s + 1);
else
ipn.in_age[1] = ipn.in_age[0];
cpp++;
}
if (*cpp) {
fprintf(stderr,
"%d: extra junk at the end of rdr: %s\n",
"%d: extra junk at the end of the line: %s\n",
linenum, *cpp);
return NULL;
}
}
}
if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
if (!portnum(port1a, &ipn.in_pmin, linenum))
return NULL;
ipn.in_pmin = htons(ipn.in_pmin);
if (port1b != NULL) {
if (!portnum(port1b, &ipn.in_pmax, linenum))
return NULL;
ipn.in_pmax = htons(ipn.in_pmax);
} else
ipn.in_pmax = ipn.in_pmin;
}
if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
if (!portnum(port2a, &ipn.in_pnext, linenum))
return NULL;
ipn.in_pnext = htons(ipn.in_pnext);
}
if (!(ipn.in_flags & IPN_SPLIT))
ipn.in_inip &= ipn.in_inmsk;
if ((ipn.in_flags & IPN_IPRANGE) == 0)
@ -665,6 +564,11 @@ int linenum;
}
if (!strcasecmp(*cpp, "proxy")) {
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr, "%d: cannot use proxy with bimap\n",
linenum);
return NULL;
}
cpp++;
if (!*cpp) {
fprintf(stderr,
@ -720,63 +624,85 @@ int linenum;
linenum);
return NULL;
}
return &ipn;
} else if (!strcasecmp(*cpp, "portmap")) {
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr, "%d: cannot use portmap with bimap\n",
linenum);
return NULL;
}
cpp++;
if (!*cpp) {
fprintf(stderr,
"%d: missing expression following portmap\n",
linenum);
return NULL;
}
if (!strcasecmp(*cpp, "tcp"))
ipn.in_flags |= IPN_TCP;
else if (!strcasecmp(*cpp, "udp"))
ipn.in_flags |= IPN_UDP;
else if (!strcasecmp(*cpp, "tcpudp"))
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
else {
fprintf(stderr,
"%d: expected protocol name - got \"%s\"\n",
linenum, *cpp);
return NULL;
}
proto = *cpp;
cpp++;
if (!*cpp) {
fprintf(stderr, "%d: no port range found\n", linenum);
return NULL;
}
if (!strcasecmp(*cpp, "auto")) {
ipn.in_flags |= IPN_AUTOPORTMAP;
ipn.in_pmin = htons(1024);
ipn.in_pmax = htons(65535);
nat_setgroupmap(&ipn);
cpp++;
} else {
if (!(t = strchr(*cpp, ':'))) {
fprintf(stderr,
"%d: no port range in \"%s\"\n",
linenum, *cpp);
return NULL;
}
*t++ = '\0';
if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
!portnum(t, &ipn.in_pmax, linenum))
return NULL;
ipn.in_pmin = htons(ipn.in_pmin);
ipn.in_pmax = htons(ipn.in_pmax);
cpp++;
}
}
if (strcasecmp(*cpp, "portmap")) {
fprintf(stderr,
"%d: expected \"portmap\" - got \"%s\"\n", linenum,
*cpp);
return NULL;
}
cpp++;
if (!*cpp) {
fprintf(stderr, "%d: missing expression following portmap\n",
linenum);
return NULL;
if (*cpp && !strcasecmp(*cpp, "age")) {
cpp++;
if (!*cpp) {
fprintf(stderr, "%d: age with no parameters\n",
linenum);
return NULL;
}
s = index(*cpp, '/');
if (s != NULL)
ipn.in_age[1] = atoi(s + 1);
else
ipn.in_age[1] = ipn.in_age[0];
cpp++;
}
if (!strcasecmp(*cpp, "tcp"))
ipn.in_flags |= IPN_TCP;
else if (!strcasecmp(*cpp, "udp"))
ipn.in_flags |= IPN_UDP;
else if (!strcasecmp(*cpp, "tcpudp"))
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
else {
fprintf(stderr,
"%d: expected protocol name - got \"%s\"\n",
if (*cpp) {
fprintf(stderr, "%d: extra junk at the end of the line: %s\n",
linenum, *cpp);
return NULL;
}
proto = *cpp;
cpp++;
if (!*cpp) {
fprintf(stderr, "%d: no port range found\n", linenum);
return NULL;
}
if (!strcasecmp(*cpp, "auto")) {
ipn.in_flags |= IPN_AUTOPORTMAP;
ipn.in_pmin = htons(1024);
ipn.in_pmax = htons(65535);
nat_setgroupmap(&ipn);
return &ipn;
}
if (!(t = strchr(*cpp, ':'))) {
fprintf(stderr, "%d: no port range in \"%s\"\n",
linenum, *cpp);
return NULL;
}
*t++ = '\0';
if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
!portnum(t, &ipn.in_pmax, linenum))
return NULL;
ipn.in_pmin = htons(ipn.in_pmin);
ipn.in_pmax = htons(ipn.in_pmax);
return &ipn;
}
@ -812,7 +738,7 @@ int opts;
linenum, line);
} else {
if ((opts & OPT_VERBOSE) && np)
printnat(np, opts, NULL);
printnat(np, opts);
if (!(opts & OPT_NODO)) {
if (!(opts & OPT_REMOVE)) {
if (ioctl(fd, SIOCADNAT, &np) == -1) {

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -25,7 +28,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: opt.c,v 2.2.2.1 2001/06/26 10:43:20 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: opt.c,v 2.2.2.2 2002/02/22 15:32:56 darrenr Exp $";
#endif
extern int opts;

View File

@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#ifdef __sgi
# include <sys/ptimers.h>
#endif
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
@ -44,9 +47,7 @@ static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 da
extern struct ipopt_names ionames[], secclass[];
extern int opts;
#ifdef USE_INET6
extern int use_inet6;
#endif
int addicmp __P((char ***, struct frentry *, int));
int extras __P((char ***, struct frentry *, int));
@ -57,6 +58,7 @@ void print_toif __P((char *, frdest_t *));
void optprint __P((u_short *, u_long, u_long));
int loglevel __P((char **, u_int *, int));
void printlog __P((frentry_t *));
void printifname __P((char *, char *, void *));
extern char *proto;
extern char flagset[];
@ -72,8 +74,8 @@ char *line;
int linenum;
{
static struct frentry fil;
char *cps[31], **cpp, *endptr, *s;
struct protoent *p = NULL;
char *cps[31], **cpp, *endptr;
int i, cnt = 1, j, ch;
u_int k;
@ -84,11 +86,7 @@ int linenum;
bzero((char *)&fil, sizeof(fil));
fil.fr_mip.fi_v = 0xf;
#ifdef USE_INET6
fil.fr_ip.fi_v = use_inet6 ? 6 : 4;
#else
fil.fr_ip.fi_v = 4;
#endif
fil.fr_loglevel = 0xffff;
/*
@ -106,10 +104,18 @@ int linenum;
}
cpp = cps;
/*
* The presence of an '@' followed by a number gives the position in
* the current rule list to insert this one.
*/
if (**cpp == '@')
fil.fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1;
/*
* Check the first keyword in the rule and any options that are
* expected to follow it.
*/
if (!strcasecmp("block", *cpp)) {
fil.fr_flags |= FR_BLOCK;
if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) &&
@ -149,6 +155,8 @@ int linenum;
fil.fr_flags |= FR_ACCOUNT;
} else if (!strcasecmp("pass", *cpp)) {
fil.fr_flags |= FR_PASS;
} else if (!strcasecmp("nomatch", *cpp)) {
fil.fr_flags |= FR_NOMATCH;
} else if (!strcasecmp("auth", *cpp)) {
fil.fr_flags |= FR_AUTH;
} else if (!strcasecmp("preauth", *cpp)) {
@ -194,6 +202,10 @@ int linenum;
return NULL;
}
/*
* Get the direction for filtering. Impose restrictions on direction
* if blocking with returning ICMP or an RST has been requested.
*/
if (!strcasecmp("in", *cpp))
fil.fr_flags |= FR_INQUE;
else if (!strcasecmp("out", *cpp)) {
@ -252,19 +264,39 @@ int linenum;
}
if (*cpp && !strcasecmp("quick", *cpp)) {
if (fil.fr_skip != 0) {
fprintf(stderr, "%d: cannot use skip with quick\n",
linenum);
return NULL;
}
cpp++;
fil.fr_flags |= FR_QUICK;
}
/*
* Parse rule options that are available if a rule is tied to an
* interface.
*/
*fil.fr_ifname = '\0';
*fil.fr_oifname = '\0';
if (*cpp && !strcasecmp(*cpp, "on")) {
if (!*++cpp) {
fprintf(stderr, "%d: interface name missing\n",
linenum);
return NULL;
}
(void)strncpy(fil.fr_ifname, *cpp, IFNAMSIZ-1);
fil.fr_ifname[IFNAMSIZ-1] = '\0';
s = index(*cpp, ',');
if (s != NULL) {
*s++ = '\0';
(void)strncpy(fil.fr_ifnames[1], s, IFNAMSIZ - 1);
fil.fr_ifnames[1][IFNAMSIZ - 1] = '\0';
} else
strcpy(fil.fr_ifnames[1], "*");
(void)strncpy(fil.fr_ifnames[0], *cpp, IFNAMSIZ - 1);
fil.fr_ifnames[0][IFNAMSIZ - 1] = '\0';
cpp++;
if (!*cpp) {
if ((fil.fr_flags & FR_RETMASK) == FR_RETRST) {
@ -299,6 +331,33 @@ int linenum;
cpp++;
}
}
/*
* Set the "other" interface name. Lets you specify both
* inbound and outbound interfaces for state rules. Do not
* prevent both interfaces from being the same.
*/
strcpy(fil.fr_ifnames[3], "*");
if ((*cpp != NULL) && (*(cpp + 1) != NULL) &&
((((fil.fr_flags & FR_INQUE) != 0) &&
(strcasecmp(*cpp, "out-via") == 0)) ||
(((fil.fr_flags & FR_OUTQUE) != 0) &&
(strcasecmp(*cpp, "in-via") == 0)))) {
cpp++;
s = index(*cpp, ',');
if (s != NULL) {
*s++ = '\0';
(void)strncpy(fil.fr_ifnames[3], s,
IFNAMSIZ - 1);
fil.fr_ifnames[3][IFNAMSIZ - 1] = '\0';
}
(void)strncpy(fil.fr_ifnames[2], *cpp, IFNAMSIZ - 1);
fil.fr_ifnames[2][IFNAMSIZ - 1] = '\0';
cpp++;
} else
strcpy(fil.fr_ifnames[2], "*");
}
if (*cpp && !strcasecmp(*cpp, "tos")) {
if (!*++cpp) {
@ -340,6 +399,10 @@ int linenum;
if (!strcasecmp(proto, "tcp/udp")) {
fil.fr_ip.fi_fl |= FI_TCPUDP;
fil.fr_mip.fi_fl |= FI_TCPUDP;
} else if (use_inet6 && !strcasecmp(proto, "icmp")) {
fprintf(stderr,
"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n",
linenum);
} else {
if (!(p = getprotobyname(proto)) && !isdigit(*proto)) {
fprintf(stderr,
@ -411,6 +474,15 @@ int linenum;
return NULL;
}
if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
(fil.fr_proto != IPPROTO_UDP) &&
!(fil.fr_ip.fi_fl & FI_TCPUDP)) {
fprintf(stderr,
"%d: cannot use port and neither tcp or udp\n",
linenum);
return NULL;
}
fil.fr_scmp = ch;
if (!*cpp) {
fprintf(stderr, "%d: missing to fields\n", linenum);
@ -447,6 +519,15 @@ int linenum;
&fil.fr_dtop, linenum)) {
return NULL;
}
if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
(fil.fr_proto != IPPROTO_UDP) &&
!(fil.fr_ip.fi_fl & FI_TCPUDP)) {
fprintf(stderr,
"%d: cannot use port and neither tcp or udp\n",
linenum);
return NULL;
}
fil.fr_dcmp = ch;
}
@ -489,7 +570,8 @@ int linenum;
* icmp types for use with the icmp protocol
*/
if (*cpp && !strcasecmp(*cpp, "icmp-type")) {
if (fil.fr_proto != IPPROTO_ICMP) {
if (fil.fr_proto != IPPROTO_ICMP &&
fil.fr_proto != IPPROTO_ICMPV6) {
fprintf(stderr,
"%d: icmp with wrong protocol (%d)\n",
linenum, fil.fr_proto);
@ -508,10 +590,28 @@ int linenum;
if (addkeep(&cpp, &fil, linenum))
return NULL;
/*
* This is here to enforce the old interface binding behaviour.
* That is, "on X" is equivalent to "<dir> on X <!dir>-via -,X"
*/
if (fil.fr_flags & FR_KEEPSTATE) {
if (*fil.fr_ifnames[0] && !*fil.fr_ifnames[3]) {
bcopy(fil.fr_ifnames[0], fil.fr_ifnames[3],
sizeof(fil.fr_ifnames[3]));
strncpy(fil.fr_ifnames[2], "*",
sizeof(fil.fr_ifnames[3]));
}
}
/*
* head of a new group ?
*/
if (*cpp && !strcasecmp(*cpp, "head")) {
if (fil.fr_skip != 0) {
fprintf(stderr, "%d: cannot use skip with head\n",
linenum);
return NULL;
}
if (!*++cpp) {
fprintf(stderr, "%d: head without group #\n", linenum);
return NULL;
@ -658,6 +758,15 @@ frdest_t *fdp;
{
printf("%s %s%s", tag, fdp->fd_ifname,
(fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)");
#ifdef USE_INET6
if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) {
char ipv6addr[80];
inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr,
sizeof(fdp->fd_ip6));
printf(":%s", ipv6addr);
} else
#endif
if (fdp->fd_ip.s_addr)
printf(":%s", inet_ntoa(fdp->fd_ip));
putchar(' ');
@ -685,9 +794,9 @@ int linenum;
return -1;
while (**cp && (!strncasecmp(**cp, "ipopt", 5) ||
!strncasecmp(**cp, "not", 3) || !strncasecmp(**cp, "opt", 3) ||
!strncasecmp(**cp, "frag", 4) || !strncasecmp(**cp, "no", 2) ||
!strncasecmp(**cp, "short", 5))) {
!strcasecmp(**cp, "not") || !strncasecmp(**cp, "opt", 3) ||
!strncasecmp(**cp, "frag", 4) || !strcasecmp(**cp, "no") ||
!strcasecmp(**cp, "short"))) {
if (***cp == 'n' || ***cp == 'N') {
notopt = 1;
(*cp)++;
@ -899,10 +1008,10 @@ char *icmptypes[] = {
/*
* set the icmp field to the correct type if "icmp" word is found
*/
int addicmp(cp, fp, linenum)
char ***cp;
struct frentry *fp;
int linenum;
int addicmp(cp, fp, linenum)
char ***cp;
struct frentry *fp;
int linenum;
{
char **t;
int i;
@ -910,8 +1019,7 @@ int linenum;
(*cp)++;
if (!**cp)
return -1;
if (!fp->fr_proto) /* to catch lusers */
fp->fr_proto = IPPROTO_ICMP;
if (isdigit(***cp)) {
if (!ratoi(**cp, &i, 0, 255)) {
fprintf(stderr,
@ -919,6 +1027,10 @@ int linenum;
linenum, **cp);
return -1;
}
} else if (fp->fr_proto == IPPROTO_ICMPV6) {
fprintf(stderr, "%d: Unknown ICMPv6 type (%s) specified, %s",
linenum, **cp, "(use numeric value instead\n");
return -1;
} else {
for (t = icmptypes, i = 0; ; t++, i++) {
if (!*t)
@ -973,10 +1085,10 @@ int linenum;
#define MAX_ICMPCODE 15
char *icmpcodes[] = {
"net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail",
"net-unk", "host-unk", "isolate", "net-prohib", "host-prohib",
"net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff",
NULL };
"net-unr", "host-unr", "proto-unr", "port-unr", "needfrag",
"srcfail", "net-unk", "host-unk", "isolate", "net-prohib",
"host-prohib", "net-tos", "host-tos", "filter-prohib", "host-preced",
"preced-cutoff", NULL };
/*
* Return the number for the associated ICMP unreachable code.
*/
@ -1006,47 +1118,73 @@ char *str;
/*
* set the icmp field to the correct type if "icmp" word is found
*/
int addkeep(cp, fp, linenum)
char ***cp;
struct frentry *fp;
int linenum;
int addkeep(cp, fp, linenum)
char ***cp;
struct frentry *fp;
int linenum;
{
if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP &&
#ifdef USE_INET6
fp->fr_proto != IPPROTO_ICMPV6 &&
#endif
fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) {
fprintf(stderr, "%d: Can only use keep with UDP/ICMP/TCP\n",
char *s;
(*cp)++;
if (!**cp) {
fprintf(stderr, "%d: Missing keyword after keep\n",
linenum);
return -1;
}
(*cp)++;
if (!**cp) {
fprintf(stderr, "%d: Missing state/frag after keep\n",
linenum);
return -1;
}
if (strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
if (strcasecmp(**cp, "state") == 0)
fp->fr_flags |= FR_KEEPSTATE;
else if (strncasecmp(**cp, "frag", 4) == 0)
fp->fr_flags |= FR_KEEPFRAG;
else if (strcasecmp(**cp, "state-age") == 0) {
if (fp->fr_ip.fi_p == IPPROTO_TCP) {
fprintf(stderr, "%d: cannot use state-age with tcp\n",
linenum);
return -1;
}
if ((fp->fr_flags & FR_KEEPSTATE) == 0) {
fprintf(stderr, "%d: state-age with no 'keep state'\n",
linenum);
return -1;
}
(*cp)++;
if (!**cp) {
fprintf(stderr, "%d: state-age with no arg\n",
linenum);
return -1;
}
fp->fr_age[0] = atoi(**cp);
s = index(**cp, '/');
if (s != NULL) {
s++;
fp->fr_age[1] = atoi(s);
} else
fp->fr_age[1] = fp->fr_age[0];
} else {
fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n",
linenum, **cp);
return -1;
}
if (***cp == 's' || ***cp == 'S')
fp->fr_flags |= FR_KEEPSTATE;
else if (***cp == 'f' || ***cp == 'F')
fp->fr_flags |= FR_KEEPFRAG;
(*cp)++;
return 0;
}
void printifname(format, name, ifp)
char *format, *name;
void *ifp;
{
printf("%s%s", format, name);
if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*"))
printf("(!)");
}
/*
* print the filter structure in a useful way
*/
void printfr(fp)
struct frentry *fp;
void printfr(fp)
struct frentry *fp;
{
struct protoent *p;
u_short sec[2];
@ -1056,6 +1194,8 @@ struct frentry *fp;
if (fp->fr_flags & FR_PASS)
printf("pass");
if (fp->fr_flags & FR_NOMATCH)
printf("nomatch");
else if (fp->fr_flags & FR_BLOCK) {
printf("block");
if (fp->fr_flags & FR_RETICMP) {
@ -1098,8 +1238,11 @@ struct frentry *fp;
printf("quick ");
if (*fp->fr_ifname) {
printf("on %s%s ", fp->fr_ifname,
(fp->fr_ifa || (long)fp->fr_ifa == -1) ? "" : "(!)");
printifname("on ", fp->fr_ifname, fp->fr_ifa);
if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
putchar(' ');
if (*fp->fr_dif.fd_ifname)
print_toif("dup-to", &fp->fr_dif);
if (*fp->fr_tif.fd_ifname)
@ -1107,7 +1250,26 @@ struct frentry *fp;
if (fp->fr_flags & FR_FASTROUTE)
printf("fastroute ");
if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
(*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
if (fp->fr_flags & FR_OUTQUE)
printf("in-via ");
else
printf("out-via ");
if (*fp->fr_ifnames[2]) {
printifname("", fp->fr_ifnames[2],
fp->fr_ifas[2]);
putchar(',');
}
if (*fp->fr_ifnames[3])
printifname("", fp->fr_ifnames[3],
fp->fr_ifas[3]);
putchar(' ');
}
}
if (fp->fr_mip.fi_tos)
printf("tos %#x ", fp->fr_tos);
if (fp->fr_mip.fi_ttl)
@ -1161,7 +1323,7 @@ struct frentry *fp;
printf(" frag");
}
}
if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) {
if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm != 0) {
int type = fp->fr_icmp, code;
type = ntohs(fp->fr_icmp);
@ -1175,6 +1337,16 @@ struct frentry *fp;
if (ntohs(fp->fr_icmpm) & 0xff)
printf(" code %d", code);
}
if (fp->fr_proto == IPPROTO_ICMPV6 && fp->fr_icmpm != 0) {
int type = fp->fr_icmp, code;
type = ntohs(fp->fr_icmp);
code = type & 0xff;
type /= 256;
printf(" icmp-type %d", type);
if (ntohs(fp->fr_icmpm) & 0xff)
printf(" code %d", code);
}
if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
printf(" flags ");
if (fp->fr_tcpf & ~TCPF_ALL)
@ -1198,6 +1370,8 @@ struct frentry *fp;
printf(" keep state");
if (fp->fr_flags & FR_KEEPFRAG)
printf(" keep frags");
if (fp->fr_age[0] != 0 || fp->fr_age[1]!= 0)
printf(" state-age %u/%u", fp->fr_age[0], fp->fr_age[1]);
if (fp->fr_grhead)
printf(" head %d", fp->fr_grhead);
if (fp->fr_group)

View File

@ -1,10 +1,22 @@
CC=gcc
all:
@echo "Please do one of the following:"
@echo "make bsd"
@echo "make bsdi"
@echo "make freebsd"
@echo "make freebsd22"
@echo "make netbsd"
@echo "make openbsd"
@echo "make sunos4"
@echo "make sunos5"
sunos5:
$(CC) -I.. userauth.c -o userauth -lsocket -lnsl
$(CC) -I.. proxy.c -o proxy -lsocket -lnsl
$(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \
-I.. userauth.c -o userauth -lsocket -lnsl
$(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \
-I.. proxy.c -o proxy -lsocket -lnsl
freebsd freebsd22 netbsd bsd bsdi sunos4:
freebsd freebsd22 netbsd bsd bsdi sunos4 openbsd:
$(CC) -I.. userauth.c -o userauth
$(CC) -I.. proxy.c -o proxy

View File

@ -41,6 +41,8 @@
#include <ctype.h>
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
@ -81,19 +83,25 @@ char *argv[];
bzero((char *)&natlook, sizeof(natlook));
natlook.nl_outip = sin.sin_addr;
natlook.nl_inip = sloc.sin_addr;
natlook.nl_flags = IPN_TCP;
natlook.nl_outport = sin.sin_port;
natlook.nl_inport = sloc.sin_port;
natlook.nl_flags = IPN_TCPUDP;
natlook.nl_outport = ntohs(sin.sin_port);
natlook.nl_inport = ntohs(sloc.sin_port);
/*
* Open the NAT device and lookup the mapping pair.
*/
fd = open(IPL_NAT, O_RDONLY);
if (ioctl(fd, SIOCGNATL, &natlookp) == -1) {
perror("ioctl");
perror("ioctl(SIOCGNATL)");
exit(-1);
}
close(fd);
#define DO_NAT_OUT
#ifdef DO_NAT_OUT
if (argc > 1)
do_nat_out(0, 1, fd, &natlook, argv[1]);
#else
/*
* Log it
*/
@ -109,4 +117,181 @@ char *argv[];
if (write(1, buffer, n) != n)
break;
close(0);
#endif
}
#ifdef DO_NAT_OUT
do_nat_out(in, out, fd, nlp, extif)
int fd;
natlookup_t *nlp;
char *extif;
{
nat_save_t ns, *nsp = &ns;
struct sockaddr_in usin;
u_32_t sum1, sum2, sumd;
int onoff, ofd, slen;
ipnat_t *ipn;
nat_t *nat;
bzero((char *)&ns, sizeof(ns));
nat = &ns.ipn_nat;
nat->nat_p = IPPROTO_TCP;
nat->nat_dir = NAT_OUTBOUND;
if ((extif != NULL) && (*extif != '\0')) {
strncpy(nat->nat_ifname, extif, sizeof(nat->nat_ifname));
nat->nat_ifname[sizeof(nat->nat_ifname) - 1] = '\0';
}
ofd = socket(AF_INET, SOCK_DGRAM, 0);
bzero((char *)&usin, sizeof(usin));
usin.sin_family = AF_INET;
usin.sin_addr = nlp->nl_realip;
usin.sin_port = nlp->nl_realport;
(void) connect(ofd, (struct sockaddr *)&usin, sizeof(usin));
slen = sizeof(usin);
(void) getsockname(ofd, (struct sockaddr *)&usin, &slen);
close(ofd);
printf("local IP# to use: %s\n", inet_ntoa(usin.sin_addr));
if ((ofd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
perror("socket");
usin.sin_port = 0;
if (bind(ofd, (struct sockaddr *)&usin, sizeof(usin)))
perror("bind");
slen = sizeof(usin);
if (getsockname(ofd, (struct sockaddr *)&usin, &slen))
perror("getsockname");
printf("local port# to use: %d\n", ntohs(usin.sin_port));
nat->nat_inip = usin.sin_addr;
nat->nat_outip = nlp->nl_outip;
nat->nat_oip = nlp->nl_realip;
sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr)) + ntohs(usin.sin_port);
sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)) + ntohs(nlp->nl_outport);
CALC_SUMD(sum1, sum2, sumd);
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
nat->nat_sumd[1] = nat->nat_sumd[0];
sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr));
sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
CALC_SUMD(sum1, sum2, sumd);
nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
nat->nat_inport = usin.sin_port;
nat->nat_outport = nlp->nl_outport;
nat->nat_oport = nlp->nl_realport;
nat->nat_flags = IPN_TCPUDP;
onoff = 1;
if (ioctl(fd, SIOCSTLCK, &onoff) == 0) {
if (ioctl(fd, SIOCSTPUT, &nsp) != 0)
perror("SIOCSTPUT");
onoff = 0;
if (ioctl(fd, SIOCSTLCK, &onoff) != 0)
perror("SIOCSTLCK");
}
usin.sin_addr = nlp->nl_realip;
usin.sin_port = nlp->nl_realport;
printf("remote end for connection: %s,%d\n", inet_ntoa(usin.sin_addr),
ntohs(usin.sin_port));
fflush(stdout);
if (connect(ofd, (struct sockaddr *)&usin, sizeof(usin)))
perror("connect");
relay(in, out, ofd);
}
relay(in, out, net)
int in, out, net;
{
char netbuf[1024], outbuf[1024];
char *nwptr, *nrptr, *owptr, *orptr;
size_t nsz, osz;
fd_set rd, wr;
int i, n, maxfd;
n = 0;
maxfd = in;
if (out > maxfd)
maxfd = out;
if (net > maxfd)
maxfd = net;
nrptr = netbuf;
nwptr = netbuf;
nsz = sizeof(netbuf);
orptr = outbuf;
owptr = outbuf;
osz = sizeof(outbuf);
while (n >= 0) {
FD_ZERO(&rd);
FD_ZERO(&wr);
if (nrptr - netbuf < sizeof(netbuf))
FD_SET(in, &rd);
if (orptr - outbuf < sizeof(outbuf))
FD_SET(net, &rd);
if (nsz < sizeof(netbuf))
FD_SET(net, &wr);
if (osz < sizeof(outbuf))
FD_SET(out, &wr);
n = select(maxfd + 1, &rd, &wr, NULL, NULL);
if ((n > 0) && FD_ISSET(in, &rd)) {
i = read(in, nrptr, sizeof(netbuf) - (nrptr - netbuf));
if (i <= 0)
break;
nsz -= i;
nrptr += i;
n--;
}
if ((n > 0) && FD_ISSET(net, &rd)) {
i = read(net, orptr, sizeof(outbuf) - (orptr - outbuf));
if (i <= 0)
break;
osz -= i;
orptr += i;
n--;
}
if ((n > 0) && FD_ISSET(out, &wr)) {
i = write(out, owptr, orptr - owptr);
if (i <= 0)
break;
osz += i;
if (osz == sizeof(outbuf) || owptr == orptr) {
orptr = outbuf;
owptr = outbuf;
} else
owptr += i;
n--;
}
if ((n > 0) && FD_ISSET(net, &wr)) {
i = write(net, nwptr, nrptr - nwptr);
if (i <= 0)
break;
nsz += i;
if (nsz == sizeof(netbuf) || nwptr == nrptr) {
nrptr = netbuf;
nwptr = netbuf;
} else
nwptr += i;
}
}
close(net);
close(out);
close(in);
}
#endif

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1993-2001 by Darren Reed.
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/
#pragma ident "@(#)$Id: solaris.c,v 2.15.2.20 2001/07/18 14:58:28 darrenr Exp $"
#pragma ident "@(#)$Id: solaris.c,v 2.15.2.29 2002/01/15 14:36:54 darrenr Exp $"
#include <sys/systm.h>
#include <sys/types.h>
@ -93,10 +93,16 @@ extern void ipfr_slowtimer __P((void));
int ipfr_timer_id;
static int synctimeoutid = 0;
#endif
int ipf_debug = 0;
int ipf_debug_verbose = 0;
/* #undef IPFDEBUG 1 */
/* #undef IPFDEBUG_VERBOSE 1 */
#ifdef IPFDEBUG
void printire __P((ire_t *));
#endif
#define isdigit(x) ((x) >= '0' && (x) <= '9')
static int fr_precheck __P((mblk_t **, queue_t *, qif_t *, int));
@ -150,7 +156,7 @@ static size_t hdrsizes[57][2] = {
{ IFT_X25DDN, 0 },
{ IFT_X25, 0 },
{ IFT_ETHER, 14 },
{ IFT_ISO88023, 0 },
{ IFT_ISO88023, 14 },
{ IFT_ISO88024, 0 },
{ IFT_ISO88025, 0 },
{ IFT_ISO88026, 0 },
@ -210,7 +216,8 @@ int _init()
ipfinst = mod_install(&modlink1);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
#endif
return ipfinst;
}
@ -222,7 +229,8 @@ int _fini(void)
ipfinst = mod_remove(&modlink1);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
#endif
return ipfinst;
}
@ -235,7 +243,9 @@ struct modinfo *modinfop;
ipfinst = mod_info(&modlink1, modinfop);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x", modinfop, ipfinst);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x",
modinfop, ipfinst);
#endif
if (fr_running > 0)
ipfsync();
@ -249,7 +259,8 @@ dev_info_t *dip;
if (fr_running < 0)
return DDI_PROBE_FAILURE;
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_probe(%x)", dip);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: ipf_probe(%x)", dip);
#endif
return DDI_PROBE_SUCCESS;
}
@ -259,7 +270,8 @@ static int ipf_identify(dip)
dev_info_t *dip;
{
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip);
#endif
if (strcmp(ddi_get_name(dip), "ipf") == 0)
return (DDI_IDENTIFIED);
@ -299,7 +311,8 @@ ddi_attach_cmd_t cmd;
#ifdef IPFDEBUG
int instance;
cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd);
#endif
switch (cmd) {
case DDI_ATTACH:
@ -308,6 +321,7 @@ ddi_attach_cmd_t cmd;
#ifdef IPFDEBUG
instance = ddi_get_instance(dip);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: attach ipf instance %d", instance);
#endif
if (ddi_create_minor_node(dip, "ipf", S_IFCHR, IPL_LOGIPF,
@ -344,7 +358,8 @@ ddi_attach_cmd_t cmd;
solattach();
solipdrvattach();
RWLOCK_EXIT(&ipf_solaris);
cmn_err(CE_CONT, "%s, attaching complete.\n", ipfilter_version);
cmn_err(CE_CONT, "%s, attaching complete.\n",
ipfilter_version);
sync();
if (fr_running == 0)
fr_running = 1;
@ -383,7 +398,8 @@ ddi_detach_cmd_t cmd;
int i;
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd);
#endif
switch (cmd) {
case DDI_DETACH:
@ -459,7 +475,9 @@ void *arg, **result;
return DDI_FAILURE;
error = DDI_FAILURE;
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)", dip, infocmd, arg);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)",
dip, infocmd, arg);
#endif
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
@ -784,15 +802,7 @@ int out;
#endif
) {
m->b_rptr -= off;
if (!synced) {
synced = 1;
RWLOCK_EXIT(&ipfs_mutex);
ipfsync();
READ_ENTER(&ipfs_mutex);
goto tryagain;
}
frstats[out].fr_notip++;
return (fr_flags & FF_BLOCKNONIP) ? -1 : 0;
return -2;
}
#ifndef sparc
@ -969,27 +979,40 @@ mblk_t *mb;
int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0;
qif_t qf, *qif;
#ifdef IPFDEBUG_VERBOSE
if (ipf_debug_verbose)
cmn_err(CE_CONT,
"fr_qin(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n",
q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref,
msgdsize(mb));
#endif
/*
* IPFilter is still in the packet path but not enabled. Drop whatever
* it is that has come through.
*/
if (fr_running <= 0) {
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
return 0;
}
type = MTYPE(mb);
/*
* If a mblk has more than one reference, make a copy, filter that and
* free a reference to the original.
*/
if (mb->b_datap->db_ref > 1) {
mblk_t *m1;
m1 = copymsg(mb);
if (!m1) {
frstats[0].fr_drop++;
mb->b_next = NULL;
mb->b_prev = NULL;
freemsg(mb);
return 0;
}
m1->b_next = mb->b_next;
mb->b_next = NULL;
m1->b_prev = mb->b_prev;
mb->b_prev = NULL;
freemsg(mb);
mb = m1;
@ -999,10 +1022,9 @@ mblk_t *mb;
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
READ_ENTER(&ipfs_mutex);
@ -1030,7 +1052,7 @@ mblk_t *mb;
}
cmn_err(CE_WARN,
"!IP Filter: dropped: fr_qin(%x,%x): type %x qif %x",
q, mb, MTYPE(mb), qif);
q, mb, type, qif);
cmn_err(CE_CONT,
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
@ -1044,40 +1066,52 @@ mblk_t *mb;
#endif
);
frstats[0].fr_drop++;
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
qif->qf_incnt++;
pnext = qif->qf_rqinfo->qi_putp;
type = MTYPE(mb);
if (type == M_IOCACK)
fr_qif_update(qif, mb);
else {
bcopy((char *)qif, (char *)&qf, sizeof(qf));
if (datamsg(type) || (type == M_BREAK))
err = fr_precheck(&mb, q, &qf, 0);
}
bcopy((char *)qif, (char *)&qf, sizeof(qf));
if (datamsg(type) || (type == M_BREAK))
err = fr_precheck(&mb, q, &qf, 0);
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
if ((err == 0) && (mb != NULL)) {
if (pnext)
if (pnext) {
RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
}
cmn_err(CE_WARN,
"!IP Filter: inp NULL: qif %x %s q %x info %x",
&qf, qf.qf_name, q, q->q_qinfo);
qif, qf.qf_name, q, q->q_qinfo);
}
if (err == -2) {
if (synced == 0) {
ipfsync();
synced = 1;
goto again;
}
frstats[0].fr_notip++;
if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) {
RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
}
}
if (mb) {
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
}
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
@ -1089,13 +1123,22 @@ mblk_t *mb;
int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0;
qif_t qf, *qif;
#ifdef IPFDEBUG_VERBOSE
if (ipf_debug_verbose)
cmn_err(CE_CONT,
"fr_qout(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n",
q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref,
msgdsize(mb));
#endif
if (fr_running <= 0) {
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
return 0;
}
type = MTYPE(mb);
#if SOLARIS2 >= 6
if ((!dohwcksum || mb->b_ick_flag != ICK_VALID) &&
(mb->b_datap->db_ref > 1))
@ -1108,14 +1151,10 @@ mblk_t *mb;
m1 = copymsg(mb);
if (!m1) {
frstats[1].fr_drop++;
mb->b_next = NULL;
mb->b_prev = NULL;
freemsg(mb);
return 0;
}
m1->b_next = mb->b_next;
mb->b_next = NULL;
m1->b_prev = mb->b_prev;
mb->b_prev = NULL;
freemsg(mb);
mb = m1;
@ -1125,10 +1164,9 @@ mblk_t *mb;
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
READ_ENTER(&ipfs_mutex);
@ -1156,7 +1194,7 @@ mblk_t *mb;
}
cmn_err(CE_WARN,
"!IP Filter: dropped: fr_qout(%x,%x): type %x: qif %x",
q, mb, MTYPE(mb), qif);
q, mb, type, qif);
cmn_err(CE_CONT,
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
@ -1180,40 +1218,51 @@ mblk_t *mb;
q->q_nbsrv->q_qinfo, q->q_nbsrv->q_next,
q->q_nbsrv->q_ptr);
frstats[1].fr_drop++;
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
qif->qf_outcnt++;
pnext = qif->qf_wqinfo->qi_putp;
type = MTYPE(mb);
if (type == M_IOCACK)
fr_qif_update(qif, mb);
else {
bcopy((char *)qif, (char *)&qf, sizeof(qf));
if (datamsg(type) || (type == M_BREAK))
err = fr_precheck(&mb, q, &qf, 1);
}
bcopy((char *)qif, (char *)&qf, sizeof(qf));
if (datamsg(type) || (type == M_BREAK))
err = fr_precheck(&mb, q, &qf, 1);
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
if ((err == 0) && (mb != NULL)) {
if (pnext)
if (pnext) {
RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
}
cmn_err(CE_WARN,
"!IP Filter: outp NULL: qif %x %s q %x info %x",
&qf, qf.qf_name, q, q->q_qinfo);
qif, qf.qf_name, q, q->q_qinfo);
}
if (err == -2) {
if (synced == 0) {
ipfsync();
synced = 1;
goto again;
}
frstats[1].fr_notip++;
if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) {
RWLOCK_EXIT(&ipf_solaris);
return (*pnext)(q, mb);
}
}
if (mb) {
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
}
RWLOCK_EXIT(&ipf_solaris);
return 0;
}
@ -1241,7 +1290,6 @@ mblk_t *mb;
if (fr_running <= 0) {
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
return 0;
}
@ -1253,7 +1301,6 @@ mblk_t *mb;
if (fr_running <= 0) {
RWLOCK_EXIT(&ipf_solaris);
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
return 0;
}
@ -1269,8 +1316,10 @@ mblk_t *mb;
case SIOCSIFADDR:
case SIOCSIFFLAGS:
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_ip_qin() M_IOCTL type=0x%x",
ioc->ioc_cmd);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: ipf_ip_qin() M_IOCTL type=0x%x",
ioc->ioc_cmd);
#endif
WRITE_ENTER(&ipfs_mutex);
if (synctimeoutid == 0) {
@ -1294,8 +1343,9 @@ extern struct streamtab ipinfo;
void solipdrvattach()
{
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: solipdrvattach() %d ipinfo=0x%lx",
ipdrvattcnt, &ipinfo);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: solipdrvattach() %d ipinfo=0x%lx",
ipdrvattcnt, &ipinfo);
#endif
if (++ipdrvattcnt == 1) {
@ -1309,8 +1359,9 @@ void solipdrvattach()
int solipdrvdetach()
{
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() %d ipinfo=0x%lx",
ipdrvattcnt, &ipinfo);
if (ipf_debug)
cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() %d ipinfo=0x%lx",
ipdrvattcnt, &ipinfo);
#endif
WRITE_ENTER(&ipfs_mutex);
@ -1362,7 +1413,8 @@ void solattach()
RWLOCK_EXIT(&ipfs_mutex);
continue;
}
#ifdef IPFDEBUG
#ifdef IPFDEBUGX
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: il %x ipt %x opt %x ipu %x opu %x i %x/%x",
il, in->q_ptr, out->q_ptr, in->q_qinfo->qi_putp,
@ -1384,7 +1436,8 @@ void solattach()
break;
}
if (!qf2) {
#ifdef IPFDEBUG
#ifdef IPFDEBUGX
if (ipf_debug)
cmn_err(CE_WARN,
"IP Filter: rq:%s put %x qi %x",
il->ill_name, in->q_qinfo->qi_putp,
@ -1404,7 +1457,8 @@ void solattach()
break;
}
if (!qf2) {
#ifdef IPFDEBUG
#ifdef IPFDEBUGX
if (ipf_debug)
cmn_err(CE_WARN,
"IP Filter: wq:%s put %x qi %x",
il->ill_name, out->q_qinfo->qi_putp,
@ -1447,6 +1501,15 @@ void solattach()
(hdrsizes[il->ill_type][0] == il->ill_type))
qif->qf_hl = hdrsizes[il->ill_type][1];
/* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */
if (il->ill_type == IFT_ETHER &&
il->ill_name[0] == 'c' && il->ill_name[1] == 'e' &&
isdigit(il->ill_name[2]) && il->ill_name_length >= 6) {
cmn_err(CE_NOTE, "VLAN HACK ENABLED");
qif->qf_hl += 4;
}
/* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */
if (qif->qf_hl == 0 && il->ill_type != IFT_OTHER)
cmn_err(CE_WARN,
"Unknown layer 2 header size for %s type %d",
@ -1524,10 +1587,10 @@ void solattach()
sizeof(struct qinit));
qif->qf_rqinit.qi_putp = fr_qin;
#ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: solattach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, &qif->qf_rqinit
);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: solattach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, &qif->qf_rqinit);
#endif
in->q_qinfo = &qif->qf_rqinit;
@ -1535,10 +1598,10 @@ void solattach()
sizeof(struct qinit));
qif->qf_wqinit.qi_putp = fr_qout;
#ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: solattach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, &qif->qf_wqinit
);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: solattach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, &qif->qf_wqinit);
#endif
out->q_qinfo = &qif->qf_wqinit;
@ -1638,19 +1701,19 @@ int ipfsync()
in = qif->qf_in;
if (in) {
# ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: ipfsync: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, qif->qf_rqinfo
);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: ipfsync: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, qif->qf_rqinfo);
# endif
in->q_qinfo = qif->qf_rqinfo;
}
if (out) {
# ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: ipfsync: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, qif->qf_wqinfo
);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: ipfsync: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, qif->qf_wqinfo);
# endif
out->q_qinfo = qif->qf_wqinfo;
}
@ -1719,9 +1782,10 @@ int soldetach()
);
#ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: soldetach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, qif->qf_rqinfo);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: soldetach: in queue(%lx)->q_qinfo FROM %lx TO %lx",
in, in->q_qinfo, qif->qf_rqinfo);
#endif
in->q_qinfo = qif->qf_rqinfo;
@ -1729,9 +1793,10 @@ int soldetach()
* and the write queue...
*/
#ifdef IPFDEBUG
cmn_err(CE_NOTE,
"IP Filter: soldetach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, qif->qf_wqinfo);
if (ipf_debug)
cmn_err(CE_NOTE,
"IP Filter: soldetach: out queue(%lx)->q_qinfo FROM %lx TO %lx",
out, out->q_qinfo, qif->qf_wqinfo);
#endif
out->q_qinfo = qif->qf_wqinfo;
}
@ -1746,6 +1811,8 @@ int soldetach()
void printire(ire)
ire_t *ire;
{
if (!ipf_debug)
return;
printf("ire: ll_hdr_mp %p rfq %p stq %p src_addr %x max_frag %d\n",
# if SOLARIS2 >= 8
NULL,
@ -1812,7 +1879,6 @@ frdest_t *fdp;
mp = (*mpp)->b_cont;
(*mpp)->b_cont = NULL;
(*mpp)->b_prev = NULL;
(*mpp)->b_next = NULL;
freemsg(*mpp);
*mpp = mp;
}
@ -1951,7 +2017,6 @@ frdest_t *fdp;
q = WR(ir->ire_rfq);
if (q) {
mb->b_prev = NULL;
mb->b_next = NULL;
mb->b_queue = q;
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
@ -1979,7 +2044,6 @@ frdest_t *fdp;
}
bad_fastroute:
mb->b_prev = NULL;
mb->b_next = NULL;
freemsg(mb);
ipl_frouteok[1]++;
*mpp = NULL;

View File

@ -9,19 +9,23 @@ BINDEST=/usr/local/bin
SBINDEST=/sbin
MANDIR=/usr/share/man
tests: first 0 ftests ptests ntests
tests: first 0 ftests ptests ntests nitests logtests
first:
-mkdir -p results
# Filtering tests
ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14
ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16
# Rule parsing tests
ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11
ntests: n1 n2 n3 n4 n5 n6 n7
nitests: ni1 ni2
logtests: l1
0:
@(cd ..; make ipftest; )
@ -31,13 +35,25 @@ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f14:
f12 f13:
@/bin/sh ./hextest $@
f15 f16:
@/bin/sh ./mtest $@
i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11:
@/bin/sh ./itest $@
n1 n2 n3 n4 n5 n6 n7:
@/bin/sh ./nattest $@
ni1 ni2:
@/bin/sh ./natipftest $@
l1:
@/bin/sh ./logtest $@
clean:
/bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f13 f12 f14 results/*
/bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f13 f12 f14 f15 f16
/bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11
/bin/rm -f n1 n2 n3 n4 n5 n6 n7
/bin/rm -f ni1 ni2
/bin/rm -f l1
/bin/rm -f results/*

View File

@ -91,6 +91,7 @@ IPv6:
BSD:
* "to <if>" and "to <if>:<ip>" are not supported, but "fastroute" is.
fixed.
Solaris:
* "to <if>:<ip>" is not supported, but "fastroute" is and "to <if>" are.