This commit was generated by cvs2svn to compensate for changes in r60841,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Darren Reed 2000-05-24 02:14:22 +00:00
commit 5bca461d6f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=60842
87 changed files with 9943 additions and 3251 deletions

View File

@ -40,16 +40,18 @@ INSTALL=install
MODOBJS=ip_fil.o fil_k.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \
ip_auth.o ip_log.o
DFLAGS=$(IPFLKM) $(IPFLOG) $(DEF) $(DLKM)
IPF=ipf.o parse.o opt.o facpri.o
IPT=ipt.o parse.o fil.o ipft_sn.o ipft_ef.o ipft_td.o ipft_pc.o opt.o \
ipft_tx.o misc.o ip_frag_u.o ip_state_u.o ip_nat_u.o ip_proxy_u.o \
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
FILS=fils.o parse.o kmem.o opt.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
build all: ipf ipfstat ipftest ipmon ipnat $(LKM)
build all: ipf ipfs ipfstat ipftest ipmon ipnat $(LKM)
ipfstat: $(FILS)
$(CC) $(DEBUG) $(CFLAGS) $(FILS) -o $@ $(LIBS)
$(CC) $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) $(FILS) \
-o $@ $(LIBS) $(STATETOP_LIB)
ipf: $(IPF)
$(CC) $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
@ -61,20 +63,29 @@ ipftest: $(IPT)
/bin/rm -f $(TOP)/ipftest
ln -s `pwd`/ipftest $(TOP)
ipnat: ipnat.o kmem.o natparse.o
$(CC) $(DEBUG) $(CFLAGS) ipnat.o kmem.o natparse.o -o $@ $(LIBS)
ipnat: $(IPNAT)
$(CC) $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS)
ipfs: ipfs.o
$(CC) $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
tests:
(cd test; make )
fils.o: $(TOP)/fils.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_frag.h \
$(TOP)/ip_compat.h $(TOP)/ip_state.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/fils.c -o $@
$(TOP)/ip_compat.h $(TOP)/ip_state.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
-c $(TOP)/fils.c -o $@
ipfs.o: $(TOP)/ipfs.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_state.h \
$(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipfs.c -o $@
fil.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/fil.c -o $@
fil_k.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h
fil_k.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h \
$(TOP)/ipl.h
$(CC) $(DEBUG) $(CFLAGS) $(POLICY) $(DFLAGS) -c $(TOP)/fil.c -o $@
ipf.o: $(TOP)/ipf.c $(TOP)/ip_fil.h $(TOP)/ipf.h
@ -92,7 +103,8 @@ opt.o: $(TOP)/opt.c $(TOP)/ip_fil.h $(TOP)/ipf.h
ipnat.o: $(TOP)/ipnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipnat.c -o $@
natparse.o: $(TOP)/natparse.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h
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 $@
ipft_sn.o: $(TOP)/ipft_sn.c $(TOP)/ipt.h $(TOP)/ipf.h $(TOP)/ip_fil.h \
@ -126,7 +138,7 @@ ip_frag_u.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h \
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_frag.c -o $@
ip_state_u.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
$(TOP)/ip_fil.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_state.c -o $@
ip_auth_u.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
@ -140,6 +152,12 @@ if_ipl.o: $(MODOBJS)
ld -r $(MODOBJS) -o $(LKM)
${RM} -f if_ipl
ipf.ko ipl.ko: $(MODOBJS)
gensetdefs $(MODOBJS)
$(CC) $(DEBUG) $(CFLAGS) -c setdef0.c
$(CC) $(DEBUG) $(CFLAGS) -c setdef1.c
ld -Bshareable -o $(LKM) setdef0.o $(MODOBJS) setdef1.o
ip_nat.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_nat.c -o $@
@ -147,7 +165,7 @@ ip_frag.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_frag.c -o $@
ip_state.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
$(TOP)/ip_fil.h $(TOP)/ip_nat.h
$(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_state.c -o $@
ip_proxy.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
@ -181,6 +199,9 @@ kmem.o: $(TOP)/kmem.c
parse.o: $(TOP)/parse.c $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/parse.c -o $@
common.o: $(TOP)/common.c $(TOP)/ip_fil.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/common.c -o $@
facpri.o: $(TOP)/facpri.c $(TOP)/facpri.h
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/facpri.c -o $@
@ -189,7 +210,9 @@ ipmon: $(TOP)/ipmon.c
clean:
${RM} -f *.core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipnat \
vnode_if.h $(LKM) ioconf.h
vnode_if.h $(LKM) ioconf.h *.ko setdef1.c setdef0.c setdefs.h \
y.tab.? lex.yy.c ipfs
${MAKE} -f Makefile.ipsend ${MFLAGS} clean
-(for i in *; do \
if [ -d $${i} -a -f $${i}/Makefile ] ; then \
@ -205,9 +228,10 @@ install:
-if [ -d /lkm -a -f if_ipl.o ] ; then \
cp if_ipl.o /lkm; \
fi
-$(INSTALL) -cs -g wheel -m 755 -o root ipfstat ipf ipnat $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipmon ipftest $(BINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipftest ipftest $(BINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipf ipftest $(SBINDEST)
-$(INSTALL) -cs -g wheel -m 755 -o root ipnat ipftest $(SBINDEST)
-$(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)
(cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP))

View File

@ -1,3 +1,11 @@
#
# $Id: Makefile.ipsend,v 2.2 2000/02/28 08:27:51 darrenr Exp $
#
BINDEST=/usr/sbin
SBINDEST=/sbin
MANDIR=/usr/share/man
OBJS=ipsend.o ip.o ipsopt.o y.tab.o lex.yy.o
IPFTO=ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o
ROBJS=ipresend.o ip.o resend.o $(IPFTO) opt.o

View File

@ -1,4 +1,4 @@
To build a kernel with the IP filter, follow these steps:
To build a kernel with the IP filter, follow these seven steps:
1. do "make freebsd3"

View File

@ -1,5 +1,6 @@
#!/bin/csh -f
#
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"

View File

@ -0,0 +1,61 @@
*** ip6_input.c.orig Sun Feb 13 14:32:01 2000
--- ip6_input.c Wed Apr 26 22:31:34 2000
***************
*** 121,126 ****
--- 121,127 ----
extern struct domain inet6domain;
extern struct ip6protosw inet6sw[];
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
u_char ip6_protox[IPPROTO_MAX];
static int ip6qmaxlen = IFQ_MAXLEN;
***************
*** 302,307 ****
--- 303,317 ----
ip6stat.ip6s_badvers++;
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
goto bad;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif,
+ 0, &m1) || !m1)
+ return;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
*** ip6_output.c.orig Fri Mar 10 01:57:16 2000
--- ip6_output.c Wed Apr 26 22:34:34 2000
***************
*** 108,113 ****
--- 108,115 ----
#include <netinet6/ip6_fw.h>
#endif
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+
static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options");
struct ip6_exthdrs {
***************
*** 754,759 ****
--- 756,770 ----
ip6->ip6_src.s6_addr16[1] = 0;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) ||
+ !m1)
+ goto done;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
#ifdef IPV6FIREWALL

View File

@ -0,0 +1,50 @@
#!/bin/csh -f
#
set dir=`pwd`
set karch=`uname -m`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c ipl.h \
ip_compat.h ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
ln -s /usr/include/osreldate.h /sys/sys/osreldate.h
echo ""
echo "Patching ip6_input.c and ip6_output.c"
cat FreeBSD-4.0/ipv6-patch | (cd /sys/netinet6; patch)
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
set newconfig=$<
if ( "$newconfig" != "" ) then
set config="$confdir/$newconfig"
else
set newconfig=$config
endif
echo "Rewriting $newconfig..."
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak
endif
if ( -d $archdir/../compile/$newconfig ) then
set bak=".bak"
set dot=0
while ( -d $archdir/../compile/${newconfig}.${bak} )
set bak=".bak.$dot"
set dot=`expr 1 + $dot`
end
mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak}
endif
awk '{print $0;if($2=="INET"){print"options IPFILTER\noptions IPFILTER_LOG"}}'\
$confdir/$newconfig.bak > $confdir/$newconfig
echo "You will now need to run config on $newconfig and build a new kernel."
exit 0

View File

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

View File

@ -20,6 +20,159 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.4.4 23/05/2000 - Released
don't add TCP state if it is an RST packet and (attempt) to send out
RST/ICMP packets in a manner that bypasses IP Filter.
add patch to work with 4.0_STABLE delayed checksums
3.4.3 20/05/2000 - Released
fix ipmon -F
don't truncate IPv6 packets on Solaris
fix keep state for ICMP ECHO
add some NAT stats and use def_nat_age rather than DEF_NAT_AGE
don't make ftp proxy drop packets
use MCLISREFERENCED() in tandem with M_EXT to check if IP fields need to be
swapped back.
fix up RST generation for non-Solaris
get "short" flag right for IPv6
3.4.2 - 10/5/2000 - Released
Fix bug in dealing with "hlen == 1 and opt > 1" - Itojun
ignore previous NAT mappings for 0/0 and 0/32 rules
bring in a completely new ftp proxy
allow NAT to cause packets to be dropped.
add NetBSD callout support for 1.4-current
3.4.1 - 30/4/2000 - Released
add ratoui() and fix parsing of group numbers to allow 0 - UINT_MAX
don't include opt_inet6.h for FreeBSD if KLD_MODULE is defined
Solaris must use copyin() for all types of ioctl() args
fix up screen/tty when leaving "top mode" of ipfstat
linked list for maptable not setup correctly in nat_hostmap()
check for maptable rather than nat_table[1] to see if malloc for maptable
succeeded in nat_init
fix handling of map NAT rules with "from/to" host specs
fix printout out of source address when using "from/to" with map rules
convert ip_len back to network byte order, not plen, for solaris as ip_len
may have been changed by NAT and plen won't reflect this
3.4 - 27/4/2000 - Released
source address spoofing can be turned on (fr_chksrc) without using
filter rules
group numbers are now 32bits in size, up from 16bits
IPv6 filtering available
add frank volf's state-top patches
add load splitting and round-robin attribute to redirect rules
FreeBSD-4.0 support (including KLD)
add top-style operation mode for ipfstat (-t)
add save/restore of IP Filter state/NAT information (ipfs)
further ftp proxy security checks
support for adding and removing proxies at runtime
3.3.13 26/04/2000 - Released
Fix parsing of "range" with "portmap"
Relax checking of ftp replies, slightly.
Fix NAT timeouts for ICMP packets
SunOS4 patches for ICMP redirects from Jurgen Keil (jk@tools.de)
3.3.12 16/03/2000 - Released
tighten up ftp proxy behaviour. sigh. yuck. hate.
fix bug in range check for NAT where the last IP# was not used.
fix problem with icmp codes > 127 in filter rules caused bad things to
happen and in particular, where #18 caused the rule to be printed
erroneously.
fix bug with the spl level not being reset when returning EIO from
iplioctl due to ipfilter not being initialized yet.
3.3.11 04/03/2000 - Released
make "or-block" work with lines that start with "log"
fix up parsing and printing of rules with syslog levels in them
fix from Cy Schubert for calling of apr_fini only if non-null
3.3.10 24/02/2000 - Released
* fix back from guido for state tracking interfaces
* update for NetBSD pfil interface changes
* if attaching fails and we can abort, then cleanup when doing so.
julian@computer.org:
* solaris.c (fr_precheck): After calling freemsg on mt, set it point to *mp.
* ipf.c (packetlogon): use flag to store the return value from get_flags.
* ipmon.c (init_tabs): General cleanup so we do not have to cast
an int s->s_port to u_int port and try to check if the u_int port
is less than zero.
3.3.9 15/02/2000 - Released
fix scheduling of bad locking in fr_addstate() used when we attach onto
a filter rule.
fix up ip_statesync() with storing interface names in ipstate_t
fix fr_running for LKM's - Eugene Polovnikov
junk using pullupmsg() for solaris - it's next to useless for what we
need to do here anyway - and implement what we require.
don't call fr_delstate() in fr_checkstate(), when compiled for a user
program, early but when we're finished with it (got fr & pass)
ipnat(5) fix from Guido
on solaris2, copy message and use that with filter if there is another
copy if it being used (db_ref > 1). bad for performance, but better
than causing a crash.
patch for solaris8-fcs compile from Casper Dik
3.3.8 01/02/2000 - Released
fix state handling of SYN packets.
@ -85,11 +238,6 @@ fix yet another problem with real audio.
3.3.4 4/12/1999 - Released
patches from Guido: fix panic in ip_state:fr_checkicmpmatchingstate(), fix
byte order problem in ip_id (host order when called from ip_input(), vs
network byte order when called from ip_output()) and fix a problem where the
fragment cache was never timedout early.
fix up the real audio proxy to properly setup state information and NAT
entries, thanks to Laine Stump for testing/advice/fixes.

465
contrib/ipfilter/IPF.KANJI Normal file
View File

@ -0,0 +1,465 @@
IP filter $B%7%g!<%H%,%$%I(B Dec, 1999
$B%[!<%`%Z!<%8(B: http://coombs.anu.edu.au/~avalon/ip-filter.html
FTP: ftp://coombs.anu.edu.au/pub/net/ip-filter/
$B30;3(B $B=c@8(B <sumio@is.s.u-tokyo.ac.jp>
$B;3K\(B $BBY1'(B <ymmt@is.s.u-tokyo.ac.jp>
-----
$B$O$8$a$K(B
IP filter $B$r(B gateway $B%^%7%s$K%$%s%9%H!<%k$9$k$3$H$G%Q%1%C%H%U%#(B
$B%k%?%j%s%0$r9T$&$3$H$,$G$-$^$9!#(B
$B%$%s%9%H!<%k$NJ}K!$O!"(BINSTALL$B$K=q$$$F$"$k$N$G!"$=$A$i$r;2>H$7$F(B
$B$/$@$5$$!#(BIP filter $B$N%P!<%8%g%s(B 3.3.5 $B$O!"(B
Solaris/Solaris-x86 2.3 - 8 (early access)
SunOS 4.1.1 - 4.1.4
NetBSD 1.0 - 1.4
FreeBSD 2.0.0 - 2.2.8
BSD/OS-1.1 - 4
IRIX 6.2
$B$GF0:n$9$k$3$H$,3NG'$5$l$F$$$^$9!#(B
$B$J$*!"(B64 bit kernel $B$NAv$C$F$k(B Solaris7 $B%^%7%s$G$O!"(Bgcc $B$H$+$G%3(B
$B%s%Q%$%k$7$?(B kernel driver $B$OF0:n$7$^$;$s!#(B
$B$=$N$h$&$J>l9g$K$O!"(Bprecompiled binary $B$r(B
ftp://coombs.anu.edu.au/pub/net/ip-filter/ip_fil3.3.2-sparcv9.pkg.gz
(1999$BG/(B12$B7n(B14$BF|8=:_!"$^$@(B3.3.5$B$O%Q%C%1!<%8$K$J$C$F$$$^$;$s(B)
$B$+$i<h$C$F$/$k$+!"(BWorkshop Compiler 5.0 $B$G%3%s%Q%$%k$7$F(B 64bit
driver $B$r:n$C$F$/$@$5$$!#(B
-----
$B@_Dj%U%!%$%k$N5-=RJ}K!(B
IP filter$B$N@_Dj$O!V$I$N%"%I%l%9!W$N!V$I$N%]!<%H!W$+$i!V$I$N%"%I(B
$B%l%9!W$N!V$I$N%]!<%H!W$X$N%Q%1%C%H$r(B block $B$9$k$+(B pass $B$9$k$+!"(B
$B$r;XDj$9$k$3$H$G9T$$$^$9!#(B
$B0J2<$NNc$G$O!"2f!9$,4IM}$7$F$$$k%5%V%M%C%H$h$j30$+$iFb$N%"%/%;%9(B
$B$O!"0lIt$N%^%7%s$r=|$$$F$OA4$F%V%m%C%/$7!"Fb$+$i30$X$N%"%/%;%9$O!"(B
$B86B'$H$7$FA4$FAGDL$7$9$k%]%j%7!<$G5-=R$5$l$F$$$^$9!#(B
$B0J2<!"4IM}$7$F$$$k%5%V%M%C%H$r(B
123.45.1.0/24
$B$H$7$FNc$r<($7$^$9!#(B24$B$O%5%V%M%C%H%^%9%/$G$9!#(B
$B$^$?!"(Bgateway $B$O(B
123.45.1.111 (hme0)
$B$,(B LAN$BB&$N%$%s%?!<%U%'!<%9!"(B
123.45.2.10 (hme1)
$B$,30B&$N%$%s%?!<%U%'!<%9$H$7$^$9!#(B
===================== $B$3$3$+$i(B ====================
########## quickly deny malicious packets
#
block in quick from any to any with short
block in log quick from any to any with ipopts
===================== $B$3$3$^$G(B ====================
$B$^$:$O$3$N%k!<%k$G!"IT@5$J%Q%1%C%H$r$O$M$^$9!#(Bblock $B$O(B block $B$9(B
$B$k0UL#$G!"H?BP$KDL$9>l9g$O(B pass $B$H$J$j$^$9!#(B
log $B$H$$$&$N$O!"$3$N%k!<%k$K%^%C%A$9$k%Q%1%C%H$N%m%0$r<h$k;X<($G(B
$B$9!#%m%0$O(B /dev/ipl $B$H$$$&%G%P%$%9%U%!%$%k$+$i%"%/%;%9$G$-$^$9$,!"(B
$B$3$N%G%P%$%9$O(B bounded buffer $B$J$N$G!"$"$kDxEY0J>e$N%m%0$O>C$($F(B
$B$7$^$$$^$9!#(B
/dev/ipl $B$NFbMF$rFI$_=P$9$K$O(B ipmon $B$H$$$&%W%m%0%i%`$r;H$$$^$9!#(B
ipmon $B$O(B stdout, syslog, $B$b$7$/$ODL>o$N%U%!%$%k$K%m%0$r=PNO$7$^(B
$B$9!#5/F0;~$K(B ipmon $B$rN)$A>e$2$k$J$i!"<!$N$h$&$J9T$r(B rc $B%U%!%$%k(B
$B$K=q$/$H$h$$$G$7$g$&!#(B
ipmon -n -o I ${IPMONLOG} < /dev/null > /dev/null 2>&1 &
${IPMONLOG} $B$OE,Ev$J%U%!%$%kL>$KCV49$7$F$/$@$5$$!#(Bsyslog $B$K=PNO(B
$B$9$k>l9g$O!"(B-s $B%*%W%7%g%s$rIU$1$^$9!#(Bsyslog $B$K=PNO$9$k>l9g!"(B
local0.info $B$r5-O?$9$k$h$&$K(B syslog.conf $B$rJT=8$7$F$/$@$5$$!#(B
$BNc$($P!"(B
local0.info ifdef(`LOGHOST', /var/log/syslog, @loghost)
quick $B$H$$$&$N$O!"$3$N%k!<%k$K%^%C%A$7$?%Q%1%C%H$O0J9_$N%k!<%k$r(B
$BD4$Y$:$K!"%"%/%7%g%s(B(block or pass)$B$K=>$o$;$k$H$$$&$b$N$G$9!#$?(B
$B$@$7!"Nc30$,$"$j$^$9!#8e=R$7$^$9!#(B
===================== $B$3$3$+$i(B ====================
########## group setup
#
block in on hme1 all head 100
block out on hme1 all head 150
pass in quick on hme0 all
pass out quick on hme0 all
===================== $B$3$3$^$G(B ====================
$B<!$K@)8f$r$+$1$k%$%s%?!<%U%'!<%9Kh$K%Q%1%C%H$KE,MQ$9$k%k!<%k$rJ,(B
$BN`$7$^$9!#(Bhme0 $B$O(B LAN $BB&$N%$%s%?!<%U%'!<%9$J$N$G!"B(:B$K5v2D(B
(pass quick)$B$7$F$$$^$9!#(B
all $B$H$$$&$N$O!"(Bfrom any to any $B$N>JN,7A$G$9!#(B
$B30It$H$N%$%s%?!<%U%'!<%9$G$"$k(B hme1 $B$O(B incoming $B$H(B outgoing $B$G!"(B
$B$=$l$>$l(B group 100 $BHV$H(B 150 $BHV$KJ,N`$7$^$9!#(Bhead $B$H$$$&$N$O!"$3(B
$B$N%k!<%k$K%^%C%A$7$?%Q%1%C%H$r<!$NHV9f$N%0%k!<%W$KJ,N`$9$k$H$$$&(B
$B0UL#$G$9!#(B
===================== $B$3$3$+$i(B ====================
########## deny IP spoofing
#
block in log quick from 127.0.0.0/8 to any group 100
block in log quick from 123.45.2.10/32 to any group 100
block in log quick from 123.45.1.111/24 to any group 100
#
########## deny reserved addresses
#
block in log quick from 10.0.0.0/8 to any group 100
block in log quick from 192.168.0.0/16 to any group 100
block in log quick from 172.16.0.0/12 to any group 100
#
===================== $B$3$3$^$G(B ====================
IP $B%"%I%l%9$r2~cb$7$?%Q%1%C%H$rB(:B$K5qH]$7$F$$$^$9!#KvHx$N(B
group 100 $B$H$$$&$N$O(B head 100 $B$GJ,N`$5$l$?%Q%1%C%H$K$N$_%^%C%A$9(B
$B$k%k!<%k$H$$$&0UL#$G$9!#(B
-----
$B$3$3$^$G$G!"4pK\E*$K(BLAN$BFb$NDL?.$OAGDL$7$@$,30It$H$NDL?.$O%G%U%)(B
$B%k%H$G0l@Z6X;_$H$$$&@_Dj$K$J$j$^$9!#0J9_$G$O!"$=$N%G%U%)%k%H$KBP(B
$B$9$kNc30$H$$$&7A$G!"DL$7$?$$%Q%1%C%H$r5-=R$7$F$$$-$^$9!#(B
$B$^$:!"FbIt$+$i30It$X$N@\B3$K4X$9$k@_Dj$r$7$^$9!#(B
===================== $B$3$3$+$i(B ====================
########## OUTGOING
#
## allow ping out
#
pass out quick proto icmp from any to any keep state group 150
#
## allow all outgoing UDP packets except for netbios ports (137-139).
#
pass out quick proto udp from any to any keep state head 160 group 150
block out log quick proto udp from any to any port 136 >< 140 group 160
#
## pass all TCP connection setup packets except for netbios ports (137-139).
#
pass out quick proto tcp from any to any flags S/SAFR keep state head 170 group 150
block out log quick proto tcp from any to any port 136 >< 140 group 170
===================== $B$3$3$^$G(B ====================
$B$3$l$O4pK\E*$KA4$F$N%Q%1%C%H$r5v$9%k!<%k$G$9!#$7$+$7!"(Bnetbios
(137-139/udp, tcp)$B$N%]!<%H$@$1$O6X;_$7$F$$$^$9!#(Bnetbios$B$O(B Windows
$B$N%U%!%$%k6&M-$G;H$o$l$k%]!<%H$G!"$3$N%]!<%H$,3+$$$F$$$k$H!"(B
Windows$B$N@_Dj$K$h$C$F$O!"@$3&Cf$+$i%U%!%$%k$rFI$_=q$-$G$-$k(B
$B62$l$,$"$j$^$9!#(B
$B$3$3$G!"4JC1$K=q<0$r8+$F$*$/$H!"(B
* $B:G=i$NC18l$G!"(Bblock$B$9$k$+(Bpass$B$9$k$+;XDj$9$k(B
* proto $B$N8e$NC18l$G!"(Bprotocol$B$r;XDj$9$k(B(udp, tcp, icmp, etc.)$B!#(B
* from A to B $B$G!"$I$3$+$i$I$3$X$N%Q%1%C%H$+$r;XDj$9$k(B
* head XXX$B$r;XDj$9$k$H!"$=$N9T$G;XDj$5$l$"$?%Q%1%C%H$O!"(Bgroup
XXX$B$H$7$F;2>H$G$-$k(B
* group$B$r;XDj$9$k$3$H$G!"5,B'$rE,MQ$9$k8uJd$r(B($BM=$a(Bhead$B$G@_Dj$7$?(B)
group$B$K8BDj$G$-$k!#(B
$B$^$?!"(Bfrom A to B$B$N(BA$B$d(BB$B$O!"(BIP$B%"%I%l%9$H(Bport$B$r=q$/$3$H$,$G$-$^$9!#(B
from any to any port 136 >< 140
$B$H$$$&$N$O!"(B
$B!VG$0U$N%]!<%H$NG$0U$N%"%I%l%9$+$i!"(B137$BHV$+$i(B139$BHV%]!<%H$NG$0U$N(B
$B%"%I%l%9$X$N%Q%1%C%H!W(B
$B;XDj$7$F$$$k$3$H$K$J$j$^$9!#$^$?!"HV9f$NBe$o$j$K(B/etc/service$B$K5-(B
$B=R$5$l$F$$$k%5!<%S%9L>$r5-=R$9$k$3$H$b$G$-$^$9!#(B
$B$?$H$($P(B
from any to any port = telnet
$B$H(B
from any to any port = 23
$B$OF1$80UL#$H$J$j$^$9!#(B
$B$5$F!"$3$3$G(B quick $B$NNc30$r@bL@$7$F$*$-$^$9!#(Bquick $B$NIU$$$?(B
rule $B$,(B head $B$G?7$?$J%0%k!<%W$r:n$k>l9g!"=hM}$O$^$@$3$N;~E@(B
$B$G$O3NDj$7$^$;$s!#0J9_!"!V(Bhead $B$G@k8@$5$l$?%0%k!<%W$N%k!<%k!W(B
$B$N$_=hM}$9$k$H$$$&0UL#$K$J$j$^$9!#$G$9$+$i>e$N!"(B
pass out quick proto udp from any to any keep state head 160 group 150
block out log quick proto udp from any to any port 136 >< 140 group 160
$B$O!"$^$:(B 150$BHV%0%k!<%W$K%^%C%A$9$k(B UDP $B%Q%1%C%H$OAGDL$7(B
$B$9$k!"$,!"0J2<$N(B 160$BHV$KB0$9$k%k!<%k$r$^$@=hM}$9$k!#(B
$B$=$7$F(B2$B9TL\$G(B 160$BHV%0%k!<%W$KBP$7$F(B netbios packet $B$r(B
block $B$7$F$$$kLu$G$9!#(B
$B0l9TL\$K%^%C%A$7$?%Q%1%C%H$O0J2<$K$b$7(B150$BHV$N%0%k!<%W$N(B
$B%k!<%k$,$"$C$?$H$7$F$b!"L5;k$9$k$3$H$KCm0U$7$F$/$@$5$$!#(B
----------
$B<!$K!"30It$+$iFbIt$X$N%"%/%;%9$N@_Dj$r$7$^$9!#(B
* $B%k!<%F%#%s%0>pJs(B(RIP)$B$N%Q%1%C%H$O!"A4It5v$7$^$9!#(B
pass in quick proto udp from any to any port = 520 keep state group 100
* ICMP$B$N%Q%1%C%H$OA4It5v$7$^$9!#(B
pass in quick proto icmp from any to any group 100
* $BFbIt$+$i30It$X$N(Bftp$B$r5v$9$?$a$K!"(Bftp-data port$B$+$i0lHL%]!<%H$X(B
$B$NG$0U$N@\B3$r<u$1IU$1$^$9!#$3$l$O(Bpassive mode$B$G$J$$(BFTP$B$N5sF0(B
$B$G$9!#(B
pass in quick proto tcp from any port = ftp-data to any port > 1023 flags S/SA keep state group 100
$B$7$+$7!"$3$l$O0lHL$K8@$C$FB?>/4m81$J9T0Y$G$9!#@\B3$G$-$k$N$,(B
1024$BHV0J9_$N0lHL%]!<%H$K8BDj$O$5$l$^$9$,!"$"$^$j$*4+$a$G$-$^$;$s!#(B
$B$3$N9T$r2C$($:$K!"(Bpassive mode (ftp $B$G(B pasv $B%3%^%s%I$GF~$l$k(B)
$B$G(B FTP $B$r$9$k$3$H$r4+$a$^$9!#$J$*!":G6a$N(B FTP client $B$O:G=i(B
$B$+$i(B passive mode $B$KL5>r7o$G$7$F$7$^$&$b$N$,B?$$$h$&$G$9!#(B
* sendmail$B$d(Bftpd$B$K7R$0$H!"Aj<j$,(Bident$B%]!<%H$X%"%/%;%9$7$F$/$k$3(B
$B$H$,$"$k$N$G!"(Bident port$B$r3+$1$^$9!#(Bident $B$ODL>o$O5/F0$5$l$F$$(B
$B$J$$(B daemon $B$J$N$G!"AGDL$7$7$F$b%;%-%e%j%F%#%[!<%k$K$J$k$3$H$O$"(B
$B$j$^$;$s(B(connection refused$B$K$J$k$@$1$G$9(B)$B!#$3$l$r3+$1$J$$$H!"(B
$BAj<jB&$O(B timeout $B$9$k$^$G@h$K?J$^$J$$$N$G!"(BFTP $B$d(B mail $B$NAw?.(B
$B$,$d$?$i$KCY$/$J$k$3$H$,$"$j$^$9!#(B
$B$b$7(B 113 $BHV%]!<%H$K@\B3$G$-$k$h$&$J$i!"$=$N%5!<%S%9$OB(:B$K(B
$BDd;_$9$k$3$H$r4+$a$^$9!#(B
pass in quick proto tcp from any to any port = 113 flags S/SA keep state group 100
------
$B<!$K!"30It$+$i(B firewall $B$X$N%"%/%;%9$r5v$9%5!<%S%9$r5-=R$7$F$$$-(B
$B$^$9!#$^$:$O!"30It$+$i$N@\B3$r5v$7$?$$%[%9%H$K$D$$$F!"%0%k!<%WHV(B
$B9f$r$D$1$^$9!#(B
===================== $B$3$3$+$i(B ====================
## grouping by host
block in log quick proto tcp from any to 123.45.1.X flags S/SA head 110 group 100
block in log quick proto tcp from any to 123.45.1.Y flags S/SA head 111 group 100
===================== $B$3$3$^$G(B ====================
$B$3$l$G!"(B
$B30It$+$i(B 123.45.1.X $B$X$N@\B3$O(B group 110
$B30It$+$i(B 123.45.1.Y $B$X$N@\B3$O(B group 111
$B$G;2>H$9$k$3$H$,$G$-$^$9!#(B
$BB>$K$b5v$7$?$$%[%9%H$rA}$d$7$?$$$H$-$O!">e$HF1MM$K$7$F!"(Bhead$B$N8e(B
$B$K!"?7$7$$?t;z(B(112, 113$B$J$I(B)$B$r3d$jEv$F$F$/$@$5$$!#(B
$B$b$&0lEYCm0U$7$F$*$-$^$9$,!"(Bquick $B$H(B head $B$,F1;~$K8=$l$k%k!<%k(B
$B0J9_$G$O!"(Bhead $B$G@k8@$5$l$?%0%k!<%W$N%k!<%k$7$+E,MQ$5$l$J$/$J$j(B
$B$^$9!#$G$9$+$i!">e$N(B ident $B$d(B ftp data-port $B$N$h$&$K!"FbIt$N(B
$BA4$F$N%[%9%H$K%^%C%A$9$k%k!<%k$O!"$3$N%[%9%H$K$h$k%0%k!<%WJ,$1(B
$B$NA0$KCV$/I,MW$,$"$j$^$9!#(B
X$B$X$O!"(Btelnet, ftp, ssh $B$r!"(BY$B$X$O!"(Bftp, http, smtp, pop $B$r5v$9$3(B
$B$H$K$7$^$9!#(B
* X(group 110)$B$X$N(Btelnet$B$r5v$7$^$9(B
pass in quick proto tcp from any to any port = telnet keep state group 110
* X$B$X$N(Bftp$B$r5v$7$^$9!#(Bftp-data port $B$b3+$1$F$*$-$^$9!#(B
($BI,MW$,$"$k$+$I$&$+3NG'$O$7$F$$$^$;$s$,!"3+$1$F$$$F$b0BA4$G$7$g$&(B)$B!#(B
pass in quick proto tcp from any to any port = ftp keep state group 110
pass in quick proto tcp from any to any port = ftp-data keep state group 110
* X$B$X$N(Bssh$B$r5v$7$^$9!#(B
pass in quick proto tcp from any to any port = 22 keep state group 110
* Y$B$X$N(Bftp$B$r5v$7$^$9!#(B
pass in quick proto tcp from any to any port = ftp keep state group 111
pass in quick proto tcp from any to any port = ftp-data keep state group 111
pass in quick proto tcp from any to any port 2999 >< 3100 keep state group 111
Y$B$O(B anonoymous ftp $B%5!<%P$r1?1D$7$F$$$k$?$a(B wu-ftpd $B$r;H$C$F$$(B
$B$^$9!#(Bwu-ftpd $B$O(B passive mode $B$N(BFTP$B$K$bBP1~$7$F$$$^$9$N$G!"$I(B
$B$N%]!<%H$r(BPASV$BMQ$K;H$&$+!"(Bwu-ftpd $B$N@_Dj$K=q$$$F$*$/I,MW$,$"$j(B
$B$^$9!#$3$3$G$O(B3000$B$+$i(B3099$BHV%]!<%H$r;HMQ$9$k$h$&$K!"(Bwu-ftpd $B$r(B
$B@_Dj$7$F$$$^$9!#(B
passive FTP $B$K$D$$$F2r@b$7$^$9!#(Bpassive FTP $B$O!"%/%i%$%"%s%H$,(B
$B%U%!%$%"%&%)!<%k$NFbB&$K$$$k>l9g$N$?$a$K3+H/$5$l$?%W%m%H%3%k$G(B
$B$9!#%G%U%)%k%H$G$O>e$G@bL@$7$?$h$&$K!"%G!<%?E>Aw$N$?$a!"%5!<%P(B
$B$N(B ftp-data port $B$+$i%/%i%$%"%s%H$K@\B3$,$$$-$^$9!#(B
passive FTP $B$G$O!"%G!<%?E>Aw$b(B client $B$+$i%5!<%P$K@\B3$9$k$h$&(B
$B$K$J$j$^$9!#$=$N:]!"%5!<%P$OE,Ev$J%]!<%HHV9f$r3d$j?6$C$F!"$=$3(B
$B$K%/%i%$%"%s%H$,@\B3$9$k$h$&;X<($7$^$9!#(B
$B$3$N$?$a!"%5!<%P$,%U%!%$%"%&%)!<%kFb$K$$$k>l9g!"E,Ev$J%]!<%HHV(B
$B9f$O%U%!%$%"%&%)!<%k$G$O$M$i$l$F$7$^$$$^$9!#$=$3$G!"(Bwu-ftpd $B$N(B
$B@_Dj$G!"3d$j?6$k%]!<%HHV9f$NHO0O$r8BDj$7$F!"$=$3$@$1%U%!%$%"(B
$B%&%)!<%k$K7j$r3+$1$F$$$k$o$1$G$9!#(Bwu-ftpd $B$N>l9g$O!"(Bftpaccess
$B$H$$$&%U%!%$%k$K(B
# passive ports <cidr> <min> <max>
passive ports 0.0.0.0/0 3000 3099
$B$HDI2C$9$k$3$H$G@_Dj$G$-$^$9!#(Bftpaccess(5)$B$r;2>H$7$F$/$@$5$$!#(B
* Y$B$X$N(Bhttp$B$r5v$7$^$9!#(B
pass in quick proto tcp from any to any port = 80 keep state group 111
* Y$B$X$N(Bsmtp$B$r5v$7$^$9!#(B
pass in quick proto tcp from any to any port = smtp keep state group 111
* Y$B$X$N(Bpop$B$r5v$7$^$9!#(B
pass in quick proto tcp from any to any port = 110 keep state group 111
$B0J>e$N@_Dj$K$h$j!"(BX, Y $B0J30$N%^%7%s$X$N!"30It$+$i$N@\B3$O!"0l@Z(B
$B9T$($J$/$J$j$^$9$N$G!"(Bremote exploit $BBP:v$O!"(BX, Y $B$K$N$_9T$($P$h(B
$B$/$J$j!"4IM}$N<j4V$,7Z8:$G$-$^$9!#(B
$BB>$N%W%m%H%3%k$rDL$9>l9g$b!">e$r;29M$K$7$FDL$7$?$$%]!<%HHV9f$r=q(B
$B$/$@$1$G$9$,!"$$$/$D$+Cm0UE@$,$"$j$^$9!#0J2<$bL\$rDL$7$F$/$@$5$$!#(B
-----
$B$=$NB>$NCm0U(B
1) gateway $B%^%7%s$N$h$&$K!"J#?t$N(BIP$B%"%I%l%9$r;}$D%^%7%s$G%5!<%S(B
$B%9$rN)$A>e$2$k>l9g$O!"$=$l$>$l$N(BIP$B%"%I%l%9$KBP$7$F!"(Bport $B$r3+$/(B
$BI,MW$,$"$j$^$9!#Nc$($P(B X $B$,(B IP:a $B$H(B IP:b $B$r;}$D$J$i!"(Bgroup $B$O(B a,
b $B$=$l$>$lMQ0U$7$F!"N>J}$N%0%k!<%WMQ$K(B rule $B$rDI2C$9$kI,MW$,$"$j(B
$B$^$9!#0J2<$NNc$G$O!"%2!<%H%&%'%$%^%7%s(B(123.45.2.10$B$H(B123.45.1.111
$B$N(BIP$B$r;}$D(B)$B$K(BNNTP$B%5!<%P$rN)$F$F$$$^$9!#(B
($BNc(B)
#### grouping by host
block in log quick proto tcp from any to 123.45.2.10 flags S/SA head 112 group 100
block in log quick proto tcp from any to 123.45.1.111 flags S/SA head 113 group 100
#### allow NNTP
pass in quick proto tcp from any to any port = nntp keep state group 112
pass in quick proto tcp from any to any port = nntp keep state group 113
gateway $B$,(B2$B$D0J>e$"$k%M%C%H%o!<%/$G$O!"N>J}$N(B gateway $B$K(B IP
filter $B$,I,MW$K$J$j!"@_Dj$O99$KJ#;($K$J$j$^$9!#$=$N$h$&$J4D6-$N(B
$B>l9g$K$O!"%^%K%e%"%k$rFI$s$G8!F$$7$F$/$@$5$$!#(B
2) NFS$B$H(Brsh$B$O%W%m%H%3%k$N4X78>e!"(Bfirewall$BD6$($OIT2DG=$G$9!#(B
NFS$B$NBeBX$K$D$$$F$OITL@$G$9$,!"(Brsh$B$NBeBX$H$7$F$O(Bssh$B$,;H$($^$9!#(B
3) $B30It$N(BX client $B$r!"%U%!%$%"%&%)!<%kFb$N(BX$B%5!<%P$K@\B3$5$;$?$$!"(B
$B$H$$$&$N$O(B FAQ $B$N0l$D$G$9!#$*4+$a$N2r7h:v$O!"(Bssh $B$N(B X forwarding
$B5!9=$r;H$&$3$H$G$9!#(Bssh$B$G@\B3$G$-$k$J$i$P!"$3$l$O40A4$K(B secure
$B$GHFMQE*$JJ}K!$G$9!#(B
$B$=$l$,=PMh$J$$>l9g$O!"2f!9$O@\B3$5$;$?$$%[%9%H$N%Z%"$r%f!<%6$KJs(B
$B9p$7$F$b$i$C$F!"0J2<$N$h$&$J%k!<%k$rDI2C$7$F$$$^$9!#(B
# X:0 $B$O(B tcp:6000 $BHV$K$J$j$^$9!#(B
# 123.45.1.Z:0 (server) <-> A.B.C.D (client)
pass in quick proto tcp from A.B.C.D port > 1023 to 123.45.1.Z port = 6000 flags S/SA keep state group 100
-----
$B:G8e$K!";D$k%Q%1%C%H$OA4$F%V%m%C%/$5$l$kLu$G$9$,!"$=$l$K$D$$$F$N(B
$BA4$F$N%m%0$r;D$9$3$H$r4uK>$9$k>l9g!"<!$N%k!<%k$r!VI,$::G8e$K!W2C(B
$B$($^$9!#(B
## log blocked packets
block in log quick from any to 123.45.1.111/24 group 100
block in log quick from any to 123.45.2.10 group 100
------
$B:#Kx$N@_Dj$r$R$H$D$K$^$H$a$?%U%!%$%k$r:G8e$KE:IU$7$^$9!#(B
===================== $B$3$3$+$i(B ====================
########## Packet Filtering Rules for 123.45.1. ##########
#
# The following routes should be configured, if not already:
#
# route add 123.45.1.111 localhost 0 (hme0) (LAN)
# route add 123.45.2.10 localhost 0 (hme1) (upstream)
#
########## quickly deny malicious packets
#
block in quick from any to any with short
block in log quick from any to any with ipopts
#
########## group setup
#
block in on hme1 all head 100
block out on hme1 all head 150
pass in quick on hme0 all
pass out quick on hme0 all
#
########## deny IP spoofing
#
block in log quick from 127.0.0.0/8 to any group 100
block in log quick from 123.45.2.10/32 to any group 100
block in log quick from 123.45.1.111/24 to any group 100
#
########## deny reserved addresses
#
block in log quick from 10.0.0.0/8 to any group 100
block in log quick from 192.168.0.0/16 to any group 100
block in log quick from 172.16.0.0/12 to any group 100
#
########## OUTGOING
#
## allow ping out
pass out quick proto icmp from any to any keep state group 150
#
## allow all outgoing UDP packets except for netbios ports (137-139).
#
pass out quick proto udp from any to any keep state head 160 group 150
block out log quick proto udp from any to any port 136 >< 140 group 160
#
## pass all TCP connection setup packets except for netbios ports (137-139).
#
pass out quick proto tcp from any to any flags S/SAFR keep state head 170 group 150
block out log quick proto tcp from any to any port 136 >< 140 group 170
#
######### INCOMING
## ICMP
pass in quick proto icmp from any to any group 100
## RIP
pass in quick proto udp from any to any port = 520 keep state group 100
## FTP
pass in quick proto tcp from any port = ftp-data to any port > 1023 flags S/SA keep state group 100
## IDENT
pass in quick proto tcp from any to any port = 113 flags S/SA keep state group 100
#
## grouping by host (112 & 113 is the gateway address)
block in log quick proto tcp from any to 123.45.1.X flags S/SA head 110 group 100
block in log quick proto tcp from any to 123.45.1.Y flags S/SA head 111 group 100
block in log quick proto tcp from any to 123.45.2.10 flags S/SA head 112 group 100
block in log quick proto tcp from any to 123.45.1.111 flags S/SA head 113 group 100
#
## telnet, ftp, ssh, www, smtp, pop
pass in quick proto tcp from any to any port = telnet keep state group 110
pass in quick proto tcp from any to any port = ftp keep state group 110
pass in quick proto tcp from any to any port = ftp-data keep state group 110
pass in quick proto tcp from any to any port = 22 keep state group 110
pass in quick proto tcp from any to any port = ftp keep state group 111
pass in quick proto tcp from any to any port = ftp-data keep state group 111
pass in quick proto tcp from any to any port 2999 >< 3100 keep state group 111
pass in quick proto tcp from any to any port = 80 keep state group 111
pass in quick proto tcp from any to any port = smtp keep state group 111
pass in quick proto tcp from any to any port = 110 keep state
group 111
#
## allow NNTP on the gateway
pass in quick proto tcp from any to any port = nntp keep state group 112
pass in quick proto tcp from any to any port = nntp keep state group 113
#
## X connections
# 123.45.1.Z:0 (server) <-> A.B.C.D (client)
pass in quick proto tcp from A.B.C.D port > 1023 to 123.45.1.Z port = 6000 flags S/SA keep state group 100
#
## log blocked packets
## THIS MUST BE THE LAST RULE!
block in log quick from any to 123.45.1.111/24 group 100
block in log quick from any to 123.45.2.10 group 100
===================== $B$3$3$^$G(B ====================
----
$B$3$NJ8=q$N<h$j07$$$K$D$$$F(B
Copyright (C) 1999 TOYAMA Sumio <sumio@is.s.u-tokyo.ac.jp>
and YAMAMOTO Hirotaka <ymmt@is.s.u-tokyo.ac.jp>
THIS DOCUMENT IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
Permission to modify this document and to distribute it is hereby
granted, as long as above notices and copyright notice are retained.

View File

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

View File

@ -1,11 +1,11 @@
#
# Copyright (C) 1993-1998 by Darren Reed.
# Copyright (C) 1993-2000 by Darren Reed.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and due credit is given
# to the original author and the contributors.
#
# $Id: Makefile,v 2.2 1999/08/04 17:29:52 darrenr Exp $
# $Id: Makefile,v 2.11.2.1 2000/04/26 12:14:58 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@ -15,7 +15,7 @@ CC=gcc -Wstrict-prototypes -Wmissing-prototypes
#CC=gcc
#CC=cc -Dconst=
DEBUG=-g
CFLAGS=-I$$(TOP)
CFLAGS=-I$$(TOP) -g
CPU=`uname -m`
CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`
#
@ -30,6 +30,26 @@ IPFLOG=-DIPFILTER_LOG
# The facility you wish to log messages from ipmon to syslogd with.
#
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
#
# Where to find the ncurses include files (if not in default path),
#
#STATETOP_INC=
#STATETOP_INC=-I/usr/local/include
#
# How to link the ncurses library
#
#STATETOP_LIB=-lncurses
#STATETOP_LIB=-L/usr/local/lib -lncurses
#
# Uncomment this when building IPv6 capability.
#
#INET6=-DUSE_INET6
#
# For packets which don't match any pass rules or any block rules, set either
# FR_PASS or FR_BLOCK (respectively). It defaults to FR_PASS if left
@ -39,11 +59,12 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
#
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
MFLAGS1="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2)' \
MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)"
"CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \
'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)'
DEST="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)"
MFLAGS=$(MFLAGS1) "IPFLKM=$(IPFLKM)"
#
SHELL=/bin/sh
@ -65,6 +86,7 @@ all:
@echo "freebsd - compile for FreeBSD 2.0, 2.1 or earlier"
@echo "freebsd22 - compile for FreeBSD-2.2 or greater"
@echo "freebsd3 - compile for FreeBSD-3.x"
@echo "freebsd4 - compile for FreeBSD-4.x"
@echo "bsd - compile for generic 4.4BSD systems"
@echo "bsdi - compile for BSD/OS"
@echo "irix - compile for SGI IRIX"
@ -103,6 +125,11 @@ freebsd22: include
fi
make freebsd
freebsd4: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "DLKM=-DKLD_MODULE"; cd ..)
(cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..)
freebsd3 freebsd30: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS1) "ML=mlf_ipl.c" LKM= ; cd ..)
@ -135,16 +162,16 @@ bsdi bsdos: include
irix IRIX: include
make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
(cd IRIX/$(CPUDIR); smake build TOP=../.. $(MFLAGS); cd ..)
(cd IRIX/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
(cd IRIX/$(CPUDIR); smake build TOP=../.. $(DEST) $(MFLAGS); cd ..)
(cd IRIX/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); cd ..)
linux: include
make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
./buildlinux
linuxrev:
(cd Linux/$(CPUDIR); make build TOP=../.. $(MFLAGS) LKM= ; cd ..)
(cd Linux/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
(cd Linux/$(CPUDIR); make build TOP=../.. $(DEST) $(MFLAGS) LKM= ; cd ..)
(cd Linux/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); cd ..)
setup:
-if [ ! -d $(TARGOS)/$(CPUDIR) ] ; then mkdir $(TARGOS)/$(CPUDIR); fi
@ -155,8 +182,8 @@ setup:
clean: clean-include
${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \
vnode_if.h $(LKM) *~
if [ "`uname -s`" = "SunOS" ]; then (cd SunOS4; make clean); fi
if [ "`uname -s`" = "SunOS" ]; then (cd SunOS5; make clean); fi
(cd SunOS4; make clean)
(cd SunOS5; make clean)
(cd BSD; make clean)
(cd Linux; make clean)
if [ "`uname -s`" = "IRIX" ]; then (cd IRIX; make clean); fi
@ -196,20 +223,20 @@ get:
done
sunos4 solaris1:
(cd SunOS4; make build TOP=.. "CC=$(CC)" $(MFLAGS); cd ..)
(cd SunOS4; make -f Makefile.ipsend "CC=$(CC)" TOP=.. $(MFLAGS); cd ..)
(cd SunOS4; make build TOP=.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
(cd SunOS4; make -f Makefile.ipsend "CC=$(CC)" TOP=.. $(DEST) $(MFLAGS); cd ..)
sunos5 solaris2:
(cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
(cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(MFLAGS); cd ..)
(cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
(cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
sunos5x86 solaris2x86:
(cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
(cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(MFLAGS); cd ..)
(cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
(cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
install-linux:
(cd Linux/$(CPUDIR); make install "TOP=../.." $(MFLAGS); cd ..)
(cd Linux/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
(cd Linux/$(CPUDIR); make install "TOP=../.." $(DEST) $(MFLAGS); cd ..)
(cd Linux/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(DEST) $(MFLAGS); cd ..)
install-bsd:
(cd BSD/$(CPUDIR); make install "TOP=../.." $(MFLAGS); cd ..)
@ -222,7 +249,7 @@ install-sunos5: solaris
(cd SunOS5; $(MAKE) "CPU=$(CPU) TOP=.." install)
install-irix: irix
(cd IRIX; smake install "CPU=$(CPU) TOP=.." $(MFLAGS))
(cd IRIX; smake install "CPU=$(CPU) TOP=.." $(DEST) $(MFLAGS))
rcsget:
-@for i in ipf.c ipt.h solaris.c ipf.h kmem.c ipft_ef.c linux.h \

595
contrib/ipfilter/common.c Normal file
View File

@ -0,0 +1,595 @@
/*
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
#include <syslog.h>
#include "ip_compat.h"
#include "ip_fil.h"
#include "ipf.h"
#include "facpri.h"
#if !defined(lint)
static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
extern int opts;
#ifdef USE_INET6
extern int use_inet6;
#endif
char *proto = NULL;
char flagset[] = "FSRPAU";
u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG };
#ifdef USE_INET6
void fill6bits __P((int, u_32_t *));
int count6bits __P((u_32_t *));
#endif
static char thishost[MAXHOSTNAMELEN];
void initparse()
{
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
}
int genmask(msk, mskp)
char *msk;
u_32_t *mskp;
{
char *endptr = NULL;
#ifdef USE_INET6
u_32_t addr;
#endif
int bits;
if (index(msk, '.') || index(msk, 'x') || index(msk, ':')) {
/* possibly of the form xxx.xxx.xxx.xxx
* or 0xYYYYYYYY */
#ifdef USE_INET6
if (use_inet6) {
if (inet_pton(AF_INET6, msk, &addr) != 1)
return -1;
} else
#endif
if (inet_aton(msk, (struct in_addr *)mskp) == 0)
return -1;
} else {
/*
* 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));
}
return 0;
}
#ifdef USE_INET6
void fill6bits(bits, msk)
int bits;
u_32_t *msk;
{
int i;
for (i = 0; bits >= 32 && i < 4 ; ++i, bits -= 32)
msk[i] = 0xffffffff;
if (bits > 0 && i < 4)
msk[i++] = htonl(0xffffffff << (32 - bits));
while (i < 4)
msk[i++] = 0;
}
#endif
/*
* returns -1 if neither "hostmask/num" or "hostmask mask addr" are
* found in the line segments, there is an error processing this information,
* or there is an error processing ports information.
*/
int hostmask(seg, sa, msk, pp, cp, tp, linenum)
char ***seg;
u_32_t *sa, *msk;
u_short *pp, *tp;
int *cp;
int linenum;
{
struct in_addr maskaddr;
char *s;
/*
* is it possibly hostname/num ?
*/
if ((s = index(**seg, '/')) ||
((s = index(**seg, ':')) && !index(s + 1, ':'))) {
*s++ = '\0';
if (genmask(s, msk) == -1) {
fprintf(stderr, "%d: bad mask (%s)\n", linenum, s);
return -1;
}
if (hostnum(sa, **seg, linenum) == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
*sa &= *msk;
(*seg)++;
return ports(seg, pp, cp, tp, linenum);
}
/*
* look for extra segments if "mask" found in right spot
*/
if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) {
if (hostnum(sa, **seg, linenum) == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
(*seg)++;
(*seg)++;
if (inet_aton(**seg, &maskaddr) == 0) {
fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg);
return -1;
}
*msk = maskaddr.s_addr;
(*seg)++;
*sa &= *msk;
return ports(seg, pp, cp, tp, linenum);
}
if (**seg) {
if (hostnum(sa, **seg, linenum) == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
(*seg)++;
#ifdef USE_INET6
if (use_inet6) {
u_32_t k = 0;
if (sa[0] || sa[1] || sa[2] || sa[3])
k = 0xffffffff;
msk[0] = msk[1] = msk[2] = msk[3] = k;
}
else
#endif
*msk = *sa ? 0xffffffff : 0;
return ports(seg, pp, cp, tp, linenum);
}
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
/*
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
int hostnum(ipa, host, linenum)
u_32_t *ipa;
char *host;
int linenum;
{
struct hostent *hp;
struct netent *np;
struct in_addr ip;
if (!strcasecmp("any", host))
return 0;
#ifdef USE_INET6
if (use_inet6) {
if (inet_pton(AF_INET6, host, ipa) == 1)
return 0;
else
return -1;
}
#endif
if (isdigit(*host) && inet_aton(host, &ip)) {
*ipa = ip.s_addr;
return 0;
}
if (!strcasecmp("<thishost>", host))
host = thishost;
if (!(hp = gethostbyname(host))) {
if (!(np = getnetbyname(host))) {
fprintf(stderr, "%d: can't resolve hostname: %s\n",
linenum, host);
return -1;
}
*ipa = htonl(np->n_net);
return 0;
}
*ipa = *(u_32_t *)hp->h_addr;
return 0;
}
/*
* check for possible presence of the port fields in the line
*/
int ports(seg, pp, cp, tp, linenum)
char ***seg;
u_short *pp, *tp;
int *cp;
int linenum;
{
int comp = -1;
if (!*seg || !**seg || !***seg)
return 0;
if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
(*seg)++;
if (isdigit(***seg) && *(*seg + 2)) {
if (portnum(**seg, pp, linenum) == 0)
return -1;
(*seg)++;
if (!strcmp(**seg, "<>"))
comp = FR_OUTRANGE;
else if (!strcmp(**seg, "><"))
comp = FR_INRANGE;
else {
fprintf(stderr,
"%d: unknown range operator (%s)\n",
linenum, **seg);
return -1;
}
(*seg)++;
if (**seg == NULL) {
fprintf(stderr, "%d: missing 2nd port value\n",
linenum);
return -1;
}
if (portnum(**seg, tp, linenum) == 0)
return -1;
} else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
comp = FR_EQUAL;
else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
comp = FR_NEQUAL;
else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
comp = FR_LESST;
else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
comp = FR_GREATERT;
else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
comp = FR_LESSTE;
else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
comp = FR_GREATERTE;
else {
fprintf(stderr, "%d: unknown comparator (%s)\n",
linenum, **seg);
return -1;
}
if (comp != FR_OUTRANGE && comp != FR_INRANGE) {
(*seg)++;
if (portnum(**seg, pp, linenum) == 0)
return -1;
}
*cp = comp;
(*seg)++;
}
return 0;
}
/*
* find the port number given by the name, either from getservbyname() or
* straight atoi(). Return 1 on success, 0 on failure
*/
int portnum(name, port, linenum)
char *name;
u_short *port;
int linenum;
{
struct servent *sp, *sp2;
u_short p1 = 0;
int i;
if (isdigit(*name)) {
if (ratoi(name, &i, 0, USHRT_MAX)) {
*port = (u_short)i;
return 1;
}
fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name);
return 0;
}
if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) {
sp = getservbyname(name, proto);
if (sp) {
*port = ntohs(sp->s_port);
return 1;
}
fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
return 0;
}
sp = getservbyname(name, "tcp");
if (sp)
p1 = sp->s_port;
sp2 = getservbyname(name, "udp");
if (!sp || !sp2) {
fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
linenum, name);
return 0;
}
if (p1 != sp2->s_port) {
fprintf(stderr, "%d: %s %d/tcp is a different port to ",
linenum, name, p1);
fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
return 0;
}
*port = ntohs(p1);
return 1;
}
u_char tcp_flags(flgs, mask, linenum)
char *flgs;
u_char *mask;
int linenum;
{
u_char tcpf = 0, tcpfm = 0, *fp = &tcpf;
char *s, *t;
if (*flgs == '0') {
s = strchr(flgs, '/');
if (s)
*s++ = '\0';
tcpf = strtol(flgs, NULL, 0);
fp = &tcpfm;
} else
s = flgs;
for (; *s; s++) {
if (*s == '/' && fp == &tcpf) {
fp = &tcpfm;
if (*(s + 1) == '0')
break;
continue;
}
if (!(t = index(flagset, *s))) {
fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s);
return 0;
}
*fp |= flags[t - flagset];
}
if (s && *s == '0')
tcpfm = strtol(s, NULL, 0);
if (!tcpfm)
tcpfm = 0xff;
*mask = tcpfm;
return tcpf;
}
/*
* count consecutive 1's in bit mask. If the mask generated by counting
* consecutive 1's is different to that passed, return -1, else return #
* of bits.
*/
int countbits(ip)
u_32_t ip;
{
u_32_t ipn;
int cnt = 0, i, j;
ip = ipn = ntohl(ip);
for (i = 32; i; i--, ipn *= 2)
if (ipn & 0x80000000)
cnt++;
else
break;
ipn = 0;
for (i = 32, j = cnt; i; i--, j--) {
ipn *= 2;
if (j > 0)
ipn++;
}
if (ipn == ip)
return cnt;
return -1;
}
#ifdef USE_INET6
int count6bits(msk)
u_32_t *msk;
{
int i = 0, k;
u_32_t j;
for (k = 3; k >= 0; k--)
if (msk[k] == 0xffffffff)
i += 32;
else {
for (j = msk[k]; j; j <<= 1)
if (j & 0x80000000)
i++;
}
return i;
}
#endif
char *portname(pr, port)
int pr, port;
{
static char buf[32];
struct protoent *p = NULL;
struct servent *sv = NULL, *sv1 = NULL;
if (pr == -1) {
if ((sv = getservbyport(htons(port), "tcp"))) {
strncpy(buf, sv->s_name, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
sv1 = getservbyport(htons(port), "udp");
sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
NULL : sv1;
}
if (sv)
return buf;
} else if (pr && (p = getprotobynumber(pr))) {
if ((sv = getservbyport(htons(port), p->p_name))) {
strncpy(buf, sv->s_name, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
return buf;
}
}
(void) sprintf(buf, "%d", port);
return buf;
}
int ratoi(ps, pi, min, max)
char *ps;
int *pi, min, max;
{
int i;
char *pe;
i = (int)strtol(ps, &pe, 0);
if (*pe != '\0' || i < min || i > max)
return 0;
*pi = i;
return 1;
}
int ratoui(ps, pi, min, max)
char *ps;
u_int *pi, min, max;
{
u_int i;
char *pe;
i = (u_int)strtol(ps, &pe, 0);
if (*pe != '\0' || i < min || i > max)
return 0;
*pi = i;
return 1;
}
void printhostmask(v, addr, mask)
int v;
u_32_t *addr, *mask;
{
struct in_addr ipa;
int ones;
#ifdef USE_INET6
if (v == 6) {
ones = count6bits(mask);
if (ones == 0 && !addr[0] && !addr[1] && !addr[2] && !addr[3])
printf("any");
else {
char ipbuf[64];
printf("%s/%d",
inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf)),
ones);
}
}
else
#endif
if (!*addr && !*mask)
printf("any");
else {
ipa.s_addr = *addr;
printf("%s", inet_ntoa(ipa));
if ((ones = countbits(*mask)) == -1) {
ipa.s_addr = *mask;
printf("/%s", inet_ntoa(ipa));
} else
printf("/%d", ones);
}
}
void printportcmp(pr, frp)
int pr;
frpcmp_t *frp;
{
static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
"<>", "><"};
if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE)
printf(" port %d %s %d", frp->frp_port,
pcmp1[frp->frp_cmp], frp->frp_top);
else
printf(" port %s %s", pcmp1[frp->frp_cmp],
portname(pr, frp->frp_port));
}
void printbuf(buf, len, zend)
char *buf;
int len, zend;
{
char *s, c;
int i;
for (s = buf, i = len; i; i--) {
c = *s++;
if (isprint(c))
putchar(c);
else
printf("\\%03o", c);
if ((c == '\0') && zend)
break;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -19,7 +19,7 @@
#include "facpri.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: facpri.c,v 1.2 1999/08/01 11:10:45 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: facpri.c,v 1.3 2000/03/13 22:10:18 darrenr Exp $";
#endif
typedef struct table {

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1999 by Darren Reed.
* Copyright (C) 1999-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: facpri.h,v 1.2 1999/08/01 11:10:46 darrenr Exp $
* $Id: facpri.h,v 1.3 2000/03/13 22:10:18 darrenr Exp $
*/
#ifndef __FACPRI_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1998 by Darren Reed & Guido van Rooij.
* Copyright (C) 1998-2000 by Darren Reed & Guido van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.2 2000/01/16 10:12:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.2 2000/05/22 10:26:11 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -19,7 +19,7 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.2 2000/01/16 10:12:14 da
# include <stdlib.h>
# include <string.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
@ -30,7 +30,7 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.2 2000/01/16 10:12:14 da
# include <sys/protosw.h>
#endif
#include <sys/socket.h>
#if defined(_KERNEL) && !defined(linux)
#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
@ -123,11 +123,12 @@ static struct wait_queue *ipfauthwait = NULL;
int fr_authsize = FR_NUMAUTH;
int fr_authused = 0;
int fr_defaultauthage = 600;
int fr_auth_lock = 0;
fr_authstat_t fr_authstats;
frauth_t fr_auth[FR_NUMAUTH];
static frauth_t fr_auth[FR_NUMAUTH];
mb_t *fr_authpkts[FR_NUMAUTH];
int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
frauthent_t *fae_list = NULL;
static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
static frauthent_t *fae_list = NULL;
frentry_t *ipauth = NULL;
@ -144,6 +145,9 @@ fr_info_t *fin;
u_32_t pass;
int i;
if (fr_auth_lock)
return 0;
READ_ENTER(&ipf_auth);
for (i = fr_authstart; i != fr_authend; ) {
/*
@ -196,19 +200,19 @@ fr_info_t *fin;
* If we do, store it and wake up any user programs which are waiting to
* hear about these events.
*/
int fr_newauth(m, fin, ip
#if defined(_KERNEL) && SOLARIS
, qif)
qif_t *qif;
#else
)
#endif
int fr_newauth(m, fin, ip)
mb_t *m;
fr_info_t *fin;
ip_t *ip;
{
#if defined(_KERNEL) && SOLARIS
qif_t *qif = fin->fin_qif;
#endif
int i;
if (fr_auth_lock)
return 0;
WRITE_ENTER(&ipf_auth);
if (fr_authstart > fr_authend) {
fr_authstats.fas_nospace++;
@ -238,14 +242,15 @@ ip_t *ip;
* them.
*/
# if SOLARIS && defined(_KERNEL)
if (ip == (ip_t *)m->b_rptr)
if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
# endif
{
register u_short bo;
bo = ip->ip_len;
ip->ip_len = htons(bo);
# if !SOLARIS /* 4.4BSD converts this ip_input.c, but I don't in solaris.c */
# if !SOLARIS && !defined(__NetBSD__)
/* 4.4BSD converts this ip_input.c, but I don't in solaris.c */
bo = ip->ip_id;
ip->ip_id = htons(bo);
# endif
@ -272,7 +277,7 @@ ip_t *ip;
int fr_auth_ioctl(data, cmd, fr, frptr)
caddr_t data;
#if defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
u_long cmd;
#else
int cmd;
@ -280,11 +285,8 @@ int cmd;
frentry_t *fr, **frptr;
{
mb_t *m;
#if defined(_KERNEL)
# if !SOLARIS
#if defined(_KERNEL) && !SOLARIS
struct ifqueue *ifq;
int s;
# endif
#endif
frauth_t auth, *au = &auth;
frauthent_t *fae, **faep;
@ -292,12 +294,17 @@ frentry_t *fr, **frptr;
switch (cmd)
{
case SIOCSTLCK :
error = fr_lock(data, &fr_auth_lock);
break;
case SIOCINIFR :
case SIOCRMIFR :
case SIOCADIFR :
error = EINVAL;
break;
case SIOCINAFR :
error = EINVAL;
break;
case SIOCRMAFR :
case SIOCADAFR :
for (faep = &fae_list; (fae = *faep); )
@ -318,8 +325,8 @@ frentry_t *fr, **frptr;
} else {
KMALLOC(fae, frauthent_t *);
if (fae != NULL) {
IRCOPY((char *)data, (char *)&fae->fae_fr,
sizeof(fae->fae_fr));
bcopy((char *)fr, (char *)&fae->fae_fr,
sizeof(*fr));
WRITE_ENTER(&ipf_auth);
fae->fae_age = fr_defaultauthage;
fae->fae_fr.fr_hits = 0;
@ -337,15 +344,18 @@ frentry_t *fr, **frptr;
READ_ENTER(&ipf_auth);
fr_authstats.fas_faelist = fae_list;
RWLOCK_EXIT(&ipf_auth);
IWCOPY((char *)&fr_authstats, data, sizeof(fr_authstats));
error = IWCOPYPTR((char *)&fr_authstats, data,
sizeof(fr_authstats));
break;
case SIOCAUTHW:
fr_authioctlloop:
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
IWCOPY((char *)&fr_auth[fr_authnext], data,
sizeof(fr_info_t));
error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data,
sizeof(fr_info_t));
RWLOCK_EXIT(&ipf_auth);
if (error)
break;
WRITE_ENTER(&ipf_auth);
fr_authnext++;
if (fr_authnext == FR_NUMAUTH)
@ -376,7 +386,9 @@ frentry_t *fr, **frptr;
goto fr_authioctlloop;
break;
case SIOCAUTHR:
IRCOPY(data, (caddr_t)&auth, sizeof(auth));
error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth));
if (error)
return error;
WRITE_ENTER(&ipf_auth);
i = au->fra_index;
if ((i < 0) || (i > FR_NUMAUTH) ||
@ -390,7 +402,6 @@ frentry_t *fr, **frptr;
fr_authpkts[i] = NULL;
#ifdef _KERNEL
RWLOCK_EXIT(&ipf_auth);
SPL_NET(s);
# ifndef linux
if (m && au->fra_info.fin_out) {
# if SOLARIS
@ -456,7 +467,6 @@ frentry_t *fr, **frptr;
}
}
# endif
SPL_X(s);
#endif /* _KERNEL */
break;
default :
@ -510,6 +520,9 @@ void fr_authexpire()
int s;
#endif
if (fr_auth_lock)
return;
SPL_NET(s);
WRITE_ENTER(&ipf_auth);
for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 1997-1998 by Darren Reed & Guido Van Rooij.
* Copyright (C) 1997-2000 by Darren Reed & Guido Van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_auth.h,v 2.1 1999/08/04 17:29:54 darrenr Exp $
* $Id: ip_auth.h,v 2.3.2.1 2000/05/22 10:26:11 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@ -50,15 +50,12 @@ extern int fr_authstart;
extern int fr_authend;
extern int fr_authsize;
extern int fr_authused;
extern int fr_auth_lock;
extern u_32_t fr_checkauth __P((ip_t *, fr_info_t *));
extern void fr_authexpire __P((void));
extern void fr_authunload __P((void));
extern mb_t *fr_authpkts[];
#if defined(_KERNEL) && SOLARIS
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *));
#else
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
#else

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.1.2.3 1999/11/18 13:55:26 darrenr Exp $
* $Id: ip_compat.h,v 2.26.2.3 2000/04/28 14:56:49 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -27,6 +27,11 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#if SOLARIS2 >= 8
# ifndef USE_INET6
# define USE_INET6
# endif
#endif
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
@ -90,19 +95,29 @@ struct ether_addr {
# ifndef KERNEL
# define _KERNEL
# undef RES_INIT
# if SOLARIS2 >= 8
# include <netinet/ip6.h>
# endif
# include <inet/common.h>
# include <inet/ip.h>
# include <inet/ip_ire.h>
# undef _KERNEL
# else /* _KERNEL */
# if SOLARIS2 >= 8
# include <netinet/ip6.h>
# endif
# include <inet/common.h>
# include <inet/ip.h>
# include <inet/ip_ire.h>
# endif /* _KERNEL */
# if SOLARIS2 >= 8
# include <inet/ip_if.h>
# include <netinet/ip6.h>
# include <inet/ip6.h>
# define ipif_local_addr ipif_lcl_addr
/* Only defined in private include file */
# ifndef V4_PART_OF_V6
# define V4_PART_OF_V6(v6) v6.s6_addr32[3]
# endif
# endif
#else
# if !defined(__sgi)
@ -124,12 +139,25 @@ typedef int minor_t;
# define QUAD_T long
#endif /* BSD > 199306 */
/*
* These operating systems already take care of the problem for us.
*/
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
defined(__sgi)
typedef u_int32_t u_32_t;
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 104110000)
# include "opt_inet.h"
# endif
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
!defined(KLD_MODULE)
# include "opt_inet6.h"
# endif
# ifdef INET6
# define USE_INET6
# endif
# endif
#else
/*
* Really, any arch where sizeof(long) != sizeof(int).
@ -137,10 +165,38 @@ typedef u_int32_t u_32_t;
# if defined(__alpha__) || defined(__alpha) || defined(_LP64)
typedef unsigned int u_32_t;
# else
typedef unsigned long u_32_t;
# if SOLARIS2 >= 6
typedef uint32_t u_32_t;
# else
typedef unsigned int u_32_t;
# endif
# endif
#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */
#ifdef USE_INET6
# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
# include <netinet/ip6.h>
# ifdef _KERNEL
# include <netinet6/ip6_var.h>
# endif
typedef struct ip6_hdr ip6_t;
# endif
union i6addr {
u_32_t i6[4];
struct in_addr in4;
struct in6_addr in6;
};
#else
union i6addr {
u_32_t i6[4];
struct in_addr in4;
};
#endif
#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)
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
@ -202,12 +258,15 @@ typedef unsigned long u_32_t;
#define IPOPT_FINN 205 /* FINN */
#if defined(__FreeBSD__) && defined(KERNEL)
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
# if __FreeBSD__ < 3
# include <machine/spl.h>
# endif
# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
# define ACTUALLY_LKM_NOT_KERNEL
# else
# if __FreeBSD__ == 3
# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
# define ACTUALLY_LKM_NOT_KERNEL
# endif
# endif
# endif
#endif /* __FreeBSD__ && KERNEL */
@ -215,12 +274,39 @@ typedef unsigned long u_32_t;
* Build some macros and #defines to enable the same code to compile anywhere
* Well, that's the idea, anyway :-)
*/
#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
# define ATOMIC_INCL ATOMIC_INC
# define ATOMIC_INC64 ATOMIC_INC
# define ATOMIC_INC32 ATOMIC_INC
# define ATOMIC_INC16 ATOMIC_INC
# define ATOMIC_DECL ATOMIC_DEC
# define ATOMIC_DEC64 ATOMIC_DEC
# define ATOMIC_DEC32 ATOMIC_DEC
# define ATOMIC_DEC16 ATOMIC_DEC
#endif
#ifdef KERNEL
# if SOLARIS
# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
# if SOLARIS2 >= 6
# include <sys/atomic.h>
# if SOLARIS2 == 6
# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1)
# define ATOMIC_DECL(x) atomic_add_long((uint32_t*)&(x), -1)
# else
# define ATOMIC_INCL(x) atomic_add_long(&(x), 1)
# define ATOMIC_DECL(x) atomic_add_long(&(x), -1)
# endif
# define ATOMIC_INC64(x) atomic_add_64((uint64_t*)&(x), 1)
# define ATOMIC_INC32(x) atomic_add_32((uint32_t*)&(x), 1)
# define ATOMIC_INC16(x) atomic_add_16((uint16_t*)&(x), 1)
# define ATOMIC_DEC64(x) atomic_add_64((uint64_t*)&(x), -1)
# define ATOMIC_DEC32(x) atomic_add_32((uint32_t*)&(x), -1)
# define ATOMIC_DEC16(x) atomic_add_16((uint16_t*)&(x), -1)
# else
# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
mutex_exit(&ipf_rw); }
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
mutex_exit(&ipf_rw); }
# endif
# define MUTEX_ENTER(x) mutex_enter(x)
# if 1
# define KRWLOCK_T krwlock_t
@ -243,10 +329,14 @@ typedef unsigned long u_32_t;
# define RWLOCK_EXIT(x) mutex_exit(x)
# define RW_DESTROY(x) mutex_destroy(x)
# endif
# define MUTEX_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
# define MUTEX_DESTROY(x) mutex_destroy(x)
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
# define IWCOPY(a,b,c) copyout((a), (b), (c))
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
# define FREE_MB_T(m) freemsg(m)
# define SPL_NET(x) ;
# define SPL_IMP(x) ;
@ -282,9 +372,11 @@ typedef struct qif {
* in case the ILL has disappeared...
*/
size_t qf_hl; /* header length */
int qf_sap;
} qif_t;
extern ill_t *get_unit __P((char *));
# define GETUNIT(n) get_unit((n))
extern ill_t *get_unit __P((char *, int));
# define GETUNIT(n, v) get_unit(n, v)
# define IFNAME(x) ((ill_t *)x)->ill_name
# else /* SOLARIS */
# if defined(__sgi)
# define hz HZ
@ -306,35 +398,48 @@ typedef struct {
# define WRITE_ENTER(x) MUTEX_ENTER(x)
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
# define MUTEX_INIT(x,y,z) (x).l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
# define MUTEX_DESTROY(x) LOCK_DEALLOC((x).l)
# else /* __sgi */
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define RW_UPGRADE(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# define MUTEX_INIT(x,y,z) ;
# define MUTEX_DESTROY(x) ;
# endif /* __sgi */
# ifndef linux
# define FREE_MB_T(m) m_freem(m)
# define MTOD(m,t) mtod(m,t)
# define IRCOPY(a,b,c) bcopy((a), (b), (c))
# define IWCOPY(a,b,c) bcopy((a), (b), (c))
# 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
# endif /* !linux */
# endif /* SOLARIS */
# ifdef sun
# if !SOLARIS
# include <sys/kmem_alloc.h>
# define GETUNIT(n) ifunit((n), IFNAMSIZ)
# define GETUNIT(n, v) ifunit(n, IFNAMSIZ)
# define IFNAME(x) ((struct ifnet *)x)->if_name
# endif
# else
# ifndef linux
# define GETUNIT(n) ifunit((n))
# define GETUNIT(n, v) ifunit(n)
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
# define IFNAME(x) ((struct ifnet *)x)->if_xname
# else
# define IFNAME(x) ((struct ifnet *)x)->if_name
# endif
# endif
# endif /* sun */
@ -408,6 +513,8 @@ extern vm_map_t kmem_map;
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define MUTEX_INIT(x,y,z) ;
# define MUTEX_DESTROY(x) ;
# define WRITE_ENTER(x) ;
# define RW_UPGRADE(x) ;
# define MUTEX_DOWNGRADE(x) ;
@ -421,9 +528,11 @@ 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 GETUNIT(x) get_unit(x)
# define IRCOPY(a,b,c) bcopy((a), (b), (c))
# define IWCOPY(a,b,c) bcopy((a), (b), (c))
# 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
#endif /* KERNEL */
#if SOLARIS
@ -745,7 +854,7 @@ typedef struct uio {
# define if_name name
# ifdef KERNEL
# define GETUNIT(x) dev_get(x)
# define GETUNIT(x, v) dev_get(x)
# define FREE_MB_T(m) kfree_skb(m, FREE_WRITE)
# define uniqtime do_gettimeofday
# undef INT_MAX
@ -767,16 +876,50 @@ typedef struct uio {
# define KMALLOCS(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
# define KFREE(x) kfree_s((x), sizeof(*(x)))
# define KFREES(x,s) kfree_s((x), (s))
# define IRCOPY(a,b,c) { \
error = verify_area(VERIFY_READ, (a) ,(c)); \
if (!error) \
memcpy_fromfs((b), (a), (c)); \
}
# define IWCOPY(a,b,c) { \
error = verify_area(VERIFY_WRITE, (b), (c)); \
if (!error) \
memcpy_tofs((b), (a), (c)); \
}
#define IRCOPY(const void *a, void *b, size_t c) { \
int error; \
error = verify_area(VERIFY_READ, a ,c); \
if (!error) \
memcpy_fromfs(b, a, c); \
return error; \
}
static inline int IWCOPY(const void *a, void *b, size_t c)
{
int error;
error = verify_area(VERIFY_WRITE, b, c);
if (!error)
memcpy_tofs(b, a, c);
return error;
}
static inline int IRCOPYPTR(const void *a, void *b, size_t c) {
caddr_t ca;
int error;
error = verify_area(VERIFY_READ, a ,sizeof(ca));
if (!error) {
memcpy_fromfs(ca, a, sizeof(ca));
error = verify_area(VERIFY_READ, ca , c);
if (!error)
memcpy_fromfs(b, ca, c);
}
return error;
}
static inline int IWCOPYPTR(const void *a, void *b, size_t c) {
caddr_t ca;
int error;
error = verify_area(VERIFY_READ, b ,sizeof(ca));
if (!error) {
memcpy_fromfs(ca, b, sizeof(ca));
error = verify_area(VERIFY_WRITE, ca, c);
if (!error)
memcpy_tofs(ca, a, c);
}
return error;
}
# else
# define __KERNEL__
# undef INT_MAX
@ -817,12 +960,18 @@ struct ether_addr {
#define A_A &
#endif
#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG)
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
#ifndef ICMP_ROUTERSOLICIT
# define ICMP_ROUTERSOLICIT 10
#endif
#undef ICMP_MAX_UNREACH
#define ICMP_MAX_UNREACH 14
#undef ICMP_MAXTYPE
#define ICMP_MAXTYPE 18
/*
* ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
* another IP header and then 64 bits of data, totalling 56. Of course,
@ -832,5 +981,6 @@ struct ether_addr {
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
#define ICMP6ERR_MINPKTLEN (20 + 8)
#endif /* __IP_COMPAT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_fil.h,v 2.3.2.7 2000/01/27 08:49:41 darrenr Exp $
* $Id: ip_fil.h,v 2.29.2.2 2000/05/22 10:26:13 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -37,58 +37,69 @@
#endif
#if defined(__STDC__) || defined(__GNUC__)
# define SIOCADAFR _IOW('r', 60, struct frentry)
# define SIOCRMAFR _IOW('r', 61, struct frentry)
# define SIOCADAFR _IOW('r', 60, struct frentry *)
# define SIOCRMAFR _IOW('r', 61, struct frentry *)
# define SIOCSETFF _IOW('r', 62, u_int)
# define SIOCGETFF _IOR('r', 63, u_int)
# define SIOCGETFS _IOR('r', 64, struct friostat)
# define SIOCGETFS _IOWR('r', 64, struct friostat *)
# define SIOCIPFFL _IOWR('r', 65, int)
# define SIOCIPFFB _IOR('r', 66, int)
# define SIOCADIFR _IOW('r', 67, struct frentry)
# define SIOCRMIFR _IOW('r', 68, struct frentry)
# define SIOCADIFR _IOW('r', 67, struct frentry *)
# define SIOCRMIFR _IOW('r', 68, struct frentry *)
# define SIOCSWAPA _IOR('r', 69, u_int)
# define SIOCINAFR _IOW('r', 70, struct frentry)
# define SIOCINIFR _IOW('r', 71, struct frentry)
# define SIOCINAFR _IOW('r', 70, struct frentry *)
# define SIOCINIFR _IOW('r', 71, struct frentry *)
# define SIOCFRENB _IOW('r', 72, u_int)
# define SIOCFRSYN _IOW('r', 73, u_int)
# define SIOCFRZST _IOWR('r', 74, struct friostat)
# define SIOCZRLST _IOWR('r', 75, struct frentry)
# define SIOCAUTHW _IOWR('r', 76, struct fr_info)
# define SIOCAUTHR _IOWR('r', 77, struct fr_info)
# define SIOCATHST _IOWR('r', 78, struct fr_authstat)
# define SIOCFRZST _IOWR('r', 74, struct friostat *)
# define SIOCZRLST _IOWR('r', 75, struct frentry *)
# define SIOCAUTHW _IOWR('r', 76, struct fr_info *)
# define SIOCAUTHR _IOWR('r', 77, struct fr_info *)
# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR('r', 79, u_int)
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
# define SIOCSTGET _IOWR('r', 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR('r', 82, struct natget *)
# define SIOCGFRST _IOWR('r', 83, struct ipfrstat *)
#else
# define SIOCADAFR _IOW(r, 60, struct frentry)
# define SIOCRMAFR _IOW(r, 61, struct frentry)
# define SIOCADAFR _IOW(r, 60, struct frentry *)
# define SIOCRMAFR _IOW(r, 61, struct frentry *)
# define SIOCSETFF _IOW(r, 62, u_int)
# define SIOCGETFF _IOR(r, 63, u_int)
# define SIOCGETFS _IOR(r, 64, struct friostat)
# define SIOCGETFS _IOWR(r, 64, struct friostat *)
# define SIOCIPFFL _IOWR(r, 65, int)
# define SIOCIPFFB _IOR(r, 66, int)
# define SIOCADIFR _IOW(r, 67, struct frentry)
# define SIOCRMIFR _IOW(r, 68, struct frentry)
# define SIOCADIFR _IOW(r, 67, struct frentry *)
# define SIOCRMIFR _IOW(r, 68, struct frentry *)
# define SIOCSWAPA _IOR(r, 69, u_int)
# define SIOCINAFR _IOW(r, 70, struct frentry)
# define SIOCINIFR _IOW(r, 71, struct frentry)
# define SIOCINAFR _IOW(r, 70, struct frentry *)
# define SIOCINIFR _IOW(r, 71, struct frentry *)
# define SIOCFRENB _IOW(r, 72, u_int)
# define SIOCFRSYN _IOW(r, 73, u_int)
# define SIOCFRZST _IOWR(r, 74, struct friostat)
# define SIOCZRLST _IOWR(r, 75, struct frentry)
# define SIOCAUTHW _IOWR(r, 76, struct fr_info)
# define SIOCAUTHR _IOWR(r, 77, struct fr_info)
# define SIOCATHST _IOWR(r, 78, struct fr_authstat)
# define SIOCFRZST _IOWR(r, 74, struct friostat *)
# define SIOCZRLST _IOWR(r, 75, struct frentry *)
# define SIOCAUTHW _IOWR(r, 76, struct fr_info *)
# define SIOCAUTHR _IOWR(r, 77, struct fr_info *)
# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR(r, 79, u_int)
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
# define SIOCSTGET _IOWR(r, 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR(r, 82, struct natget *)
# define SIOCGFRST _IOWR(r, 83, struct ipfrstat *)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
#define SIOCINSFR SIOCINAFR
typedef struct fr_ip {
u_char fi_v:4; /* IP version */
u_char fi_fl:4; /* packet flags */
u_char fi_tos; /* IP packet TOS */
u_char fi_ttl; /* IP packet TTL */
u_char fi_p; /* IP packet protocol */
struct in_addr fi_src; /* source address from packet */
struct in_addr fi_dst; /* destination address from packet */
u_32_t fi_v:4; /* IP version */
u_32_t fi_fl:4; /* packet flags */
u_32_t fi_tos:8; /* IP packet TOS */
u_32_t fi_ttl:8; /* IP packet TTL */
u_32_t fi_p:8; /* IP packet protocol */
union i6addr fi_src; /* source address from packet */
union i6addr fi_dst; /* destination address from packet */
u_32_t fi_optmsk; /* bitmask composed from IP options */
u_short fi_secmsk; /* bitmask composed from IP security options */
u_short fi_auth; /* authentication code from IP sec. options */
@ -100,13 +111,21 @@ typedef struct fr_ip {
#define FI_SHORT (FF_SHORT >> 24)
#define FI_CMP (FI_OPTIONS|FI_TCPUDP|FI_SHORT)
#define fi_saddr fi_src.in4.s_addr
#define fi_daddr fi_dst.in4.s_addr
/*
* These are both used by the state and NAT code to indicate that one port or
* the other should be treated as a wildcard.
*/
#define FI_W_SPORT 0x00000100
#define FI_W_DPORT 0x00000200
#define FI_WILD (FI_W_SPORT|FI_W_DPORT)
#define FI_WILDP (FI_W_SPORT|FI_W_DPORT)
#define FI_W_SADDR 0x00000400
#define FI_W_DADDR 0x00000800
#define FI_WILDA (FI_W_SADDR|FI_W_DADDR)
#define FI_NEWFR 0x00001000
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
@ -119,18 +138,22 @@ typedef struct fr_info {
/* From here on is packet specific */
u_char fin_icode; /* ICMP error to return */
u_short fin_rule; /* rule # last matched */
u_short fin_group; /* group number, -1 for none */
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_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
void *fin_mp; /* pointer to pointer to mbuf */
#if SOLARIS && defined(_KERNEL)
#if SOLARIS
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
/*
* Size for compares on fr_info structures
*/
@ -147,10 +170,30 @@ typedef struct frdest {
char fd_ifname[IFNAMSIZ];
} frdest_t;
typedef struct frpcmp {
int frp_cmp; /* data for port comparisons */
u_short frp_port; /* top port for <> and >< */
u_short frp_top; /* top port for <> and >< */
} frpcmp_t;
typedef struct frtuc {
u_char ftu_tcpfm; /* tcp flags mask */
u_char ftu_tcpf; /* tcp flags */
frpcmp_t ftu_src;
frpcmp_t ftu_dst;
} frtuc_t;
#define ftu_scmp ftu_src.frp_cmp
#define ftu_dcmp ftu_dst.frp_cmp
#define ftu_sport ftu_src.frp_port
#define ftu_dport ftu_dst.frp_port
#define ftu_stop ftu_src.frp_top
#define ftu_dtop ftu_dst.frp_top
typedef struct frentry {
struct frentry *fr_next;
u_short fr_group; /* group to which this rule belongs */
u_short fr_grhead; /* group # which this rule starts */
u_32_t fr_group; /* group to which this rule belongs */
u_32_t fr_grhead; /* group # which this rule starts */
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
void *fr_ifa;
@ -169,38 +212,42 @@ typedef struct frentry {
struct fr_ip fr_ip;
struct fr_ip fr_mip; /* mask structure */
u_char fr_tcpfm; /* tcp flags mask */
u_char fr_tcpf; /* tcp flags */
u_short fr_icmpm; /* data for ICMP packets (mask) */
u_short fr_icmp;
u_char fr_scmp; /* data for port comparisons */
u_char fr_dcmp;
u_short fr_dport;
u_short fr_sport;
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
frtuc_t fr_tuc;
u_32_t fr_flags; /* per-rule flags && options (see below) */
u_short fr_skip; /* # of rules to skip */
u_short fr_loglevel; /* syslog log facility + priority */
u_int fr_skip; /* # of rules to skip */
u_int fr_loglevel; /* syslog log facility + priority */
int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
char fr_icode; /* return ICMP code */
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
struct frdest fr_tif; /* "to" interface */
struct frdest fr_dif; /* duplicate packet interfaces */
u_int fr_cksum; /* checksum on filter rules for performance */
} frentry_t;
#define fr_v fr_ip.fi_v
#define fr_proto fr_ip.fi_p
#define fr_ttl fr_ip.fi_ttl
#define fr_tos fr_ip.fi_tos
#define fr_dst fr_ip.fi_dst
#define fr_src fr_ip.fi_src
#define fr_dmsk fr_mip.fi_dst
#define fr_smsk fr_mip.fi_src
#define fr_tcpfm fr_tuc.ftu_tcpfm
#define fr_tcpf fr_tuc.ftu_tcpf
#define fr_scmp fr_tuc.ftu_scmp
#define fr_dcmp fr_tuc.ftu_dcmp
#define fr_dport fr_tuc.ftu_dport
#define fr_sport fr_tuc.ftu_sport
#define fr_stop fr_tuc.ftu_stop
#define fr_dtop fr_tuc.ftu_dtop
#define fr_dst fr_ip.fi_dst.in4
#define fr_src fr_ip.fi_src.in4
#define fr_dmsk fr_mip.fi_dst.in4
#define fr_smsk fr_mip.fi_src.in4
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
@ -287,13 +334,16 @@ typedef struct filterstats {
u_long fr_chit; /* cached hit */
u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
u_long fr_badsrc; /* source received doesn't match route */
#if SOLARIS
u_long fr_notdata; /* PROTO/PCPROTO that have no data */
u_long fr_nodata; /* mblks that have no data */
u_long fr_bad; /* bad IP packets to the filter */
u_long fr_notip; /* packets passed through no on ip queue */
u_long fr_drop; /* packets dropped - no info for them! */
u_long fr_copy; /* messages copied due to db_ref > 1 */
#endif
u_long fr_ipv6[2]; /* IPv6 packets in/out */
} filterstats_t;
/*
@ -305,6 +355,10 @@ typedef struct friostat {
struct frentry *f_fout[2];
struct frentry *f_acctin[2];
struct frentry *f_acctout[2];
struct frentry *f_fin6[2];
struct frentry *f_fout6[2];
struct frentry *f_acctin6[2];
struct frentry *f_acctout6[2];
struct frentry *f_auth;
struct frgroup *f_groups[3][2];
u_long f_froute[2];
@ -312,11 +366,8 @@ typedef struct friostat {
char f_active; /* 1 or 0 - active rule set */
char f_running; /* 1 if running, else 0 */
char f_logging; /* 1 if enabled, else 0 */
#if !SOLARIS && defined(sun)
char f_version[25]; /* version string */
#else
char f_version[32]; /* version string */
#endif
int f_locks[4];
} friostat_t;
typedef struct optlist {
@ -329,7 +380,7 @@ typedef struct optlist {
* Group list structure.
*/
typedef struct frgroup {
u_short fg_num;
u_32_t fg_num;
struct frgroup *fg_next;
struct frentry *fg_head;
struct frentry **fg_start;
@ -362,9 +413,9 @@ typedef struct ipflog {
#endif
u_char fl_plen; /* extra data after hlen */
u_char fl_hlen; /* length of IP headers saved */
u_short fl_rule; /* assume never more than 64k rules, total */
u_short fl_group;
u_short fl_loglevel; /* syslog log level */
u_32_t fl_rule;
u_32_t fl_group;
u_32_t fl_flags;
u_32_t fl_lflags;
} ipflog_t;
@ -433,7 +484,7 @@ extern int send_reset __P((ip_t *, struct ifnet *));
extern int icmp_error __P((ip_t *, struct ifnet *));
extern int ipf_log __P((void));
extern int ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
extern struct ifnet *get_unit __P((char *));
extern struct ifnet *get_unit __P((char *, int));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
extern int iplioctl __P((dev_t, u_long, caddr_t, int));
@ -454,11 +505,12 @@ 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
extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *,
int, qif_t *, mb_t **));
extern int icmp_error __P((ip_t *, int, int, qif_t *, struct in_addr));
# if SOLARIS2 >= 7
extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
# else
@ -467,25 +519,18 @@ extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
extern int iplopen __P((dev_t *, int, int, cred_t *));
extern int iplclose __P((dev_t, int, int, cred_t *));
extern int ipfsync __P((void));
extern int send_reset __P((fr_info_t *, ip_t *, qif_t *));
extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **,
fr_info_t *, frdest_t *));
extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *));
extern void copyout_mblk __P((mblk_t *, size_t, size_t, char *));
extern int fr_qin __P((queue_t *, mblk_t *));
extern int fr_qout __P((queue_t *, mblk_t *));
# ifdef IPFILTER_LOG
extern int iplread __P((dev_t, struct uio *, cred_t *));
# endif
# else /* SOLARIS */
extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
# ifdef linux
extern int send_reset __P((tcpiphdr_t *, struct ifnet *));
# else
extern int send_reset __P((fr_info_t *, struct ip *));
extern int send_icmp_err __P((ip_t *, int, int, void *, struct in_addr));
# endif
extern int send_reset __P((struct ip *, fr_info_t *));
extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
extern size_t mbufchainlen __P((mb_t *));
# ifdef __sgi
@ -536,35 +581,49 @@ extern int iplread(struct inode *, struct file *, char *, int);
# endif /* SOLARIS */
#endif /* #ifndef _KERNEL */
extern char *memstr __P((char *, char *, int, int));
extern void fixskip __P((frentry_t **, frentry_t *, int));
extern int countbits __P((u_32_t));
extern int ipldetach __P((void));
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
extern u_short ipf_cksum __P((u_short *, int));
extern int fr_copytolog __P((int, char *, int));
extern void fr_forgetifp __P((void *));
extern int ircopyptr __P((void *, void *, size_t));
extern int iwcopyptr __P((void *, void *, size_t));
extern int frflush __P((minor_t, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_int, frentry_t *, minor_t, int));
extern frgroup_t *fr_findgroup __P((u_int, u_32_t, minor_t, int, frgroup_t ***));
extern void fr_delgroup __P((u_int, u_32_t, minor_t, int));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
extern void fr_delgroup __P((u_32_t, u_32_t, minor_t, int));
extern frgroup_t *fr_findgroup __P((u_32_t, u_32_t, minor_t, int,
frgroup_t ***));
extern int fr_copytolog __P((int, char *, int));
extern void fr_forgetifp __P((void *));
extern void fr_getstat __P((struct friostat *));
extern int fr_ifpaddr __P((int, void *, struct in_addr *));
extern int fr_lock __P((caddr_t, int *));
extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
extern int fr_ifpaddr __P((void *, struct in_addr *));
extern char *memstr __P((char *, char *, int, int));
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
extern int fr_tcpudpchk __P((frtuc_t *, fr_info_t *));
extern int fr_verifysrc __P((struct in_addr, void *));
extern int ipl_unreach;
extern int fr_running;
extern u_long ipl_frouteok[2];
extern int fr_pass;
extern int fr_flags;
extern int fr_active;
extern int fr_chksrc;
extern fr_info_t frcache[2];
extern char ipfilter_version[];
#ifdef IPFILTER_LOG
extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
extern size_t iplused[IPL_LOGMAX + 1];
#endif
extern struct frentry *ipfilter[2][2], *ipacct[2][2];
#ifdef USE_INET6
extern struct frentry *ipfilter6[2][2], *ipacct6[2][2];
extern int icmptoicmp6types[ICMP_MAXTYPE+1];
extern int icmptoicmp6unreach[ICMP_MAX_UNREACH];
#endif
extern struct frgroup *ipfgroups[3][2];
extern struct filterstats frstats[];

View File

@ -1,13 +1,13 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.4 1999/11/28 04:52:10 darrenr Exp $";
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.3 2000/05/05 15:10:23 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@ -24,7 +24,7 @@ static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.4 1999/11/28 04:52:10 da
# include <string.h>
# include <stdlib.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
@ -85,13 +85,20 @@ static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.4 1999/11/28 04:52:10 da
extern struct callout_handle ipfr_slowtimer_ch;
# endif
#endif
#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
# include <sys/callout.h>
extern struct callout ipfr_slowtimer_ch;
#endif
ipfr_t *ipfr_heads[IPFT_SIZE];
ipfr_t *ipfr_nattab[IPFT_SIZE];
ipfrstat_t ipfr_stats;
int ipfr_inuse = 0,
fr_ipfrttl = 120; /* 60 seconds */
static ipfr_t *ipfr_heads[IPFT_SIZE];
static ipfr_t *ipfr_nattab[IPFT_SIZE];
static ipfrstat_t ipfr_stats;
static int ipfr_inuse = 0;
int fr_ipfrttl = 120; /* 60 seconds */
int fr_frag_lock = 0;
#ifdef _KERNEL
# if SOLARIS2 >= 7
extern timeout_id_t ipfr_timer_id;
@ -155,7 +162,7 @@ ipfr_t *table[];
for (fp = &table[idx]; (fra = *fp); fp = &fra->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fra->ipfr_src,
IPFR_CMPSZ)) {
ATOMIC_INC(ipfr_stats.ifs_exists);
ATOMIC_INCL(ipfr_stats.ifs_exists);
return NULL;
}
@ -165,12 +172,12 @@ ipfr_t *table[];
*/
KMALLOC(fra, ipfr_t *);
if (fra == NULL) {
ATOMIC_INC(ipfr_stats.ifs_nomem);
ATOMIC_INCL(ipfr_stats.ifs_nomem);
return NULL;
}
if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
ATOMIC_INC(fin->fin_fr->fr_ref);
ATOMIC_INC32(fin->fin_fr->fr_ref);
}
@ -190,8 +197,8 @@ ipfr_t *table[];
* Compute the offset of the expected start of the next packet.
*/
fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
ATOMIC_INC(ipfr_stats.ifs_new);
ATOMIC_INC(ipfr_inuse);
ATOMIC_INCL(ipfr_stats.ifs_new);
ATOMIC_INC32(ipfr_inuse);
return fra;
}
@ -203,6 +210,8 @@ u_int pass;
{
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
@ -218,6 +227,8 @@ nat_t *nat;
{
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@ -291,7 +302,7 @@ ipfr_t *table[];
else
f->ipfr_off = atoff;
}
ATOMIC_INC(ipfr_stats.ifs_hits);
ATOMIC_INCL(ipfr_stats.ifs_hits);
return f;
}
return NULL;
@ -308,6 +319,8 @@ fr_info_t *fin;
nat_t *nat;
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
@ -336,6 +349,8 @@ fr_info_t *fin;
frentry_t *fr = NULL;
ipfr_t *fra;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
READ_ENTER(&ipf_frag);
fra = ipfr_lookup(ip, fin, ipfr_heads);
if (fra != NULL)
@ -371,7 +386,7 @@ ipfr_t *fra;
fr = fra->ipfr_rule;
if (fr != NULL) {
ATOMIC_DEC(fr->fr_ref);
ATOMIC_DEC32(fr->fr_ref);
if (fr->fr_ref == 0)
KFREE(fr);
}
@ -418,19 +433,7 @@ void ipfr_unload()
#ifdef _KERNEL
/*
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
# else
void ipfr_slowtimer __P((void *ptr))
# endif
# else
int ipfr_slowtimer()
# endif
void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
nat_t *nat;
@ -438,18 +441,11 @@ int ipfr_slowtimer()
#if defined(_KERNEL)
# if !SOLARIS
int s;
# else
extern int fr_running;
if (fr_running <= 0)
return;
# endif
#endif
READ_ENTER(&ipf_solaris);
#ifdef __sgi
ipfilter_sgi_intfsync();
#endif
if (fr_frag_lock)
return;
SPL_NET(s);
WRITE_ENTER(&ipf_frag);
@ -465,8 +461,8 @@ int ipfr_slowtimer()
if (fra->ipfr_ttl == 0) {
*fp = fra->ipfr_next;
ipfr_delete(fra);
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
ATOMIC_INCL(ipfr_stats.ifs_expire);
ATOMIC_DEC32(ipfr_inuse);
} else
fp = &fra->ipfr_next;
}
@ -485,8 +481,8 @@ int ipfr_slowtimer()
for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
--fra->ipfr_ttl;
if (fra->ipfr_ttl == 0) {
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
ATOMIC_INCL(ipfr_stats.ifs_expire);
ATOMIC_DEC32(ipfr_inuse);
nat = fra->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fra)
@ -500,23 +496,55 @@ int ipfr_slowtimer()
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}
/*
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
# else
void ipfr_slowtimer __P((void *ptr))
# endif
# else
int ipfr_slowtimer()
# endif
{
#if defined(_KERNEL) && SOLARIS
extern int fr_running;
if (fr_running <= 0)
return;
#endif
READ_ENTER(&ipf_solaris);
#ifdef __sgi
ipfilter_sgi_intfsync();
#endif
ipfr_fragexpire();
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
# if SOLARIS
# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
RWLOCK_EXIT(&ipf_solaris);
# else
# ifndef linux
# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000)
callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
# else
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
# endif
# if (BSD < 199306) && !defined(__sgi)
# if (BSD < 199306) && !defined(__sgi)
return 0;
# endif
# endif
RWLOCK_EXIT(&ipf_solaris);
# endif /* FreeBSD */
# endif /* NetBSD */
# endif /* SOLARIS */
}
#endif /* defined(_KERNEL) */

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.2 1999/08/06 06:26:38 darrenr Exp $
* $Id: ip_frag.h,v 2.4 2000/03/13 22:10:21 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@ -42,6 +42,7 @@ typedef struct ipfrstat {
#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
extern int fr_ipfrttl;
extern int fr_frag_lock;
extern ipfrstat_t *ipfr_fragstats __P((void));
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
@ -49,6 +50,7 @@ extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
extern void ipfr_forget __P((void *));
extern void ipfr_unload __P((void));
extern void ipfr_fragexpire __P((void));
#if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)

View File

@ -1,12 +1,15 @@
/*
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_ftp_pxy.c,v 2.7.2.7 2000/05/13 14:28:14 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
#define isdigit(x) ((x) >= '0' && (x) <= '9')
#define isupper(x) ((unsigned)((x) - 'A') <= 'Z' - 'A')
#define IPF_FTP_PROXY
@ -14,17 +17,24 @@ extern kmutex_t ipf_rw;
#define IPF_MAXPORTLEN 30
#define IPF_MIN227LEN 39
#define IPF_MAX227LEN 51
#define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */
int ippr_ftp_init __P((void));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_complete __P((char *, size_t));
int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_portmsg __P((fr_info_t *, ip_t *, nat_t *));
int ippr_ftp_pasvmsg __P((fr_info_t *, ip_t *, nat_t *));
u_short ipf_ftp_atoi __P((char **));
int ippr_ftp_init __P((void));
int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
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));
u_short ippr_ftp_atoi __P((char **));
static frentry_t natfr;
int ippr_ftp_pasvonly = 0;
/*
@ -39,48 +49,47 @@ int ippr_ftp_init()
}
/*
* ipf_ftp_atoi - implement a version of atoi which processes numbers in
* pairs separated by commas (which are expected to be in the range 0 - 255),
* returning a 16 bit number combining either side of the , as the MSB and
* LSB.
*/
u_short ipf_ftp_atoi(ptr)
char **ptr;
int ippr_ftp_new(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
register char *s = *ptr, c;
register u_char i = 0, j = 0;
ftpinfo_t *ftp;
ftpside_t *f;
while ((c = *s++) && isdigit(c)) {
i *= 10;
i += c - '0';
}
if (c != ',') {
*ptr = NULL;
return 0;
}
while ((c = *s++) && isdigit(c)) {
j *= 10;
j += c - '0';
}
*ptr = s;
return (i << 8) | j;
KMALLOC(ftp, ftpinfo_t *);
if (ftp == NULL)
return -1;
aps->aps_data = ftp;
aps->aps_psiz = sizeof(ftpinfo_t);
bzero((char *)ftp, sizeof(*ftp));
f = &ftp->ftp_side[0];
f->ftps_rptr = f->ftps_buf;
f->ftps_wptr = f->ftps_buf;
f = &ftp->ftp_side[1];
f->ftps_rptr = f->ftps_buf;
f->ftps_wptr = f->ftps_buf;
return 0;
}
int ippr_ftp_portmsg(fin, ip, nat)
int ippr_ftp_port(fin, ip, nat, f, dlen)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
ftpside_t *f;
int dlen;
{
char portbuf[IPF_MAXPORTLEN + 1], newbuf[IPF_MAXPORTLEN + 1], *s;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
size_t nlen = 0, dlen, olen;
char newbuf[IPF_FTPBUFSZ], *s;
u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
struct in_addr swip;
int off, inc = 0;
size_t nlen, olen;
fr_info_t fi;
int inc, off;
nat_t *ipn;
mb_t *m;
#if SOLARIS
@ -88,46 +97,34 @@ nat_t *nat;
#endif
tcp = (tcphdr_t *)fin->fin_dp;
bzero(portbuf, sizeof(portbuf));
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
if (dlen > 0)
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
m = *(mb_t **)fin->fin_mp;
dlen = mbufchainlen(m) - off;
if (dlen > 0)
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
if (dlen == 0)
off = f->ftps_seq - ntohl(tcp->th_seq);
if (off < 0)
return 0;
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if (!strncmp(portbuf, "PORT ", 5)) {
if (dlen < IPF_MINPORTLEN)
return 0;
} else
/*
* Check for client sending out PORT message.
*/
if (dlen < IPF_MINPORTLEN)
return 0;
/*
* Count the number of bytes in the PORT message is.
*/
if (off < 0)
return 0;
off += fin->fin_hlen + (tcp->th_off << 2);
/*
* Skip the PORT command + space
*/
s = portbuf + 5;
s = f->ftps_rptr + 5;
/*
* Pick out the address components, two at a time.
*/
a1 = ipf_ftp_atoi(&s);
a1 = ippr_ftp_atoi(&s);
if (!s)
return 0;
a2 = ipf_ftp_atoi(&s);
a2 = ippr_ftp_atoi(&s);
if (!s)
return 0;
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
@ -137,7 +134,7 @@ nat_t *nat;
if (a1 != ntohl(nat->nat_inip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
a5 = ippr_ftp_atoi(&s);
if (!s)
return 0;
if (*s == ')')
@ -162,13 +159,18 @@ nat_t *nat;
a3 = (a1 >> 8) & 0xff;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf;
olen = s - f->ftps_rptr;
/* DO NOT change this to sprintf! */
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
if ((inc + ip->ip_len) > 65535)
return 0;
#if SOLARIS
m = fin->fin_qfm;
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
@ -194,6 +196,7 @@ nat_t *nat;
}
copyin_mblk(m, off, nlen, newbuf);
#else
m = *((mb_t **)fin->fin_mp);
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
@ -222,6 +225,12 @@ nat_t *nat;
* other way.
*/
sp = htons(a5 << 8 | a6);
/*
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
if (ntohs(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
@ -231,10 +240,15 @@ nat_t *nat;
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
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_off = 5;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
@ -247,82 +261,92 @@ nat_t *nat;
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
ip->ip_len = slen;
ip->ip_src = swip;
}
return inc;
}
int ippr_ftp_out(fin, ip, aps, nat)
int ippr_ftp_client(fin, ip, nat, ftp, dlen)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
ftpinfo_t *ftp;
ip_t *ip;
int dlen;
{
return ippr_ftp_portmsg(fin, ip, nat);
char *rptr, *wptr;
ftpside_t *f;
int inc;
inc = 0;
f = &ftp->ftp_side[0];
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
if ((ftp->ftp_passok == 0) && !strncmp(rptr, "USER ", 5))
ftp->ftp_passok = 1;
else if ((ftp->ftp_passok == 2) && !strncmp(rptr, "PASS ", 5))
ftp->ftp_passok = 3;
else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly &&
!strncmp(rptr, "PORT ", 5)) {
inc = ippr_ftp_port(fin, ip, nat, f, dlen);
}
while ((*rptr++ != '\n') && (rptr < wptr))
;
f->ftps_seq += rptr - f->ftps_rptr;
f->ftps_rptr = rptr;
return inc;
}
int ippr_ftp_pasvmsg(fin, ip, nat)
int ippr_ftp_pasv(fin, ip, nat, f, dlen)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
ftpside_t *f;
int dlen;
{
char portbuf[IPF_MAX227LEN + 1], newbuf[IPF_MAX227LEN + 1], *s;
int off, olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
struct in_addr swip, swip2;
u_short a5, a6, dp, sp;
u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
tcphdr_t *tcp;
fr_info_t fi;
int inc, off;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
char *s;
/*
* Check for PASV reply message.
*/
if (dlen < IPF_MIN227LEN)
return 0;
else if (strncmp(f->ftps_rptr, "227 Entering Passive Mode", 25))
return 0;
/*
* Count the number of bytes in the 227 reply is.
*/
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
bzero(portbuf, sizeof(portbuf));
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
if (dlen > 0)
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
dlen = mbufchainlen(m) - off;
if (dlen > 0)
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
if (dlen == 0)
off = f->ftps_seq - ntohl(tcp->th_seq);
if (off < 0)
return 0;
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if (!strncmp(portbuf, "227 ", 4)) {
if (dlen < IPF_MIN227LEN)
return 0;
else if (strncmp(portbuf, "227 Entering Passive Mode", 25))
return 0;
} else
return 0;
off += fin->fin_hlen + (tcp->th_off << 2);
/*
* Skip the PORT command + space
*/
s = portbuf + 25;
s = f->ftps_rptr + 25;
while (*s && !isdigit(*s))
s++;
/*
* Pick out the address components, two at a time.
*/
a1 = ipf_ftp_atoi(&s);
a1 = ippr_ftp_atoi(&s);
if (!s)
return 0;
a2 = ipf_ftp_atoi(&s);
a2 = ippr_ftp_atoi(&s);
if (!s)
return 0;
@ -335,7 +359,7 @@ nat_t *nat;
if (a1 != ntohl(nat->nat_oip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
a5 = ippr_ftp_atoi(&s);
if (!s)
return 0;
@ -360,13 +384,18 @@ nat_t *nat;
a3 = (a1 >> 8) & 0xff;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf;
inc = 0;
#if 0
olen = s - f->ftps_rptr;
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
if ((inc + ip->ip_len) > 65535)
return 0;
#if SOLARIS
m = fin->fin_qfm;
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
@ -387,12 +416,13 @@ nat_t *nat;
} else {
m1->b_wptr += inc;
}
copyin_mblk(m, off, nlen, newbuf);
/*copyin_mblk(m, off, nlen, newbuf);*/
#else
m = *((mb_t **)fin->fin_mp);
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
/*m_copyback(m, off, nlen, newbuf);*/
#endif
if (inc != 0) {
#if SOLARIS || defined(__sgi)
@ -411,6 +441,7 @@ nat_t *nat;
#endif
ip->ip_len += inc;
}
#endif
/*
* Add skeleton NAT entry for connection which will come back the
@ -421,10 +452,15 @@ nat_t *nat;
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
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;
tcp2->th_dport = htons(fi.fin_data[0]);
fi.fin_data[1] = 0;
@ -439,6 +475,7 @@ nat_t *nat;
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_SPORT);
}
ip->ip_len = slen;
ip->ip_src = swip;
ip->ip_dst = swip2;
}
@ -446,12 +483,274 @@ nat_t *nat;
}
int ippr_ftp_server(fin, ip, nat, ftp, dlen)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
ftpinfo_t *ftp;
int dlen;
{
char *rptr, *wptr;
ftpside_t *f;
int inc;
inc = 0;
f = &ftp->ftp_side[1];
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
if ((ftp->ftp_passok == 1) && !strncmp(rptr, "331", 3))
ftp->ftp_passok = 2;
else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "230", 3))
ftp->ftp_passok = 4;
else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "530", 3))
ftp->ftp_passok = 0;
else if ((ftp->ftp_passok == 4) && !strncmp(rptr, "227 ", 4)) {
inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
}
while ((*rptr++ != '\n') && (rptr < wptr))
;
f->ftps_seq += rptr - f->ftps_rptr;
f->ftps_rptr = rptr;
return inc;
}
/*
* 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)
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 if (isupper(c)) {
c = *s++;
i--;
if (isupper(c)) {
c = *s++;
i--;
if (isupper(c)) {
c = *s++;
i--;
if (isupper(c)) {
c = *s++;
i--;
if ((c != ' ') && (c != '\r'))
return 1;
} else if ((c != ' ') && (c != '\r'))
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_process(fin, ip, nat, ftp, rv)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
ftpinfo_t *ftp;
int rv;
{
int mlen, len, off, inc, i;
char *rptr, *wptr;
tcphdr_t *tcp;
ftpside_t *f;
mb_t *m;
tcp = (tcphdr_t *)fin->fin_dp;
off = fin->fin_hlen + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
#else
m = *((mb_t **)fin->fin_mp);
#endif
#if SOLARIS
mlen = msgdsize(m) - off;
#else
mlen = mbufchainlen(m) - off;
#endif
if (!mlen)
return 0;
inc = 0;
f = &ftp->ftp_side[rv];
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
if ((wptr == f->ftps_buf) && (f->ftps_seq <= ntohl(tcp->th_seq)))
f->ftps_seq = ntohl(tcp->th_seq);
/*
* XXX - Ideally, this packet should get dropped because we now know
* that it is out of order (and there is no real danger in doing so
* apart from causing packets to go through here ordered).
*/
if (ntohl(tcp->th_seq) != f->ftps_seq + (wptr - rptr)) {
return APR_ERR(0);
}
while (mlen > 0) {
len = MIN(mlen, FTP_BUFSZ / 2);
#if SOLARIS
copyout_mblk(m, off, len, wptr);
#else
m_copydata(m, off, len, wptr);
#endif
mlen -= len;
off += len;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
if (f->ftps_junk == 0) {
len = wptr - rptr;
f->ftps_rptr = rptr;
if (rv)
inc += ippr_ftp_server(fin, ip, nat,
ftp, len);
else
inc += ippr_ftp_client(fin, ip, nat,
ftp, len);
rptr = f->ftps_rptr;
}
}
while ((f->ftps_junk == 1) && (rptr < wptr)) {
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;
if ((*rptr == '\r') && (rptr + 1 < wptr)) {
if (*(rptr + 1) == '\n') {
rptr += 2;
f->ftps_junk = 0;
} else
rptr++;
}
f->ftps_seq += rptr - f->ftps_rptr;
f->ftps_rptr = rptr;
}
if (rptr == wptr) {
rptr = wptr = f->ftps_buf;
} else {
if ((wptr > f->ftps_buf + FTP_BUFSZ / 2)) {
i = wptr - rptr;
if ((rptr == f->ftps_buf) ||
(wptr - rptr > FTP_BUFSZ / 2)) {
f->ftps_seq += i;
f->ftps_junk = 1;
rptr = wptr = f->ftps_buf;
} else {
bcopy(rptr, f->ftps_buf, i);
wptr = f->ftps_buf + i;
rptr = f->ftps_buf;
}
}
f->ftps_rptr = rptr;
f->ftps_wptr = wptr;
}
}
f->ftps_rptr = rptr;
f->ftps_wptr = wptr;
return inc;
}
int ippr_ftp_out(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
ftpinfo_t *ftp;
ftp = aps->aps_data;
if (ftp == NULL)
return 0;
return ippr_ftp_process(fin, ip, nat, ftp, 0);
}
int ippr_ftp_in(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
ftpinfo_t *ftp;
return ippr_ftp_pasvmsg(fin, ip, nat);
ftp = aps->aps_data;
if (ftp == NULL)
return 0;
return ippr_ftp_process(fin, ip, nat, ftp, 1);
}
/*
* ippr_ftp_atoi - implement a version of atoi which processes numbers in
* pairs separated by commas (which are expected to be in the range 0 - 255),
* returning a 16 bit number combining either side of the , as the MSB and
* LSB.
*/
u_short ippr_ftp_atoi(ptr)
char **ptr;
{
register char *s = *ptr, c;
register u_char i = 0, j = 0;
while ((c = *s++) && isdigit(c)) {
i *= 10;
i += c - '0';
}
if (c != ',') {
*ptr = NULL;
return 0;
}
while ((c = *s++) && isdigit(c)) {
j *= 10;
j += c - '0';
}
*ptr = s;
return (i << 8) | j;
}

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.1.2.1 2000/01/16 10:13:02 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6 2000/03/13 22:10:21 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@ -179,8 +179,9 @@ caddr_t data;
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
bzero((char *)frstats, sizeof(*frstats) * 2);
error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
if (!error)
bzero((char *)frstats, sizeof(*frstats) * 2);
return error;
}
@ -219,8 +220,8 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
switch (cmd) {
case FIONREAD :
#ifdef IPFILTER_LOG
IWCOPY((caddr_t)&iplused[IPL_LOGIPF], data,
sizeof(iplused[IPL_LOGIPF]));
error = IWCOPY((caddr_t)&iplused[IPL_LOGIPF], data,
sizeof(iplused[IPL_LOGIPF]));
#endif
break;
#if !defined(IPFILTER_LKM) && defined(_KERNEL)
@ -231,7 +232,7 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
if (!(mode & FWRITE))
error = EPERM;
else {
IRCOPY(data, (caddr_t)&enable, sizeof(enable));
error = IRCOPY(data, (caddr_t)&enable, sizeof(enable));
if (error)
break;
if (enable)
@ -246,10 +247,11 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
if (!(mode & FWRITE))
error = EPERM;
else
IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags));
error = IRCOPY(data, (caddr_t)&fr_flags,
sizeof(fr_flags));
break;
case SIOCGETFF :
IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
error = IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
break;
case SIOCINAFR :
case SIOCRMAFR :
@ -295,22 +297,25 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
break;
}
case SIOCFRZST :
if (!(mode & FWRITE))
error = EPERM;
else
frzerostats(data);
error = frzerostats(data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
error = EPERM;
else {
IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
tmp = frflush(unit, tmp);
IWCOPY((caddr_t)&tmp, data, sizeof(tmp));
error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
if (!error) {
tmp = frflush(unit, tmp);
error = IWCOPY((caddr_t)&tmp, data,
sizeof(tmp));
}
}
break;
#ifdef IPFILTER_LOG
@ -322,7 +327,8 @@ int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
break;
#endif /* IPFILTER_LOG */
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
error = IWCOPYPTR((caddr_t)ipfr_fragstats(), data,
sizeof(ipfrstat_t));
break;
case SIOCAUTHW :
case SIOCAUTHR :
@ -377,7 +383,7 @@ caddr_t data;
u_int group;
fp = &frd;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp));
if (error)
return error;
@ -412,7 +418,7 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (*fp->fr_ifname) {
fp->fr_ifa = GETUNIT(fp->fr_ifname);
fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_ip.fi_v);
if (!fp->fr_ifa)
fp->fr_ifa = (void *)-1;
}
@ -420,7 +426,7 @@ caddr_t data;
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
if (*fdp->fd_ifname) {
fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v);
if (!fdp->fd_ifp)
fdp->fd_ifp = (struct ifnet *)-1;
else
@ -429,7 +435,7 @@ caddr_t data;
fdp = &fp->fr_tif;
if (*fdp->fd_ifname) {
fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v);
if (!fdp->fd_ifp)
fdp->fd_ifp = (struct ifnet *)-1;
}
@ -449,7 +455,7 @@ caddr_t data;
if (req == SIOCZRLST) {
if (!f)
return ESRCH;
IWCOPY((caddr_t)f, data, sizeof(*f));
error = IWCOPYPTR((caddr_t)f, data, sizeof(*f));
if (error)
return error;
f->fr_hits = 0;
@ -458,17 +464,18 @@ caddr_t data;
}
if (!f) {
ftail = fprev;
if (req != SIOCINAFR && req != SIOCINIFR)
while ((f = *ftail))
ftail = &f->fr_next;
else if (fp->fr_hits)
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
if (req == SIOCINAFR || req == SIOCINIFR) {
ftail = fprev;
if (fp->fr_hits) {
while (--fp->fr_hits && (f = *ftail)) {
ftail = &f->fr_next;
}
}
}
f = NULL;
}
if (req == SIOCDELFR || req == SIOCRMIFR) {
if (req == SIOCRMAFR || req == SIOCRMIFR) {
if (!f)
error = ESRCH;
else {
@ -796,9 +803,9 @@ int uiomove(caddr_t src, size_t ssize, int rw, struct uio *uio)
size_t mv = MIN(ssize, uio->uio_resid);
if (rw == UIO_READ) {
IWCOPY(src, (caddr_t)uio->uio_buf, mv);
error = IWCOPY(src, (caddr_t)uio->uio_buf, mv);
} else if (rw == UIO_WRITE) {
IRCOPY((caddr_t)uio->uio_buf, src, mv);
error = IRCOPY((caddr_t)uio->uio_buf, src, mv);
} else
error = EINVAL;
if (!error) {
@ -880,8 +887,9 @@ static int write_output __P((mb_t *m, struct ifnet *ifp))
}
struct ifnet *get_unit(name)
struct ifnet *get_unit(name, v)
char *name;
int v;
{
struct ifnet *ifp, **ifa;
char ifname[32], *s;

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 1997-1998 by Darren Reed.
* Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_log.c,v 2.1.2.2 1999/09/21 11:55:44 darrenr Exp $
* $Id: ip_log.c,v 2.5 2000/03/13 22:10:21 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@ -16,7 +16,6 @@
#endif
#ifdef __FreeBSD__
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include "opt_ipfilter.h"
# endif
@ -128,7 +127,7 @@ extern kcondvar_t iplwait;
iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1], *ipll[IPL_LOGMAX+1];
size_t iplused[IPL_LOGMAX+1];
fr_info_t iplcrc[IPL_LOGMAX+1];
static fr_info_t iplcrc[IPL_LOGMAX+1];
# ifdef linux
static struct wait_queue *iplwait[IPL_LOGMAX+1];
# endif
@ -171,6 +170,7 @@ mb_t *m;
size_t sizes[2];
void *ptrs[2];
int types[2];
u_char p;
# if SOLARIS
ill_t *ifp = fin->fin_ifp;
# else
@ -181,15 +181,16 @@ mb_t *m;
* calculate header size.
*/
hlen = fin->fin_hlen;
if ((ip->ip_off & IP_OFFMASK) == 0) {
if (ip->ip_p == IPPROTO_TCP)
if (fin->fin_off == 0) {
p = fin->fin_fi.fi_p;
if (p == IPPROTO_TCP)
hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_UDP)
else if (p == IPPROTO_UDP)
hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_ICMP) {
struct icmp *icmp;
else if (p == IPPROTO_ICMP) {
struct icmp *icmp;
icmp = (struct icmp *)((char *)ip + hlen);
icmp = (struct icmp *)fin->fin_dp;
/*
* For ICMP, if the packet is an error packet, also
@ -234,7 +235,7 @@ mb_t *m;
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
ipfl.fl_ifname[3] = ifp->if_name[3];
# endif
mlen = (flags & FR_LOGBODY) ? MIN(ip->ip_len - hlen, 128) : 0;
mlen = (flags & FR_LOGBODY) ? MIN(fin->fin_plen - hlen, 128) : 0;
# endif
ipfl.fl_plen = (u_char)mlen;
ipfl.fl_hlen = (u_char)hlen;

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1995-1998 by Darren Reed.
* Copyright (C) 1995-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
* $Id: ip_nat.h,v 2.1.2.3 2000/01/24 12:44:24 darrenr Exp $
* $Id: ip_nat.h,v 2.17.2.1 2000/05/15 06:50:14 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -17,23 +17,15 @@
#endif
#if defined(__STDC__) || defined(__GNUC__)
#define SIOCADNAT _IOW('r', 80, struct ipnat)
#define SIOCRMNAT _IOW('r', 81, struct ipnat)
#define SIOCGNATS _IOR('r', 82, struct natstat)
#define SIOCGNATL _IOWR('r', 83, struct natlookup)
#define SIOCGFRST _IOR('r', 84, struct ipfrstat)
#define SIOCGIPST _IOR('r', 85, struct ips_stat)
#define SIOCFLNAT _IOWR('r', 86, int)
#define SIOCCNATL _IOWR('r', 87, int)
#define SIOCADNAT _IOW('r', 60, struct ipnat *)
#define SIOCRMNAT _IOW('r', 61, struct ipnat *)
#define SIOCGNATS _IOWR('r', 62, struct natstat *)
#define SIOCGNATL _IOWR('r', 63, struct natlookup *)
#else
#define SIOCADNAT _IOW(r, 80, struct ipnat)
#define SIOCRMNAT _IOW(r, 81, struct ipnat)
#define SIOCGNATS _IOR(r, 82, struct natstat)
#define SIOCGNATL _IOWR(r, 83, struct natlookup)
#define SIOCGFRST _IOR(r, 84, struct ipfrstat)
#define SIOCGIPST _IOR(r, 85, struct ips_stat)
#define SIOCFLNAT _IOWR(r, 86, int)
#define SIOCCNATL _IOWR(r, 87, int)
#define SIOCADNAT _IOW(r, 60, struct ipnat *)
#define SIOCRMNAT _IOW(r, 61, struct ipnat *)
#define SIOCGNATS _IOWR(r, 62, struct natstat *)
#define SIOCGNATL _IOWR(r, 63, struct natlookup *)
#endif
#undef LARGE_NAT /* define this if you're setting up a system to NAT
@ -45,14 +37,17 @@
*/
#define NAT_SIZE 127
#define RDR_SIZE 127
#define HOSTMAP_SIZE 127
#define NAT_TABLE_SZ 127
#ifdef LARGE_NAT
#undef NAT_SIZE
#undef RDR_SIZE
#undef NAT_TABLE_SZ
#undef HOSTMAP_SIZE 127
#define NAT_SIZE 2047
#define RDR_SIZE 2047
#define NAT_TABLE_SZ 16383
#define HOSTMAP_SIZE 8191
#endif
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
@ -61,14 +56,16 @@
#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */
struct ap_session;
typedef struct nat {
u_long nat_age;
int nat_flags;
u_32_t nat_sumd[2];
u_32_t nat_ipsumd;
void *nat_data;
void *nat_aps; /* proxy session */
frentry_t *nat_fr; /* filter rule ptr if appropriate */
struct ap_session *nat_aps; /* proxy session */
struct frentry *nat_fr; /* filter rule ptr if appropriate */
struct in_addr nat_inip;
struct in_addr nat_outip;
struct in_addr nat_oip; /* other ip */
@ -81,17 +78,24 @@ typedef struct nat {
u_char nat_tcpstate[2];
u_char nat_p; /* protocol for NAT */
struct ipnat *nat_ptr; /* pointer back to the rule */
struct hostmap *nat_hm;
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_hstart[2];
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
#if SOLARIS || defined(_sgi)
kmutex_t nat_lock;
#endif
} nat_t;
typedef struct ipnat {
struct ipnat *in_next;
struct ipnat *in_rnext;
struct ipnat **in_prnext;
struct ipnat *in_mnext;
struct ipnat **in_pmnext;
void *in_ifp;
void *in_apr;
u_long in_space;
@ -106,11 +110,11 @@ typedef struct ipnat {
struct in_addr in_in[2];
struct in_addr in_out[2];
struct in_addr in_src[2];
struct frtuc in_tuc;
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 */
char in_p; /* protocol */
u_short in_dport;
} ipnat_t;
#define in_pmin in_port[0] /* Also holds static redir port */
@ -122,6 +126,12 @@ typedef struct ipnat {
#define in_outmsk in_out[1].s_addr
#define in_srcip in_src[0].s_addr
#define in_srcmsk in_src[1].s_addr
#define in_scmp in_tuc.ftu_scmp
#define in_dcmp in_tuc.ftu_dcmp
#define in_stop in_tuc.ftu_stop
#define in_dtop in_tuc.ftu_dtop
#define in_sport in_tuc.ftu_sport
#define in_dport in_tuc.ftu_dport
#define NAT_OUTBOUND 0
#define NAT_INBOUND 1
@ -146,6 +156,34 @@ typedef struct natlookup {
u_short nl_realport;
} natlookup_t;
typedef struct nat_save {
void *ipn_next;
struct nat ipn_nat;
struct ipnat ipn_ipnat;
struct frentry ipn_fr;
int ipn_dsize;
char ipn_data[4];
} nat_save_t;
#define ipn_rule ipn_nat.nat_fr
typedef struct natget {
void *ng_ptr;
int ng_sz;
} natget_t;
typedef struct hostmap {
struct hostmap *hm_next;
struct hostmap **hm_pnext;
struct ipnat *hm_ipnat;
struct in_addr hm_realip;
struct in_addr hm_mapip;
int hm_ref;
} hostmap_t;
typedef struct natstat {
u_long ns_mapped[2];
u_long ns_rules;
@ -154,6 +192,8 @@ typedef struct natstat {
u_long ns_inuse;
u_long ns_logged;
u_long ns_logfail;
u_long ns_memfail;
u_long ns_badnat;
nat_t **ns_table[2];
ipnat_t *ns_list;
void *ns_apslist;
@ -163,16 +203,20 @@ typedef struct natstat {
nat_t *ns_instances;
} natstat_t;
#define IPN_ANY 0x00
#define IPN_TCP 0x01
#define IPN_UDP 0x02
#define IPN_ANY 0x000
#define IPN_TCP 0x001
#define IPN_UDP 0x002
#define IPN_TCPUDP (IPN_TCP|IPN_UDP)
#define IPN_DELETE 0x04
#define IPN_ICMPERR 0x08
#define IPN_DELETE 0x004
#define IPN_ICMPERR 0x008
#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
#define IPN_AUTOPORTMAP 0x10
#define IPN_RANGE 0x20
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_RANGE)
#define IPN_AUTOPORTMAP 0x010
#define IPN_IPRANGE 0x020
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|\
IPN_SPLIT|IPN_ROUNDR|IPN_FILTER)
#define IPN_FILTER 0x040
#define IPN_SPLIT 0x080
#define IPN_ROUNDR 0x100
typedef struct natlog {
@ -194,7 +238,7 @@ typedef struct natlog {
#define NL_NEWRDR NAT_REDIRECT
#define NL_EXPIRE 0xffff
#define NAT_HASH_FN(k,m) (((k) + ((k) >> 12)) % (m))
#define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m))
#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
@ -213,6 +257,7 @@ typedef struct natlog {
extern u_int ipf_nattable_sz;
extern u_int ipf_natrules_sz;
extern u_int ipf_rdrrules_sz;
extern int fr_nat_lock;
extern void ip_natsync __P((void *));
extern u_long fr_defnatage;
extern u_long fr_defnaticmpage;
@ -221,7 +266,7 @@ extern nat_t *nat_instances;
extern ipnat_t **nat_rules;
extern ipnat_t **rdr_rules;
extern natstat_t nat_stats;
#if defined(__NetBSD__) || defined(__OpenBSD__)
#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));
@ -235,8 +280,9 @@ extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
struct in_addr));
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *));
extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, u_int *));
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 void nat_insert __P((nat_t *));
extern int ip_natout __P((ip_t *, fr_info_t *));
extern int ip_natin __P((ip_t *, fr_info_t *));

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1997-1998 by Darren Reed.
* Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.2.2.1 1999/09/19 12:18:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.1 2000/05/06 12:30:50 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -98,23 +98,62 @@ static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
ippr_ftp_in, ippr_ftp_out },
{ NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
#endif
#ifdef IPF_RCMD_PROXY
{ "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_new,
NULL, ippr_rcmd_out },
{ NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
ippr_rcmd_new, NULL, ippr_rcmd_out },
#endif
#ifdef IPF_RAUDIO_PROXY
{ "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init,
{ NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
#endif
{ "", '\0', 0, 0, NULL, NULL }
{ NULL, "", '\0', 0, 0, NULL, NULL }
};
int appr_add(ap)
aproxy_t *ap;
{
aproxy_t *a;
for (a = ap_proxies; a->apr_p; a++)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
sizeof(ap->apr_label)))
return -1;
for (a = ap_proxylist; a->apr_p; a = a->apr_next)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
sizeof(ap->apr_label)))
return -1;
ap->apr_next = ap_proxylist;
ap_proxylist = ap;
return (*ap->apr_init)();
}
int appr_del(ap)
aproxy_t *ap;
{
aproxy_t *a, **app;
for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
if (a == ap) {
if (ap->apr_ref != 0)
return 1;
*app = a->apr_next;
return 0;
}
return -1;
}
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@ -152,16 +191,18 @@ nat_t *nat;
if (!aps)
return NULL;
bzero((char *)aps, sizeof(*aps));
aps->aps_next = ap_sess_list;
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
aps->aps_apr = apr;
aps->aps_psiz = 0;
ap_sess_list = aps;
aps->aps_nat = nat;
nat->nat_aps = aps;
if (apr->apr_new != NULL)
(void) (*apr->apr_new)(fin, ip, aps, nat);
if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
KFREE(aps);
return NULL;
}
aps->aps_nat = nat;
aps->aps_next = ap_sess_list;
ap_sess_list = aps;
return aps;
}
@ -179,6 +220,7 @@ nat_t *nat;
aproxy_t *apr;
tcphdr_t *tcp = NULL;
u_32_t sum;
short rv;
int err;
if (nat->nat_aps == NULL)
@ -213,8 +255,12 @@ nat_t *nat;
err = (*apr->apr_inpkt)(fin, ip, aps, nat);
}
rv = APR_EXIT(err);
if (rv == -1)
return rv;
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, err);
err = appr_fixseqack(fin, ip, aps, APR_INC(err));
#if SOLARIS && defined(_KERNEL)
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
@ -223,9 +269,9 @@ nat_t *nat;
}
aps->aps_bytes += ip->ip_len;
aps->aps_pkts++;
return 2;
return 1;
}
return -1;
return 0;
}
@ -241,6 +287,13 @@ char *name;
ap->apr_ref++;
return ap;
}
for (ap = ap_proxylist; ap; ap = ap->apr_next)
if ((ap->apr_p == pr) &&
!strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
ap->apr_ref++;
return ap;
}
return NULL;
}
@ -266,11 +319,9 @@ ap_session_t *aps;
break;
}
if (a) {
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
@ -385,3 +436,16 @@ int appr_init()
}
return err;
}
void appr_unload()
{
aproxy_t *ap;
for (ap = ap_proxies; ap->apr_p; ap++)
if (ap->apr_fini)
(*ap->apr_fini)();
for (ap = ap_proxylist; ap; ap = ap->apr_next)
if (ap->apr_fini)
(*ap->apr_fini)();
}

View File

@ -1,11 +1,11 @@
/*
* Copyright (C) 1997-1998 by Darren Reed.
* Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_proxy.h,v 2.1.2.1 1999/09/19 12:18:20 darrenr Exp $
* $Id: ip_proxy.h,v 2.8.2.3 2000/05/06 12:32:43 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@ -54,7 +54,7 @@ typedef struct ap_session {
int aps_psiz; /* size of private data */
struct ap_session *aps_hnext;
struct ap_session *aps_next;
} ap_session_t ;
} ap_session_t;
#define aps_sport aps_un.apu_tcp.apt_sport
#define aps_dport aps_un.apu_tcp.apt_dport
@ -67,11 +67,13 @@ typedef struct ap_session {
typedef struct aproxy {
struct aproxy *apr_next;
char apr_label[APR_LABELLEN]; /* Proxy label # */
u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((void));
void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
@ -82,6 +84,26 @@ typedef struct aproxy {
#define APR_DELETE 1
#define APR_ERR(x) (((x) & 0xffff) << 16)
#define APR_EXIT(x) (((x) >> 16) & 0xffff)
#define APR_INC(x) ((x) & 0xffff)
#define FTP_BUFSZ 160
/*
* For the ftp proxy.
*/
typedef struct ftpside {
char *ftps_rptr;
char *ftps_wptr;
u_32_t ftps_seq;
int ftps_junk;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
typedef struct ftpinfo {
u_int ftp_passok;
ftpside_t ftp_side[2];
} ftpinfo_t;
/*
* Real audio proxy structure and #defines
@ -118,8 +140,12 @@ typedef struct {
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
extern aproxy_t ap_proxies[];
extern int ippr_ftp_pasvonly;
extern int appr_add __P((aproxy_t *));
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 void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));

View File

@ -1,3 +1,6 @@
/*
* $Id: ip_raudio_pxy.c,v 1.7.2.1 2000/05/06 11:19:33 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
@ -38,12 +41,13 @@ nat_t *nat;
KMALLOCS(aps->aps_data, void *, sizeof(raudio_t));
if (aps->aps_data != NULL) {
bzero(aps->aps_data, sizeof(raudio_t));
rap = aps->aps_data;
aps->aps_psiz = sizeof(raudio_t);
rap->rap_mode = RAP_M_TCP; /* default is for TCP */
}
if (aps->aps_data == NULL)
return -1;
bzero(aps->aps_data, sizeof(raudio_t));
rap = aps->aps_data;
aps->aps_psiz = sizeof(raudio_t);
rap->rap_mode = RAP_M_TCP; /* default is for TCP */
return 0;
}
@ -168,8 +172,8 @@ nat_t *nat;
raudio_t *rap = aps->aps_data;
struct in_addr swa, swb;
u_int a1, a2, a3, a4;
int off, dlen, slen;
u_short sp, dp;
int off, dlen;
fr_info_t fi;
tcp_seq seq;
nat_t *ipn;
@ -258,9 +262,12 @@ nat_t *nat;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_off = 5;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &raudiofr;
tcp2->th_win = htons(8192);
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp);
if (((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) &&
(rap->rap_srport != 0)) {
@ -271,8 +278,7 @@ nat_t *nat;
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
ipn = nat_new(nat->nat_ptr, ip, &fi,
IPN_UDP | (sp ? 0 : FI_W_SPORT),
NAT_OUTBOUND);
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);
@ -292,8 +298,9 @@ nat_t *nat;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
}
ip->ip_p = swp;
ip->ip_len = slen;
ip->ip_src = swa;
ip->ip_dst = swb;
return 0;

View File

@ -1,3 +1,6 @@
/*
* $Id: ip_rcmd_pxy.c,v 1.4.2.1 2000/05/06 11:19:34 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code.
@ -123,11 +126,16 @@ nat_t *nat;
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
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_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;
@ -140,6 +148,7 @@ nat_t *nat;
fi.fin_fr = &rcmdfr;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
ip->ip_len = slen;
ip->ip_src = swip;
}
return 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -8,8 +8,8 @@
* I hate legaleese, don't you ?
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.6 2000/01/16 10:12:44 darrenr Exp $";
static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.2 2000/05/22 10:26:14 darrenr Exp $";
#endif
#include <sys/types.h>
@ -42,6 +42,9 @@ static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.6 2000/01/16 10:12:44 da
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
#endif
#include "ip_fil.h"
#include "ip_state.h"
#include "ip_nat.h"
@ -58,10 +61,10 @@ extern fr_flags, fr_active;
int fr_running = 0;
int ipl_unreach = ICMP_UNREACH_HOST;
u_long ipl_frouteok[2] = {0, 0};
static void frzerostats __P((caddr_t));
static int frzerostats __P((caddr_t));
static int frrequest __P((minor_t, int, caddr_t, int));
kmutex_t ipl_mutex, ipf_authmx, ipf_rw;
kmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
KRWLOCK_T ipf_mutex, ipfs_mutex, ipf_solaris;
KRWLOCK_T ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
kcondvar_t iplwait, ipfauthwait;
@ -85,6 +88,7 @@ int ipldetach()
ip_natunload();
cv_destroy(&iplwait);
cv_destroy(&ipfauthwait);
mutex_destroy(&ipf_hostmap);
mutex_destroy(&ipf_authmx);
mutex_destroy(&ipl_mutex);
mutex_destroy(&ipf_rw);
@ -108,9 +112,10 @@ int iplattach __P((void))
cmn_err(CE_CONT, "iplattach()\n");
#endif
bzero((char *)frcache, sizeof(frcache));
mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_rw, "ipf rw mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_authmx, "ipf auth log mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_hostmap, "ipf hostmap mutex", MUTEX_DRIVER, NULL);
RWLOCK_INIT(&ipf_solaris, "ipf filter load/unload mutex", NULL);
RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock", NULL);
RWLOCK_INIT(&ipfs_mutex, "ipf solaris mutex", NULL);
@ -134,26 +139,20 @@ int iplattach __P((void))
}
static void frzerostats(data)
static int frzerostats(data)
caddr_t data;
{
friostat_t fio;
int error;
fr_getstat(&fio);
error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
if (error)
return EFAULT;
bcopy((char *)frstats, (char *)fio.f_st,
sizeof(struct filterstats) * 2);
fio.f_fin[0] = ipfilter[0][0];
fio.f_fin[1] = ipfilter[0][1];
fio.f_fout[0] = ipfilter[1][0];
fio.f_fout[1] = ipfilter[1][1];
fio.f_acctin[0] = ipacct[0][0];
fio.f_acctin[1] = ipacct[0][1];
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
bzero((char *)frstats, sizeof(*frstats) * 2);
return 0;
}
@ -197,6 +196,11 @@ int *rp;
RWLOCK_EXIT(&ipf_solaris);
return error;
}
if (unit == IPL_LOGAUTH) {
error = fr_auth_ioctl((caddr_t)data, cmd, NULL, NULL);
RWLOCK_EXIT(&ipf_solaris);
return error;
}
switch (cmd) {
case SIOCFRENB :
@ -206,7 +210,8 @@ int *rp;
if (!(mode & FWRITE))
error = EPERM;
else
IRCOPY((caddr_t)data, (caddr_t)&enable, sizeof(enable));
error = IRCOPY((caddr_t)data, (caddr_t)&enable,
sizeof(enable));
break;
}
case SIOCSETFF :
@ -214,13 +219,14 @@ int *rp;
error = EPERM;
else {
WRITE_ENTER(&ipf_mutex);
IRCOPY((caddr_t)data, (caddr_t)&fr_flags,
error = IRCOPY((caddr_t)data, (caddr_t)&fr_flags,
sizeof(fr_flags));
RWLOCK_EXIT(&ipf_mutex);
}
break;
case SIOCGETFF :
IWCOPY((caddr_t)&fr_flags, (caddr_t)data, sizeof(fr_flags));
error = IWCOPY((caddr_t)&fr_flags, (caddr_t)data,
sizeof(fr_flags));
break;
case SIOCINAFR :
case SIOCRMAFR :
@ -246,71 +252,61 @@ int *rp;
else {
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
IWCOPY((caddr_t)&fr_active, (caddr_t)data,
sizeof(fr_active));
error = IWCOPY((caddr_t)&fr_active, (caddr_t)data,
sizeof(fr_active));
fr_active = 1 - fr_active;
RWLOCK_EXIT(&ipf_mutex);
}
break;
case SIOCGETFS :
{
struct friostat fio;
friostat_t fio;
READ_ENTER(&ipf_mutex);
bcopy((char *)frstats, (char *)fio.f_st,
sizeof(struct filterstats) * 2);
fio.f_fin[0] = ipfilter[0][0];
fio.f_fin[1] = ipfilter[0][1];
fio.f_fout[0] = ipfilter[1][0];
fio.f_fout[1] = ipfilter[1][1];
fio.f_acctin[0] = ipacct[0][0];
fio.f_acctin[1] = ipacct[0][1];
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
fio.f_active = fr_active;
fio.f_froute[0] = ipl_frouteok[0];
fio.f_froute[1] = ipl_frouteok[1];
fio.f_running = fr_running;
fio.f_groups[0][0] = ipfgroups[0][0];
fio.f_groups[0][1] = ipfgroups[0][1];
fio.f_groups[1][0] = ipfgroups[1][0];
fio.f_groups[1][1] = ipfgroups[1][1];
fio.f_groups[2][0] = ipfgroups[2][0];
fio.f_groups[2][1] = ipfgroups[2][1];
#ifdef IPFILTER_LOG
fio.f_logging = 1;
#else
fio.f_logging = 0;
#endif
fio.f_defpass = fr_pass;
strncpy(fio.f_version, fio.f_version,
sizeof(fio.f_version));
fr_getstat(&fio);
RWLOCK_EXIT(&ipf_mutex);
IWCOPY((caddr_t)&fio, (caddr_t)data, sizeof(fio));
error = IWCOPYPTR((caddr_t)&fio, (caddr_t)data, sizeof(fio));
if (error)
error = EFAULT;
break;
}
case SIOCFRZST :
if (!(mode & FWRITE))
error = EPERM;
else
frzerostats((caddr_t)data);
error = frzerostats((caddr_t)data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
error = EPERM;
else {
IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
tmp = frflush(unit, tmp);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
error = IRCOPY((caddr_t)data, (caddr_t)&tmp,
sizeof(tmp));
if (!error) {
tmp = frflush(unit, tmp);
error = IWCOPY((caddr_t)&tmp, (caddr_t)data,
sizeof(tmp));
}
}
break;
case SIOCSTLCK :
error = IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
if (!error) {
fr_state_lock = tmp;
fr_nat_lock = tmp;
fr_frag_lock = tmp;
fr_auth_lock = tmp;
} else
error = EFAULT;
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
error = EPERM;
else {
tmp = ipflog_clear(unit);
IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
error = IWCOPY((caddr_t)&tmp, (caddr_t)data,
sizeof(tmp));
}
break;
#endif /* IPFILTER_LOG */
@ -321,27 +317,20 @@ int *rp;
error = ipfsync();
break;
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), (caddr_t)data,
sizeof(ipfrstat_t));
error = IWCOPYPTR((caddr_t)ipfr_fragstats(), (caddr_t)data,
sizeof(ipfrstat_t));
if (error)
error = EFAULT;
break;
case FIONREAD :
{
#ifdef IPFILTER_LOG
int copy = (int)iplused[IPL_LOGIPF];
IWCOPY((caddr_t)&copy, (caddr_t)data, sizeof(copy));
error = IWCOPY((caddr_t)&copy, (caddr_t)data, sizeof(copy));
#endif
break;
}
case SIOCAUTHW :
case SIOCAUTHR :
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
case SIOCATHST :
error = fr_auth_ioctl((caddr_t)data, cmd, NULL, NULL);
break;
default :
error = EINVAL;
break;
@ -351,14 +340,22 @@ int *rp;
}
ill_t *get_unit(name)
ill_t *get_unit(name, v)
char *name;
int v;
{
size_t len = strlen(name) + 1; /* includes \0 */
ill_t *il;
size_t len = strlen(name) + 1; /* includes \0 */
ill_t *il;
int sap;
if (v == 4)
sap = 0x0800;
else if (v == 6)
sap = 0x86dd;
else
return NULL;
for (il = ill_g_head; il; il = il->ill_next)
if ((len == il->ill_name_length) &&
if ((len == il->ill_name_length) && (il->ill_sap == sap) &&
!strncmp(il->ill_name, name, len))
return il;
return NULL;
@ -375,15 +372,28 @@ caddr_t data;
frentry_t fr;
frdest_t *fdp;
frgroup_t *fg = NULL;
u_int *p, *pp;
int error = 0, in;
u_int group;
u_32_t group;
ill_t *ill;
ipif_t *ipif;
ire_t *ire;
fp = &fr;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp));
if (error)
return EFAULT;
fp->fr_ref = 0;
#if SOLARIS2 >= 8
if (fp->fr_v == 4)
fp->fr_sap = IP_DL_SAP;
else if (fp->fr_v == 6)
fp->fr_sap = IP6_DL_SAP;
else
return EINVAL;
#else
fp->fr_sap = 0;
#endif
WRITE_ENTER(&ipf_mutex);
/*
@ -391,12 +401,12 @@ caddr_t data;
* has been specified, doesn't exist.
*/
if ((req != SIOCZRLST) && fp->fr_grhead &&
fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL)) {
fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL)) {
error = EEXIST;
goto out;
}
if ((req != SIOCZRLST) && fp->fr_group &&
!fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL)) {
!fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL)) {
error = ESRCH;
goto out;
}
@ -405,10 +415,16 @@ caddr_t data;
if (unit == IPL_LOGAUTH)
ftail = fprev = &ipauth;
else if (fp->fr_flags & FR_ACCOUNT)
else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 4))
ftail = fprev = &ipacct[in][set];
else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 4))
ftail = fprev = &ipfilter[in][set];
#ifdef USE_INET6
else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 6))
ftail = fprev = &ipacct6[in][set];
else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 6))
ftail = fprev = &ipfilter6[in][set];
#endif
else {
error = ESRCH;
goto out;
@ -427,7 +443,8 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (*fp->fr_ifname) {
fp->fr_ifa = (void *)get_unit((char *)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;
}
@ -435,10 +452,10 @@ caddr_t data;
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
if (*fdp->fd_ifname) {
ill = get_unit(fdp->fd_ifname);
ill = get_unit(fdp->fd_ifname, (int)fp->fr_v);
if (!ill)
ire = (ire_t *)-1;
else if ((ipif = ill->ill_ipif)) {
else if ((ipif = ill->ill_ipif) && (fp->fr_v == 4)) {
#if SOLARIS2 > 5
ire = ire_ctable_lookup(ipif->ipif_local_addr, 0,
IRE_LOCAL, NULL, NULL,
@ -451,15 +468,26 @@ caddr_t data;
else
fp->fr_flags |= FR_DUP;
}
#ifdef USE_INET6
else if ((ipif = ill->ill_ipif) && (fp->fr_v == 6)) {
ire = ire_ctable_lookup_v6(&ipif->ipif_v6lcl_addr, 0,
IRE_LOCAL, NULL, NULL,
MATCH_IRE_TYPE);
if (!ire)
ire = (ire_t *)-1;
else
fp->fr_flags |= FR_DUP;
}
#endif
fdp->fd_ifp = (struct ifnet *)ire;
}
fdp = &fp->fr_tif;
if (*fdp->fd_ifname) {
ill = get_unit(fdp->fd_ifname);
ill = get_unit(fdp->fd_ifname, (int)fp->fr_v);
if (!ill)
ire = (ire_t *)-1;
else if ((ipif = ill->ill_ipif)) {
else if ((ipif = ill->ill_ipif) && (fp->fr_v == 4)) {
#if SOLARIS2 > 5
ire = ire_ctable_lookup(ipif->ipif_local_addr, 0,
IRE_LOCAL, NULL, NULL,
@ -470,6 +498,15 @@ caddr_t data;
if (!ire)
ire = (ire_t *)-1;
}
#ifdef USE_INET6
else if ((ipif = ill->ill_ipif) && (fp->fr_v == 6)) {
ire = ire_ctable_lookup_v6(&ipif->ipif_v6lcl_addr, 0,
IRE_LOCAL, NULL, NULL,
MATCH_IRE_TYPE);
if (!ire)
ire = (ire_t *)-1;
}
#endif
fdp->fd_ifp = (struct ifnet *)ire;
}
@ -477,9 +514,13 @@ caddr_t data;
* Look for a matching filter rule, but don't include the next or
* interface pointer in the comparison (fr_next, fr_ifa).
*/
for (fp->fr_cksum = 0, p = (u_int *)&fp->fr_ip, pp = &fp->fr_cksum;
p != pp; p++)
fp->fr_cksum += *p;
for (; (f = *ftail); ftail = &f->fr_next)
if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip,
FR_CMPSIZ) == 0)
if ((fp->fr_cksum == f->fr_cksum) &&
!bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, FR_CMPSIZ))
break;
/*
@ -491,7 +532,11 @@ caddr_t data;
goto out;
}
MUTEX_DOWNGRADE(&ipf_mutex);
IWCOPY((caddr_t)f, data, sizeof(*f));
error = IWCOPYPTR((caddr_t)f, data, sizeof(*f));
if (error) {
error = EFAULT;
goto out;
}
f->fr_hits = 0;
f->fr_bytes = 0;
goto out;
@ -511,26 +556,33 @@ caddr_t data;
}
}
if (req == SIOCDELFR || req == SIOCRMIFR) {
if (req == SIOCRMAFR || req == SIOCRMIFR) {
if (!f)
error = ESRCH;
else {
if (f->fr_ref > 1) {
/*
* Only return EBUSY if there is a group list, else
* it's probably just state information referencing
* the rule.
*/
if ((f->fr_ref > 1) && f->fr_grp) {
error = EBUSY;
goto out;
}
if (fg && fg->fg_head)
fg->fg_head->fr_ref--;
if (unit == IPL_LOGAUTH) {
error = fr_auth_ioctl(data, req, f, ftail);
error = fr_auth_ioctl(data, req, fp, ftail);
goto out;
}
if (f->fr_grhead)
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
fr_delgroup(f->fr_grhead, fp->fr_flags,
unit, set);
fixskip(fprev, f, -1);
*ftail = f->fr_next;
KFREE(f);
f->fr_next = NULL;
if (f->fr_ref == 0)
KFREE(f);
}
} else {
if (f) {
@ -623,14 +675,16 @@ cred_t *cp;
* send_reset - this could conceivably be a call to tcp_respond(), but that
* requires a large amount of setting up and isn't any more efficient.
*/
int send_reset(fin, iphdr, qif)
int send_reset(oip, fin)
ip_t *oip;
fr_info_t *fin;
ip_t *iphdr;
qif_t *qif;
{
tcphdr_t *tcp, *tcp2;
int tlen = 0;
int tlen = 0, hlen;
mblk_t *m;
#ifdef USE_INET6
ip6_t *ip6, *oip6 = (ip6_t *)oip;
#endif
ip_t *ip;
tcp = (struct tcphdr *)fin->fin_dp;
@ -638,105 +692,212 @@ qif_t *qif;
return -1;
if (tcp->th_flags & TH_SYN)
tlen = 1;
if ((m = (mblk_t *)allocb(sizeof(*ip) + sizeof(*tcp),BPRI_HI)) == NULL)
#ifdef USE_INET6
if (fin->fin_v == 6)
hlen = sizeof(ip6_t);
else
#endif
hlen = sizeof(ip_t);
hlen += sizeof(*tcp2);
if ((m = (mblk_t *)allocb(hlen + 16, BPRI_HI)) == NULL)
return -1;
m->b_rptr += 16;
MTYPE(m) = M_DATA;
m->b_wptr += sizeof(*ip) + sizeof(*tcp);
bzero((char *)m->b_rptr, sizeof(*ip) + sizeof(*tcp));
ip = (ip_t *)m->b_rptr;
tcp2 = (struct tcphdr *)(m->b_rptr + sizeof(*ip));
ip->ip_src.s_addr = iphdr->ip_dst.s_addr;
ip->ip_dst.s_addr = iphdr->ip_src.s_addr;
m->b_wptr = m->b_rptr + hlen;
bzero((char *)m->b_rptr, hlen);
tcp2 = (struct tcphdr *)(m->b_rptr + hlen - sizeof(*tcp2));
tcp2->th_dport = tcp->th_sport;
tcp2->th_sport = tcp->th_dport;
tcp2->th_ack = htonl(ntohl(tcp->th_seq) + tlen);
tcp2->th_seq = tcp->th_ack;
tcp2->th_off = sizeof(struct tcphdr) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
/*
* This is to get around a bug in the Solaris 2.4/2.5 TCP checksum
* computation that is done by their put routine.
*/
tcp2->th_sum = htons(0x14);
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
ip->ip_p = IPPROTO_TCP;
ip->ip_len = htons(sizeof(*ip) + sizeof(*tcp));
ip->ip_tos = iphdr->ip_tos;
ip->ip_off = 0;
ip->ip_ttl = 60;
ip->ip_sum = 0;
#ifdef USE_INET6
if (fin->fin_v == 6) {
ip6 = (ip6_t *)m->b_rptr;
ip6->ip6_src = oip6->ip6_dst;
ip6->ip6_dst = oip6->ip6_src;
ip6->ip6_plen = htons(sizeof(*tcp));
ip6->ip6_nxt = IPPROTO_TCP;
} else
#endif
{
ip = (ip_t *)m->b_rptr;
ip->ip_src.s_addr = oip->ip_dst.s_addr;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_TCP;
ip->ip_len = htons(sizeof(*ip) + sizeof(*tcp));
ip->ip_tos = oip->ip_tos;
}
return send_ip(fin, m);
}
int send_ip(fin, m)
fr_info_t *fin;
mblk_t *m;
{
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
ip_wput(qif->qf_ill->ill_wq, m);
#ifdef USE_INET6
if (fin->fin_v == 6) {
ip6_t *ip6;
ip6 = (ip6_t *)m->b_rptr;
ip6->ip6_flow = 0;
ip6->ip6_vfc = 0x60;
ip6->ip6_hlim = 127;
ip_wput_v6(((qif_t *)fin->fin_qif)->qf_ill->ill_wq, m);
} else
#endif
{
ip_t *ip;
ip = (ip_t *)m->b_rptr;
ip->ip_v = IPVERSION;
ip->ip_ttl = 60;
ip_wput(((qif_t *)fin->fin_qif)->qf_ill->ill_wq, m);
}
READ_ENTER(&ipf_solaris);
READ_ENTER(&ipfs_mutex);
return 0;
}
int icmp_error(ip, type, code, qif, dst)
ip_t *ip;
int type, code;
qif_t *qif;
struct in_addr dst;
int send_icmp_err(oip, type, fin, dst)
ip_t *oip;
int type;
fr_info_t *fin;
int dst;
{
mblk_t *mb;
struct in_addr dst4;
struct icmp *icmp;
ip_t *nip;
u_short sz = sizeof(*nip) + sizeof(*icmp) + 8;
mblk_t *m, *mb;
int hlen, code;
qif_t *qif;
u_short sz;
#ifdef USE_INET6
ip6_t *ip6, *oip6;
#endif
ip_t *ip;
if ((mb = (mblk_t *)allocb((size_t)sz, BPRI_HI)) == NULL)
if ((type < 0) || (type > ICMP_MAXTYPE))
return -1;
code = fin->fin_icode;
#ifdef USE_INET6
if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int)))
return -1;
#endif
qif = fin->fin_qif;
m = fin->fin_qfm;
#ifdef USE_INET6
if (oip->ip_v == 6) {
oip6 = (ip6_t *)oip;
sz = sizeof(ip6_t);
sz += MIN(m->b_wptr - m->b_rptr, 512);
hlen = sizeof(ip6_t);
type = icmptoicmp6types[type];
if (type == ICMP6_DST_UNREACH)
code = icmptoicmp6unreach[code];
} else
#endif
{
if ((oip->ip_p == IPPROTO_ICMP) &&
!(fin->fin_fi.fi_fl & FI_SHORT))
switch (ntohs(fin->fin_data[0]) >> 8)
{
case ICMP_ECHO :
case ICMP_TSTAMP :
case ICMP_IREQ :
case ICMP_MASKREQ :
break;
default :
return 0;
}
sz = sizeof(ip_t) * 2;
sz += 8; /* 64 bits of data */
hlen = sz;
}
sz += offsetof(struct icmp, icmp_ip);
if ((mb = (mblk_t *)allocb((size_t)sz + 16, BPRI_HI)) == NULL)
return -1;
MTYPE(mb) = M_DATA;
mb->b_wptr += sz;
mb->b_rptr += 16;
mb->b_wptr = mb->b_rptr + sz;
bzero((char *)mb->b_rptr, (size_t)sz);
nip = (ip_t *)mb->b_rptr;
icmp = (struct icmp *)(nip + 1);
nip->ip_v = IPVERSION;
nip->ip_hl = (sizeof(*nip) >> 2);
nip->ip_p = IPPROTO_ICMP;
nip->ip_id = ip->ip_id;
nip->ip_sum = 0;
nip->ip_ttl = 60;
nip->ip_tos = ip->ip_tos;
nip->ip_len = (u_short)htons(sz);
if (dst.s_addr == 0) {
if (fr_ifpaddr(qif->qf_ill, &dst) == -1)
return -1;
}
nip->ip_src = dst;
nip->ip_dst = ip->ip_src;
icmp = (struct icmp *)(mb->b_rptr + sizeof(*ip));
icmp->icmp_type = type;
icmp->icmp_code = code;
icmp->icmp_cksum = 0;
bcopy((char *)ip, (char *)&icmp->icmp_ip, sizeof(*ip));
bcopy((char *)ip + (ip->ip_hl << 2),
(char *)&icmp->icmp_ip + sizeof(*ip), 8); /* 64 bits */
#ifndef sparc
ip = &icmp->icmp_ip;
{
u_short __iplen, __ipoff;
__iplen = ip->ip_len;
__ipoff = ip->ip_len;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
}
#ifdef USE_INET6
if (oip->ip_v == 6) {
struct in6_addr dst6;
int csz;
if (dst == 0) {
if (fr_ifpaddr(6, ((qif_t *)fin->fin_qif)->qf_ill,
(struct in_addr *)&dst6) == -1)
return -1;
} else
dst6 = oip6->ip6_dst;
csz = sz;
sz -= sizeof(ip6_t);
ip6 = (ip6_t *)mb->b_rptr;
ip6->ip6_flow = 0;
ip6->ip6_vfc = 0x60;
ip6->ip6_hlim = 127;
ip6->ip6_plen = htons(sz);
ip6->ip6_nxt = IPPROTO_ICMPV6;
ip6->ip6_src = dst6;
ip6->ip6_dst = oip6->ip6_src;
sz -= offsetof(struct icmp, icmp_ip);
bcopy((char *)m->b_rptr, (char *)&icmp->icmp_ip, sz);
icmp->icmp_cksum = csz - sizeof(ip6_t);
} else
#endif
icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8);
{
ip = (ip_t *)mb->b_rptr;
ip->ip_v = IPVERSION;
ip->ip_hl = (sizeof(*ip) >> 2);
ip->ip_p = IPPROTO_ICMP;
ip->ip_id = oip->ip_id;
ip->ip_sum = 0;
ip->ip_ttl = 60;
ip->ip_tos = oip->ip_tos;
ip->ip_len = (u_short)htons(sz);
if (dst == 0) {
if (fr_ifpaddr(4, ((qif_t *)fin->fin_qif)->qf_ill,
&dst4) == -1)
return -1;
} else
dst4 = oip->ip_dst;
ip->ip_src = dst4;
ip->ip_dst = oip->ip_src;
bcopy((char *)oip, (char *)&icmp->icmp_ip, sizeof(*oip));
bcopy((char *)oip + (oip->ip_hl << 2),
(char *)&icmp->icmp_ip + sizeof(*oip), 8);
icmp->icmp_cksum = ipf_cksum((u_short *)icmp,
sizeof(*icmp) + 8);
}
/*
* Need to exit out of these so we don't recursively call rw_enter
* from fr_qout.
*/
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
ip_wput(qif->qf_ill->ill_wq, mb);
READ_ENTER(&ipf_solaris);
READ_ENTER(&ipfs_mutex);
return 0;
return send_ip(fin, mb);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,22 @@
/*
* Copyright (C) 1995-1998 by Darren Reed.
* Copyright (C) 1995-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* $Id: ip_state.h,v 2.1.2.2 2000/01/24 13:13:52 darrenr Exp $
* $Id: ip_state.h,v 2.13 2000/03/13 22:10:23 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
#if defined(__STDC__) || defined(__GNUC__)
# define SIOCDELST _IOW('r', 61, struct ipstate *)
#else
# define SIOCDELST _IOW(r, 61, struct ipstate *)
#endif
#define IPSTATE_SIZE 257
#define IPSTATE_MAX 2048 /* Maximum number of states held */
@ -46,17 +52,20 @@ typedef struct tcpstate {
typedef struct ipstate {
struct ipstate *is_next;
struct ipstate **is_pnext;
struct ipstate *is_hnext;
struct ipstate **is_phnext;
u_long is_age;
u_int is_pass;
U_QUAD_T is_pkts;
U_QUAD_T is_bytes;
void *is_ifpin;
void *is_ifpout;
void *is_ifp[2];
frentry_t *is_rule;
struct in_addr is_src;
struct in_addr is_dst;
union i6addr is_src;
union i6addr is_dst;
u_char is_p; /* Protocol */
u_char is_rout; /* Is rule in/out ? */
u_char is_v;
u_int is_hv;
u_32_t is_flags;
u_32_t is_opt; /* packet options set */
u_32_t is_optmsk; /* " " mask */
@ -69,15 +78,21 @@ typedef struct ipstate {
tcpstate_t is_ts;
udpstate_t is_us;
} is_ps;
char is_ifname[2][IFNAMSIZ];
#if SOLARIS || defined(__sgi)
kmutex_t is_lock;
#endif
} ipstate_t;
#define is_icmp is_ps.is_ics
#define is_type is_icmp.ics_type
#define is_code is_icmp.ics_code
#define is_tcp is_ps.is_ts
#define is_udp is_ps.is_us
#define is_send is_tcp.ts_data[0].td_end
#define is_dend is_tcp.ts_data[1].td_end
#define is_saddr is_src.in4.s_addr
#define is_daddr is_dst.in4.s_addr
#define is_icmp is_ps.is_ics
#define is_type is_icmp.ics_type
#define is_code is_icmp.ics_code
#define is_tcp is_ps.is_ts
#define is_udp is_ps.is_us
#define is_send is_tcp.ts_data[0].td_end
#define is_dend is_tcp.ts_data[1].td_end
#define is_maxswin is_tcp.ts_data[0].td_maxwin
#define is_maxdwin is_tcp.ts_data[1].td_maxwin
#define is_maxsend is_tcp.ts_data[0].td_maxend
@ -85,6 +100,8 @@ typedef struct ipstate {
#define is_sport is_tcp.ts_sport
#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 TH_OPENING (TH_SYN|TH_ACK)
/*
@ -96,21 +113,30 @@ typedef struct ipstate {
* Bits 8,9 are used to indicate wildcard source/destination port matching.
*/
typedef struct ipstate_save {
void *ips_next;
struct ipstate ips_is;
struct frentry ips_fr;
} ipstate_save_t;
#define ips_rule ips_is.is_rule
typedef struct ipslog {
U_QUAD_T isl_pkts;
U_QUAD_T isl_bytes;
struct in_addr isl_src;
struct in_addr isl_dst;
u_char isl_p;
u_char isl_flags;
u_char isl_state[2];
union i6addr isl_src;
union i6addr isl_dst;
u_short isl_type;
union {
u_short isl_filler[2];
u_short isl_ports[2];
u_short isl_icmp;
} isl_ps;
u_char isl_v;
u_char isl_p;
u_char isl_flags;
u_char isl_state[2];
} ipslog_t;
#define isl_sport isl_ps.isl_ports[0]
@ -120,6 +146,7 @@ typedef struct ipslog {
#define ISL_NEW 0
#define ISL_EXPIRE 0xffff
#define ISL_FLUSH 0xfffe
#define ISL_REMOVE 0xfffd
typedef struct ips_stat {
@ -137,6 +164,7 @@ typedef struct ips_stat {
u_long iss_logfail;
u_long iss_inuse;
ipstate_t **iss_table;
ipstate_t *iss_list;
} ips_stat_t;
@ -147,13 +175,14 @@ extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_udptimeout;
extern u_long fr_icmptimeout;
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 void ip_statesync __P((void *));
extern void fr_timeoutstate __P((void));
extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));
extern void fr_stateunload __P((void));
extern void ipstate_log __P((struct ipstate *, u_int));
#if defined(__NetBSD__) || defined(__OpenBSD__)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -42,8 +42,8 @@
#include "ipl.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.2 1999/08/06 15:26:08 darrenr Exp $";
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 2000/03/13 22:10:23 darrenr Exp $";
#endif
#if SOLARIS
@ -60,6 +60,9 @@ void zerostats __P((void));
int main __P((int, char *[]));
int opts = 0;
#ifdef USE_INET6
int use_inet6 = 0;
#endif
static int fd = -1;
@ -77,7 +80,7 @@ static int get_flags __P((void));
static void usage()
{
fprintf(stderr, "usage: ipf [-AdDEInoPrsUvVyzZ] %s %s %s\n",
fprintf(stderr, "usage: ipf [-6AdDEInoPrsUvVyzZ] %s %s %s\n",
"[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");
exit(1);
}
@ -89,11 +92,16 @@ char *argv[];
{
int c;
while ((c = getopt(argc, argv, "AdDEf:F:Il:noPrsUvVyzZ")) != -1) {
while ((c = getopt(argc, argv, "6AdDEf:F:Il:noPrsUvVyzZ")) != -1) {
switch (c)
{
case '?' :
usage();
#ifdef USE_INET6
case '6' :
use_inet6 = 1;
break;
#endif
case 'A' :
opts &= ~OPT_INACTIVE;
break;
@ -122,7 +130,6 @@ char *argv[];
opts |= OPT_DONOTHING;
break;
case 'o' :
opts |= OPT_OUTQUE;
break;
case 'P' :
ipfname = IPL_AUTH;
@ -175,7 +182,7 @@ char *ipfdev;
if (!(opts & OPT_DONOTHING) && fd == -1)
if ((fd = open(ipfdev, O_RDWR)) == -1)
if ((fd = open(ipfname, O_RDONLY)) == -1)
if ((fd = open(ipfdev, O_RDONLY)) == -1)
perror("open device");
return fd;
}
@ -193,7 +200,7 @@ static int get_flags()
int i;
if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) {
perror("SIOCFRENB");
perror("SIOCGETFF");
return 0;
}
return i;
@ -204,8 +211,13 @@ static void set_state(enable)
u_int enable;
{
if (opendevice(ipfname) != -2)
if (ioctl(fd, SIOCFRENB, &enable) == -1)
perror("SIOCFRENB");
if (ioctl(fd, SIOCFRENB, &enable) == -1) {
if (errno == EBUSY)
fprintf(stderr,
"IP FIlter: already initialized\n");
else
perror("SIOCFRENB");
}
return;
}
@ -283,24 +295,26 @@ char *name, *file;
if ((opts & OPT_ZERORULEST) &&
!(opts & OPT_DONOTHING)) {
if (ioctl(fd, add, fr) == -1)
if (ioctl(fd, add, &fr) == -1)
perror("ioctl(SIOCZRLST)");
else {
#ifdef USE_QUAD_T
printf("hits %qd bytes %qd ",
(long long)fr->fr_hits,
(long long)fr->fr_bytes);
#else
printf("hits %ld bytes %ld ",
#endif
fr->fr_hits, fr->fr_bytes);
#endif
printfr(fr);
}
} else if ((opts & OPT_REMOVE) &&
!(opts & OPT_DONOTHING)) {
if (ioctl(fd, del, fr) == -1)
perror("ioctl(SIOCDELFR)");
if (ioctl(fd, del, &fr) == -1)
perror("ioctl(delete rule)");
} else if (!(opts & OPT_DONOTHING)) {
if (ioctl(fd, add, fr) == -1)
perror("ioctl(SIOCADDFR)");
if (ioctl(fd, add, &fr) == -1)
perror("ioctl(add/insert rule)");
}
}
}
@ -348,8 +362,8 @@ char *opt;
{
int flag, err;
err = get_flags();
if (err != 0) {
flag = get_flags();
if (flag != 0) {
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
printf("log flag is currently %#x\n", flag);
}
@ -452,13 +466,14 @@ void frsync()
void zerostats()
{
friostat_t fio;
friostat_t *fiop = &fio;
if (opendevice(ipfname) != -2) {
if (ioctl(fd, SIOCFRZST, &fio) == -1) {
if (ioctl(fd, SIOCFRZST, &fiop) == -1) {
perror("ioctl(SIOCFRZST)");
exit(-1);
}
showstats(&fio);
showstats(fiop);
}
}
@ -526,12 +541,13 @@ static void blockunknown()
static void showversion()
{
struct friostat fio;
struct friostat *fiop=&fio;
u_32_t flags;
char *s;
printf("ipf: %s (%d)\n", IPL_VERSION, sizeof(frentry_t));
printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fio)) {
if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fiop)) {
perror("ioctl(SIOCGETFS");
return;
}

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ipf.h 1.12 6/5/96
* $Id: ipf.h,v 2.1.2.1 1999/10/05 12:59:25 darrenr Exp $
* $Id: ipf.h,v 2.9.2.2 2000/05/06 11:20:20 darrenr Exp $
*/
#ifndef __IPF_H__
@ -37,6 +37,14 @@
#define OPT_RAW 0x080000
#define OPT_NAT 0x100000
#define OPT_GROUPS 0x200000
#define OPT_STATETOP 0x400000
#define OPT_FLUSH 0x800000
#define OPT_CLEAR 0x1000000
#define OPT_NODO 0x80000000
#define OPT_STAT OPT_FRSTATES
#define OPT_LIST OPT_SHOWLIST
#ifndef __P
# ifdef __STDC__
@ -46,6 +54,8 @@
# endif
#endif
struct frpcmp;
#ifdef ultrix
extern char *strdup __P((char *));
#endif
@ -65,10 +75,26 @@ struct ipopt_names {
};
extern char *proto;
extern char flagset[];
extern u_char flags[];
extern u_char tcp_flags __P((char *, u_char *, int));
extern int countbits __P((u_32_t));
extern int ratoi __P((char *, int *, int, int));
extern int ratoui __P((char *, u_int *, u_int, u_int));
extern int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, int *,
u_short *, int));
extern int ports __P((char ***, u_short *, int *, u_short *, int));
extern char *portname __P((int, int));
extern u_32_t buildopts __P((char *, char *, int));
extern u_32_t hostnum __P((char *, int *, int));
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 printportcmp __P((int, struct frpcmp *));
extern void printhostmask __P((int, u_32_t *, u_32_t *));
extern void printbuf __P((char *, int, int));
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
extern int gethostname __P((char *, int ));

763
contrib/ipfilter/ipfs.c Normal file
View File

@ -0,0 +1,763 @@
/*
* Copyright (C) 1999 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#ifdef __FreeBSD__
# include <osreldate.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#if !defined(__SVR4) && !defined(__GNUC__)
#include <strings.h>
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <sys/time.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include <netinet/ip.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ip_compat.h"
#include "ip_fil.h"
#include "ip_nat.h"
#include "ip_state.h"
#include "ipf.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.1 2000/05/06 00:11:18 darrenr Exp $";
#endif
#ifndef IPF_SAVEDIR
# define IPF_SAVEDIR "/var/db/ipf"
#endif
#if !defined(__SVR4) && defined(__GNUC__)
extern char *index __P((const char *, int));
#endif
extern char *optarg;
int main __P((int, char *[]));
void usage __P((void));
int changestateif __P((char *, char *));
int changenatif __P((char *, char *));
int readstate __P((int, char *));
int readnat __P((int, char *));
int writestate __P((int, char *));
int opendevice __P((char *));
void closedevice __P((int));
int setlock __P((int, int));
int writeall __P((char *));
int readall __P((char *));
int writenat __P((int, char *));
int opts = 0;
void usage()
{
fprintf(stderr, "usage: ipfs [-nv] -l\n");
fprintf(stderr, "usage: ipfs [-nv] -u\n");
fprintf(stderr, "usage: ipfs [-nv] [-d <dir>] -R\n");
fprintf(stderr, "usage: ipfs [-nv] [-d <dir>] -W\n");
fprintf(stderr, "usage: ipfs [-nNSv] [-f <file>] -r\n");
fprintf(stderr, "usage: ipfs [-nNSv] [-f <file>] -w\n");
fprintf(stderr, "usage: ipfs [-nNSv] -f <filename> -i <if1>,<if2>\n");
exit(1);
}
/*
* Change interface names in state information saved out to disk.
*/
int changestateif(ifs, fname)
char *ifs, *fname;
{
int fd, olen, nlen, rw;
ipstate_save_t ips;
off_t pos;
char *s;
s = strchr(ifs, ',');
if (!s)
usage();
*s++ = '\0';
nlen = strlen(s);
olen = strlen(ifs);
if (nlen >= sizeof(ips.ips_is.is_ifname) ||
olen >= sizeof(ips.ips_is.is_ifname))
usage();
fd = open(fname, O_RDWR);
if (fd == -1) {
perror("open");
exit(1);
}
for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) {
rw = 0;
if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) {
strcpy(ips.ips_is.is_ifname[0], s);
rw = 1;
}
if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) {
strcpy(ips.ips_is.is_ifname[1], s);
rw = 1;
}
if (rw == 1) {
if (lseek(fd, pos, SEEK_SET) != pos) {
perror("lseek");
exit(1);
}
if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) {
perror("write");
exit(1);
}
}
pos = lseek(fd, 0, SEEK_CUR);
}
close(fd);
return 0;
}
/*
* Change interface names in NAT information saved out to disk.
*/
int changenatif(ifs, fname)
char *ifs, *fname;
{
int fd, olen, nlen, rw;
nat_save_t ipn;
nat_t *nat;
off_t pos;
char *s;
s = strchr(ifs, ',');
if (!s)
usage();
*s++ = '\0';
nlen = strlen(s);
olen = strlen(ifs);
nat = &ipn.ipn_nat;
if (nlen >= sizeof(nat->nat_ifname) || olen >= sizeof(nat->nat_ifname))
usage();
fd = open(fname, O_RDWR);
if (fd == -1) {
perror("open");
exit(1);
}
for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) {
rw = 0;
if (!strncmp(nat->nat_ifname, ifs, olen + 1)) {
strcpy(nat->nat_ifname, s);
rw = 1;
}
if (rw == 1) {
if (lseek(fd, pos, SEEK_SET) != pos) {
perror("lseek");
exit(1);
}
if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) {
perror("write");
exit(1);
}
}
pos = lseek(fd, 0, SEEK_CUR);
}
close(fd);
return 0;
}
int main(argc,argv)
int argc;
char *argv[];
{
int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0;
char *dirname = NULL, *filename = NULL, *ifs = NULL;
while ((c = getopt(argc, argv, "d:f:lNnSRruvWw")) != -1)
switch (c)
{
case 'd' :
if ((set == 0) && !dirname && !filename)
dirname = optarg;
else
usage();
break;
case 'f' :
if ((set == 0) && !dirname && !filename)
filename = optarg;
else
usage();
break;
case 'i' :
ifs = optarg;
set = 1;
break;
case 'l' :
if (filename || dirname || set)
usage();
lock = 1;
set = 1;
break;
case 'n' :
opts |= OPT_DONOTHING;
break;
case 'N' :
if ((ns > 0) || dirname || (rw != -1) || set)
usage();
ns = 0;
set = 1;
break;
case 'r' :
if ((ns > 0) || dirname || (rw != -1))
usage();
rw = 0;
set = 1;
break;
case 'R' :
rw = 2;
set = 1;
break;
case 'S' :
if ((ns > 0) || dirname || (rw != -1) || set)
usage();
ns = 1;
set = 1;
break;
case 'u' :
if (filename || dirname || set)
usage();
lock = 0;
set = 1;
break;
case 'v' :
opts |= OPT_VERBOSE;
break;
case 'w' :
if ((ns > 0) || dirname || (rw != -1) || (ns == -1))
usage();
rw = 1;
set = 1;
break;
case 'W' :
rw = 3;
set = 1;
break;
case '?' :
default :
usage();
}
if (ifs)
return changestateif(ifs, filename);
if ((ns >= 0) || (lock >= 0)) {
if (lock >= 0)
devfd = opendevice(NULL);
else if (ns >= 0) {
if (ns == 1)
devfd = opendevice(IPL_STATE);
else if (ns == 0)
devfd = opendevice(IPL_NAT);
}
if (devfd == -1)
exit(1);
}
if (lock >= 0)
err = setlock(devfd, lock);
else if (rw >= 0) {
if (rw & 1) { /* WRITE */
if (rw & 2)
err = writeall(dirname);
else {
if (ns == 0)
err = writenat(devfd, filename);
else if (ns == 1)
err = writestate(devfd, filename);
}
} else {
if (rw & 2)
err = readall(dirname);
else {
if (ns == 0)
err = readnat(devfd, filename);
else if (ns == 1)
err = readstate(devfd, filename);
}
}
}
return err;
}
int opendevice(ipfdev)
char *ipfdev;
{
int fd = -1;
if (opts & OPT_DONOTHING)
return -2;
if (!ipfdev)
ipfdev = IPL_NAME;
if ((fd = open(ipfdev, O_RDWR)) == -1)
if ((fd = open(ipfdev, O_RDONLY)) == -1)
perror("open device");
return fd;
}
void closedevice(fd)
int fd;
{
close(fd);
}
int setlock(fd, lock)
int fd, lock;
{
if (opts & OPT_VERBOSE)
printf("Turn lock %s\n", lock ? "on" : "off");
if (!(opts & OPT_DONOTHING)) {
if (ioctl(fd, SIOCSTLCK, &lock) == -1) {
perror("SIOCSTLCK");
return 1;
}
if (opts & OPT_VERBOSE)
printf("Lock now %s\n", lock ? "on" : "off");
}
return 0;
}
int writestate(fd, file)
int fd;
char *file;
{
ipstate_save_t ips, *ipsp;
int wfd = -1;
wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600);
if (wfd == -1) {
fprintf(stderr, "%s ", file);
perror("state:open");
return 1;
}
ipsp = &ips;
bzero((char *)ipsp, sizeof(ips));
do {
if (opts & OPT_VERBOSE)
printf("Getting state from addr %p\n", ips.ips_next);
if (ioctl(fd, SIOCSTGET, &ipsp)) {
if (errno == ENOENT)
break;
perror("state:SIOCSTGET");
close(wfd);
return 1;
}
if (opts & OPT_VERBOSE)
printf("Got state next %p\n", ips.ips_next);
if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) {
perror("state:write");
close(wfd);
return 1;
}
} while (ips.ips_next != NULL);
close(wfd);
return 0;
}
int readstate(fd, file)
int fd;
char *file;
{
ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL;
int sfd = -1, i;
sfd = open(file, O_RDONLY, 0600);
if (sfd == -1) {
fprintf(stderr, "%s ", file);
perror("open");
return 1;
}
bzero((char *)&ips, sizeof(ips));
/*
* 1. Read all state information in.
*/
do {
i = read(sfd, &ips, sizeof(ips));
if (i == -1) {
perror("read");
close(sfd);
return 1;
}
if (i == 0)
break;
if (i != sizeof(ips)) {
fprintf(stderr, "incomplete read: %d != %d\n", i,
(int)sizeof(ips));
close(sfd);
return 1;
}
is = (ipstate_save_t *)malloc(sizeof(*is));
bcopy((char *)&ips, (char *)is, sizeof(ips));
/*
* Check to see if this is the first state entry that will
* reference a particular rule and if so, flag it as such
* else just adjust the rule pointer to become a pointer to
* the other. We do this so we have a means later for tracking
* who is referencing us when we get back the real pointer
* in is_rule after doing the ioctl.
*/
for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next)
if (is1->ips_rule == is->ips_rule)
break;
if (is1 == NULL)
is->ips_is.is_flags |= FI_NEWFR;
else
is->ips_rule = (void *)&is1->ips_rule;
/*
* Use a tail-queue type list (add things to the end)..
*/
is->ips_next = NULL;
if (!ipshead)
ipshead = is;
if (ipstail)
ipstail->ips_next = is;
ipstail = is;
} while (1);
close(sfd);
for (is = ipshead; is; is = is->ips_next) {
if (opts & OPT_VERBOSE)
printf("Loading new state table entry\n");
if (is->ips_is.is_flags & FI_NEWFR) {
if (opts & OPT_VERBOSE)
printf("Loading new filter rule\n");
}
if (!(opts & OPT_DONOTHING))
if (ioctl(fd, SIOCSTPUT, &is)) {
perror("SIOCSTPUT");
return 1;
}
if (is->ips_is.is_flags & FI_NEWFR) {
if (opts & OPT_VERBOSE)
printf("Real rule addr %p\n", is->ips_rule);
for (is1 = is->ips_next; is1; is1 = is1->ips_next)
if (is1->ips_rule == (frentry_t *)&is->ips_rule)
is1->ips_rule = is->ips_rule;
}
}
return 0;
}
int readnat(fd, file)
int fd;
char *file;
{
nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL, *ipnp;
int nfd = -1, i;
nat_t *nat;
nfd = open(file, O_RDONLY);
if (nfd == -1) {
fprintf(stderr, "%s ", file);
perror("nat:open");
return 1;
}
bzero((char *)&ipn, sizeof(ipn));
/*
* 1. Read all state information in.
*/
do {
i = read(nfd, &ipn, sizeof(ipn));
if (i == -1) {
perror("read");
close(nfd);
return 1;
}
if (i == 0)
break;
if (i != sizeof(ipn)) {
fprintf(stderr, "incomplete read: %d != %d\n", i,
(int)sizeof(ipn));
close(nfd);
return 1;
}
if (ipn.ipn_dsize > 0) {
char *s = ipnp->ipn_data;
int n = ipnp->ipn_dsize;
n -= sizeof(ipnp->ipn_data);
in = malloc(sizeof(*in) + n);
if (!in)
break;
s += sizeof(ipnp->ipn_data);
i = read(nfd, s, n);
if (i == 0)
break;
if (i != n) {
fprintf(stderr, "incomplete read: %d != %d\n",
i, n);
close(nfd);
return 1;
}
} else
in = (nat_save_t *)malloc(sizeof(*in));
bcopy((char *)&ipnp, (char *)in, sizeof(ipn));
/*
* Check to see if this is the first state entry that will
* reference a particular rule and if so, flag it as such
* else just adjust the rule pointer to become a pointer to
* the other. We do this so we have a means later for tracking
* who is referencing us when we get back the real pointer
* in is_rule after doing the ioctl.
*/
nat = &in->ipn_nat;
if (nat->nat_fr != NULL) {
for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next)
if (in1->ipn_rule == nat->nat_fr)
break;
if (in1 == NULL)
nat->nat_flags |= FI_NEWFR;
else
nat->nat_fr = &in1->ipn_fr;
}
/*
* Use a tail-queue type list (add things to the end)..
*/
in->ipn_next = NULL;
if (!ipnhead)
ipnhead = in;
if (ipntail)
ipntail->ipn_next = in;
ipntail = in;
} while (1);
close(nfd);
for (in = ipnhead; in; in = in->ipn_next) {
if (opts & OPT_VERBOSE)
printf("Loading new NAT table entry\n");
nat = &in->ipn_nat;
if (nat->nat_flags & FI_NEWFR) {
if (opts & OPT_VERBOSE)
printf("Loading new filter rule\n");
}
if (!(opts & OPT_DONOTHING))
if (ioctl(fd, SIOCSTPUT, &in)) {
perror("SIOCSTPUT");
return 1;
}
if (nat->nat_flags & FI_NEWFR) {
if (opts & OPT_VERBOSE)
printf("Real rule addr %p\n", nat->nat_fr);
for (in1 = in->ipn_next; in1; in1 = in1->ipn_next)
if (in1->ipn_rule == &in->ipn_fr)
in1->ipn_rule = nat->nat_fr;
}
}
return 0;
}
int writenat(fd, file)
int fd;
char *file;
{
nat_save_t *ipnp = NULL, *next = NULL;
int nfd = -1;
natget_t ng;
nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600);
if (nfd == -1) {
fprintf(stderr, "%s ", file);
perror("nat:open");
return 1;
}
do {
if (opts & OPT_VERBOSE)
printf("Getting nat from addr %p\n", ipnp);
ng.ng_ptr = next;
ng.ng_sz = 0;
if (ioctl(fd, SIOCSTGSZ, &ng)) {
perror("nat:SIOCSTGSZ");
close(nfd);
return 1;
}
if (opts & OPT_VERBOSE)
printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr);
if (ng.ng_sz == 0)
break;
if (!ipnp)
ipnp = malloc(ng.ng_sz);
else
ipnp = realloc((char *)ipnp, ng.ng_sz);
if (!ipnp) {
fprintf(stderr,
"malloc for %d bytes failed\n", ng.ng_sz);
break;
}
bzero((char *)ipnp, ng.ng_sz);
ipnp->ipn_next = next;
if (ioctl(fd, SIOCSTGET, &ipnp)) {
if (errno == ENOENT)
break;
perror("nat:SIOCSTGET");
close(nfd);
return 1;
}
if (opts & OPT_VERBOSE)
printf("Got nat next %p\n", ipnp->ipn_next);
if (write(nfd, ipnp, ng.ng_sz) != ng.ng_sz) {
perror("nat:write");
close(nfd);
return 1;
}
next = ipnp->ipn_next;
} while (ipnp && next);
close(nfd);
return 0;
}
int writeall(dirname)
char *dirname;
{
int fd, devfd;
if (!dirname)
dirname = IPF_SAVEDIR;
if (chdir(dirname)) {
perror("chdir(IPF_SAVEDIR)");
return 1;
}
fd = opendevice(NULL);
if (fd == -1)
return 1;
if (setlock(fd, 1)) {
close(fd);
return 1;
}
devfd = opendevice(IPL_STATE);
if (devfd == -1)
return 1;
if (writestate(devfd, "ipstate.ipf"))
return 1;
close(devfd);
devfd = opendevice(IPL_NAT);
if (devfd == -1)
return 1;
if (writenat(devfd, "ipnat.ipf"))
return 1;
close(devfd);
if (setlock(fd, 0)) {
close(fd);
return 1;
}
return 0;
}
int readall(dirname)
char *dirname;
{
int fd, devfd;
if (!dirname)
dirname = IPF_SAVEDIR;
if (chdir(dirname)) {
perror("chdir(IPF_SAVEDIR)");
return 1;
}
fd = opendevice(NULL);
if (fd == -1)
return 1;
if (setlock(fd, 1)) {
close(fd);
return 1;
}
devfd = opendevice(IPL_STATE);
if (devfd == -1)
return 1;
if (readstate(devfd, "ipstate.ipf"))
return 1;
close(devfd);
devfd = opendevice(IPL_NAT);
if (devfd == -1)
return 1;
if (readnat(devfd, "ipnat.ipf"))
return 1;
close(devfd);
if (setlock(fd, 0)) {
close(fd);
return 1;
}
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -51,7 +51,7 @@ etherfind -n -t
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.1 1999/08/04 17:30:02 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2 2000/03/13 22:10:24 darrenr Exp $";
#endif
static int etherf_open __P((char *));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1998 by Darren Reed.
* Copyright (C) 1995-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -42,7 +42,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.1 1999/08/04 17:30:03 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.2 2000/03/13 22:10:24 darrenr Exp $";
#endif
extern int opts;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -33,7 +33,7 @@
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.1 1999/08/04 17:30:03 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2 2000/03/13 22:10:24 darrenr Exp $";
#endif
struct llc {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -37,7 +37,7 @@
#include "ipt.h"
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.1 1999/08/04 17:30:04 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2 2000/03/13 22:10:24 darrenr Exp $";
#endif
struct llc {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -60,7 +60,7 @@ tcpdump -nqte
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.1 1999/08/04 17:30:04 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2 2000/03/13 22:10:24 darrenr Exp $";
#endif
static int tcpd_open __P((char *));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1995-1998 by Darren Reed.
* Copyright (C) 1995-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -43,7 +43,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.1 1999/08/04 17:30:05 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.3 2000/03/13 22:10:24 darrenr Exp $";
#endif
extern int opts;
@ -54,8 +54,8 @@ static int text_open __P((char *)), text_close __P((void));
static int text_readip __P((char *, int, char **, int *));
static int parseline __P((char *, ip_t *, char **, int *));
static char tcp_flagset[] = "FSRPAU";
static u_char tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
static char _tcp_flagset[] = "FSRPAU";
static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
TH_ACK, TH_URG };
struct ipread iptext = { text_open, text_close, text_readip };
@ -301,13 +301,13 @@ int *out;
ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);
cpp++;
if (*cpp && ip->ip_p == IPPROTO_TCP) {
extern char tcp_flagset[];
extern u_char tcp_flags[];
extern char _tcp_flagset[];
extern u_char _tcp_flags[];
char *s, *t;
for (s = *cpp; *s; s++)
if ((t = index(tcp_flagset, *s)))
tcp->th_flags |= tcp_flags[t - tcp_flagset];
if ((t = index(_tcp_flagset, *s)))
tcp->th_flags |= _tcp_flags[t - _tcp_flagset];
if (tcp->th_flags)
cpp++;
assert(tcp->th_flags != 0);

View File

@ -1,16 +1,17 @@
/*
* Copyright (C) 1993-1999 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ipl.h 1.21 6/5/96
* $Id: ipl.h,v 2.15.2.5 2000/05/22 10:26:16 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.3.8"
#define IPL_VERSION "IP Filter: v3.4.4"
#endif

View File

@ -6,13 +6,13 @@
#CC=gcc -Wuninitialized -Wstrict-prototypes -Werror -O
CFLAGS=-I..
all: $(DESTDIR)/y.tab.o $(DESTDIR)/lex.yy.o y.tab.o lex.yy.o
all: $(DESTDIR)/y.tab.o $(DESTDIR)/lex.yy.o
$(DESTDIR)/y.tab.o: y.tab.c
$(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c y.tab.c -o $@
$(DESTDIR)/y.tab.o: $(DESTDIR)/y.tab.c
$(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/y.tab.c -o $@
$(DESTDIR)/lex.yy.o: lex.yy.c
$(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c lex.yy.c -o $@
$(DESTDIR)/lex.yy.o: $(DESTDIR)/lex.yy.c
$(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/lex.yy.c -o $@
y.tab.o: y.tab.c
$(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c y.tab.c -o $@
@ -20,11 +20,14 @@ y.tab.o: y.tab.c
lex.yy.o: lex.yy.c
$(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c lex.yy.c -o $@
lex.yy.c: iplang_l.l y.tab.h
$(DESTDIR)/lex.yy.c: iplang_l.l $(DESTDIR)/y.tab.h
lex iplang_l.l
mv lex.yy.c $(DESTDIR)
y.tab.c y.tab.h: iplang_y.y
$(DESTDIR)/y.tab.c $(DESTDIR)/y.tab.h: iplang_y.y
yacc -d iplang_y.y
mv y.tab.c $(DESTDIR)
mv y.tab.h $(DESTDIR)
clean:
/bin/rm -f *.o lex.yy.c y.tab.c y.tab.h

View File

@ -6,7 +6,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_l.l,v 2.1 1999/08/04 17:30:53 darrenr Exp $
* $Id: iplang_l.l,v 2.2 2000/02/18 00:18:05 darrenr Exp $
*/
#include <stdio.h>
#include <string.h>
@ -31,7 +31,7 @@
extern int opts;
int lineNum = 0, proto = 0, oldproto = 0, next = -1, laststate = 0;
int lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0;
int *prstack = NULL, numpr = 0, state = 0, token = 0;
void yyerror __P((char *));
@ -197,14 +197,14 @@ void push_proto()
prstack = (int *)malloc(sizeof(int));
else
prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
prstack[numpr - 1] = oldproto;
prstack[numpr - 1] = oldipproto;
}
void pop_proto()
{
numpr--;
proto = prstack[numpr];
ipproto = prstack[numpr];
if (!numpr) {
free(prstack);
prstack = NULL;
@ -262,45 +262,45 @@ int nstate, fornext;
case IL_DATA :
case IL_INTERFACE :
case IL_ARP :
oldproto = proto;
proto = nstate;
oldipproto = ipproto;
ipproto = nstate;
break;
case IL_SUM :
if (proto == IL_IPV4)
if (ipproto == IL_IPV4)
nstate = IL_V4SUM;
else if (proto == IL_TCP)
else if (ipproto == IL_TCP)
nstate = IL_TCPSUM;
else if (proto == IL_UDP)
else if (ipproto == IL_UDP)
nstate = IL_UDPSUM;
break;
case IL_OPT :
if (proto == IL_IPV4)
if (ipproto == IL_IPV4)
nstate = IL_V4OPT;
else if (proto == IL_TCP)
else if (ipproto == IL_TCP)
nstate = IL_TCPOPT;
break;
case IL_IPO_NOP :
if (proto == IL_TCP)
if (ipproto == IL_TCP)
nstate = IL_TCPO_NOP;
break;
case IL_IPO_EOL :
if (proto == IL_TCP)
if (ipproto == IL_TCP)
nstate = IL_TCPO_EOL;
break;
case IL_IPO_TS :
if (proto == IL_TCP)
if (ipproto == IL_TCP)
nstate = IL_TCPO_TS;
break;
case IL_OFF :
if (proto == IL_IPV4)
if (ipproto == IL_IPV4)
nstate = IL_V4OFF;
else if (proto == IL_TCP)
else if (ipproto == IL_TCP)
nstate = IL_TCPOFF;
break;
case IL_LEN :
if (proto == IL_IPV4)
if (ipproto == IL_IPV4)
nstate = IL_V4LEN;
else if (proto == IL_UDP)
else if (ipproto == IL_UDP)
nstate = IL_UDPLEN;
break;
}

View File

@ -6,7 +6,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_y.y,v 2.1.2.1 1999/11/21 11:05:09 darrenr Exp $
* $Id: iplang_y.y,v 2.2 1999/12/04 03:37:04 darrenr Exp $
*/
#include <stdio.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -45,6 +45,7 @@
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "ipf.h"
#include "kmem.h"
#if defined(sun) && !SOLARIS2
@ -56,21 +57,25 @@ 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.1.2.2 1999/12/04 02:09:30 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.2 2000/05/15 06:54:18 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];
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 *));
u_32_t hostnum __P((char *, int *, int));
u_32_t hostmask __P((char *));
void dostats __P((int, int)), flushtable __P((int, int));
void usage __P((char *));
int countbits __P((u_32_t));
@ -79,15 +84,6 @@ int main __P((int, char*[]));
void printaps __P((ap_session_t *, int));
char *getsumd __P((u_32_t));
#define OPT_REM 1
#define OPT_NODO 2
#define OPT_STAT 4
#define OPT_LIST 8
#define OPT_VERBOSE 16
#define OPT_FLUSH 32
#define OPT_CLEAR 64
#define OPT_HITS 128
void usage(name)
char *name;
@ -117,12 +113,15 @@ char *argv[];
char *file = NULL;
int fd = -1, opts = 0, c;
while ((c = getopt(argc, argv, "CFf:hlnrsv")) != -1)
while ((c = getopt(argc, argv, "CdFf:hlnrsv")) != -1)
switch (c)
{
case 'C' :
opts |= OPT_CLEAR;
break;
case 'd' :
opts |= OPT_DEBUG;
break;
case 'f' :
file = optarg;
break;
@ -139,7 +138,7 @@ char *argv[];
opts |= OPT_NODO;
break;
case 'r' :
opts |= OPT_REM;
opts |= OPT_REMOVE;
break;
case 's' :
opts |= OPT_STAT;
@ -151,6 +150,9 @@ char *argv[];
usage(argv[0]);
}
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, O_RDWR)) == -1) &&
((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
(void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
@ -168,40 +170,12 @@ char *argv[];
}
/*
* count consecutive 1's in bit mask. If the mask generated by counting
* consecutive 1's is different to that passed, return -1, else return #
* of bits.
*/
int countbits(ip)
u_32_t ip;
{
u_32_t ipn;
int cnt = 0, i, j;
ip = ipn = ntohl(ip);
for (i = 32; i; i--, ipn *= 2)
if (ipn & 0x80000000)
cnt++;
else
break;
ipn = 0;
for (i = 32, j = cnt; i; i--, j--) {
ipn *= 2;
if (j > 0)
ipn++;
}
if (ipn == ip)
return cnt;
return -1;
}
void printaps(aps, opts)
ap_session_t *aps;
int opts;
{
ap_session_t ap;
ftpinfo_t ftp;
aproxy_t apr;
raudio_t ra;
@ -213,7 +187,8 @@ int opts;
apr.apr_p, apr.apr_ref, apr.apr_flags);
printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags);
#ifdef USE_QUAD_T
printf("%qu pkts %qu", ap.aps_bytes, ap.aps_pkts);
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
@ -249,6 +224,27 @@ int opts;
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 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_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 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_junk);
printf("\t\tbuf [");
printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1);
printf("]\n");
}
}
@ -291,14 +287,13 @@ ipnat_t *ipnat;
void dostats(fd, opts)
int fd, opts;
{
natstat_t ns;
natstat_t ns, *nsp = &ns;
nat_t **nt[2], *np, nat;
ipnat_t ipn;
nat_t **nt[2], *np, nat;
int i = 0;
bzero((char *)&ns, sizeof(ns));
if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &ns) == -1) {
if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &nsp) == -1) {
perror("ioctl(SIOCGNATS)");
return;
}
@ -308,6 +303,8 @@ int fd, opts;
ns.ns_mapped[0], ns.ns_mapped[1]);
printf("added\t%lu\texpired\t%lu\n",
ns.ns_added, ns.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);
if (opts & OPT_VERBOSE)
printf("table %p list %p\n", ns.ns_table, ns.ns_list);
@ -322,7 +319,8 @@ int fd, opts;
}
if (opts & OPT_HITS)
printf("%d ", ipn.in_hits);
printnat(&ipn, opts & OPT_VERBOSE, (void *)ns.ns_list);
printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE),
(void *)ns.ns_list);
ns.ns_list = ipn.in_next;
}
@ -349,12 +347,19 @@ int fd, opts;
printf("\n\tage %lu use %hu sumd %s/",
nat.nat_age, nat.nat_use,
getsumd(nat.nat_sumd[0]));
printf("%s pr %u bkt %d flags %x ",
printf("%s pr %u bkt %d/%d flags %x ",
getsumd(nat.nat_sumd[1]), nat.nat_p,
i, nat.nat_flags);
(int)NAT_HASH_FN(nat.nat_inip.s_addr,
nat.nat_inport,
NAT_TABLE_SZ),
(int)NAT_HASH_FN(nat.nat_outip.s_addr,
nat.nat_outport,
NAT_TABLE_SZ),
nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
nat.nat_bytes, nat.nat_pkts);
(unsigned long long)nat.nat_bytes,
(unsigned long long)nat.nat_pkts);
#else
printf("bytes %lu pkts %lu",
nat.nat_bytes, nat.nat_pkts);
@ -373,60 +378,6 @@ int fd, opts;
}
u_32_t hostmask(msk)
char *msk;
{
int bits = -1;
u_32_t mask;
if (!isdigit(*msk))
return (u_32_t)-1;
if (strchr(msk, '.'))
return inet_addr(msk);
if (strchr(msk, 'x'))
return (u_32_t)strtol(msk, NULL, 0);
/*
* set x most significant bits
*/
for (mask = 0, bits = atoi(msk); bits; bits--) {
mask /= 2;
mask |= ntohl(inet_addr("128.0.0.0"));
}
mask = htonl(mask);
return mask;
}
/*
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
u_32_t hostnum(host, resolved, linenum)
char *host;
int *resolved;
int linenum;
{
struct hostent *hp;
struct netent *np;
*resolved = 0;
if (!strcasecmp("any", host))
return 0L;
if (isdigit(*host))
return inet_addr(host);
if (!(hp = gethostbyname(host))) {
if (!(np = getnetbyname(host))) {
*resolved = -1;
fprintf(stderr, "Line %d: can't resolve hostname: %s\n", linenum, host);
return 0;
}
return htonl(np->n_net);
}
return *(u_32_t *)hp->h_addr;
}
void flushtable(fd, opts)
int fd, opts;
{
@ -434,15 +385,15 @@ int fd, opts;
if (opts & OPT_FLUSH) {
n = 0;
if (!(opts & OPT_NODO) && ioctl(fd, SIOCFLNAT, &n) == -1)
if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
perror("ioctl(SIOCFLNAT)");
else
printf("%d entries flushed from NAT table\n", n);
}
if (opts & OPT_CLEAR) {
n = 0;
if (!(opts & OPT_NODO) && ioctl(fd, SIOCCNATL, &n) == -1)
n = 1;
if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
perror("ioctl(SIOCCNATL)");
else
printf("%d entries flushed from NAT list\n", n);

View File

@ -12,7 +12,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.1.2.2 1999/11/28 03:43:45 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2 1999/12/04 03:37:05 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -54,19 +54,22 @@
#include "ipt.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipt.c,v 2.1.2.1 2000/01/24 14:49:11 darrenr Exp $";
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 2000/03/13 22:10:25 darrenr Exp $";
#endif
extern char *optarg;
extern struct frentry *ipfilter[2][2];
extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
extern struct ifnet *get_unit __P((char *));
extern struct ifnet *get_unit __P((char *, int));
extern void init_ifp __P((void));
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 main(argc,argv)
@ -80,9 +83,14 @@ char *argv[];
ip_t *ip;
int fd, i, dir = 0, c;
while ((c = getopt(argc, argv, "bdEHi:I:NoPr:STvX")) != -1)
while ((c = getopt(argc, argv, "6bdEHi:I:NoPr:STvX")) != -1)
switch (c)
{
#ifdef USE_INET6
case '6' :
use_inet6 = 1;
break;
#endif
case 'b' :
opts |= OPT_BRIEF;
break;
@ -175,7 +183,8 @@ char *argv[];
if (!(fr = natparse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT,
fr, FWRITE|FREAD);
(caddr_t)&fr,
FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
"iplioctl(ADNAT,%p,1) = %d\n",
@ -183,11 +192,12 @@ char *argv[];
} else {
if (!(fr = parse(line, linenum)))
continue;
i = IPL_EXTERN(ioctl)(0, SIOCADDFR, fr,
i = IPL_EXTERN(ioctl)(0, SIOCADAFR,
(caddr_t)&fr,
FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
"iplioctl(ADDFR,%p,1) = %d\n",
"iplioctl(ADAFR,%p,1) = %d\n",
fr, i);
}
}
@ -208,7 +218,7 @@ char *argv[];
ip = (ip_t *)buf;
while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
&iface, &dir)) > 0) {
ifp = iface ? get_unit(iface) : NULL;
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);

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: ipt.h,v 2.1 1999/08/04 17:30:08 darrenr Exp $
* $Id: ipt.h,v 2.2 2000/03/13 22:10:25 darrenr Exp $
*/
#ifndef __IPT_H__

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -20,7 +20,7 @@
#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.1 1999/08/04 17:30:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2 2000/03/13 22:10:25 darrenr Exp $";
#endif
static int kmemfd = -1;

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: kmem.h,v 2.1 1999/08/04 17:30:10 darrenr Exp $
* $Id: kmem.h,v 2.2 2000/03/13 22:10:25 darrenr Exp $
*/
#ifndef __KMEM_H__

View File

@ -0,0 +1,10 @@
# For Solaris
#LIBS=-lsocket -lnsl
all: l4check
l4check: l4check.c
$(CC) -g -I.. $(CFLAGS) $(LIBS) l4check.c -o $@
clean:
/bin/rm -f l4check

View File

@ -0,0 +1,2 @@
GET /

View File

@ -0,0 +1 @@
<HTML>

View File

@ -0,0 +1,805 @@
/*
* (C)Copyright March, 2000 - Darren Reed.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/if.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "ip_compat.h"
#include "ip_fil.h"
#include "ip_nat.h"
#include "ipf.h"
extern char *optarg;
typedef struct l4cfg {
struct l4cfg *l4_next;
struct ipnat l4_nat; /* NAT rule */
struct sockaddr_in l4_sin; /* remote socket to connect */
time_t l4_last; /* when we last connected */
int l4_alive; /* 1 = remote alive */
int l4_fd;
int l4_rw; /* 0 = reading, 1 = writing */
char *l4_rbuf; /* read buffer */
int l4_rsize; /* size of buffer */
int l4_rlen; /* how much used */
char *l4_wptr; /* next byte to write */
int l4_wlen; /* length yet to be written */
} l4cfg_t;
l4cfg_t *l4list = NULL;
char *response = NULL;
char *probe = NULL;
l4cfg_t template;
int frequency = 20;
int ctimeout = 1;
int rtimeout = 1;
size_t plen = 0;
size_t rlen = 0;
int natfd = -1;
int opts = 0;
#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
# define strerror(x) sys_errlist[x]
#endif
char *copystr(dst, src)
char *dst, *src;
{
register char *s, *t, c;
register int esc = 0;
for (s = src, t = dst; s && t && (c = *s++); )
if (esc) {
esc = 0;
switch (c)
{
case 'n' :
*t++ = '\n';
break;
case 'r' :
*t++ = '\r';
break;
case 't' :
*t++ = '\t';
break;
}
} else if (c != '\\')
*t++ = c;
else
esc = 1;
*t = '\0';
return dst;
}
void addnat(l4)
l4cfg_t *l4;
{
ipnat_t *ipn = &l4->l4_nat;
printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0]),
ipn->in_outmsk, ntohs(ipn->in_pmin));
printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ntohs(ipn->in_pnext));
if (!(opts & OPT_DONOTHING)) {
if (ioctl(natfd, SIOCADNAT, &ipn) == -1)
perror("ioctl(SIOCADNAT)");
}
}
void delnat(l4)
l4cfg_t *l4;
{
ipnat_t *ipn = &l4->l4_nat;
printf("Remove NAT rule for %s/%#x,%u -> ",
inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin);
printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ipn->in_pnext);
if (!(opts & OPT_DONOTHING)) {
if (ioctl(natfd, SIOCRMNAT, &ipn) == -1)
perror("ioctl(SIOCRMNAT)");
}
}
void connectl4(l4)
l4cfg_t *l4;
{
l4->l4_rw = 1;
l4->l4_rlen = 0;
l4->l4_wlen = plen;
if (!l4->l4_wlen) {
l4->l4_alive = 1;
addnat(l4);
} else
l4->l4_wptr = probe;
}
void closel4(l4, dead)
l4cfg_t *l4;
int dead;
{
close(l4->l4_fd);
l4->l4_fd = -1;
l4->l4_rw = -1;
if (dead && l4->l4_alive) {
l4->l4_alive = 0;
delnat(l4);
}
}
void connectfd(l4)
l4cfg_t *l4;
{
if (connect(l4->l4_fd, (struct sockaddr *)&l4->l4_sin,
sizeof(l4->l4_sin)) == -1) {
if (errno == EISCONN) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "Connected fd %d\n",
l4->l4_fd);
connectl4(l4);
return;
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Connect failed fd %d: %s\n",
l4->l4_fd, strerror(errno));
closel4(l4, 1);
return;
}
l4->l4_rw = 1;
}
void writefd(l4)
l4cfg_t *l4;
{
char buf[80], *ptr;
int n, i, fd;
fd = l4->l4_fd;
if (l4->l4_rw == -2) {
connectfd(l4);
return;
}
n = l4->l4_wlen;
i = send(fd, l4->l4_wptr, n, 0);
if (i == 0 || i == -1) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "Send on fd %d failed: %s\n",
fd, strerror(errno));
closel4(l4, 1);
} else {
l4->l4_wptr += i;
l4->l4_wlen -= i;
if (l4->l4_wlen == 0)
l4->l4_rw = 0;
if (opts & OPT_VERBOSE)
fprintf(stderr, "Sent %d bytes to fd %d\n", i, fd);
}
}
void readfd(l4)
l4cfg_t *l4;
{
char buf[80], *ptr;
int n, i, fd;
fd = l4->l4_fd;
if (l4->l4_rw == -2) {
connectfd(l4);
return;
}
if (l4->l4_rsize) {
n = l4->l4_rsize - l4->l4_rlen;
ptr = l4->l4_rbuf + l4->l4_rlen;
} else {
n = sizeof(buf) - 1;
ptr = buf;
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Read %d bytes on fd %d to %p\n",
n, fd, ptr);
i = recv(fd, ptr, n, 0);
if (i == 0 || i == -1) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "Read error on fd %d: %s\n",
fd, (i == 0) ? "EOF" : strerror(errno));
closel4(l4, 1);
} else {
if (ptr == buf)
ptr[i] = '\0';
if (opts & OPT_VERBOSE)
fprintf(stderr, "%d: Read %d bytes [%*.*s]\n",
fd, i, i, i, ptr);
if (ptr != buf) {
l4->l4_rlen += i;
if (l4->l4_rlen >= l4->l4_rsize) {
if (!strncmp(response, l4->l4_rbuf,
l4->l4_rsize)) {
printf("%d: Good response\n",
fd);
if (!l4->l4_alive) {
l4->l4_alive = 1;
addnat(l4);
}
closel4(l4, 0);
} else {
if (opts & OPT_VERBOSE)
printf("%d: Bad response\n",
fd);
closel4(l4, 1);
}
}
} else if (!l4->l4_alive) {
l4->l4_alive = 1;
addnat(l4);
closel4(l4, 0);
}
}
}
int runconfig()
{
int fd, opt, res, mfd, i;
struct timeval tv;
time_t now, now1;
fd_set rfd, wfd;
l4cfg_t *l4;
mfd = 0;
opt = 1;
now = time(NULL);
/*
* First, initiate connections that are closed, as required.
*/
for (l4 = l4list; l4; l4 = l4->l4_next) {
if ((l4->l4_last + frequency < now) && (l4->l4_fd == -1)) {
l4->l4_last = now;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
continue;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
#ifdef O_NONBLOCK
if ((res = fcntl(fd, F_GETFL, 0)) != -1)
fcntl(fd, F_SETFL, res | O_NONBLOCK);
#endif
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Connecting to %s,%d (fd %d)...",
inet_ntoa(l4->l4_sin.sin_addr),
ntohs(l4->l4_sin.sin_port), fd);
if (connect(fd, (struct sockaddr *)&l4->l4_sin,
sizeof(l4->l4_sin)) == -1) {
if (errno != EINPROGRESS) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "failed\n");
perror("connect");
close(fd);
fd = -1;
} else {
if (opts & OPT_VERBOSE)
fprintf(stderr, "waiting\n");
l4->l4_rw = -2;
}
} else {
if (opts & OPT_VERBOSE)
fprintf(stderr, "connected\n");
connectl4(l4);
}
l4->l4_fd = fd;
}
}
/*
* Now look for fd's which we're expecting to read/write from.
*/
FD_ZERO(&rfd);
FD_ZERO(&wfd);
tv.tv_sec = MIN(rtimeout, ctimeout);
tv.tv_usec = 0;
for (l4 = l4list; l4; l4 = l4->l4_next)
if (l4->l4_rw == 0) {
if (now - l4->l4_last > rtimeout) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "%d: Read timeout\n",
l4->l4_fd);
closel4(l4, 1);
continue;
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Wait for read on fd %d\n",
l4->l4_fd);
FD_SET(l4->l4_fd, &rfd);
if (l4->l4_fd > mfd)
mfd = l4->l4_fd;
} else if ((l4->l4_rw == 1 && l4->l4_wlen) ||
l4->l4_rw == -2) {
if ((l4->l4_rw == -2) &&
(now - l4->l4_last > ctimeout)) {
if (opts & OPT_VERBOSE)
fprintf(stderr,
"%d: connect timeout\n",
l4->l4_fd);
closel4(l4);
continue;
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Wait for write on fd %d\n",
l4->l4_fd);
FD_SET(l4->l4_fd, &wfd);
if (l4->l4_fd > mfd)
mfd = l4->l4_fd;
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Select: max fd %d wait %d\n", mfd + 1,
tv.tv_sec);
i = select(mfd + 1, &rfd, &wfd, NULL, &tv);
if (i == -1) {
perror("select");
return -1;
}
now1 = time(NULL);
for (l4 = l4list; (i > 0) && l4; l4 = l4->l4_next) {
if (l4->l4_fd < 0)
continue;
if (FD_ISSET(l4->l4_fd, &rfd)) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "Ready to read on fd %d\n",
l4->l4_fd);
readfd(l4);
i--;
}
if ((l4->l4_fd >= 0) && FD_ISSET(l4->l4_fd, &wfd)) {
if (opts & OPT_VERBOSE)
fprintf(stderr, "Ready to write on fd %d\n",
l4->l4_fd);
writefd(l4);
i--;
}
}
return 0;
}
int gethostport(str, lnum, ipp, portp)
char *str;
int lnum;
u_32_t *ipp;
u_short *portp;
{
struct servent *sp;
struct hostent *hp;
char *host, *port;
struct in_addr ip;
host = str;
port = strchr(host, ',');
if (port)
*port++ = '\0';
#ifdef HAVE_INET_ATON
if (isdigit(*host) && inet_aton(host, &ip))
*ipp = ip.s_addr;
#else
if (isdigit(*host))
*ipp = inet_addr(host);
#endif
else {
if (!(hp = gethostbyname(host))) {
fprintf(stderr, "%d: can't resolve hostname: %s\n",
lnum, host);
return 0;
}
*ipp = *(u_32_t *)hp->h_addr;
}
if (port) {
if (isdigit(*port))
*portp = htons(atoi(port));
else {
sp = getservbyname(port, "tcp");
if (sp)
*portp = sp->s_port;
else {
fprintf(stderr, "%d: unknown service %s\n",
lnum, port);
return 0;
}
}
} else
*portp = 0;
return 1;
}
char *mapfile(file, sizep)
char *file;
size_t *sizep;
{
struct stat sb;
caddr_t addr;
int fd;
fd = open(file, O_RDONLY);
if (fd == -1) {
perror("open(mapfile)");
return NULL;
}
if (fstat(fd, &sb) == -1) {
perror("fstat(mapfile)");
close(fd);
return NULL;
}
addr = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (addr == (caddr_t)-1) {
perror("mmap(mapfile)");
close(fd);
return NULL;
}
close(fd);
*sizep = sb.st_size;
return (char *)addr;
}
int readconfig(filename)
char *filename;
{
char c, buf[512], *s, *t, *errtxt = NULL, *line;
int num, err = 0;
ipnat_t *ipn;
l4cfg_t *l4;
FILE *fp;
fp = fopen(filename, "r");
if (!fp) {
perror("open(configfile)");
return -1;
}
bzero((char *)&template, sizeof(template));
template.l4_fd = -1;
template.l4_rw = -1;
template.l4_sin.sin_family = AF_INET;
ipn = &template.l4_nat;
ipn->in_flags = IPN_TCP|IPN_ROUNDR;
ipn->in_redir = NAT_REDIRECT;
for (num = 1; fgets(buf, sizeof(buf), fp); num++) {
s = strchr(buf, '\n');
if (!s) {
fprintf(stderr, "%d: line too long\n", num);
fclose(fp);
return -1;
}
*s = '\0';
/*
* lines which are comments
*/
s = strchr(buf, '#');
if (s)
*s = '\0';
/*
* Skip leading whitespace
*/
for (line = buf; (c = *line) && isspace(c); line++)
;
if (!*line)
continue;
if (opts & OPT_VERBOSE)
fprintf(stderr, "Parsing: [%s]\n", line);
t = strtok(line, " \t");
if (!t)
continue;
if (!strcasecmp(t, "interface")) {
s = strtok(NULL, " \t");
if (s)
t = strtok(NULL, "\t");
if (!s || !t) {
errtxt = line;
err = -1;
break;
}
if (!strchr(t, ',')) {
fprintf(stderr,
"%d: local address,port missing\n",
num);
err = -1;
break;
}
strncpy(ipn->in_ifname, s, sizeof(ipn->in_ifname));
if (!gethostport(t, num, &ipn->in_outip,
&ipn->in_pmin)) {
errtxt = line;
err = -1;
break;
}
ipn->in_outmsk = 0xffffffff;
ipn->in_pmax = ipn->in_pmin;
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Interface %s %s/%#x port %u\n",
ipn->in_ifname,
inet_ntoa(ipn->in_out[0]),
ipn->in_outmsk, ipn->in_pmin);
} else if (!strcasecmp(t, "remote")) {
if (!*ipn->in_ifname) {
fprintf(stderr,
"%d: ifname not set prior to remote\n",
num);
err = -1;
break;
}
s = strtok(NULL, " \t");
if (s)
t = strtok(NULL, "");
if (!s || !t || strcasecmp(s, "server")) {
errtxt = line;
err = -1;
break;
}
ipn->in_pnext = 0;
if (!gethostport(t, num, &ipn->in_inip,
&ipn->in_pnext)) {
errtxt = line;
err = -1;
break;
}
ipn->in_inmsk = 0xffffffff;
if (ipn->in_pnext == 0)
ipn->in_pnext = ipn->in_pmin;
l4 = (l4cfg_t *)malloc(sizeof(*l4));
if (!l4) {
fprintf(stderr, "%d: out of memory (%d)\n",
num, sizeof(*l4));
err = -1;
break;
}
bcopy((char *)&template, (char *)l4, sizeof(*l4));
l4->l4_sin.sin_addr = ipn->in_in[0];
l4->l4_sin.sin_port = ipn->in_pnext;
l4->l4_next = l4list;
l4list = l4;
} else if (!strcasecmp(t, "connect")) {
s = strtok(NULL, " \t");
if (s)
t = strtok(NULL, "\t");
if (!s || !t) {
errtxt = line;
err = -1;
break;
} else if (!strcasecmp(s, "timeout")) {
ctimeout = atoi(t);
if (opts & OPT_VERBOSE)
fprintf(stderr, "connect timeout %d\n",
ctimeout);
} else if (!strcasecmp(s, "frequency")) {
frequency = atoi(t);
if (opts & OPT_VERBOSE)
fprintf(stderr,
"connect frequency %d\n",
frequency);
} else {
errtxt = line;
err = -1;
break;
}
} else if (!strcasecmp(t, "probe")) {
s = strtok(NULL, " \t");
if (!s) {
errtxt = line;
err = -1;
break;
} else if (!strcasecmp(s, "string")) {
if (probe) {
fprintf(stderr,
"%d: probe already set\n",
num);
err = -1;
break;
}
t = strtok(NULL, "");
if (!t) {
fprintf(stderr,
"%d: No probe string\n", num);
err = -1;
break;
}
probe = malloc(strlen(t));
copystr(probe, t);
plen = strlen(probe);
if (opts & OPT_VERBOSE)
fprintf(stderr, "Probe string [%s]\n",
probe);
} else if (!strcasecmp(s, "file")) {
t = strtok(NULL, " \t");
if (!t) {
errtxt = line;
err = -1;
break;
}
if (probe) {
fprintf(stderr,
"%d: probe already set\n",
num);
err = -1;
break;
}
probe = mapfile(t, &plen);
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Probe file %s len %u@%p\n",
t, plen, probe);
}
} else if (!strcasecmp(t, "response")) {
s = strtok(NULL, " \t");
if (!s) {
errtxt = line;
err = -1;
break;
} else if (!strcasecmp(s, "timeout")) {
t = strtok(NULL, " \t");
if (!t) {
errtxt = line;
err = -1;
break;
}
rtimeout = atoi(t);
if (opts & OPT_VERBOSE)
fprintf(stderr,
"response timeout %d\n",
rtimeout);
} else if (!strcasecmp(s, "string")) {
if (response) {
fprintf(stderr,
"%d: response already set\n",
num);
err = -1;
break;
}
response = strdup(strtok(NULL, ""));
rlen = strlen(response);
template.l4_rsize = rlen;
template.l4_rbuf = malloc(rlen);
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Response string [%s]\n",
response);
} else if (!strcasecmp(s, "file")) {
t = strtok(NULL, " \t");
if (!t) {
errtxt = line;
err = -1;
break;
}
if (response) {
fprintf(stderr,
"%d: response already set\n",
num);
err = -1;
break;
}
response = mapfile(t, &rlen);
template.l4_rsize = rlen;
template.l4_rbuf = malloc(rlen);
if (opts & OPT_VERBOSE)
fprintf(stderr,
"Response file %s len %u@%p\n",
t, rlen, response);
}
} else {
errtxt = line;
err = -1;
break;
}
}
if (errtxt)
fprintf(stderr, "%d: syntax error at \"%s\"\n", num, errtxt);
fclose(fp);
return err;
}
void usage(prog)
char *prog;
{
fprintf(stderr, "Usage: %s -f <configfile>\n", prog);
exit(1);
}
int main(argc, argv)
int argc;
char *argv[];
{
char *config = NULL;
int c;
while ((c = getopt(argc, argv, "f:nv")) != -1)
switch (c)
{
case 'f' :
config = optarg;
break;
case 'n' :
opts |= OPT_DONOTHING;
break;
case 'v' :
opts |= OPT_VERBOSE;
break;
}
if (config == NULL)
usage(argv[0]);
if (readconfig(config))
exit(1);
if (!l4list) {
fprintf(stderr, "No remote servers, exiting.");
exit(1);
}
if (!(opts & OPT_DONOTHING)) {
natfd = open(IPL_NAT, O_RDWR);
if (natfd == -1) {
perror("open(IPL_NAT)");
exit(1);
}
}
if (opts & OPT_VERBOSE)
fprintf(stderr, "Starting...\n");
while (runconfig() == 0)
;
}

View File

@ -0,0 +1,31 @@
#
# NOTE: ORDER IS IMPORTANT IN THIS FILE
#
# Interface to do the redirections on and the IP address which will be
# targeted.
#
interface nf0 192.168.1.1,2100
#
connect timeout 1
connect frequency 20
#
# If no probe string is specified, a successful connection implies the
# server is still alive.
#
probe string GET /\n\n
#probe file http.check
#
response timeout 4
response string <HTML>
#response file http.ok
#
# Here we have multiple servers, listed because that's what happens to be
# used for testing of connect timeoutes, read timeouts, success and things
# which don't connect.
#
remote server 192.168.1.2,23
remote server 192.168.1.2,2101
remote server 192.168.1.3,25
remote server 192.168.1.254,8000
remote server 192.168.1.1,9
#

View File

@ -17,6 +17,7 @@ install:
$(INSTALL) -m 0644 -c -o root -g bin ipf.5 $(MANDIR)/man5
$(INSTALL) -m 0644 -c -o root -g bin ipnat.5 $(MANDIR)/man5
$(INSTALL) -m 0644 -c -o root -g bin ipf.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipfs.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipmon.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipfstat.8 $(MANDIR)/man8
@echo "Remember to rebuild the whatis database."

119
contrib/ipfilter/man/ipfs.8 Normal file
View File

@ -0,0 +1,119 @@
.TH IPFS 8
.SH NAME
ipfs \- saves and restores information for NAT and state tables.
.SH SYNOPSIS
.B ipfs
[-nv] -l
.PP
.B ipfs
[-nv] -u
.PP
.B ipfs
[-nv] [
.B \-d
<\fIdirname\fP>
] -R
.PP
.B ipfs
[-nv] [
.B \-d
<\fIdirname\fP>
] -W
.PP
.B ipfs
[-nNSv] [
.B \-f
<\fIfilename\fP>
] -r
.PP
.B ipfs
[-nNSv] [
.B \-f
<\fIfilename\fP>
] -w
.PP
.B ipfs
[-nNSv]
.B \-f
<\fIfilename\fP>
.B \-i
<if1>,<if2>
.SH DESCRIPTION
.PP
\fBipfs\fP allows state information created for NAT entries and rules using
\fIkeep state\fP to be locked (modification prevented) and then saved to disk,
allowing for the system to experience a reboot, followed by the restoration
of that information, resulting in connections not being interrupted.
.SH OPTIONS
.TP
.B \-d
Change the default directory used with
.B \-R
and
.B \-W
options for saving state information.
.B \-n
Don't actually take any action that would effect information stored in
the kernel or on disk.
.TP
.B \-v
Provides a verbose description of what's being done.
.TP
.B \-N
Operate on NAT information.
.TP
.B \-S
Operate on filtering state information.
.TP
.B \-u
Unlock state tables in the kernel.
.TP
.B \-l
Unlock state tables in the kernel.
.TP
.B \-r
Read information in from the specified file and load it into the
kernel. This requires the state tables to have already been locked
and does not change the lock once comlete.
.TP
.B \-w
Write information out to the specified file and from the kernel.
This requires the state tables to have already been locked
and does not change the lock once comlete.
.TP
.B \-R
Restores all saved state information, if any, from two files,
\fIipstate.ipf\fP and \fIipnat.ipf\fP, stored in the \fI/var/db/ipf\fP
directory unless otherwise specified the
.B \-d
option is used. The state tables are locked at the beginning of this
operation and unlocked once complete.
.TP
.B \-W
Saves in-kernel state information, if any, out to two files,
\fIipstate.ipf\fP and \fIipnat.ipf\fP, stored in the \fI/var/db/ipf\fP
directory unless otherwise specified the
.B \-d
option is used. The state tables are locked at the beginning of this
operation and unlocked once complete.
.DT
.SH FILES
/var/db/ipf/ipstate.ipf
.br
/var/db/ipf/ipnat.ipf
.br
/dev/ipl
.br
/dev/ipstate
.br
/dev/ipnat
.SH SEE ALSO
ipf(8), ipl(4), ipmon(8), ipnat(8)
.SH DIAGNOSTICS
.PP
Perhaps the -W and -R operations should set the locking but rather than
undo it, restore it to what it was previously. Fragment table information
is currently not saved.
.SH BUGS
.PP
If you find any, please send email to me at darrenr@pobox.com

View File

@ -8,14 +8,24 @@ The format for files accepted by ipnat is described by the following grammar:
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 [ fromspec ] ipmask "->" ip [ ports ] [ tcpudp ] .
redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] [ ports ] options .
dport ::= "port" portnum [ "-" portnum ] .
ports ::= "ports" numports | "auto" .
mapit ::= "map" | "bimap" .
fromto ::= "from" object "to" object .
ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
mapport ::= "portmap" tcpudp portnumber ":" portnumber .
options ::= [ tcpudp ] [ rr ] .
fromspec ::= "from" ip "/" ipmask .
object = addr [ port-comp | port-range ] .
addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
port-comp = "port" compare port-num .
port-range = "port" port-num range port-num .
rr ::= "round-robin" .
tcpudp ::= "tcp" | "udp" | "tcp/udp" .
portnumber ::= number { numbers } | "auto" .
ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers .
@ -40,7 +50,7 @@ When remapping TCP and UDP packets, it is also possible to change the source
port number. Either TCP or UDP or both can be selected by each rule, with a
range of port numbers to remap into given as \fBport-number:port-number\fP.
.SH COMMANDS
There are found commands recognised by IP Filter's NAT code:
There are four commands recognised by IP Filter's NAT code:
.TP
.B map
that is used for mapping one address or network to another in an unregulated
@ -60,10 +70,26 @@ squeeze the addresses to be translated into the destination range.
.SH MATCHING
.PP
For basic NAT and redirection of packets, the address subject to change is used
along with its protocol to check if a packet should be altered. In the case
of redirects, it is also possible to select packets on a source address basis
using the \fBfrom\fP keyword, as well as the manditory destination port. The
packet \fImatching\fP part of the rule is to the left of the "->" in each rule.
along with its protocol to check if a packet should be altered. The packet
\fImatching\fP part of the rule is to the left of the "->" in each rule.
.PP
Matching of packets has now been extended to allow more complex compares.
In place of the address which is to be translated, an IP address and port
number comparison can be made using the same expressions available with
\fBipf\fP. A simple NAT rule could be written as:
.LP
.nf
map de0 10.1.0.0/16 -> 201.2.3.4/32
.fi
.LP
or as
.LP
.nf
map de0 from 10.1.0.0/16 to any -> 201.2.3.4/32
.fi
.LP
Only IP address and port numbers can be compared against. This is available
with all NAT rules.
.SH TRANSLATION
.PP
To the right of the "->" is the address and port specificaton which will be
@ -93,6 +119,30 @@ True transparent proxying should be performed using the redirect (\fBrdr\fP)
rules directing ports to localhost (127.0.0.1) with the proxy program doing
a lookup through \fB/dev/ipnat\fP to determine the real source and address
of the connection.
.SH LOAD-BALANCING
.PP
Two options for use with \fBrdr\fP are available to support primitive,
\fIround-robin\fP based load balancing. The first option allows for a
\fBrdr\fP to specify a second destination, as follows:
.LP
.nf
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp
.fi
.LP
This would send alternate connections to either 203.1.2.3 or 203.1.2.4.
In scenarios where the load is being spread amongst a larger set of
servers, you can use:
.LP
.nf
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp round-robin
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.5 port 80 tcp round-robin
.fi
.LP
In this case, a connection will be redirected to 203.1.2.3, then 203.1.2.4
and then 203.1.2.5 before going back to 203.1.2.3. In accomplishing this,
the rule is removed from the top of the list and added to the end,
automatically, as required. This will not effect the display of rules
using "ipnat -l", only the internal application order.
.SH EXAMPLES
.PP
This section deals with the \fBmap\fP command and it's variations.

View File

@ -1,4 +1,4 @@
.TH IPF 1
.TH MKFILTERS 1
.SH NAME
mkfilters \- generate a minimal firewall ruleset for ipfilter
.SH SYNOPSIS

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -74,6 +74,7 @@
#include "netinet/ip_nat.h"
#include "netinet/ip_auth.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_proxy.h"
#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
@ -91,6 +92,7 @@ SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
&fr_tcpidletimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
@ -119,6 +121,8 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
&fr_authused, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
&fr_defaultauthage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW,
&ippr_ftp_pasvonly, 0, "");
#endif
#ifdef DEVFS

181
contrib/ipfilter/mlfk_ipl.c Normal file
View File

@ -0,0 +1,181 @@
/*
* Copyright 1999 Guido van Rooij. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mlfk_ipl.c,v 2.1.2.1 2000/04/26 12:17:24 darrenr Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/conf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ipl.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_state.h>
#include <netinet/ip_nat.h>
#include <netinet/ip_auth.h>
#include <netinet/ip_frag.h>
static dev_t ipf_devs[IPL_LOGMAX + 1];
SYSCTL_DECL(_net_inet);
SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
&fr_tcpidletimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
&fr_tcpclosewait, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW,
&fr_tcplastack, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
&fr_tcptimeout, 0, "");
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_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 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,
&fr_ipfrttl, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
&ipl_unreach, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
&fr_running, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD,
&fr_authsize, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
&fr_authused, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
&fr_defaultauthage, 0, "");
#define CDEV_MAJOR 79
static struct cdevsw ipl_cdevsw = {
/* open */ iplopen,
/* close */ iplclose,
/* read */ iplread,
/* write */ nowrite,
/* ioctl */ iplioctl,
/* poll */ nopoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "ipl",
/* maj */ CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
/* flags */ 0,
/* bmaj */ -1
};
static int
ipfilter_modevent(module_t mod, int type, void *unused)
{
char *c;
int i, error = 0;
switch (type) {
case MOD_LOAD :
error = iplattach();
if (error)
break;
c = NULL;
for(i=strlen(IPL_NAME); i>0; i--)
if (IPL_NAME[i] == '/') {
c = &IPL_NAME[i+1];
break;
}
if (!c)
c = IPL_NAME;
ipf_devs[IPL_LOGIPF] =
make_dev(&ipl_cdevsw, IPL_LOGIPF, 0, 0, 0600, c);
c = NULL;
for(i=strlen(IPL_NAT); i>0; i--)
if (IPL_NAT[i] == '/') {
c = &IPL_NAT[i+1];
break;
}
if (!c)
c = IPL_NAT;
ipf_devs[IPL_LOGNAT] =
make_dev(&ipl_cdevsw, IPL_LOGNAT, 0, 0, 0600, c);
c = NULL;
for(i=strlen(IPL_STATE); i>0; i--)
if (IPL_STATE[i] == '/') {
c = &IPL_STATE[i+1];
break;
}
if (!c)
c = IPL_STATE;
ipf_devs[IPL_LOGSTATE] =
make_dev(&ipl_cdevsw, IPL_LOGSTATE, 0, 0, 0600, c);
c = NULL;
for(i=strlen(IPL_AUTH); i>0; i--)
if (IPL_AUTH[i] == '/') {
c = &IPL_AUTH[i+1];
break;
}
if (!c)
c = IPL_AUTH;
ipf_devs[IPL_LOGAUTH] =
make_dev(&ipl_cdevsw, IPL_LOGAUTH, 0, 0, 0600, c);
break;
case MOD_UNLOAD :
destroy_dev(ipf_devs[IPL_LOGIPF]);
destroy_dev(ipf_devs[IPL_LOGNAT]);
destroy_dev(ipf_devs[IPL_LOGSTATE]);
destroy_dev(ipf_devs[IPL_LOGAUTH]);
error = ipldetach();
break;
default:
error = EINVAL;
break;
}
return error;
}
static moduledata_t ipfiltermod = {
IPL_VERSION,
ipfilter_modevent,
0
};
DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
* (C)opyright 1997 by Marc Boucher.
*
* Redistribution and use in source and binary forms are permitted
@ -49,7 +49,7 @@ unsigned IPL_EXTERN(devflag) = D_MP;
char *IPL_EXTERN(mversion) = M_VERSION;
#endif
kmutex_t ipl_mutex, ipf_mutex, ipfi_mutex, ipf_rw;
kmutex_t ipl_mutex, ipf_mutex, ipfi_mutex, ipf_rw, ipf_hostmap;
kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
int (*fr_checkp) __P((struct ip *, int, void *, int, mb_t **));
@ -313,14 +313,14 @@ nifattach()
for (f = ipfilter[0][0]; f; f = f->fr_next) {
if ((f->fr_ifa == (struct ifnet *)-1)) {
if (f->fr_ifname[0] &&
(GETUNIT(f->fr_ifname) == ifp))
(GETUNIT(f->fr_ifname, 4) == ifp))
f->fr_ifa = ifp;
}
}
for (f = ipfilter[1][0]; f; f = f->fr_next) {
if ((f->fr_ifa == (struct ifnet *)-1)) {
if (f->fr_ifname[0] &&
(GETUNIT(f->fr_ifname) == ifp))
(GETUNIT(f->fr_ifname, 4) == ifp))
f->fr_ifa = ifp;
}
}
@ -329,7 +329,7 @@ nifattach()
for (np = nat_list; np; np = np->in_next) {
if ((np->in_ifp == (void *)-1)) {
if (np->in_ifname[0] &&
(GETUNIT(np->in_ifname) == ifp))
(GETUNIT(np->in_ifname, 4) == ifp))
np->in_ifp = (void *)ifp;
}
}
@ -539,6 +539,7 @@ IPL_EXTERN(unload)(void)
LOCK_DEALLOC(ipf_rw.l);
LOCK_DEALLOC(ipf_auth.l);
LOCK_DEALLOC(ipf_natfrag.l);
LOCK_DEALLOC(ipf_hostmap.l);
LOCK_DEALLOC(ipf_nat.l);
LOCK_DEALLOC(ipf_state.l);
LOCK_DEALLOC(ipf_frag.l);
@ -561,6 +562,7 @@ IPL_EXTERN(init)(void)
ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_hostmap.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
@ -568,7 +570,7 @@ IPL_EXTERN(init)(void)
if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_frag.l || !ipf_state.l ||
!ipf_nat.l || !ipf_natfrag.l || !ipf_auth.l || !ipf_rw.l ||
!ipl_mutex.l)
!ipl_mutex.l || !ipf_hostmap.l)
panic("IP Filter: LOCK_ALLOC failed");
#ifdef IPFILTER_LKM

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -41,8 +41,8 @@
#if !defined(lint)
static const char sccsid[] = "@(#)mls_ipl.c 2.6 10/15/95 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: mls_ipl.c,v 2.1 1999/08/04 17:30:14 darrenr Exp $";
static const char sccsid[] = "@(#)mls_ipl.c 2.6 10/15/95 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: mls_ipl.c,v 2.2 2000/03/13 22:10:26 darrenr Exp $";
#endif
extern int ipldetach __P((void));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -43,6 +43,7 @@
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "ipf.h"
#if defined(sun) && !SOLARIS2
# define STRERROR(x) sys_errlist[x]
@ -53,7 +54,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.2.2.1 1999/11/20 22:50:30 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.1 2000/04/28 18:08:00 darrenr Exp $";
#endif
@ -62,27 +63,17 @@ static const char rcsid[] = "@(#)$Id: natparse.c,v 1.2.2.1 1999/11/20 22:50:30 d
#endif
extern int countbits __P((u_32_t));
extern u_32_t hostnum __P((char *, int *, int));
extern char *proto;
ipnat_t *natparse __P((char *, int));
void printnat __P((ipnat_t *, int, void *));
void natparsefile __P((int, char *, int));
u_32_t n_hostmask __P((char *));
u_short n_portnum __P((char *, char *, int));
void nat_setgroupmap __P((struct ipnat *));
#define OPT_REM 1
#define OPT_NODO 2
#define OPT_STAT 4
#define OPT_LIST 8
#define OPT_VERBOSE 16
#define OPT_FLUSH 32
#define OPT_CLEAR 64
void printnat(np, verbose, ptr)
void printnat(np, opts, ptr)
ipnat_t *np;
int verbose;
int opts;
void *ptr;
{
struct protoent *pr;
@ -92,16 +83,16 @@ void *ptr;
switch (np->in_redir)
{
case NAT_REDIRECT :
printf("rdr ");
printf("rdr");
break;
case NAT_MAP :
printf("map ");
printf("map");
break;
case NAT_MAPBLK :
printf("map-block ");
printf("map-block");
break;
case NAT_BIMAP :
printf("bimap ");
printf("bimap");
break;
default :
fprintf(stderr, "unknown value for in_redir: %#x\n",
@ -109,25 +100,46 @@ void *ptr;
break;
}
printf(" %s ", np->in_ifname);
if (np->in_flags & IPN_FILTER) {
printf("from ");
if (np->in_redir == NAT_REDIRECT)
printhostmask(4, (u_32_t *)&np->in_srcip,
(u_32_t *)&np->in_srcmsk);
else
printhostmask(4, (u_32_t *)&np->in_inip,
(u_32_t *)&np->in_inmsk);
if (np->in_scmp)
printportcmp(np->in_p, &np->in_tuc.ftu_src);
printf(" to ");
if (np->in_redir == NAT_REDIRECT)
printhostmask(4, (u_32_t *)&np->in_inip,
(u_32_t *)&np->in_inmsk);
else
printhostmask(4, (u_32_t *)&np->in_srcip,
(u_32_t *)&np->in_srcmsk);
if (np->in_dcmp)
printportcmp(np->in_p, &np->in_tuc.ftu_dst);
}
if (np->in_redir == NAT_REDIRECT) {
printf("%s ", np->in_ifname);
if (np->in_src[0].s_addr || np->in_src[1].s_addr) {
printf("from %s",inet_ntoa(np->in_src[0]));
bits = countbits(np->in_src[1].s_addr);
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_src[1]));
printf("/%s ", inet_ntoa(np->in_out[1]));
}
printf("%s",inet_ntoa(np->in_out[0]));
bits = countbits(np->in_out[1].s_addr);
if (bits != -1)
printf("/%d ", bits);
else
printf("/%s ", inet_ntoa(np->in_out[1]));
if (np->in_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)
@ -136,21 +148,25 @@ void *ptr;
printf(" tcp");
else if ((np->in_flags & IPN_UDP) == IPN_UDP)
printf(" udp");
if (np->in_flags & IPN_ROUNDR)
printf(" round-robin");
printf("\n");
if (verbose)
printf("\t%p %lu %x %u %p %d\n", np->in_ifp,
np->in_space, np->in_flags, np->in_pnext, np,
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);
printf("%s %s/", np->in_ifname, inet_ntoa(np->in_in[0]));
bits = countbits(np->in_in[1].s_addr);
if (bits != -1)
printf("%d ", bits);
else
printf("%s", inet_ntoa(np->in_in[1]));
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_RANGE) {
if (np->in_flags & IPN_IPRANGE) {
printf("range %s-", inet_ntoa(np->in_out[0]));
printf("%s", inet_ntoa(np->in_out[1]));
} else {
@ -183,13 +199,13 @@ void *ptr;
printf("%d", np->in_p);
} else if (np->in_redir == NAT_MAPBLK) {
printf(" ports %d", np->in_pmin);
if (verbose)
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 (verbose)
if (opts & OPT_DEBUG)
printf(" [%d:%d %d %d]",
ntohs(np->in_pmin),
ntohs(np->in_pmax),
@ -206,7 +222,7 @@ void *ptr;
}
}
printf("\n");
if (verbose) {
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);
@ -245,161 +261,187 @@ ipnat_t *natparse(line, linenum)
char *line;
int linenum;
{
struct protoent *pr;
static ipnat_t ipn;
char *s, *t;
char *shost, *snetm, *dhost, *proto, *srchost, *srcnetm;
char *dnetm = NULL, *dport = NULL, *tport = NULL;
int resolved;
struct protoent *pr;
char *dnetm = NULL, *dport = NULL;
char *s, *t, *cps[31], **cpp;
int i, cnt;
srchost = NULL;
srcnetm = NULL;
bzero((char *)&ipn, sizeof(ipn));
if ((s = strchr(line, '\n')))
*s = '\0';
if ((s = strchr(line, '#')))
*s = '\0';
while (*line && isspace(*line))
line++;
if (!*line)
return NULL;
if (!(s = strtok(line, " \t")))
bzero((char *)&ipn, sizeof(ipn));
cnt = 0;
for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++)
cps[++i] = strtok(NULL, " \b\t\r\n");
cps[i] = NULL;
if (cnt < 3) {
fprintf(stderr, "%d: not enough segments in line\n", linenum);
return NULL;
if (!strcasecmp(s, "map"))
}
cpp = cps;
if (!strcasecmp(*cpp, "map"))
ipn.in_redir = NAT_MAP;
else if (!strcasecmp(s, "map-block"))
else if (!strcasecmp(*cpp, "map-block"))
ipn.in_redir = NAT_MAPBLK;
else if (!strcasecmp(s, "rdr"))
else if (!strcasecmp(*cpp, "rdr"))
ipn.in_redir = NAT_REDIRECT;
else if (!strcasecmp(s, "bimap"))
else if (!strcasecmp(*cpp, "bimap"))
ipn.in_redir = NAT_BIMAP;
else {
fprintf(stderr, "%d: unknown mapping: \"%s\"\n",
linenum, s);
linenum, *cpp);
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "%d: missing fields (interface)\n",
linenum);
return NULL;
}
cpp++;
strncpy(ipn.in_ifname, s, sizeof(ipn.in_ifname) - 1);
strncpy(ipn.in_ifname, *cpp, sizeof(ipn.in_ifname) - 1);
ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0';
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "%d: missing fields (%s)\n", linenum,
ipn.in_redir ? "from source | destination" : "source");
return NULL;
cpp++;
if (!strcasecmp(*cpp, "from")) {
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;
}
} else {
if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
(u_32_t *)&ipn.in_inmsk,
&ipn.in_dport, &ipn.in_dcmp,
&ipn.in_dtop, linenum)) {
return NULL;
}
}
if (strcasecmp(*cpp, "to")) {
fprintf(stderr, "%d: unexpected keyword (%s) - to\n",
linenum, *cpp);
return NULL;
}
if (!*++cpp) {
fprintf(stderr, "%d: missing host after to\n", linenum);
return NULL;
}
if (ipn.in_redir == NAT_REDIRECT) {
if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
(u_32_t *)&ipn.in_inmsk,
&ipn.in_dport, &ipn.in_dcmp,
&ipn.in_dtop, linenum)) {
return NULL;
}
} else {
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 {
s = *cpp;
if (!s)
return NULL;
t = strchr(s, '/');
if (!t)
return NULL;
*t++ = '\0';
if (ipn.in_redir == NAT_REDIRECT) {
if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1)
return NULL;
if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) {
return NULL;
}
} else {
if (hostnum((u_32_t *)&ipn.in_inip, s, linenum) == -1)
return NULL;
if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) {
return NULL;
}
}
cpp++;
if (!*cpp)
return NULL;
}
if ((ipn.in_redir == NAT_REDIRECT) && !strcasecmp(s, "from")) {
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (source address)\n",
if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
if (strcasecmp(*cpp, "port")) {
fprintf(stderr, "%d: missing fields - 1st port\n",
linenum);
return NULL;
}
srchost = s;
srcnetm = strrchr(srchost, '/');
cpp++;
if (srcnetm == NULL) {
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (source netmask)\n",
linenum);
return NULL;
}
if (strcasecmp(s, "netmask")) {
fprintf(stderr,
"%d: missing fields (netmask)\n",
linenum);
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (source netmask)\n",
linenum);
return NULL;
}
srcnetm = s;
}
if (*srcnetm == '/')
*srcnetm++ = '\0';
/* re read the next word -- destination */
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (destination)\n", linenum);
return NULL;
}
}
shost = s;
if (ipn.in_redir == NAT_REDIRECT) {
if (!(s = strtok(NULL, " \t"))) {
if (!*cpp) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
if (strcasecmp(s, "port")) {
fprintf(stderr, "%d: missing fields (port)\n", linenum);
if (isdigit(**cpp) && (s = strchr(*cpp, '-')))
*s++ = '\0';
else
s = NULL;
if (!portnum(*cpp, &ipn.in_pmin, linenum))
return NULL;
ipn.in_pmin = htons(ipn.in_pmin);
cpp++;
if (!strcmp(*cpp, "-")) {
cpp++;
s = *cpp++;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
dport = s;
if (s) {
if (!portnum(s, &ipn.in_pmax, linenum))
return NULL;
ipn.in_pmax = htons(ipn.in_pmax);
} else
ipn.in_pmax = ipn.in_pmin;
}
if (!(s = strtok(NULL, " \t"))) {
if (!*cpp) {
fprintf(stderr, "%d: missing fields (->)\n", linenum);
return NULL;
}
if (!strcmp(s, "->")) {
snetm = strrchr(shost, '/');
if (!snetm) {
fprintf(stderr,
"%d: missing fields (%s netmask)\n", linenum,
ipn.in_redir ? "destination" : "source");
return NULL;
}
} else {
if (strcasecmp(s, "netmask")) {
fprintf(stderr, "%d: missing fields (netmask)\n",
linenum);
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (%s netmask)\n", linenum,
ipn.in_redir ? "destination" : "source");
return NULL;
}
snetm = s;
if (strcmp(*cpp, "->")) {
fprintf(stderr, "%d: missing ->\n", linenum);
return NULL;
}
cpp++;
if (!(s = strtok(NULL, " \t"))) {
if (!*cpp) {
fprintf(stderr, "%d: missing fields (%s)\n",
linenum, ipn.in_redir ? "destination":"target");
linenum, ipn.in_redir ? "destination" : "target");
return NULL;
}
if (ipn.in_redir == NAT_MAP) {
if (!strcasecmp(s, "range")) {
ipn.in_flags |= IPN_RANGE;
if (!(s = strtok(NULL, " \t"))) {
if (!strcasecmp(*cpp, "range")) {
cpp++;
ipn.in_flags |= IPN_IPRANGE;
if (!*cpp) {
fprintf(stderr, "%d: missing fields (%s)\n",
linenum,
ipn.in_redir ? "destination":"target");
@ -407,187 +449,167 @@ int linenum;
}
}
}
dhost = s;
if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) {
if (ipn.in_flags & IPN_RANGE) {
dnetm = strrchr(dhost, '-');
if (dnetm == NULL) {
if (!(s = strtok(NULL, " \t")))
dnetm = NULL;
else {
if (strcmp(s, "-"))
s = NULL;
else if ((s = strtok(NULL, " \t"))) {
dnetm = s;
}
}
} else
*dnetm++ = '\0';
if (dnetm == NULL || *dnetm == '\0') {
fprintf(stderr,
"%d: desination range not specified\n",
linenum);
return NULL;
}
} else {
dnetm = strrchr(dhost, '/');
if (dnetm == NULL) {
if (!(s = strtok(NULL, " \t")))
dnetm = NULL;
else if (!strcasecmp(s, "netmask"))
if ((s = strtok(NULL, " \t")) != NULL)
dnetm = s;
}
if (dnetm == NULL) {
fprintf(stderr,
"%d: missing fields (dest netmask)\n",
linenum);
return NULL;
}
if (*dnetm == '/')
*dnetm++ = '\0';
}
s = strtok(NULL, " \t");
}
if (ipn.in_redir & NAT_MAPBLK) {
if (s && strcasecmp(s, "ports")) {
if (ipn.in_flags & IPN_IPRANGE) {
dnetm = strrchr(*cpp, '-');
if (dnetm == NULL) {
cpp++;
if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1))
dnetm = *(cpp + 1);
} else
*dnetm++ = '\0';
if (dnetm == NULL || *dnetm == '\0') {
fprintf(stderr,
"%d: expected \"ports\" - got \"%s\"\n",
linenum, s);
"%d: desination range not specified\n",
linenum);
return NULL;
}
if (s != NULL) {
if ((s = strtok(NULL, " \t")) == NULL)
return NULL;
ipn.in_pmin = atoi(s);
s = strtok(NULL, " \t");
} else if (ipn.in_redir != NAT_REDIRECT) {
dnetm = strrchr(*cpp, '/');
if (dnetm == NULL) {
cpp++;
if (*cpp && !strcasecmp(*cpp, "netmask"))
dnetm = *++cpp;
}
if (dnetm == NULL) {
fprintf(stderr,
"%d: missing fields (dest netmask)\n",
linenum);
return NULL;
}
if (*dnetm == '/')
*dnetm++ = '\0';
}
if (ipn.in_redir == NAT_REDIRECT) {
dnetm = strchr(*cpp, ',');
if (dnetm != NULL) {
ipn.in_flags |= IPN_SPLIT;
*dnetm++ = '\0';
}
if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1)
return NULL;
} else {
if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1)
return NULL;
}
cpp++;
if (ipn.in_redir & NAT_MAPBLK) {
if (*cpp && strcasecmp(*cpp, "ports")) {
fprintf(stderr,
"%d: expected \"ports\" - got \"%s\"\n",
linenum, *cpp);
return NULL;
}
cpp++;
if (*cpp) {
ipn.in_pmin = atoi(*cpp);
cpp++;
} else
ipn.in_pmin = 0;
} else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
if (strrchr(dhost, '/') != NULL) {
if (strrchr(*cpp, '/') != NULL) {
fprintf(stderr, "%d: No netmask supported in %s\n",
linenum, "destination host for redirect");
return NULL;
}
/* If it's a in_redir, expect target port */
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
if (strcasecmp(s, "port")) {
fprintf(stderr, "%d: missing fields (port)\n",
linenum);
if (strcasecmp(*cpp, "port")) {
fprintf(stderr, "%d: missing fields - 2nd port (%s)\n",
linenum, *cpp);
return NULL;
}
if (!(s = strtok(NULL, " \t"))) {
cpp++;
if (!*cpp) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
tport = s;
if (!portnum(*cpp, &ipn.in_pnext, linenum))
return NULL;
ipn.in_pnext = htons(ipn.in_pnext);
cpp++;
}
if (dnetm && *dnetm == '/')
*dnetm++ = '\0';
if (snetm && *snetm == '/')
*snetm++ = '\0';
if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) {
ipn.in_inip = hostnum(shost, &resolved, linenum);
if (resolved == -1)
return NULL;
ipn.in_inmsk = n_hostmask(snetm);
ipn.in_outip = hostnum(dhost, &resolved, linenum);
if (resolved == -1)
return NULL;
if (ipn.in_flags & IPN_RANGE) {
ipn.in_outmsk = hostnum(dnetm, &resolved, linenum);
if (resolved == -1)
if (ipn.in_flags & IPN_IPRANGE) {
if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm,
linenum) == -1)
return NULL;
} else
ipn.in_outmsk = n_hostmask(dnetm);
if (srchost) {
ipn.in_srcip = hostnum(srchost, &resolved, linenum);
if (resolved == -1)
return NULL;
}
if (srcnetm)
ipn.in_srcmsk = n_hostmask(srcnetm);
} else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk))
return NULL;
} else {
if (srchost) {
ipn.in_srcip = hostnum(srchost, &resolved, linenum);
if (resolved == -1)
if (ipn.in_flags & IPN_SPLIT) {
if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm,
linenum) == -1)
return NULL;
}
if (srcnetm)
ipn.in_srcmsk = n_hostmask(srcnetm);
ipn.in_inip = hostnum(dhost, &resolved, linenum);
if (resolved == -1)
} else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk))
return NULL;
ipn.in_inmsk = n_hostmask("255.255.255.255");
ipn.in_outip = hostnum(shost, &resolved, linenum);
if (resolved == -1)
return NULL;
ipn.in_outmsk = n_hostmask(snetm);
if (!(s = strtok(NULL, " \t"))) {
ipn.in_flags = IPN_TCP; /* XXX- TCP only by default */
if (!*cpp) {
ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */
proto = "tcp";
} else {
if (!strcasecmp(s, "tcp"))
ipn.in_flags = IPN_TCP;
else if (!strcasecmp(s, "udp"))
ipn.in_flags = IPN_UDP;
else if (!strcasecmp(s, "tcp/udp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "tcpudp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "ip"))
ipn.in_flags = IPN_ANY;
if (!strcasecmp(*cpp, "tcp"))
ipn.in_flags |= IPN_TCP;
else if (!strcasecmp(*cpp, "udp"))
ipn.in_flags |= IPN_UDP;
else if (!strcasecmp(*cpp, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "tcpudp"))
ipn.in_flags |= IPN_TCPUDP;
else if (!strcasecmp(*cpp, "ip"))
ipn.in_flags |= IPN_ANY;
else {
ipn.in_flags = IPN_ANY;
if ((pr = getprotobyname(s)))
ipn.in_flags |= IPN_ANY;
if ((pr = getprotobyname(*cpp)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(s);
ipn.in_p = atoi(*cpp);
}
proto = s;
if ((s = strtok(NULL, " \t"))) {
proto = *cpp;
cpp++;
if (*cpp && !strcasecmp(*cpp, "round-robin")) {
cpp++;
ipn.in_flags |= IPN_ROUNDR;
}
if (*cpp) {
fprintf(stderr,
"%d: extra junk at the end of rdr: %s\n",
linenum, s);
linenum, *cpp);
return NULL;
}
}
ipn.in_pmin = n_portnum(dport, proto, linenum);
ipn.in_pmax = ipn.in_pmin;
ipn.in_pnext = n_portnum(tport, proto, linenum);
s = NULL;
}
ipn.in_inip &= ipn.in_inmsk;
if ((ipn.in_flags & IPN_RANGE) == 0)
if (!(ipn.in_flags & IPN_SPLIT))
ipn.in_inip &= ipn.in_inmsk;
if ((ipn.in_flags & IPN_IPRANGE) == 0)
ipn.in_outip &= ipn.in_outmsk;
ipn.in_srcip &= ipn.in_srcmsk;
if ((ipn.in_redir & NAT_MAPBLK) != 0)
nat_setgroupmap(&ipn);
if (!s)
if (!*cpp)
return &ipn;
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr,
"%d: extra words at the end of bimap line: %s\n",
linenum, s);
linenum, *cpp);
return NULL;
}
if (!strcasecmp(s, "proxy")) {
if (!(s = strtok(NULL, " \t"))) {
if (!strcasecmp(*cpp, "proxy")) {
cpp++;
if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"proxy\"\n",
linenum);
@ -595,17 +617,19 @@ int linenum;
}
dport = NULL;
if (!strcasecmp(s, "port")) {
if (!(s = strtok(NULL, " \t"))) {
if (!strcasecmp(*cpp, "port")) {
cpp++;
if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"port\"\n",
linenum);
return NULL;
}
dport = s;
dport = *cpp;
cpp++;
if (!(s = strtok(NULL, " \t"))) {
if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"proxy\"\n",
linenum);
@ -616,73 +640,83 @@ int linenum;
"%d: missing keyword \"port\"\n", linenum);
return NULL;
}
if ((proto = index(s, '/'))) {
if ((proto = index(*cpp, '/'))) {
*proto++ = '\0';
if ((pr = getprotobyname(proto)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(proto);
if (dport)
ipn.in_dport = n_portnum(dport, proto, linenum);
} else {
} else
ipn.in_p = 0;
if (dport)
ipn.in_dport = n_portnum(dport, NULL, linenum);
}
(void) strncpy(ipn.in_plabel, s, sizeof(ipn.in_plabel));
if ((s = strtok(NULL, " \t"))) {
if (dport && !portnum(dport, &ipn.in_dport, linenum))
return NULL;
ipn.in_dport = htons(ipn.in_dport);
(void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel));
cpp++;
if (*cpp) {
fprintf(stderr,
"%d: too many parameters for \"proxy\"\n",
linenum);
return NULL;
}
return &ipn;
}
if (strcasecmp(s, "portmap")) {
if (strcasecmp(*cpp, "portmap")) {
fprintf(stderr,
"%d: expected \"portmap\" - got \"%s\"\n", linenum, s);
"%d: expected \"portmap\" - got \"%s\"\n", linenum,
*cpp);
return NULL;
}
if (!(s = strtok(NULL, " \t")))
cpp++;
if (!*cpp)
return NULL;
if (!strcasecmp(s, "tcp"))
ipn.in_flags = IPN_TCP;
else if (!strcasecmp(s, "udp"))
ipn.in_flags = IPN_UDP;
else if (!strcasecmp(s, "tcpudp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "tcp/udp"))
ipn.in_flags = IPN_TCPUDP;
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, s);
linenum, *cpp);
return NULL;
}
proto = *cpp;
cpp++;
if (!(s = strtok(NULL, " \t"))) {
if (!*cpp) {
fprintf(stderr, "%d: no port range found\n", linenum);
return NULL;
}
if (!strcasecmp(s, "auto")) {
if (!strcasecmp(*cpp, "auto")) {
ipn.in_flags |= IPN_AUTOPORTMAP;
ipn.in_pmin = htons(1024);
ipn.in_pmax = htons(65535);
nat_setgroupmap(&ipn);
return &ipn;
}
proto = s;
if (!(t = strchr(s, ':'))) {
fprintf(stderr, "%d: no port range in \"%s\"\n", linenum, s);
if (!(t = strchr(*cpp, ':'))) {
fprintf(stderr, "%d: no port range in \"%s\"\n",
linenum, *cpp);
return NULL;
}
*t++ = '\0';
ipn.in_pmin = n_portnum(s, proto, linenum);
ipn.in_pmax = n_portnum(t, proto, linenum);
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;
}
@ -718,12 +752,12 @@ int opts;
linenum, line);
} else {
if ((opts & OPT_VERBOSE) && np)
printnat(np, opts & OPT_VERBOSE, NULL);
printnat(np, opts, NULL);
if (!(opts & OPT_NODO)) {
if (!(opts & OPT_REM)) {
if (ioctl(fd, SIOCADNAT, np) == -1)
if (!(opts & OPT_REMOVE)) {
if (ioctl(fd, SIOCADNAT, &np) == -1)
perror("ioctl(SIOCADNAT)");
} else if (ioctl(fd, SIOCRMNAT, np) == -1)
} else if (ioctl(fd, SIOCRMNAT, &np) == -1)
perror("ioctl(SIOCRMNAT)");
}
}
@ -731,64 +765,3 @@ int opts;
if (fp != stdin)
fclose(fp);
}
u_32_t n_hostmask(msk)
char *msk;
{
int bits = -1;
u_32_t mask;
if (!isdigit(*msk))
return (u_32_t)-1;
if (strchr(msk, '.'))
return inet_addr(msk);
if (strchr(msk, 'x'))
return (u_32_t)strtol(msk, NULL, 0);
/*
* set x most significant bits
*/
for (mask = 0, bits = atoi(msk); bits; bits--) {
mask /= 2;
mask |= ntohl(inet_addr("128.0.0.0"));
}
mask = htonl(mask);
return mask;
}
u_short n_portnum(name, proto, linenum)
char *name, *proto;
int linenum;
{
struct servent *sp, *sp2;
u_short p1 = 0;
if (isdigit(*name))
return htons((u_short)atoi(name));
if (!proto)
proto = "tcp/udp";
if (strcasecmp(proto, "tcp/udp")) {
sp = getservbyname(name, proto);
if (sp)
return sp->s_port;
fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
return 0;
}
sp = getservbyname(name, "tcp");
if (sp)
p1 = sp->s_port;
sp2 = getservbyname(name, "udp");
if (!sp || !sp2) {
fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
linenum, name);
return 0;
}
if (p1 != sp2->s_port) {
fprintf(stderr, "%d: %s %d/tcp is a different port to ",
linenum, name, p1);
fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
return 0;
}
return p1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -26,8 +26,8 @@
#include "ipf.h"
#if !defined(lint)
static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: opt.c,v 2.1 1999/08/04 17:30:15 darrenr Exp $";
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 2000/03/13 22:10:26 darrenr Exp $";
#endif
extern int opts;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -40,46 +40,29 @@
#include "facpri.h"
#if !defined(lint)
static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: parse.c,v 2.1.2.8 2000/01/27 08:49:42 darrenr Exp $";
static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
extern int opts;
#ifdef USE_INET6
extern int use_inet6;
#endif
int portnum __P((char *, u_short *, int));
u_char tcp_flags __P((char *, u_char *, int));
int addicmp __P((char ***, struct frentry *, int));
int extras __P((char ***, struct frentry *, int));
char ***seg;
u_long *sa, *msk;
u_short *pp, *tp;
u_char *cp;
int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, u_char *,
u_short *, int));
int ports __P((char ***, u_short *, u_char *, u_short *, int));
int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *, int));
int to_interface __P((frdest_t *, char *, int));
void print_toif __P((char *, frdest_t *));
void optprint __P((u_short *, u_long, u_long));
int countbits __P((u_32_t));
char *portname __P((int, int));
int ratoi __P((char *, int *, int, int));
int loglevel __P((char **, u_int *, int));
void printlog __P((frentry_t *));
char *proto = NULL;
char flagset[] = "FSRPAU";
u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG };
static char thishost[MAXHOSTNAMELEN];
void initparse()
{
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
}
extern char *proto;
extern char flagset[];
extern u_char flags[];
/* parse()
@ -93,8 +76,8 @@ int linenum;
static struct frentry fil;
struct protoent *p = NULL;
char *cps[31], **cpp, *endptr;
u_char ch;
int i, cnt = 1, j;
int i, cnt = 1, j, ch;
u_int k;
while (*line && isspace(*line))
line++;
@ -103,7 +86,11 @@ 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;
/*
@ -170,8 +157,8 @@ int linenum;
fil.fr_flags |= FR_PREAUTH;
} else if (!strcasecmp("skip", *cpp)) {
cpp++;
if (ratoi(*cpp, &i, 0, USHRT_MAX))
fil.fr_skip = i;
if (ratoui(*cpp, &k, 0, UINT_MAX))
fil.fr_skip = k;
else {
fprintf(stderr, "%d: integer must follow skip\n",
linenum);
@ -185,42 +172,16 @@ int linenum;
}
if (!strcasecmp(*(cpp+1), "first")) {
fil.fr_flags |= FR_LOGFIRST;
cpp++;
}
if (*cpp && !strcasecmp(*(cpp+1), "or-block")) {
fil.fr_flags |= FR_LOGORBLOCK;
cpp++;
}
if (!strcasecmp(*(cpp+1), "level")) {
int fac, pri;
char *s;
fac = 0;
pri = 0;
if (!*++cpp) {
fprintf(stderr, "%d: %s\n", linenum,
"missing identifier after level");
cpp++;
if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1)
return NULL;
}
s = index(*cpp, '.');
if (s) {
*s++ = '\0';
fac = fac_findname(*cpp);
if (fac == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown facility", *cpp);
return NULL;
}
pri = pri_findname(s);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", s);
return NULL;
}
} else {
pri = pri_findname(*cpp);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", *cpp);
return NULL;
}
}
fil.fr_loglevel = fac|pri;
cpp++;
}
} else {
@ -285,40 +246,9 @@ int linenum;
cpp++;
}
if (*cpp && !strcasecmp(*cpp, "level")) {
int fac, pri;
char *s;
fac = 0;
pri = 0;
if (!*++cpp) {
fprintf(stderr, "%d: %s\n", linenum,
"missing identifier after level");
if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1)
return NULL;
}
s = index(*cpp, '.');
if (s) {
*s++ = '\0';
fac = fac_findname(*cpp);
if (fac == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown facility", *cpp);
return NULL;
}
pri = pri_findname(s);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", s);
return NULL;
}
} else {
pri = pri_findname(*cpp);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", *cpp);
return NULL;
}
}
fil.fr_loglevel = fac|pri;
cpp++;
cpp++;
}
}
@ -464,16 +394,17 @@ int linenum;
linenum);
return NULL;
}
ch = 0;
if (**cpp == '!') {
fil.fr_flags |= FR_NOTSRCIP;
(*cpp)++;
}
ch = 0;
if (hostmask(&cpp, (u_32_t *)&fil.fr_src,
(u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch,
&fil.fr_stop, linenum)) {
return NULL;
}
fil.fr_scmp = ch;
if (!*cpp) {
fprintf(stderr, "%d: missing to fields\n", linenum);
@ -535,7 +466,8 @@ int linenum;
/*
* extras...
*/
if (*cpp && (!strcasecmp(*cpp, "with") || !strcasecmp(*cpp, "and")))
if ((fil.fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") ||
!strcasecmp(*cpp, "and")))
if (extras(&cpp, &fil, linenum))
return NULL;
@ -570,8 +502,8 @@ int linenum;
fprintf(stderr, "%d: head without group #\n", linenum);
return NULL;
}
if (ratoi(*cpp, &i, 0, USHRT_MAX))
fil.fr_grhead = i;
if (ratoui(*cpp, &k, 0, UINT_MAX))
fil.fr_grhead = (u_32_t)k;
else {
fprintf(stderr, "%d: invalid group (%s)\n",
linenum, *cpp);
@ -589,8 +521,8 @@ int linenum;
linenum);
return NULL;
}
if (ratoi(*cpp, &i, 0, USHRT_MAX))
fil.fr_group = i;
if (ratoui(*cpp, &k, 0, UINT_MAX))
fil.fr_group = k;
else {
fprintf(stderr, "%d: invalid group (%s)\n",
linenum, *cpp);
@ -642,20 +574,62 @@ int linenum;
}
int loglevel(cpp, facpri, linenum)
char **cpp;
u_int *facpri;
int linenum;
{
int fac, pri;
char *s;
fac = 0;
pri = 0;
if (!*++cpp) {
fprintf(stderr, "%d: %s\n", linenum,
"missing identifier after level");
return -1;
}
s = index(*cpp, '.');
if (s) {
*s++ = '\0';
fac = fac_findname(*cpp);
if (fac == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown facility", *cpp);
return -1;
}
pri = pri_findname(s);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", s);
return -1;
}
} else {
pri = pri_findname(*cpp);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", *cpp);
return -1;
}
}
*facpri = fac|pri;
return 0;
}
int to_interface(fdp, to, linenum)
frdest_t *fdp;
char *to;
int linenum;
{
int r = 0;
char *s;
char *s;
s = index(to, ':');
fdp->fd_ifp = NULL;
if (s) {
*s++ = '\0';
fdp->fd_ip.s_addr = hostnum(s, &r, linenum);
if (r == -1)
if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum) == -1)
return -1;
}
(void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1);
@ -676,270 +650,6 @@ frdest_t *fdp;
}
/*
* returns -1 if neither "hostmask/num" or "hostmask mask addr" are
* found in the line segments, there is an error processing this information,
* or there is an error processing ports information.
*/
int hostmask(seg, sa, msk, pp, cp, tp, linenum)
char ***seg;
u_32_t *sa, *msk;
u_short *pp, *tp;
u_char *cp;
int linenum;
{
char *s, *endptr;
int bits = -1, resolved;
struct in_addr maskaddr;
/*
* is it possibly hostname/num ?
*/
if ((s = index(**seg, '/')) || (s = index(**seg, ':'))) {
*s++ = '\0';
if (index(s, '.') || index(s, 'x')) {
/* possibly of the form xxx.xxx.xxx.xxx
* or 0xYYYYYYYY */
if (inet_aton(s, &maskaddr) == 0) {
fprintf(stderr, "%d: bad mask (%s)\n",
linenum, s);
return -1;
}
*msk = maskaddr.s_addr;
} else {
/*
* set x most significant bits
*/
bits = (int)strtol(s, &endptr, 0);
if (*endptr != '\0' || bits > 32 || bits < 0) {
fprintf(stderr, "%d: bad mask (/%s)\n",
linenum, s);
return -1;
}
if (bits == 0)
*msk = 0;
else
*msk = htonl(0xffffffff << (32 - bits));
}
*sa = hostnum(**seg, &resolved, linenum) & *msk;
if (resolved == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
(*seg)++;
return ports(seg, pp, cp, tp, linenum);
}
/*
* look for extra segments if "mask" found in right spot
*/
if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) {
*sa = hostnum(**seg, &resolved, linenum);
if (resolved == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
(*seg)++;
(*seg)++;
if (inet_aton(**seg, &maskaddr) == 0) {
fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg);
return -1;
}
*msk = maskaddr.s_addr;
(*seg)++;
*sa &= *msk;
return ports(seg, pp, cp, tp, linenum);
}
if (**seg) {
*sa = hostnum(**seg, &resolved, linenum);
if (resolved == -1) {
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
(*seg)++;
*msk = (*sa ? inet_addr("255.255.255.255") : 0L);
*sa &= *msk;
return ports(seg, pp, cp, tp, linenum);
}
fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
return -1;
}
/*
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
u_32_t hostnum(host, resolved, linenum)
char *host;
int *resolved;
int linenum;
{
struct hostent *hp;
struct netent *np;
struct in_addr ip;
*resolved = 0;
if (!strcasecmp("any", host))
return 0;
if (isdigit(*host) && inet_aton(host, &ip))
return ip.s_addr;
if (!strcasecmp("<thishost>", host))
host = thishost;
if (!(hp = gethostbyname(host))) {
if (!(np = getnetbyname(host))) {
*resolved = -1;
fprintf(stderr, "%d: can't resolve hostname: %s\n",
linenum, host);
return 0;
}
return htonl(np->n_net);
}
return *(u_32_t *)hp->h_addr;
}
/*
* check for possible presence of the port fields in the line
*/
int ports(seg, pp, cp, tp, linenum)
char ***seg;
u_short *pp, *tp;
u_char *cp;
int linenum;
{
int comp = -1;
if (!*seg || !**seg || !***seg)
return 0;
if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
(*seg)++;
if (isdigit(***seg) && *(*seg + 2)) {
if (portnum(**seg, pp, linenum) == 0)
return -1;
(*seg)++;
if (!strcmp(**seg, "<>"))
comp = FR_OUTRANGE;
else if (!strcmp(**seg, "><"))
comp = FR_INRANGE;
else {
fprintf(stderr,
"%d: unknown range operator (%s)\n",
linenum, **seg);
return -1;
}
(*seg)++;
if (**seg == NULL) {
fprintf(stderr, "%d: missing 2nd port value\n",
linenum);
return -1;
}
if (portnum(**seg, tp, linenum) == 0)
return -1;
} else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
comp = FR_EQUAL;
else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
comp = FR_NEQUAL;
else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
comp = FR_LESST;
else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
comp = FR_GREATERT;
else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
comp = FR_LESSTE;
else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
comp = FR_GREATERTE;
else {
fprintf(stderr, "%d: unknown comparator (%s)\n",
linenum, **seg);
return -1;
}
if (comp != FR_OUTRANGE && comp != FR_INRANGE) {
(*seg)++;
if (portnum(**seg, pp, linenum) == 0)
return -1;
}
*cp = comp;
(*seg)++;
}
return 0;
}
/*
* find the port number given by the name, either from getservbyname() or
* straight atoi(). Return 1 on success, 0 on failure
*/
int portnum(name, port, linenum)
char *name;
u_short *port;
int linenum;
{
struct servent *sp, *sp2;
u_short p1 = 0;
int i;
if (isdigit(*name)) {
if (ratoi(name, &i, 0, USHRT_MAX)) {
*port = (u_short)i;
return 1;
}
fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name);
return 0;
}
if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) {
sp = getservbyname(name, proto);
if (sp) {
*port = ntohs(sp->s_port);
return 1;
}
fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
return 0;
}
sp = getservbyname(name, "tcp");
if (sp)
p1 = sp->s_port;
sp2 = getservbyname(name, "udp");
if (!sp || !sp2) {
fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
linenum, name);
return 0;
}
if (p1 != sp2->s_port) {
fprintf(stderr, "%d: %s %d/tcp is a different port to ",
linenum, name, p1);
fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
return 0;
}
*port = ntohs(p1);
return 1;
}
u_char tcp_flags(flgs, mask, linenum)
char *flgs;
u_char *mask;
int linenum;
{
u_char tcpf = 0, tcpfm = 0, *fp = &tcpf;
char *s, *t;
for (s = flgs; *s; s++) {
if (*s == '/' && fp == &tcpf) {
fp = &tcpfm;
continue;
}
if (!(t = index(flagset, *s))) {
fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s);
return 0;
}
*fp |= flags[t - flagset];
}
if (!tcpfm)
tcpfm = 0xff;
*mask = tcpfm;
return tcpf;
}
/*
* deal with extra bits on end of the line
*/
@ -1283,6 +993,9 @@ struct frentry *fp;
int linenum;
{
if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP &&
#ifdef USE_INET6
fp->fr_proto != IPPROTO_ICMPV6 &&
#endif
fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) {
fprintf(stderr, "%d: Can only use keep with UDP/ICMP/TCP\n",
linenum);
@ -1290,7 +1003,12 @@ int linenum;
}
(*cp)++;
if (**cp && strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
if (!**cp) {
fprintf(stderr, "%d: Missing state/frag after keep\n",
linenum);
return -1;
}
if (strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n",
linenum, **cp);
return -1;
@ -1305,78 +1023,17 @@ int linenum;
}
/*
* count consecutive 1's in bit mask. If the mask generated by counting
* consecutive 1's is different to that passed, return -1, else return #
* of bits.
*/
int countbits(ip)
u_32_t ip;
{
u_32_t ipn;
int cnt = 0, i, j;
ip = ipn = ntohl(ip);
for (i = 32; i; i--, ipn *= 2)
if (ipn & 0x80000000)
cnt++;
else
break;
ipn = 0;
for (i = 32, j = cnt; i; i--, j--) {
ipn *= 2;
if (j > 0)
ipn++;
}
if (ipn == ip)
return cnt;
return -1;
}
char *portname(pr, port)
int pr, port;
{
static char buf[32];
struct protoent *p = NULL;
struct servent *sv = NULL, *sv1 = NULL;
if (pr == -1) {
if ((sv = getservbyport(htons(port), "tcp"))) {
strncpy(buf, sv->s_name, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
sv1 = getservbyport(htons(port), "udp");
sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
NULL : sv1;
}
if (sv)
return buf;
} else if (pr && (p = getprotobynumber(pr))) {
if ((sv = getservbyport(htons(port), p->p_name))) {
strncpy(buf, sv->s_name, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
return buf;
}
}
(void) sprintf(buf, "%d", port);
return buf;
}
/*
* print the filter structure in a useful way
*/
void printfr(fp)
struct frentry *fp;
{
static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
"<>", "><"};
struct protoent *p;
int ones = 0, pr;
char *s, *u;
u_char *t;
struct protoent *p;
u_short sec[2];
char *s;
u_char *t;
int pr;
if (fp->fr_flags & FR_PASS)
printf("pass");
@ -1397,11 +1054,7 @@ struct frentry *fp;
} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
printf(" return-rst");
} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
printf("log");
if (fp->fr_flags & FR_LOGBODY)
printf(" body");
if (fp->fr_flags & FR_LOGFIRST)
printf(" first");
printlog(fp);
} else if (fp->fr_flags & FR_ACCOUNT)
printf("count");
else if (fp->fr_flags & FR_AUTH)
@ -1418,30 +1071,10 @@ struct frentry *fp;
if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
printf("log ");
if (fp->fr_flags & FR_LOGBODY)
printf("body ");
if (fp->fr_flags & FR_LOGFIRST)
printf("first ");
if (fp->fr_flags & FR_LOGORBLOCK)
printf("or-block ");
if (fp->fr_loglevel != 0xffff) {
if (fp->fr_loglevel & LOG_FACMASK) {
s = fac_toname(fp->fr_loglevel);
if (s == NULL)
s = "!!!";
} else
s = "";
u = pri_toname(fp->fr_loglevel);
if (u == NULL)
u = "!!!";
if (*s)
printf("level %s.%s ", s, u);
else
printf("level %s ", u);
}
printlog(fp);
putchar(' ');
}
if (fp->fr_flags & FR_QUICK)
printf("quick ");
@ -1471,42 +1104,17 @@ struct frentry *fp;
}
printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
if (!fp->fr_src.s_addr && !fp->fr_smsk.s_addr)
printf("any ");
else {
printf("%s", inet_ntoa(fp->fr_src));
if ((ones = countbits(fp->fr_smsk.s_addr)) == -1)
printf("/%s ", inet_ntoa(fp->fr_smsk));
else
printf("/%d ", ones);
}
if (fp->fr_scmp) {
if (fp->fr_scmp == FR_INRANGE || fp->fr_scmp == FR_OUTRANGE)
printf("port %d %s %d ", fp->fr_sport,
pcmp1[fp->fr_scmp], fp->fr_stop);
else
printf("port %s %s ", pcmp1[fp->fr_scmp],
portname(pr, fp->fr_sport));
}
printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
(u_32_t *)&fp->fr_smsk.s_addr);
if (fp->fr_scmp)
printportcmp(pr, &fp->fr_tuc.ftu_src);
printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
(u_32_t *)&fp->fr_dmsk.s_addr);
if (fp->fr_dcmp)
printportcmp(pr, &fp->fr_tuc.ftu_dst);
printf("to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
if (!fp->fr_dst.s_addr && !fp->fr_dmsk.s_addr)
printf("any");
else {
printf("%s", inet_ntoa(fp->fr_dst));
if ((ones = countbits(fp->fr_dmsk.s_addr)) == -1)
printf("/%s", inet_ntoa(fp->fr_dmsk));
else
printf("/%d", ones);
}
if (fp->fr_dcmp) {
if (fp->fr_dcmp == FR_INRANGE || fp->fr_dcmp == FR_OUTRANGE)
printf(" port %d %s %d", fp->fr_dport,
pcmp1[fp->fr_dcmp], fp->fr_dtop);
else
printf(" port %s %s", pcmp1[fp->fr_dcmp],
portname(pr, fp->fr_dport));
}
if ((fp->fr_ip.fi_fl & ~FI_TCPUDP) ||
(fp->fr_mip.fi_fl & ~FI_TCPUDP) ||
fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
@ -1540,7 +1148,7 @@ struct frentry *fp;
type = ntohs(fp->fr_icmp);
code = type & 0xff;
type /= 256;
if (type < (sizeof(icmptypes) / sizeof(char *)) &&
if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
icmptypes[type])
printf(" icmp-type %s", icmptypes[type]);
else
@ -1550,14 +1158,20 @@ struct frentry *fp;
}
if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
printf(" flags ");
for (s = flagset, t = flags; *s; s++, t++)
if (fp->fr_tcpf & *t)
(void)putchar(*s);
if (fp->fr_tcpf & ~TCPF_ALL)
printf("0x%x", fp->fr_tcpf);
else
for (s = flagset, t = flags; *s; s++, t++)
if (fp->fr_tcpf & *t)
(void)putchar(*s);
if (fp->fr_tcpfm) {
(void)putchar('/');
for (s = flagset, t = flags; *s; s++, t++)
if (fp->fr_tcpfm & *t)
(void)putchar(*s);
if (fp->fr_tcpfm & ~TCPF_ALL)
printf("0x%x", fp->fr_tcpfm);
else
for (s = flagset, t = flags; *s; s++, t++)
if (fp->fr_tcpfm & *t)
(void)putchar(*s);
}
}
@ -1591,16 +1205,32 @@ struct frentry *fp;
}
int ratoi(ps, pi, min, max)
char *ps;
int *pi, min, max;
void printlog(fp)
frentry_t *fp;
{
int i;
char *pe;
char *s, *u;
i = (int)strtol(ps, &pe, 0);
if (*pe != '\0' || i < min || i > max)
return 0;
*pi = i;
return 1;
printf("log");
if (fp->fr_flags & FR_LOGBODY)
printf(" body");
if (fp->fr_flags & FR_LOGFIRST)
printf(" first");
if (fp->fr_flags & FR_LOGORBLOCK)
printf(" or-block");
if (fp->fr_loglevel != 0xffff) {
printf(" level ");
if (fp->fr_loglevel & LOG_FACMASK) {
s = fac_toname(fp->fr_loglevel);
if (s == NULL)
s = "!!!";
} else
s = "";
u = pri_toname(fp->fr_loglevel);
if (u == NULL)
u = "!!!";
if (*s)
printf("%s.%s", s, u);
else
printf("%s", u);
}
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: pcap.h,v 2.1 1999/08/04 17:30:17 darrenr Exp $
* $Id: pcap.h,v 2.2 2000/03/13 22:10:27 darrenr Exp $
*/
/*
* This header file is constructed to match the version described by

View File

@ -0,0 +1,22 @@
#!/usr/local/bin/perl
# reads stats and uptime for ip-filter for mrtg
# ron@rosie.18james.com, 2 Jan 2000
my $firewall = "IP Filter v3.3.3";
my($in_pkts,$out_pkts) = (0,0);
open(FW, "/sbin/ipfstat -hi|") || die "cannot open ipfstat -hi\n";
while (<FW>) {
$in_pkts += $1 if (/^(\d+)\s+pass\s+in\s+quick.*group\s+1\d0/);
}
close(FW);
open(FW, "/sbin/ipfstat -ho|") || die "cannot open ipfstat -ho\n";
while (<FW>) {
$out_pkts += $1 if (/^(\d+)\s+pass\s+out\s+quick.*group\s+1\d0/);
}
print "$in_pkts\n",
"$out_pkts\n";
my $uptime = `/usr/bin/uptime`;
$uptime =~ /^\s+(\d{1,2}:\d{2}..)\s+up\s+(\d+)\s+(......),/;
print "$2 $3\n",
"$firewall\n";

File diff suppressed because it is too large Load Diff

View File

@ -103,6 +103,7 @@ char *argv[];
{
struct sockaddr_in sin;
natlookup_t nl;
natlookup_t *nlp = &nl;
int fd, sl = sizeof(sl), se;
openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON);
@ -142,7 +143,7 @@ char *argv[];
nl.nl_outport = sin.sin_port;
}
if (ioctl(fd, SIOCGNATL, &nl) == -1) {
if (ioctl(fd, SIOCGNATL, &nlp) == -1) {
se = errno;
perror("ioctl");
errno = se;

View File

@ -51,6 +51,7 @@ char *argv[];
{
struct sockaddr_in sin, sloc, sout;
natlookup_t natlook;
natlookup_t *natlookp = &natlook;
char buffer[512];
int namelen, fd, n;
@ -88,7 +89,7 @@ char *argv[];
* Open the NAT device and lookup the mapping pair.
*/
fd = open(IPL_NAT, O_RDONLY);
if (ioctl(fd, SIOCGNATL, &natlook) == -1) {
if (ioctl(fd, SIOCGNATL, &natlookp) == -1) {
perror("ioctl");
exit(-1);
}

View File

@ -15,13 +15,14 @@ extern int errno;
main()
{
struct frauth fra;
struct frauth *frap = &fra;
fr_info_t *fin = &fra.fra_info;
fr_ip_t *fi = &fin->fin_fi;
char yn[16];
int fd;
fd = open(IPL_NAME, O_RDWR);
while (ioctl(fd, SIOCAUTHW, &fra) == 0) {
while (ioctl(fd, SIOCAUTHW, &frap) == 0) {
if (fra.fra_info.fin_out)
fra.fra_pass = FR_OUTQUE;
else
@ -49,7 +50,7 @@ main()
fra.fra_pass |= FR_NOMATCH;
printf("answer = %c (%x), id %d idx %d\n", yn[0],
fra.fra_pass, fra.fra_info.fin_id, fra.fra_index);
if (ioctl(fd, SIOCAUTHR, &fra) != 0)
if (ioctl(fd, SIOCAUTHR, &frap) != 0)
perror("SIOCAUTHR");
}
fprintf(stderr, "errno=%d \n", errno);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -11,7 +11,7 @@
/*
* written to comply with the RFC (1761) from Sun.
* $Id: snoop.h,v 2.1 1999/08/04 17:30:19 darrenr Exp $
* $Id: snoop.h,v 2.2 2000/03/13 22:10:27 darrenr Exp $
*/
struct snoophdr {
char s_id[8];

View File

@ -1,12 +1,12 @@
/*
* Copyright (C) 1993-1998 by Darren Reed.
* Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/
#pragma ident "@(#)$Id: solaris.c,v 2.1.2.14 2000/01/25 15:32:03 darrenr Exp $"
#pragma ident "@(#)$Id: solaris.c,v 2.15.2.3 2000/05/22 10:26:17 darrenr Exp $"
#include <sys/systm.h>
#include <sys/types.h>
@ -213,7 +213,7 @@ int _init()
return -1;
ipfinst = mod_install(&modlink1);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _init() = %d\n", ipfinst);
cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
#endif
return ipfinst;
}
@ -227,7 +227,7 @@ int _fini(void)
return -1;
ipfinst = mod_remove(&modlink1);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _fini() = %d\n", ipfinst);
cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
#endif
return ipfinst;
}
@ -242,7 +242,7 @@ struct modinfo *modinfop;
return -1;
ipfinst = mod_info(&modlink1, modinfop);
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x\n", modinfop, ipfinst);
cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x", modinfop, ipfinst);
#endif
if (fr_running > 0)
ipfsync();
@ -399,7 +399,7 @@ ddi_detach_cmd_t cmd;
return DDI_FAILURE;
}
if (!soldetach()) {
cmn_err(CE_CONT, "IP Filter: detached\n");
cmn_err(CE_CONT, "%s detached\n", ipfilter_version);
return (DDI_SUCCESS);
}
default:
@ -528,13 +528,18 @@ int out;
{
register mblk_t *m, *mt = *mp;
register ip_t *ip;
size_t hlen, len, off, mlen, iphlen;
int err, synced = 0;
size_t hlen, len, off, mlen, iphlen, plen;
int err, synced = 0, sap, p;
u_char *bp;
#if SOLARIS2 >= 8
ip6_t *ip6;
#endif
#ifndef sparc
u_short __iplen, __ipoff;
u_short __ipoff;
#endif
tryagain:
ip = NULL;
m = NULL;
/*
* If there is only M_DATA for a packet going out, then any header
* information (which would otherwise appear in an M_PROTO mblk before
@ -552,8 +557,16 @@ int out;
dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp;
if (dl->dl_primitive != DL_UNITDATA_IND &&
dl->dl_primitive != DL_UNITDATA_REQ) {
frstats[out].fr_notdata++;
return 0;
ip = (ip_t *)dl;
if ((ip->ip_v == IPVERSION) &&
(ip->ip_hl == (sizeof(*ip) >> 2)) &&
(ntohs(ip->ip_len) == mt->b_wptr - mt->b_rptr)) {
off = 0;
m = mt;
} else {
frstats[out].fr_notdata++;
return 0;
}
}
}
@ -561,8 +574,9 @@ int out;
* Find the first data block, count the data blocks in this chain and
* the total amount of data.
*/
for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont)
off = 0; /* Any non-M_DATA cancels the offset */
if (ip == NULL)
for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont)
off = 0; /* Any non-M_DATA cancels the offset */
if (!m) {
frstats[out].fr_nodata++;
@ -598,7 +612,6 @@ int out;
off = (u_char *)ip - m->b_rptr;
if (off != 0)
m->b_rptr = (u_char *)ip;
mlen = msgdsize(m);
len = m->b_wptr - m->b_rptr;
if (m->b_wptr < m->b_rptr) {
@ -607,30 +620,72 @@ int out;
frstats[out].fr_bad++;
return -1;
}
mlen = msgdsize(m);
sap = qif->qf_ill->ill_sap;
if (sap == 0x800) {
hlen = sizeof(*ip);
plen = ntohs(ip->ip_len);
sap = 0;
}
#if SOLARIS2 >= 8
else if (sap == IP6_DL_SAP) {
hlen = sizeof(ip6_t);
ip6 = (ip6_t *)ip;
plen = ntohs(ip6->ip6_plen);
sap = IP6_DL_SAP;
}
#endif
else {
hlen = 0;
sap = -1;
}
/*
* Ok, the IP header isn't on a 32bit aligned address so junk it.
*/
if (((u_int)ip & 0x3) || (len < sizeof(*ip))) {
if (((u_int)ip & 0x3) || (len < hlen) || (sap == -1)) {
mblk_t *m2;
u_char *s;
/*
* We have link layer header and IP header in the same mbuf,
* problem being that a pullup without adjusting b_rptr will
* bring us back here again as it's likely that the start of
* the databuffer (b_datab->db_base) is already aligned. Hmm,
* should we pull it all up (length of -1 to pullupmsg) if we
* can, now ?
* Junk using pullupmsg - it's next to useless.
*/
fixalign:
if (!pullupmsg(m, sizeof(ip_t))) {
len = msgdsize(m);
m2 = allocb(len, BPRI_HI);
if (m2 == NULL) {
frstats[out].fr_pull[1]++;
return -1;
}
m2->b_wptr = m2->b_rptr + len;
s = (u_char *)ip;
for (bp = m2->b_rptr; m; bp += len) {
len = m->b_wptr - s;
bcopy(m->b_rptr, bp, len);
m = m->b_cont;
if (m)
s = m->b_rptr;
}
*mp = m2;
MTYPE(m2) = M_DATA;
freemsg(mt);
mt = m2;
frstats[out].fr_pull[0]++;
synced = 1;
off = 0;
goto tryagain;
}
if (ip->ip_v != IPVERSION) {
if (((sap == 0) && (ip->ip_v != IP_VERSION))
#if SOLARIS2 >= 8
|| ((sap == IP6_DL_SAP) && ((ip6->ip6_vfc >> 4) != 6))
#endif
) {
m->b_rptr -= off;
if (!synced) {
synced = 1;
@ -644,26 +699,48 @@ int out;
}
#ifndef sparc
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
# if SOLARIS2 >= 8
if (sap == IP6_DL_SAP) {
ip6->ip6_plen = plen;
} else {
# endif
__ipoff = (u_short)ip->ip_off;
ip->ip_len = ntohs(__iplen);
ip->ip_off = ntohs(__ipoff);
ip->ip_len = plen;
ip->ip_off = ntohs(__ipoff);
# if SOLARIS2 >= 8
}
# endif
#endif
if (sap == 0)
iphlen = ip->ip_hl << 2;
#if SOLARIS2 >= 8
else if (sap == IP6_DL_SAP)
iphlen = sizeof(ip6_t);
#endif
hlen = iphlen = ip->ip_hl << 2;
if ((iphlen < sizeof(ip_t)) || (iphlen > (u_short)ip->ip_len) ||
(mlen < (u_short)ip->ip_len)) {
if ((
#if SOLARIS2 >= 8
(sap == IP6_DL_SAP) && (mlen < iphlen + plen)) ||
((sap == 0) &&
#endif
((iphlen < hlen) || (iphlen > plen) || (mlen < plen)))) {
/*
* Bad IP packet or not enough data/data length mismatches
*/
#ifndef sparc
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
# if SOLARIS2 >= 8
if (sap == IP6_DL_SAP) {
ip6->ip6_plen = htons(plen);
} else {
# endif
__ipoff = (u_short)ip->ip_off;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
ip->ip_len = htons(plen);
ip->ip_off = htons(__ipoff);
# if SOLARIS2 >= 8
}
# endif
#endif
m->b_rptr -= off;
frstats[out].fr_bad++;
@ -674,8 +751,17 @@ int out;
* Make hlen the total size of the IP header plus TCP/UDP/ICMP header
* (if it is one of these three).
*/
if (sap == 0)
p = ip->ip_p;
#if SOLARIS2 >= 8
else if (sap == IP6_DL_SAP)
p = ip6->ip6_nxt;
if ((sap == IP6_DL_SAP) || ((ip->ip_off & IP_OFFMASK) == 0))
#else
if ((ip->ip_off & IP_OFFMASK) == 0)
switch (ip->ip_p)
#endif
switch (p)
{
case IPPROTO_TCP :
hlen += sizeof(tcphdr_t);
@ -691,8 +777,15 @@ int out;
break;
}
if (hlen > mlen)
if (hlen > mlen) {
hlen = mlen;
#if SOLARIS2 >= 8
} else if (sap == IP6_DL_SAP) {
if (m->b_wptr - m->b_rptr > plen + hlen)
m->b_wptr = m->b_rptr + plen + hlen;
#endif
} else if (m->b_wptr - m->b_rptr > plen)
m->b_wptr = m->b_rptr + plen;
/*
* If we don't have enough data in the mblk or we haven't yet copied
@ -724,11 +817,20 @@ int out;
if (*mp == mt) {
m->b_rptr -= off;
#ifndef sparc
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
# if SOLARIS2 >= 8
if (sap == IP6_DL_SAP) {
ip6->ip6_plen = htons(plen);
} else {
# endif
__ipoff = (u_short)ip->ip_off;
/*
* plen is useless because of NAT.
*/
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(__ipoff);
# if SOLARIS2 >= 8
}
# endif
#endif
} else
cmn_err(CE_NOTE,
@ -752,6 +854,15 @@ mblk_t *mb;
return 0;
}
if (mb->b_datap->db_ref > 1) {
mblk_t *m1;
m1 = copymsg(mb);
freemsg(mb);
mb = m1;
frstats[0].fr_copy++;
}
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
@ -844,6 +955,15 @@ mblk_t *mb;
return 0;
}
if (mb->b_datap->db_ref > 1) {
mblk_t *m1;
m1 = copymsg(mb);
freemsg(mb);
mb = m1;
frstats[1].fr_copy++;
}
READ_ENTER(&ipf_solaris);
again:
if (fr_running <= 0) {
@ -959,7 +1079,7 @@ mblk_t *mb;
freemsg(mb);
return 0;
}
if (MTYPE(mb) != M_IOCTL)
return (*ipf_ip_inp)(q, mb);
@ -1056,10 +1176,6 @@ void solattach()
if (!in || !il->ill_wq)
continue;
#if SOLARIS2 >= 8
if (il->ill_isv6)
continue;
#endif
out = il->ill_wq->q_next;
WRITE_ENTER(&ipfs_mutex);
@ -1142,6 +1258,7 @@ void solattach()
mblk_t *m;
qif->qf_hl = 0;
qif->qf_sap = il->ill_sap;
# if 0
/*
* Can't seem to lookup a route for the IP address on the
@ -1192,6 +1309,26 @@ void solattach()
f->fr_ifa = il;
}
}
#if SOLARIS2 >= 8
for (f = ipfilter6[0][fr_active]; f; f = f->fr_next) {
if ((f->fr_ifa == (struct ifnet *)-1)) {
len = strlen(f->fr_ifname) + 1;
if ((len != 0) &&
(len == (size_t)il->ill_name_length) &&
!strncmp(il->ill_name, f->fr_ifname, len))
f->fr_ifa = il;
}
}
for (f = ipfilter6[1][fr_active]; f; f = f->fr_next) {
if ((f->fr_ifa == (struct ifnet *)-1)) {
len = strlen(f->fr_ifname) + 1;
if ((len != 0) &&
(len == (size_t)il->ill_name_length) &&
!strncmp(il->ill_name, f->fr_ifname, len))
f->fr_ifa = il;
}
}
#endif
RWLOCK_EXIT(&ipf_mutex);
WRITE_ENTER(&ipf_nat);
for (np = nat_list; np; np = np->in_next) {
@ -1228,8 +1365,14 @@ void solattach()
out->q_qinfo = &qif->qf_wqinit;
RWLOCK_EXIT(&ipfs_mutex);
cmn_err(CE_CONT, "IP Filter: attach to [%s,%d]\n",
qif->qf_name, il->ill_ppa);
cmn_err(CE_CONT, "IP Filter: attach to [%s,%d] - %s\n",
qif->qf_name, il->ill_ppa,
#if SOLARIS2 >= 8
il->ill_isv6 ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
);
}
if (!qif_head)
cmn_err(CE_CONT, "IP Filter: not attached to any interfaces\n");
@ -1268,7 +1411,14 @@ int ipfsync()
qp = &qif->qf_next;
continue;
}
cmn_err(CE_CONT, "IP Filter: detaching [%s]\n", qif->qf_name);
cmn_err(CE_CONT, "IP Filter: detaching [%s] - %s\n",
qif->qf_name,
#if SOLARIS2 >= 8
(qif->qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
);
*qp = qif->qf_next;
/*
@ -1286,6 +1436,14 @@ int ipfsync()
for (f = ipfilter[1][fr_active]; f; f = f->fr_next)
if (f->fr_ifa == (void *)qif->qf_ill)
f->fr_ifa = (struct ifnet *)-1;
#if SOLARIS2 >= 8
for (f = ipfilter6[0][fr_active]; f; f = f->fr_next)
if (f->fr_ifa == (void *)qif->qf_ill)
f->fr_ifa = (struct ifnet *)-1;
for (f = ipfilter6[1][fr_active]; f; f = f->fr_next)
if (f->fr_ifa == (void *)qif->qf_ill)
f->fr_ifa = (struct ifnet *)-1;
#endif
#if 0 /* XXX */
/*
@ -1372,8 +1530,14 @@ int soldetach()
if (il) {
in = qif->qf_in;
out = qif->qf_out;
cmn_err(CE_CONT, "IP Filter: detaching [%s,%d]\n",
qif->qf_name, il->ill_ppa);
cmn_err(CE_CONT, "IP Filter: detaching [%s,%d] - %s\n",
qif->qf_name, il->ill_ppa,
#if SOLARIS2 >= 8
(qif->qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
);
#ifdef IPFDEBUG
cmn_err(CE_NOTE,
@ -1404,13 +1568,24 @@ void printire(ire)
ire_t *ire;
{
printf("ire: ll_hdr_mp %p rfq %p stq %p src_addr %x max_frag %d\n",
ire->ire_ll_hdr_mp, ire->ire_rfq, ire->ire_stq,
# if SOLARIS2 >= 8
NULL,
# else
ire->ire_ll_hdr_mp,
# endif
ire->ire_rfq, ire->ire_stq,
ire->ire_src_addr, ire->ire_max_frag);
printf("ire: mask %x addr %x gateway_addr %x type %d\n",
ire->ire_mask, ire->ire_addr, ire->ire_gateway_addr,
ire->ire_type);
printf("ire: ll_hdr_length %d ll_hdr_saved_mp %p\n",
ire->ire_ll_hdr_length, ire->ire_ll_hdr_saved_mp);
ire->ire_ll_hdr_length,
# if SOLARIS2 >= 8
NULL
# else
ire->ire_ll_hdr_saved_mp
# endif
);
}
#endif
@ -1422,14 +1597,20 @@ mblk_t *mb, **mpp;
fr_info_t *fin;
frdest_t *fdp;
{
#ifdef USE_INET6
ip6_t *ip6 = (ip6_t *)ip;
#endif
ire_t *ir, *dir, *gw;
struct in_addr dst;
queue_t *q = NULL;
mblk_t *mp = NULL;
size_t hlen = 0;
frentry_t *fr;
frdest_t fd;
ill_t *ifp;
qif_t *qif;
u_char *s;
int p;
#ifndef sparc
u_short __iplen, __ipoff;
@ -1455,18 +1636,50 @@ frdest_t *fdp;
*mpp = mp;
}
if (!fdp) {
ipif_t *ipif;
ifp = fin->fin_ifp;
ipif = ifp->ill_ipif;
if (!ipif)
goto bad_fastroute;
#if SOLARIS2 > 5
ir = ire_ctable_lookup(ipif->ipif_local_addr, 0, IRE_LOCAL,
NULL, NULL, MATCH_IRE_TYPE);
#else
ir = ire_lookup_myaddr(ipif->ipif_local_addr);
#endif
if (!ir)
ir = (ire_t *)-1;
fd.fd_ifp = (struct ifnet *)ir;
fd.fd_ip = ip->ip_dst;
fdp = &fd;
}
ir = (ire_t *)fdp->fd_ifp;
if (fdp->fd_ip.s_addr)
dst = fdp->fd_ip;
else
dst = fin->fin_fi.fi_dst;
dst.s_addr = fin->fin_fi.fi_daddr;
#if SOLARIS2 >= 6
gw = NULL;
dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL, &gw, NULL,
MATCH_IRE_DSTONLY|MATCH_IRE_DEFAULT|
MATCH_IRE_RECURSIVE);
if (fin->fin_v == 4) {
p = ip->ip_p;
dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL,
&gw, NULL, MATCH_IRE_DSTONLY|
MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
}
# ifdef USE_INET6
else if (fin->fin_v == 6) {
p = ip6->ip6_nxt;
dir = ire_route_lookup_v6(&ip6->ip6_dst, 0xffffffff, 0, 0,
NULL, &gw, NULL, MATCH_IRE_DSTONLY|
MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE);
}
# endif
#else
dir = ire_lookup(dst.s_addr);
#endif
@ -1502,18 +1715,22 @@ frdest_t *fdp;
fin->fin_fr = ipacct[1][fr_active];
if ((fin->fin_fr != NULL) &&
(fr_scanlist(FR_NOMATCH, ip, fin, mb)&FR_ACCOUNT)){
ATOMIC_INC(frstats[1].fr_acct);
ATOMIC_INCL(frstats[1].fr_acct);
}
fin->fin_fr = NULL;
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
}
if (!fr || !(fr->fr_flags & FR_RETMASK)) {
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
}
}
#ifndef sparc
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
if (fin->fin_v == 4) {
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
ip->ip_len = htons(__iplen);
ip->ip_off = htons(__ipoff);
}
#endif
#if SOLARIS2 < 8
@ -1541,7 +1758,7 @@ frdest_t *fdp;
mp2 = copyb(mp);
if (!mp2)
goto bad_fastroute;
mp2->b_cont = mb;
linkb(mp2, mb);
mb = mp2;
}
}
@ -1557,7 +1774,7 @@ frdest_t *fdp;
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
#if SOLARIS2 >= 6
if ((ip->ip_p == IPPROTO_TCP) && dohwcksum &&
if ((p == IPPROTO_TCP) && dohwcksum &&
(ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
tcphdr_t *tcp;
u_32_t t;
@ -1643,3 +1860,23 @@ char *buf;
bp += clen;
}
}
int fr_verifysrc(ipa, ifp)
struct in_addr ipa;
void *ifp;
{
ire_t *ir, *dir, *gw;
#if SOLARIS2 >= 6
dir = ire_route_lookup(ipa.s_addr, 0xffffffff, 0, 0, NULL, &gw, NULL,
MATCH_IRE_DSTONLY|MATCH_IRE_DEFAULT|
MATCH_IRE_RECURSIVE);
#else
dir = ire_lookup(ipa.s_addr);
#endif
if (!dir)
return 0;
return (ire_to_ill(dir) == ifp);
}

View File

@ -6,3 +6,5 @@ pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 127.0.0.1/32 to 127.0.0.1/32
block in log from any to any
block in log level auth.info on hme0(!) from any to any
log level local5.warn out from any to any

View File

@ -1,3 +1,4 @@
pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA
block in on lo0(!) proto tcp from any to any flags A/FSRPAU
block in on lo0(!) proto tcp from any to any flags A/0xff
pass in on lo0(!) proto tcp from any to any flags /SPA
block in on lo0(!) proto tcp from any to any flags 0x80/A

View File

@ -81,16 +81,16 @@ ip 20(20) 255 10.1.1.0 > 10.3.4.5
ip 20(20) 255 10.1.1.1 > 10.3.4.5
ip 20(20) 255 10.1.1.2 > 10.3.4.5
ip 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025
ip 48(20) 1 10.3.4.4 > 10.4.3.2
ip 48(20) 1 10.3.4.2 > 10.4.3.2
ip 48(20) 1 10.4.3.2 > 10.2.2.2
ip 48(20) 1 10.4.3.2 > 10.3.4.3
ip 48(20) 1 10.4.3.2 > 10.3.4.5
ip 20(20) 34 10.3.4.5 > 10.4.3.2
ip 20(20) 34 10.3.4.3 > 10.4.3.2
ip 20(20) 34 10.4.3.2 > 10.3.4.4
ip 20(20) 34 10.3.4.6 > 10.4.3.4
ip 20(20) 34 10.3.4.3 > 10.4.3.4
ip 20(20) 34 10.4.3.4 > 10.3.4.5
ip 20(20) 34 10.3.4.7 > 10.4.3.4
ip 20(20) 34 10.4.3.4 > 10.1.1.2
ip 20(20) 35 10.3.4.7 > 10.4.3.4
ip 20(20) 35 10.4.3.4 > 10.1.1.3
ip 20(20) 34 10.3.4.4 > 10.4.3.4
ip 20(20) 34 10.4.3.4 > 10.3.4.6
ip 20(20) 35 10.3.4.4 > 10.4.3.4
ip 20(20) 35 10.4.3.4 > 10.3.4.7
-------------------------------

View File

@ -6,3 +6,5 @@ pass in from 128.0.0.1 mask 0xffffff00 to 128.0.0.1 mask 0xffff0000
pass in from 128.0.0.1 mask 255.255.255.0 to 128.0.0.1 mask 255.255.0.0
pass in from localhost to localhost
block in log from 0/0 to 0/0
block in log level auth.info on hme0 all
log level local5.warn out all

View File

@ -1,3 +1,4 @@
pass in on ed0 proto tcp from localhost to localhost port = 23 flags S/SA
block in on lo0 proto tcp from any to any flags A
pass in on lo0 proto tcp from any to any flags /SAP
block in on lo0 proto tcp from any to any flags 0x80/A

View File

@ -17,20 +17,20 @@ time permitting:
* record buffering for TCP/UDP
* modular application proxying
on the way
* keep fragment information for state entries automatically.
done for NAT
available
* allow multiple ip addresses in a source route list for ipsend
* complete Linux port to implement all the IP Filter features
return-rst done, to/dup-to/fastroute remain - ip_forward() problems :-(
on hold until rewrite
* add a flag to automate src spoofing
done
* ipfsync() should change IP#'s in current mappings as well as what's
in rules.
done
* document bimap
@ -39,4 +39,59 @@ return-rst done, to/dup-to/fastroute remain - ip_forward() problems :-(
* add more docs
in progress
3.4:
XDDD. I agree. Bandwidth Shapping and QoS (Quality of Service, AKA
traffic priorization) should be *TOP* in the TO DO list.
* irc proxy for dcc
* Bandwidth limiting!!!
* More examples
* More documentation
* And did I mention bandwidth limiting???
* Load balancing features added to the NAT code, so that I can have
something coming in for 20.20.20.20:80 and it gets shuffled around between
internal addresses 10.10.10.1:8000 and 10.10.10.2:8000. or whatever.
- done, stage 1 (round robin/split)
The one thing that Cisco's PIX has on IPF that I can see is that
rewrites the sequence numbers with semi-random ones.
I would also love to see a more extensive NAT. It can choose to do
rdr and map based on saddr, daddr, sport and dport. (Does the kernel
module already have functionality for that and it just needs support in
the userland ipnat?)
* intrusion detection
detection of port scans
detection of multiple connection attempts
* support for multiple log files
i.e. all connections to ftp and telnet logged to
a seperate log file
* multiple levels of log severity with E-mail notification
of intrusion alerts or other high priority errors
* poison pill facility
after detection of a port scan, start sending back
large packets of garbage or other packets to
otherwise confuse the intruder (ping of death?)
* I ran into your solaris streams stuff and noticed you are
playing with mblk's in an unsafe way. You seem to be modifying the
underlying datab without checking db_ref. If db_ref is greater than one,
you'll need to copy the mblk,
- fixed
* fix up where manual pages go for Solaris2
IPv6:
-----
* NAT is yet not available, either as a null proxy or address translation
BSD:
* "to <if>" and "to <if>:<ip>" are not supported, but "fastroute" is.
Solaris:
* "to <if>:<ip>" is not supported, but "fastroute" is and "to <if>" are.