diff -cr ip_fil3.2.7/HISTORY ip_fil3.2.8/HISTORY *** ip_fil3.2.7/HISTORY Sun May 24 12:06:45 1998 --- ip_fil3.2.8/HISTORY Mon Jun 8 02:32:07 1998 *************** *** 11,16 **** --- 11,21 ---- # Thanks also to all those who have contributed patches and other code, # and especially those who have found the time to port IP Filter to new # platforms. + 3.2.8 08/06/98 - Released + + use readers/writers locks in Solaris2 in place of some mutexes. + + Solaris2 installation enhancements - Martin Forssen (maf@carlstedt.se) 3.2.7 24/05/98 - Released diff -cr ip_fil3.2.7/SunOS5/Makefile ip_fil3.2.8/SunOS5/Makefile *** ip_fil3.2.7/SunOS5/Makefile Fri May 22 00:46:09 1998 --- ip_fil3.2.8/SunOS5/Makefile Mon Jun 8 02:28:35 1998 *************** *** 18,23 **** --- 18,24 ---- PKGBIN=$(PKGDIR)/bin # TOP=.. + TMP=/tmp DCPU=`uname -m` CPUDIR=$(DCPU)-`uname -r` CC=gcc -Wall *************** *** 53,58 **** --- 54,61 ---- sunos5 solaris2 build: ipf.exe ipfstat ipftest ipmon ipnat ipf + pkg: ipf.pkg + ipfstat: $(FILS) $(CC) $(DEBUG) $(CFLAGS) $(FILS) -o $@ $(LIBS) *************** *** 177,183 **** ${RM} -f ipnat.5 ipnat.4 ipnat.1 ipfilter.5; \ ${RM} -f prototype pkginfo postinstall copyright; \ fi ! /bin/rm -rf */root make -f Makefile.ipsend clean -(for i in *; do \ if [ -d $${i} -a -f $${i}/Makefile ] ; then \ --- 180,186 ---- ${RM} -f ipnat.5 ipnat.4 ipnat.1 ipfilter.5; \ ${RM} -f prototype pkginfo postinstall copyright; \ fi ! /bin/rm -rf */root ipf.pkg make -f Makefile.ipsend clean -(for i in *; do \ if [ -d $${i} -a -f $${i}/Makefile ] ; then \ *************** *** 187,236 **** fi \ done) ! package install: ! @if [ `id|sed -e 's/^.[^(]*(\([^)]*\)).*/\1/'` != root ] ; then \ ! echo "Can only build package and install if root"; \ ! exit 1; \ ! fi mkdir -p $(PKGBIN) $(ROOT)/sbin $(ROOT)/usr/kernel/drv $(ROOT)/etc/init.d mkdir -p $(ROOTINC)/netinet $(PKGDIR)/examples mkdir -p $(PKGMAN)/man1 $(PKGMAN)/man4 $(PKGMAN)/man5 $(PKGMAN)/man8 ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipftest $(PKGBIN)/ipftest ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipmon $(PKGBIN)/ipmon ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipsend $(PKGBIN)/ipsend ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipresend $(PKGBIN)/ipresend ! -$(INSTALL) -c -g root -m 755 -o root $(TOP)/mkfilters $(PKGBIN)/mkfilters ! -$(INSTALL) -c -g root -m 755 -o root $(CPUDIR)/ipf $(ROOT)/usr/kernel/drv/ipf ! -$(INSTALL) -c -g root -m 644 -o root ipf.conf $(ROOT)/usr/kernel/drv ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipnat $(ROOT)/sbin/ipnat ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipf.exe $(ROOT)/sbin/ipf ! -$(INSTALL) -c -s -g root -m 755 -o root $(CPUDIR)/ipfstat $(ROOT)/sbin/ipfstat ! -$(INSTALL) -c -g root -m 755 -o root ipfboot $(ROOT)/etc/init.d -cp $(TOP)/man/*.[0-9] . ! -$(INSTALL) -g root -m 444 -o root ipf.8 $(PKGMAN)/man8 ! -$(INSTALL) -g root -m 444 -o root ipnat.1 $(PKGMAN)/man1 ! -$(INSTALL) -g root -m 444 -o root ipftest.1 $(PKGMAN)/man1 ! -$(INSTALL) -g root -m 444 -o root mkfilters.1 $(PKGMAN)/man1 ! -$(INSTALL) -g root -m 444 -o root ipf.4 $(PKGMAN)/man4 ! -$(INSTALL) -g root -m 444 -o root ipnat.4 $(PKGMAN)/man4 ! -$(INSTALL) -g root -m 444 -o root ipl.4 $(PKGMAN)/man4 ! -$(INSTALL) -g root -m 444 -o root ipf.5 $(PKGMAN)/man5 ! -$(INSTALL) -g root -m 444 -o root ipnat.5 $(PKGMAN)/man5 ! -$(INSTALL) -g root -m 444 -o root ipfilter.5 $(PKGMAN)/man5 ! -$(INSTALL) -g root -m 444 -o root ipfstat.8 $(PKGMAN)/man8 ! -$(INSTALL) -g root -m 444 -o root ipmon.8 $(PKGMAN)/man8 -cp $(TOP)/rules/* $(PKGDIR)/examples -cp $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_state.h . -cp $(TOP)/ip_nat.h $(TOP)/ip_frag.h $(TOP)/ip_proxy.h . -cp $(TOP)/ip_auth.h . ! -$(INSTALL) -g root -m 644 -o root ip_fil.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_compat.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_state.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_nat.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_frag.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_proxy.h $(ROOTINC)/netinet ! -$(INSTALL) -g root -m 644 -o root ip_auth.h $(ROOTINC)/netinet ! (cd $(CPUDIR) && rm -f prototype pkginfo copyright postinstall && ln -s ../prototype ../pkginfo ../copyright ../postinstall .) ! (cd $(CPUDIR); pkgmk -o) ! -pkgadd -d /var/spool/pkg --- 190,244 ---- fi \ done) ! ipf.pkg: mkdir -p $(PKGBIN) $(ROOT)/sbin $(ROOT)/usr/kernel/drv $(ROOT)/etc/init.d mkdir -p $(ROOTINC)/netinet $(PKGDIR)/examples mkdir -p $(PKGMAN)/man1 $(PKGMAN)/man4 $(PKGMAN)/man5 $(PKGMAN)/man8 ! -$(INSTALL) -c -s $(CPUDIR)/ipftest $(PKGBIN)/ipftest ! -$(INSTALL) -c -s $(CPUDIR)/ipmon $(PKGBIN)/ipmon ! -$(INSTALL) -c -s $(CPUDIR)/ipsend $(PKGBIN)/ipsend ! -$(INSTALL) -c -s $(CPUDIR)/ipresend $(PKGBIN)/ipresend ! -$(INSTALL) -c $(TOP)/mkfilters $(PKGBIN)/mkfilters ! -$(INSTALL) -c $(CPUDIR)/ipf $(ROOT)/usr/kernel/drv/ipf ! -$(INSTALL) -c ipf.conf $(ROOT)/usr/kernel/drv ! -$(INSTALL) -c -s $(CPUDIR)/ipnat $(ROOT)/sbin/ipnat ! -$(INSTALL) -c -s $(CPUDIR)/ipf.exe $(ROOT)/sbin/ipf ! -$(INSTALL) -c -s $(CPUDIR)/ipfstat $(ROOT)/sbin/ipfstat ! -$(INSTALL) -c ipfboot $(ROOT)/etc/init.d -cp $(TOP)/man/*.[0-9] . ! -$(INSTALL) ipf.8 $(PKGMAN)/man8 ! -$(INSTALL) ipnat.1 $(PKGMAN)/man1 ! -$(INSTALL) ipftest.1 $(PKGMAN)/man1 ! -$(INSTALL) mkfilters.1 $(PKGMAN)/man1 ! -$(INSTALL) ipf.4 $(PKGMAN)/man4 ! -$(INSTALL) ipnat.4 $(PKGMAN)/man4 ! -$(INSTALL) ipl.4 $(PKGMAN)/man4 ! -$(INSTALL) ipf.5 $(PKGMAN)/man5 ! -$(INSTALL) ipnat.5 $(PKGMAN)/man5 ! -$(INSTALL) ipfilter.5 $(PKGMAN)/man5 ! -$(INSTALL) ipfstat.8 $(PKGMAN)/man8 ! -$(INSTALL) ipmon.8 $(PKGMAN)/man8 -cp $(TOP)/rules/* $(PKGDIR)/examples -cp $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_state.h . -cp $(TOP)/ip_nat.h $(TOP)/ip_frag.h $(TOP)/ip_proxy.h . -cp $(TOP)/ip_auth.h . ! -$(INSTALL) ip_fil.h $(ROOTINC)/netinet ! -$(INSTALL) ip_compat.h $(ROOTINC)/netinet ! -$(INSTALL) ip_state.h $(ROOTINC)/netinet ! -$(INSTALL) ip_nat.h $(ROOTINC)/netinet ! -$(INSTALL) ip_frag.h $(ROOTINC)/netinet ! -$(INSTALL) ip_proxy.h $(ROOTINC)/netinet ! -$(INSTALL) ip_auth.h $(ROOTINC)/netinet ! -(cd $(CPUDIR); ln -s ../prototype ../pkginfo ../copyright ../postinstall .) ! (cd $(CPUDIR); pkgmk -o -d $(TMP)) ! pkgtrans -s ${TMP} $(CPUDIR)/ipf.pkg ipf ! /bin/rm -f ipf.pkg ! ln -s $(CPUDIR)/ipf.pkg ipf.pkg ! rm -rf $(TMP)/ipf + package install: ipf.pkg + @if [ `id|sed -e 's/^.[^(]*(\([^)]*\)).*/\1/'` != root ] ; then \ + echo "Can only install if root"; \ + exit 1; \ + fi + -pkgadd -d ipf.pkg diff -cr ip_fil3.2.7/SunOS5/pkginfo ip_fil3.2.8/SunOS5/pkginfo *** ip_fil3.2.7/SunOS5/pkginfo Sun May 24 12:06:50 1998 --- ip_fil3.2.8/SunOS5/pkginfo Mon Jun 8 02:32:45 1998 *************** *** 5,11 **** PKG=ipf NAME=IP Filter ARCH=sparc,i386 ! VERSION=3.2,REV=7 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed --- 5,11 ---- PKG=ipf NAME=IP Filter ARCH=sparc,i386 ! VERSION=3.2,REV=8 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed diff -cr ip_fil3.2.7/SunOS5/postinstall ip_fil3.2.8/SunOS5/postinstall *** ip_fil3.2.7/SunOS5/postinstall Sat Apr 11 12:58:52 1998 --- ip_fil3.2.8/SunOS5/postinstall Sun Jun 7 00:41:24 1998 *************** *** 16,22 **** echo "type=ddi_pseudo;name=ipf;minor=ipauth \M0" >>/etc/devlink.tab fi /usr/sbin/devlinks ! /usr/ucb/ucblinks if [ ! -f /etc/opt/ipf/ipf.conf ] ; then touch /etc/opt/ipf/ipf.conf fi --- 16,24 ---- echo "type=ddi_pseudo;name=ipf;minor=ipauth \M0" >>/etc/devlink.tab fi /usr/sbin/devlinks ! if [ -d /usr/ucb -a -f /usr/ucb/ucblinks ] ; then ! /usr/ucb/ucblinks ! fi if [ ! -f /etc/opt/ipf/ipf.conf ] ; then touch /etc/opt/ipf/ipf.conf fi diff -cr ip_fil3.2.7/buildsunos ip_fil3.2.8/buildsunos *** ip_fil3.2.7/buildsunos Fri May 22 00:46:04 1998 --- ip_fil3.2.8/buildsunos Sun Jun 7 01:34:06 1998 *************** *** 1,16 **** #! /bin/sh ! # $Id: buildsunos,v 2.0.2.4.2.1 1998/05/21 14:46:04 darrenr Exp $ : rev=`uname -r | sed -e 's/^\([^\.]*\)\..*/\1/'` cpu=`uname -m` cpudir=${cpu}-`uname -r` if [ $rev = 5 ] ; then solrev=`uname -r | sh -c 'IFS=. read j n x; echo $n'` ! mkdir -p SunOS5/${cpudir} /bin/rm -f SunOS5/${cpudir}/Makefile /bin/rm -f SunOS5/${cpudir}/Makefile.ipsend ! ln -s ../Makefile SunOS5/${cpudir}/Makefile ! ln -s ../Makefile.ipsend SunOS5/${cpudir}/Makefile.ipsend fi if [ $cpu = i86pc ] ; then make ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU=${cpu} CPUDIR=${cpudir} --- 1,18 ---- #! /bin/sh ! # $Id: buildsunos,v 2.0.2.4.2.2 1998/06/06 15:34:06 darrenr Exp $ : rev=`uname -r | sed -e 's/^\([^\.]*\)\..*/\1/'` cpu=`uname -m` cpudir=${cpu}-`uname -r` if [ $rev = 5 ] ; then solrev=`uname -r | sh -c 'IFS=. read j n x; echo $n'` ! if [ ! -d SunOS5/${cpudir} -a ! -h SunOS5/${cpudir} ] ; then ! mkdir -p SunOS5/${cpudir} ! fi /bin/rm -f SunOS5/${cpudir}/Makefile /bin/rm -f SunOS5/${cpudir}/Makefile.ipsend ! ln -s `pwd`/SunOS5/Makefile SunOS5/${cpudir}/Makefile ! ln -s `pwd`/SunOS5/Makefile.ipsend SunOS5/${cpudir}/Makefile.ipsend fi if [ $cpu = i86pc ] ; then make ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU=${cpu} CPUDIR=${cpudir} diff -cr ip_fil3.2.7/fil.c ip_fil3.2.8/fil.c *** ip_fil3.2.7/fil.c Sun May 24 05:20:30 1998 --- ip_fil3.2.8/fil.c Mon Jun 8 02:27:07 1998 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.14 1998/05/23 19:20:30 darrenr Exp $"; #endif #include --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 darrenr Exp $"; #endif #include *************** *** 76,82 **** # define FR_DEBUG(verb_pr) debug verb_pr # define SEND_RESET(ip, qif, if, m) send_reset(ip, if) # define IPLLOG(a, c, d, e) ipllog() ! # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) # if SOLARIS # define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip) # else --- 76,82 ---- # define FR_DEBUG(verb_pr) debug verb_pr # define SEND_RESET(ip, qif, if, m) send_reset(ip, if) # define IPLLOG(a, c, d, e) ipllog() ! # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) # if SOLARIS # define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip) # else *************** *** 88,96 **** # define FR_VERBOSE(verb_pr) # define FR_DEBUG(verb_pr) # define IPLLOG(a, c, d, e) ipflog(a, c, d, e) ! # if SOLARIS || defined(__sgi) extern kmutex_t ipf_mutex, ipf_auth; # endif # if SOLARIS # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \ ip, qif) --- 88,102 ---- # define FR_VERBOSE(verb_pr) # define FR_DEBUG(verb_pr) # define IPLLOG(a, c, d, e) ipflog(a, c, d, e) ! # if SOLARIS ! extern krwlock_t ipf_mutex, ipf_auth; ! # endif ! # if defined(__sgi) extern kmutex_t ipf_mutex, ipf_auth; # endif + # if SOLARIS || defined(__sgi) + extern kmutex_t ipf_rw; + # endif # if SOLARIS # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \ ip, qif) *************** *** 513,525 **** pass = (*fr->fr_func)(pass, ip, fin); #ifdef IPFILTER_LOG if ((pass & FR_LOGMASK) == FR_LOG) { ! if (!IPLLOG(fr->fr_flags, ip, fin, m)) ! frstats[fin->fin_out].fr_skip++; ! frstats[fin->fin_out].fr_pkl++; } #endif /* IPFILTER_LOG */ FR_DEBUG(("pass %#x\n", pass)); ! fr->fr_hits++; if (pass & FR_ACCOUNT) fr->fr_bytes += (U_QUAD_T)ip->ip_len; else --- 519,532 ---- pass = (*fr->fr_func)(pass, ip, fin); #ifdef IPFILTER_LOG if ((pass & FR_LOGMASK) == FR_LOG) { ! if (!IPLLOG(fr->fr_flags, ip, fin, m)) { ! ATOMIC_INC(frstats[fin->fin_out].fr_skip); ! } ! ATOMIC_INC(frstats[fin->fin_out].fr_pkl); } #endif /* IPFILTER_LOG */ FR_DEBUG(("pass %#x\n", pass)); ! ATOMIC_INC(fr->fr_hits); if (pass & FR_ACCOUNT) fr->fr_bytes += (U_QUAD_T)ip->ip_len; else *************** *** 580,593 **** # endif int up; ! #ifdef M_CANFASTFWD /* * XXX For now, IP Filter and fast-forwarding of cached flows * XXX are mutually exclusive. Eventually, IP Filter should * XXX get a "can-fast-forward" filter rule. */ m->m_flags &= ~M_CANFASTFWD; ! #endif /* M_CANFASTFWD */ if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_ICMP)) { --- 587,600 ---- # endif int up; ! # ifdef M_CANFASTFWD /* * XXX For now, IP Filter and fast-forwarding of cached flows * XXX are mutually exclusive. Eventually, IP Filter should * XXX get a "can-fast-forward" filter rule. */ m->m_flags &= ~M_CANFASTFWD; ! # endif /* M_CANFASTFWD */ if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_ICMP)) { *************** *** 609,649 **** up = MIN(hlen + plen, ip->ip_len); if (up > m->m_len) { ! #ifdef __sgi /* Under IRIX, avoid m_pullup as it makes ping panic */ if ((up > sizeof(hbuf)) || (m_length(m) < up)) { ! frstats[out].fr_pull[1]++; return -1; } m_copydata(m, 0, up, hbuf); ! frstats[out].fr_pull[0]++; ip = (ip_t *)hbuf; ! #else ! # ifndef linux if ((*mp = m_pullup(m, up)) == 0) { ! frstats[out].fr_pull[1]++; return -1; } else { ! frstats[out].fr_pull[0]++; m = *mp; ip = mtod(m, ip_t *); } ! # endif ! #endif } else up = 0; } else up = 0; ! # endif # if SOLARIS mb_t *m = qif->qf_m; # endif ! #endif fr_makefrip(hlen, ip, fin); fin->fin_ifp = ifp; fin->fin_out = out; fin->fin_mp = mp; ! MUTEX_ENTER(&ipf_mutex); /* * Check auth now. This, combined with the check below to see if apass --- 616,659 ---- up = MIN(hlen + plen, ip->ip_len); if (up > m->m_len) { ! # ifdef __sgi ! /* Under IRIX, avoid m_pullup as it makes ping panic */ if ((up > sizeof(hbuf)) || (m_length(m) < up)) { ! ATOMIC_INC(frstats[out].fr_pull[1]); return -1; } m_copydata(m, 0, up, hbuf); ! ATOMIC_INC(frstats[out].fr_pull[0]); ip = (ip_t *)hbuf; ! # else /* __ sgi */ ! # ifndef linux if ((*mp = m_pullup(m, up)) == 0) { ! ATOMIC_INC(frstats[out].fr_pull[1]); return -1; } else { ! ATOMIC_INC(frstats[out].fr_pull[0]); m = *mp; ip = mtod(m, ip_t *); } ! # endif /* !linux */ ! # endif /* __sgi */ } else up = 0; } else up = 0; ! # endif /* !defined(__SVR4) && !defined(__svr4__) */ # if SOLARIS mb_t *m = qif->qf_m; + + fin->fin_qfm = m; # endif ! #endif /* _KERNEL */ fr_makefrip(hlen, ip, fin); fin->fin_ifp = ifp; fin->fin_out = out; fin->fin_mp = mp; ! READ_ENTER(&ipf_mutex); /* * Check auth now. This, combined with the check below to see if apass *************** *** 657,664 **** if (!out) { changed = ip_natin(ip, hlen, fin); if (!apass && (fin->fin_fr = ipacct[0][fr_active]) && ! (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) ! frstats[0].fr_acct++; } if (apass || (!(pass = ipfr_knownfrag(ip, fin)) && --- 667,675 ---- if (!out) { changed = ip_natin(ip, hlen, fin); if (!apass && (fin->fin_fr = ipacct[0][fr_active]) && ! (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) { ! ATOMIC_INC(frstats[0].fr_acct); ! } } if (apass || (!(pass = ipfr_knownfrag(ip, fin)) && *************** *** 676,684 **** * earlier. */ bcopy((char *)fc, (char *)fin, FI_COPYSIZE); ! frstats[out].fr_chit++; if ((fr = fin->fin_fr)) { ! fr->fr_hits++; pass = fr->fr_flags; } else pass = fr_pass; --- 687,695 ---- * earlier. */ bcopy((char *)fc, (char *)fin, FI_COPYSIZE); ! ATOMIC_INC(frstats[out].fr_chit); if ((fr = fin->fin_fr)) { ! ATOMIC_INC(fr->fr_hits); pass = fr->fr_flags; } else pass = fr_pass; *************** *** 687,694 **** if ((fin->fin_fr = ipfilter[out][fr_active])) pass = FR_SCANLIST(fr_pass, ip, fin, m); bcopy((char *)fin, (char *)fc, FI_COPYSIZE); ! if (pass & FR_NOMATCH) ! frstats[out].fr_nom++; } fr = fin->fin_fr; } else --- 698,706 ---- if ((fin->fin_fr = ipfilter[out][fr_active])) pass = FR_SCANLIST(fr_pass, ip, fin, m); bcopy((char *)fin, (char *)fc, FI_COPYSIZE); ! if (pass & FR_NOMATCH) { ! ATOMIC_INC(frstats[out].fr_nom); ! } } fr = fin->fin_fr; } else *************** *** 708,736 **** #endif if (pass & FR_PREAUTH) { ! MUTEX_ENTER(&ipf_auth); if ((fin->fin_fr = ipauth) && ! (pass = FR_SCANLIST(0, ip, fin, m))) ! fr_authstats.fas_hits++; ! else ! fr_authstats.fas_miss++; ! MUTEX_EXIT(&ipf_auth); } if (pass & FR_KEEPFRAG) { if (fin->fin_fi.fi_fl & FI_FRAG) { ! if (ipfr_newfrag(ip, fin, pass) == -1) ! frstats[out].fr_bnfr++; ! else ! frstats[out].fr_nfr++; ! } else ! frstats[out].fr_cfr++; } if (pass & FR_KEEPSTATE) { ! if (fr_addstate(ip, fin, pass) == -1) ! frstats[out].fr_bads++; ! else ! frstats[out].fr_ads++; } } --- 720,752 ---- #endif if (pass & FR_PREAUTH) { ! READ_ENTER(&ipf_auth); if ((fin->fin_fr = ipauth) && ! (pass = FR_SCANLIST(0, ip, fin, m))) { ! ATOMIC_INC(fr_authstats.fas_hits); ! } else { ! ATOMIC_INC(fr_authstats.fas_miss); ! } ! RWLOCK_EXIT(&ipf_auth); } if (pass & FR_KEEPFRAG) { if (fin->fin_fi.fi_fl & FI_FRAG) { ! if (ipfr_newfrag(ip, fin, pass) == -1) { ! ATOMIC_INC(frstats[out].fr_bnfr); ! } else { ! ATOMIC_INC(frstats[out].fr_nfr); ! } ! } else { ! ATOMIC_INC(frstats[out].fr_cfr); ! } } if (pass & FR_KEEPSTATE) { ! if (fr_addstate(ip, fin, pass) == -1) { ! ATOMIC_INC(frstats[out].fr_bads); ! } else { ! ATOMIC_INC(frstats[out].fr_ads); ! } } } *************** *** 743,776 **** */ if (out && (pass & FR_PASS)) { if ((fin->fin_fr = ipacct[1][fr_active]) && ! (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) ! frstats[1].fr_acct++; fin->fin_fr = NULL; changed = ip_natout(ip, hlen, fin); } fin->fin_fr = fr; ! MUTEX_EXIT(&ipf_mutex); #ifdef IPFILTER_LOG if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) { if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) { pass |= FF_LOGNOMATCH; ! frstats[out].fr_npkl++; goto logit; } else if (((pass & FR_LOGMASK) == FR_LOGP) || ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) { if ((pass & FR_LOGMASK) != FR_LOGP) pass |= FF_LOGPASS; ! frstats[out].fr_ppkl++; goto logit; } else if (((pass & FR_LOGMASK) == FR_LOGB) || ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) { if ((pass & FR_LOGMASK) != FR_LOGB) pass |= FF_LOGBLOCK; ! frstats[out].fr_bpkl++; logit: if (!IPLLOG(pass, ip, fin, m)) { ! frstats[out].fr_skip++; if ((pass & (FR_PASS|FR_LOGORBLOCK)) == (FR_PASS|FR_LOGORBLOCK)) pass ^= FR_PASS|FR_BLOCK; --- 759,793 ---- */ if (out && (pass & FR_PASS)) { if ((fin->fin_fr = ipacct[1][fr_active]) && ! (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) { ! ATOMIC_INC(frstats[1].fr_acct); ! } fin->fin_fr = NULL; changed = ip_natout(ip, hlen, fin); } fin->fin_fr = fr; ! RWLOCK_EXIT(&ipf_mutex); #ifdef IPFILTER_LOG if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) { if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) { pass |= FF_LOGNOMATCH; ! ATOMIC_INC(frstats[out].fr_npkl); goto logit; } else if (((pass & FR_LOGMASK) == FR_LOGP) || ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) { if ((pass & FR_LOGMASK) != FR_LOGP) pass |= FF_LOGPASS; ! ATOMIC_INC(frstats[out].fr_ppkl); goto logit; } else if (((pass & FR_LOGMASK) == FR_LOGB) || ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) { if ((pass & FR_LOGMASK) != FR_LOGB) pass |= FF_LOGBLOCK; ! ATOMIC_INC(frstats[out].fr_bpkl); logit: if (!IPLLOG(pass, ip, fin, m)) { ! ATOMIC_INC(frstats[out].fr_skip); if ((pass & (FR_PASS|FR_LOGORBLOCK)) == (FR_PASS|FR_LOGORBLOCK)) pass ^= FR_PASS|FR_BLOCK; *************** *** 795,804 **** # endif # endif #endif ! if (pass & FR_PASS) ! frstats[out].fr_pass++; ! else if (pass & FR_BLOCK) { ! frstats[out].fr_block++; /* * Should we return an ICMP packet to indicate error * status passing through the packet filter ? --- 812,821 ---- # endif # endif #endif ! if (pass & FR_PASS) { ! ATOMIC_INC(frstats[out].fr_pass); ! } else if (pass & FR_BLOCK) { ! ATOMIC_INC(frstats[out].fr_block); /* * Should we return an ICMP packet to indicate error * status passing through the packet filter ? *************** *** 819,838 **** m = *mp = NULL; /* freed by icmp_error() */ # endif ! frstats[0].fr_ret++; } else if ((pass & FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { ! if (SEND_RESET(ip, qif, ifp) == 0) ! frstats[1].fr_ret++; } #else if (pass & FR_RETICMP) { verbose("- ICMP unreachable sent\n"); ! frstats[0].fr_ret++; } else if ((pass & FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { verbose("- TCP RST sent\n"); ! frstats[1].fr_ret++; } #endif } else { --- 836,856 ---- m = *mp = NULL; /* freed by icmp_error() */ # endif ! ATOMIC_INC(frstats[0].fr_ret); } else if ((pass & FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { ! if (SEND_RESET(ip, qif, ifp) == 0) { ! ATOMIC_INC(frstats[1].fr_ret); ! } } #else if (pass & FR_RETICMP) { verbose("- ICMP unreachable sent\n"); ! ATOMIC_INC(frstats[0].fr_ret); } else if ((pass & FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { verbose("- TCP RST sent\n"); ! ATOMIC_INC(frstats[1].fr_ret); } #endif } else { *************** *** 944,956 **** int add, hlen; # endif - # if SOLARIS - /* skip any leading M_PROTOs */ - while(m && (MTYPE(m) != M_DATA)) - m = m->b_cont; - PANIC((!m),("fr_tcpsum: no M_DATA")); - # endif - /* * Add up IP Header portion */ --- 962,967 ---- *************** *** 1037,1043 **** #endif /* SOLARIS */ if (len < 2) break; ! if((u_32_t)sp & 1) { bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); sum += bytes.s; } else --- 1048,1054 ---- #endif /* SOLARIS */ if (len < 2) break; ! if((u_long)sp & 1) { bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); sum += bytes.s; } else *************** *** 1091,1097 **** * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.0.2.41.2.14 1998/05/23 19:20:30 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, --- 1102,1108 ---- * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, *************** *** 1296,1301 **** --- 1307,1313 ---- { int flags = *result, flushed = 0, set = fr_active; + WRITE_ENTER(&ipf_mutex); bzero((char *)frcache, sizeof(frcache[0]) * 2); if (flags & FR_INACTIVE) *************** *** 1317,1322 **** ipacct[0][set], &ipacct[0][set]); } } ! *result = flushed; } --- 1329,1334 ---- ipacct[0][set], &ipacct[0][set]); } } ! RWLOCK_EXIT(&ipf_mutex); *result = flushed; } diff -cr ip_fil3.2.7/fils.c ip_fil3.2.8/fils.c *** ip_fil3.2.7/fils.c Thu Nov 20 23:41:04 1997 --- ip_fil3.2.8/fils.c Mon Jun 8 16:58:12 1998 *************** *** 46,52 **** #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fils.c,v 2.0.2.25.2.2 1997/11/20 12:41:04 darrenr Exp $"; #endif #ifdef _PATH_UNIX #define VMUNIX _PATH_UNIX --- 46,52 ---- #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fils.c,v 2.0.2.25.2.4 1998/06/08 06:58:12 darrenr Exp $"; #endif #ifdef _PATH_UNIX #define VMUNIX _PATH_UNIX *************** *** 446,451 **** --- 446,458 ---- PRINTF("\n"); /* ... phil@ultimate.com */ + PRINTF("\tpkt_flags & %x = %x,\t", ips.is_flags & 0xf, + ips.is_flags >> 4); + PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk, + ips.is_opt); + PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", + ips.is_secmsk, ips.is_sec, ips.is_authmsk, + ips.is_auth); istab[i] = ips.is_next; } } diff -cr ip_fil3.2.7/ip_auth.c ip_fil3.2.8/ip_auth.c *** ip_fil3.2.7/ip_auth.c Wed Apr 8 23:43:29 1998 --- ip_fil3.2.8/ip_auth.c Sun Jun 7 00:36:16 1998 *************** *** 6,12 **** * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:29 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) --- 6,12 ---- * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.4 1998/06/06 14:36:16 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) *************** *** 93,99 **** #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern kmutex_t ipf_auth; # if SOLARIS extern kcondvar_t ipfauthwait; # endif --- 93,100 ---- #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern krwlock_t ipf_auth; ! extern kmutex_t ipf_authmx; # if SOLARIS extern kcondvar_t ipfauthwait; # endif *************** *** 126,132 **** u_32_t pass; int i; ! MUTEX_ENTER(&ipf_auth); for (i = fr_authstart; i != fr_authend; ) { /* * index becomes -2 only after an SIOCAUTHW. Check this in --- 127,133 ---- u_32_t pass; int i; ! READ_ENTER(&ipf_auth); for (i = fr_authstart; i != fr_authend; ) { /* * index becomes -2 only after an SIOCAUTHW. Check this in *************** *** 141,146 **** --- 142,149 ---- */ if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH)) pass = FR_BLOCK; + RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&ipf_auth); fr_authstats.fas_hits++; fr_auth[i].fra_index = -1; fr_authused--; *************** *** 158,164 **** fr_authstart = fr_authend = 0; } } ! MUTEX_EXIT(&ipf_auth); return pass; } i++; --- 161,167 ---- fr_authstart = fr_authend = 0; } } ! RWLOCK_EXIT(&ipf_auth); return pass; } i++; *************** *** 166,172 **** i = 0; } fr_authstats.fas_miss++; ! MUTEX_EXIT(&ipf_auth); return 0; } --- 169,175 ---- i = 0; } fr_authstats.fas_miss++; ! RWLOCK_EXIT(&ipf_auth); return 0; } *************** *** 189,203 **** { int i; ! MUTEX_ENTER(&ipf_auth); if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) { fr_authstats.fas_nospace++; ! MUTEX_EXIT(&ipf_auth); return 0; } if (fr_authend - fr_authstart == FR_NUMAUTH - 1) { fr_authstats.fas_nospace++; ! MUTEX_EXIT(&ipf_auth); return 0; } --- 192,206 ---- { int i; ! WRITE_ENTER(&ipf_auth); if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) { fr_authstats.fas_nospace++; ! RWLOCK_EXIT(&ipf_auth); return 0; } if (fr_authend - fr_authstart == FR_NUMAUTH - 1) { fr_authstats.fas_nospace++; ! RWLOCK_EXIT(&ipf_auth); return 0; } *************** *** 206,212 **** i = fr_authend++; if (fr_authend == FR_NUMAUTH) fr_authend = 0; ! MUTEX_EXIT(&ipf_auth); fr_auth[i].fra_index = i; fr_auth[i].fra_pass = 0; fr_auth[i].fra_age = fr_defaultauthage; --- 209,215 ---- i = fr_authend++; if (fr_authend == FR_NUMAUTH) fr_authend = 0; ! RWLOCK_EXIT(&ipf_auth); fr_auth[i].fra_index = i; fr_auth[i].fra_pass = 0; fr_auth[i].fra_age = fr_defaultauthage; *************** *** 313,333 **** break; case SIOCAUTHW: fr_authioctlloop: ! MUTEX_ENTER(&ipf_auth); if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { ! IWCOPY((char *)&fr_auth[fr_authnext++], data, sizeof(fr_info_t)); if (fr_authnext == FR_NUMAUTH) fr_authnext = 0; ! MUTEX_EXIT(&ipf_auth); return 0; } #ifdef _KERNEL # if SOLARIS ! if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) { ! mutex_exit(&ipf_auth); return EINTR; } # else # ifdef linux interruptible_sleep_on(&ipfauthwait); --- 316,341 ---- 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)); + RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&ipf_auth); + fr_authnext++; if (fr_authnext == FR_NUMAUTH) fr_authnext = 0; ! RWLOCK_EXIT(&ipf_auth); return 0; } #ifdef _KERNEL # if SOLARIS ! mutex_enter(&ipf_authmx); ! if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) { ! mutex_exit(&ipf_authmx); return EINTR; } + mutex_exit(&ipf_authmx); # else # ifdef linux interruptible_sleep_on(&ipfauthwait); *************** *** 338,354 **** # endif # endif #endif ! MUTEX_EXIT(&ipf_auth); if (!error) goto fr_authioctlloop; break; case SIOCAUTHR: IRCOPY(data, (caddr_t)&auth, sizeof(auth)); ! MUTEX_ENTER(&ipf_auth); i = au->fra_index; if ((i < 0) || (i > FR_NUMAUTH) || (fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) { ! MUTEX_EXIT(&ipf_auth); return EINVAL; } m = fr_authpkts[i]; --- 346,362 ---- # endif # endif #endif ! RWLOCK_EXIT(&ipf_auth); if (!error) goto fr_authioctlloop; break; case SIOCAUTHR: IRCOPY(data, (caddr_t)&auth, sizeof(auth)); ! WRITE_ENTER(&ipf_auth); i = au->fra_index; if ((i < 0) || (i > FR_NUMAUTH) || (fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) { ! RWLOCK_EXIT(&ipf_auth); return EINVAL; } m = fr_authpkts[i]; *************** *** 356,362 **** fr_auth[i].fra_pass = au->fra_pass; fr_authpkts[i] = NULL; #ifdef _KERNEL ! MUTEX_EXIT(&ipf_auth); SPL_NET(s); # ifndef linux if (m && au->fra_info.fin_out) { --- 364,370 ---- fr_auth[i].fra_pass = au->fra_pass; fr_authpkts[i] = NULL; #ifdef _KERNEL ! RWLOCK_EXIT(&ipf_auth); SPL_NET(s); # ifndef linux if (m && au->fra_info.fin_out) { *************** *** 439,445 **** register frauthent_t *fae, **faep; mb_t *m; ! MUTEX_ENTER(&ipf_auth); for (i = 0; i < FR_NUMAUTH; i++) { if ((m = fr_authpkts[i])) { FREE_MB_T(m); --- 447,453 ---- register frauthent_t *fae, **faep; mb_t *m; ! WRITE_ENTER(&ipf_auth); for (i = 0; i < FR_NUMAUTH; i++) { if ((m = fr_authpkts[i])) { FREE_MB_T(m); *************** *** 453,459 **** *faep = fae->fae_next; KFREE(fae); } ! MUTEX_EXIT(&ipf_auth); } --- 461,467 ---- *faep = fae->fae_next; KFREE(fae); } ! RWLOCK_EXIT(&ipf_auth); } *************** *** 472,478 **** #endif SPL_NET(s); ! MUTEX_ENTER(&ipf_auth); for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) { if ((!--fra->fra_age) && (m = fr_authpkts[i])) { FREE_MB_T(m); --- 480,486 ---- #endif SPL_NET(s); ! WRITE_ENTER(&ipf_auth); for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) { if ((!--fra->fra_age) && (m = fr_authpkts[i])) { FREE_MB_T(m); *************** *** 491,497 **** } else faep = &fae->fae_next; } ! MUTEX_EXIT(&ipf_auth); SPL_X(s); } #endif --- 499,505 ---- } else faep = &fae->fae_next; } ! RWLOCK_EXIT(&ipf_auth); SPL_X(s); } #endif diff -cr ip_fil3.2.7/ip_compat.h ip_fil3.2.8/ip_compat.h *** ip_fil3.2.7/ip_compat.h Sun May 24 00:29:36 1998 --- ip_fil3.2.8/ip_compat.h Sun Jun 7 00:36:38 1998 *************** *** 6,12 **** * to the original author and the contributors. * * @(#)ip_compat.h 1.8 1/14/96 ! * $Id: ip_compat.h,v 2.0.2.31.2.11 1998/05/23 14:29:36 darrenr Exp $ */ #ifndef __IP_COMPAT_H__ --- 6,12 ---- * to the original author and the contributors. * * @(#)ip_compat.h 1.8 1/14/96 ! * $Id: ip_compat.h,v 2.0.2.31.2.12 1998/06/06 14:36:38 darrenr Exp $ */ #ifndef __IP_COMPAT_H__ *************** *** 201,207 **** */ #ifdef KERNEL # if SOLARIS ! # define MUTEX_ENTER(x) mutex_enter(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)) --- 201,215 ---- */ #ifdef KERNEL # if SOLARIS ! # define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \ ! mutex_exit(&ipf_rw); } ! # define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \ ! mutex_exit(&ipf_rw); } ! # define MUTEX_ENTER(x) mutex_enter(x) ! # define READ_ENTER(x) rw_enter(x, RW_READER) ! # define WRITE_ENTER(x) rw_enter(x, RW_WRITER) ! # define MUTEX_DOWNGRADE(x) rw_downgrade(x) ! # define RWLOCK_EXIT(x) rw_exit(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)) *************** *** 253,262 **** lock_t *l; int pl; } kmutex_t; ! # define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL); # define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl); # else /* __sgi */ ! # define MUTEX_ENTER(x) ; # define MUTEX_EXIT(x) ; # endif /* __sgi */ # ifndef linux --- 261,284 ---- lock_t *l; int pl; } kmutex_t; ! # define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ ! (x)++; MUTEX_EXIT(&ipf_rw); } ! # define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ ! (x)--; MUTEX_EXIT(&ipf_rw); } ! # define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL); ! # define READ_ENTER(x) MUTEX_ENTER(x) ! # define WRITE_ENTER(x) MUTEX_ENTER(x) ! # define MUTEX_DOWNGRADE(x) ; ! # define RWLOCK_EXIT(x) MUTEX_EXIT(x) # define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl); # 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 MUTEX_DOWNGRADE(x) ; ! # define RWLOCK_EXIT(x) ; # define MUTEX_EXIT(x) ; # endif /* __sgi */ # ifndef linux *************** *** 339,345 **** --- 361,373 ---- # define SLEEP(x,y) ; # define WAKEUP(x) ; # define PANIC(x,y) ; + # define ATOMIC_INC(x) (x)++ + # define ATOMIC_DEC(x) (x)-- # define MUTEX_ENTER(x) ; + # define READ_ENTER(x) ; + # define WRITE_ENTER(x) ; + # define MUTEX_DOWNGRADE(x) ; + # define RWLOCK_EXIT(x) ; # define MUTEX_EXIT(x) ; # define SPL_NET(x) ; # define SPL_IMP(x) ; diff -cr ip_fil3.2.7/ip_fil.h ip_fil3.2.8/ip_fil.h *** ip_fil3.2.7/ip_fil.h Sun May 24 00:29:37 1998 --- ip_fil3.2.8/ip_fil.h Sun Jun 7 00:36:49 1998 *************** *** 6,12 **** * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 ! * $Id: ip_fil.h,v 2.0.2.39.2.11 1998/05/23 14:29:37 darrenr Exp $ */ #ifndef __IP_FIL_H__ --- 6,12 ---- * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 ! * $Id: ip_fil.h,v 2.0.2.39.2.12 1998/06/06 14:36:49 darrenr Exp $ */ #ifndef __IP_FIL_H__ *************** *** 114,119 **** --- 114,122 ---- struct frentry *fin_fr; char *fin_dp; /* start of data past IP header */ void *fin_mp; + #if SOLARIS && defined(_KERNEL) + void *fin_qfm; + #endif } fr_info_t; /* diff -cr ip_fil3.2.7/ip_frag.c ip_fil3.2.8/ip_frag.c *** ip_fil3.2.7/ip_frag.c Wed Nov 12 21:50:21 1997 --- ip_fil3.2.8/ip_frag.c Sun Jun 7 00:37:02 1998 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:21 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.2 1998/06/06 14:37:02 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) *************** *** 76,84 **** extern int ipfr_timer_id; #endif #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern kmutex_t ipf_frag; ! extern kmutex_t ipf_natfrag; ! extern kmutex_t ipf_nat; #endif --- 76,83 ---- extern int ipfr_timer_id; #endif #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern krwlock_t ipf_frag, ipf_natfrag, ipf_nat; ! extern kmutex_t ipf_rw; #endif *************** *** 126,132 **** for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next) if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ)) { ! ipfr_stats.ifs_exists++; return NULL; } --- 125,131 ---- for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next) if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ)) { ! ATOMIC_INC(ipfr_stats.ifs_exists); return NULL; } *************** *** 136,142 **** */ KMALLOC(fr, ipfr_t *, sizeof(*fr)); if (fr == NULL) { ! ipfr_stats.ifs_nomem++; return NULL; } --- 135,141 ---- */ KMALLOC(fr, ipfr_t *, sizeof(*fr)); if (fr == NULL) { ! ATOMIC_INC(ipfr_stats.ifs_nomem); return NULL; } *************** *** 157,164 **** * Compute the offset of the expected start of the next packet. */ fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3); ! ipfr_stats.ifs_new++; ! ipfr_inuse++; return fr; } --- 156,163 ---- * Compute the offset of the expected start of the next packet. */ fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3); ! ATOMIC_INC(ipfr_stats.ifs_new); ! ATOMIC_INC(ipfr_inuse); return fr; } *************** *** 170,178 **** { ipfr_t *ipf; ! MUTEX_ENTER(&ipf_frag); ipf = ipfr_new(ip, fin, pass, ipfr_heads); ! MUTEX_EXIT(&ipf_frag); return ipf ? 0 : -1; } --- 169,177 ---- { ipfr_t *ipf; ! WRITE_ENTER(&ipf_frag); ipf = ipfr_new(ip, fin, pass, ipfr_heads); ! RWLOCK_EXIT(&ipf_frag); return ipf ? 0 : -1; } *************** *** 185,196 **** { ipfr_t *ipf; ! MUTEX_ENTER(&ipf_natfrag); if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) { ipf->ipfr_data = nat; nat->nat_data = ipf; } ! MUTEX_EXIT(&ipf_natfrag); return ipf ? 0 : -1; } --- 184,195 ---- { ipfr_t *ipf; ! WRITE_ENTER(&ipf_natfrag); if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) { ipf->ipfr_data = nat; nat->nat_data = ipf; } ! RWLOCK_EXIT(&ipf_natfrag); return ipf ? 0 : -1; } *************** *** 257,263 **** else f->ipfr_off = atoff; } ! ipfr_stats.ifs_hits++; return f; } return NULL; --- 256,262 ---- else f->ipfr_off = atoff; } ! ATOMIC_INC(ipfr_stats.ifs_hits); return f; } return NULL; *************** *** 274,280 **** nat_t *nat; ipfr_t *ipf; ! MUTEX_ENTER(&ipf_natfrag); ipf = ipfr_lookup(ip, fin, ipfr_nattab); if (ipf) { nat = ipf->ipfr_data; --- 273,279 ---- nat_t *nat; ipfr_t *ipf; ! READ_ENTER(&ipf_natfrag); ipf = ipfr_lookup(ip, fin, ipfr_nattab); if (ipf) { nat = ipf->ipfr_data; *************** *** 287,293 **** } } else nat = NULL; ! MUTEX_EXIT(&ipf_natfrag); return nat; } --- 286,292 ---- } } else nat = NULL; ! RWLOCK_EXIT(&ipf_natfrag); return nat; } *************** *** 302,311 **** int ret; ipfr_t *ipf; ! MUTEX_ENTER(&ipf_frag); ipf = ipfr_lookup(ip, fin, ipfr_heads); ret = ipf ? ipf->ipfr_pass : 0; ! MUTEX_EXIT(&ipf_frag); return ret; } --- 301,310 ---- int ret; ipfr_t *ipf; ! READ_ENTER(&ipf_frag); ipf = ipfr_lookup(ip, fin, ipfr_heads); ret = ipf ? ipf->ipfr_pass : 0; ! RWLOCK_EXIT(&ipf_frag); return ret; } *************** *** 319,331 **** ipfr_t *fr; int idx; ! MUTEX_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next) if (fr->ipfr_data == nat) fr->ipfr_data = NULL; ! MUTEX_EXIT(&ipf_natfrag); } --- 318,330 ---- ipfr_t *fr; int idx; ! WRITE_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next) if (fr->ipfr_data == nat) fr->ipfr_data = NULL; ! RWLOCK_EXIT(&ipf_natfrag); } *************** *** 338,353 **** nat_t *nat; int idx; ! MUTEX_ENTER(&ipf_frag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_heads[idx]; (fr = *fp); ) { *fp = fr->ipfr_next; KFREE(fr); } ! MUTEX_EXIT(&ipf_frag); ! MUTEX_ENTER(&ipf_nat); ! MUTEX_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { *fp = fr->ipfr_next; --- 337,352 ---- nat_t *nat; int idx; ! WRITE_ENTER(&ipf_frag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_heads[idx]; (fr = *fp); ) { *fp = fr->ipfr_next; KFREE(fr); } ! RWLOCK_EXIT(&ipf_frag); ! WRITE_ENTER(&ipf_nat); ! WRITE_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { *fp = fr->ipfr_next; *************** *** 357,364 **** } KFREE(fr); } ! MUTEX_EXIT(&ipf_natfrag); ! MUTEX_EXIT(&ipf_nat); } --- 356,363 ---- } KFREE(fr); } ! RWLOCK_EXIT(&ipf_natfrag); ! RWLOCK_EXIT(&ipf_nat); } *************** *** 382,388 **** #endif SPL_NET(s); ! MUTEX_ENTER(&ipf_frag); /* * Go through the entire table, looking for entries to expire, --- 381,387 ---- #endif SPL_NET(s); ! WRITE_ENTER(&ipf_frag); /* * Go through the entire table, looking for entries to expire, *************** *** 400,412 **** fr->ipfr_next->ipfr_prev = fr->ipfr_prev; *fp = fr->ipfr_next; ! ipfr_stats.ifs_expire++; ! ipfr_inuse--; KFREE(fr); } else fp = &fr->ipfr_next; } ! MUTEX_EXIT(&ipf_frag); /* * Same again for the NAT table, except that if the structure also --- 399,411 ---- fr->ipfr_next->ipfr_prev = fr->ipfr_prev; *fp = fr->ipfr_next; ! ATOMIC_INC(ipfr_stats.ifs_expire); ! ATOMIC_DEC(ipfr_inuse); KFREE(fr); } else fp = &fr->ipfr_next; } ! RWLOCK_EXIT(&ipf_frag); /* * Same again for the NAT table, except that if the structure also *************** *** 415,422 **** * NOTE: We need to grab both mutex's early, and in this order so as * to prevent a deadlock if both try to expire at the same time. */ ! MUTEX_ENTER(&ipf_nat); ! MUTEX_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { --fr->ipfr_ttl; --- 414,421 ---- * NOTE: We need to grab both mutex's early, and in this order so as * to prevent a deadlock if both try to expire at the same time. */ ! WRITE_ENTER(&ipf_nat); ! WRITE_ENTER(&ipf_natfrag); for (idx = IPFT_SIZE - 1; idx >= 0; idx--) for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { --fr->ipfr_ttl; *************** *** 428,435 **** fr->ipfr_next->ipfr_prev = fr->ipfr_prev; *fp = fr->ipfr_next; ! ipfr_stats.ifs_expire++; ! ipfr_inuse--; if ((nat = (nat_t *)fr->ipfr_data)) { if (nat->nat_data == fr) nat->nat_data = NULL; --- 427,434 ---- fr->ipfr_next->ipfr_prev = fr->ipfr_prev; *fp = fr->ipfr_next; ! ATOMIC_INC(ipfr_stats.ifs_expire); ! ATOMIC_DEC(ipfr_inuse); if ((nat = (nat_t *)fr->ipfr_data)) { if (nat->nat_data == fr) nat->nat_data = NULL; *************** *** 438,445 **** } else fp = &fr->ipfr_next; } ! MUTEX_EXIT(&ipf_natfrag); ! MUTEX_EXIT(&ipf_nat); SPL_X(s); fr_timeoutstate(); ip_natexpire(); --- 437,444 ---- } else fp = &fr->ipfr_next; } ! RWLOCK_EXIT(&ipf_natfrag); ! RWLOCK_EXIT(&ipf_nat); SPL_X(s); fr_timeoutstate(); ip_natexpire(); diff -cr ip_fil3.2.7/ip_ftp_pxy.c ip_fil3.2.8/ip_ftp_pxy.c *** ip_fil3.2.7/ip_ftp_pxy.c Sun May 24 05:20:31 1998 --- ip_fil3.2.8/ip_ftp_pxy.c Sun Jun 7 00:37:20 1998 *************** *** 126,135 **** #if SOLARIS mb_t *m1; ! /* skip any leading M_PROTOs */ ! while(m && (MTYPE(m) != M_DATA)) ! m = m->b_cont; ! PANIC((!m),("ippr_ftp_out: no M_DATA")); dlen = msgdsize(m) - off; bzero(portbuf, sizeof(portbuf)); --- 126,132 ---- #if SOLARIS mb_t *m1; ! m = fin->fin_qfm; dlen = msgdsize(m) - off; bzero(portbuf, sizeof(portbuf)); diff -cr ip_fil3.2.7/ip_log.c ip_fil3.2.8/ip_log.c *** ip_fil3.2.7/ip_log.c Thu Nov 20 23:41:40 1997 --- ip_fil3.2.8/ip_log.c Mon Jun 8 02:27:09 1998 *************** *** 5,11 **** * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_log.c,v 2.0.2.13.2.3 1997/11/20 12:41:40 darrenr Exp $ */ #ifdef IPFILTER_LOG # ifndef SOLARIS --- 5,11 ---- * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_log.c,v 2.0.2.13.2.4 1998/06/07 16:27:09 darrenr Exp $ */ #ifdef IPFILTER_LOG # ifndef SOLARIS *************** *** 460,465 **** --- 460,466 ---- iplog_t *ipl; int used; + MUTEX_ENTER(&ipl_mutex); while ((ipl = iplt[unit])) { iplt[unit] = ipl->ipl_next; KFREES((caddr_t)ipl, ipl->ipl_dsize); *************** *** 468,473 **** --- 469,475 ---- used = iplused[unit]; iplused[unit] = 0; iplcrc[unit] = 0; + MUTEX_EXIT(&ipl_mutex); return used; } #endif /* IPFILTER_LOG */ diff -cr ip_fil3.2.7/ip_nat.c ip_fil3.2.8/ip_nat.c *** ip_fil3.2.7/ip_nat.c Sun May 24 05:05:29 1998 --- ip_fil3.2.8/ip_nat.c Mon Jun 8 16:58:32 1998 *************** *** 9,15 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.10 1998/05/23 19:05:29 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) --- 9,15 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.12 1998/06/08 06:58:32 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) *************** *** 105,111 **** fr_defnaticmpage = 6; /* 3 seconds */ natstat_t nat_stats; #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern kmutex_t ipf_nat; #endif static int nat_flushtable __P((void)); --- 105,112 ---- fr_defnaticmpage = 6; /* 3 seconds */ natstat_t nat_stats; #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern kmutex_t ipf_rw; ! extern krwlock_t ipf_nat; #endif static int nat_flushtable __P((void)); *************** *** 211,224 **** #endif nat = NULL; /* XXX gcc -Wuninitialized */ /* * For add/delete, look to see if the NAT entry is already present */ SPL_NET(s); ! MUTEX_ENTER(&ipf_nat); if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) { - IRCOPY(data, (char *)&natd, sizeof(natd)); nat = &natd; nat->in_inip &= nat->in_inmsk; nat->in_outip &= nat->in_outmsk; --- 212,227 ---- #endif nat = NULL; /* XXX gcc -Wuninitialized */ + KMALLOC(n, ipnat_t *, sizeof(*n)); + if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) + IRCOPY(data, (char *)&natd, sizeof(natd)); /* * For add/delete, look to see if the NAT entry is already present */ SPL_NET(s); ! WRITE_ENTER(&ipf_nat); if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) { nat = &natd; nat->in_inip &= nat->in_inmsk; nat->in_outip &= nat->in_outmsk; *************** *** 239,245 **** error = EEXIST; break; } - KMALLOC(n, ipnat_t *, sizeof(*n)); if (n == NULL) { error = ENOMEM; break; --- 242,247 ---- *************** *** 271,281 **** } /* Otherwise, these fields are preset */ *np = n; ! nat_stats.ns_rules++; break; case SIOCRMNAT : if (!(mode & FWRITE)) { error = EPERM; break; } if (!n) { --- 273,285 ---- } /* Otherwise, these fields are preset */ *np = n; ! n = NULL; ! ATOMIC_INC(nat_stats.ns_rules); break; case SIOCRMNAT : if (!(mode & FWRITE)) { error = EPERM; + n = NULL; break; } if (!n) { *************** *** 287,299 **** if (n->in_apr) ap_free(n->in_apr); KFREE(n); ! nat_stats.ns_rules--; } else { n->in_flags |= IPN_DELETE; n->in_next = NULL; } break; case SIOCGNATS : nat_stats.ns_table[0] = nat_table[0]; nat_stats.ns_table[1] = nat_table[1]; nat_stats.ns_list = nat_list; --- 291,305 ---- if (n->in_apr) ap_free(n->in_apr); KFREE(n); ! ATOMIC_DEC(nat_stats.ns_rules); } else { n->in_flags |= IPN_DELETE; n->in_next = NULL; } + n = NULL; break; case SIOCGNATS : + MUTEX_DOWNGRADE(&ipf_nat); nat_stats.ns_table[0] = nat_table[0]; nat_stats.ns_table[1] = nat_table[1]; nat_stats.ns_list = nat_list; *************** *** 303,308 **** --- 309,315 ---- { natlookup_t nl; + MUTEX_DOWNGRADE(&ipf_nat); IRCOPY((char *)data, (char *)&nl, sizeof(nl)); if (nat_lookupredir(&nl)) { *************** *** 329,342 **** IWCOPY((caddr_t)&ret, data, sizeof(ret)); break; case FIONREAD : #ifdef IPFILTER_LOG IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data, sizeof(iplused[IPL_LOGNAT])); #endif break; } ! MUTEX_EXIT(&ipf_nat); SPL_X(s); return error; } --- 336,352 ---- IWCOPY((caddr_t)&ret, data, sizeof(ret)); break; case FIONREAD : + MUTEX_DOWNGRADE(&ipf_nat); #ifdef IPFILTER_LOG IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data, sizeof(iplused[IPL_LOGNAT])); #endif break; } ! RWLOCK_EXIT(&ipf_nat); SPL_X(s); + if (n) + KFREE(n); return error; } *************** *** 370,376 **** * longer being used. */ if ((ipn = natd->nat_ptr)) { ! ipn->in_space++; ipn->in_use--; if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) { if (ipn->in_apr) --- 380,386 ---- * longer being used. */ if ((ipn = natd->nat_ptr)) { ! ATOMIC_INC(ipn->in_space); ipn->in_use--; if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) { if (ipn->in_apr) *************** *** 428,434 **** if (n->in_apr) ap_free(n->in_apr); KFREE(n); ! nat_stats.ns_rules--; i++; } else { n->in_flags |= IPN_DELETE; --- 438,444 ---- if (n->in_apr) ap_free(n->in_apr); KFREE(n); ! ATOMIC_DEC(nat_stats.ns_rules); i++; } else { n->in_flags |= IPN_DELETE; *************** *** 697,705 **** if (flags & IPN_TCPUDP) tcp->th_dport = nport; } ! nat_stats.ns_added++; ! nat_stats.ns_inuse++; ! np->in_use++; return nat; } --- 707,715 ---- if (flags & IPN_TCPUDP) tcp->th_dport = nport; } ! ATOMIC_INC(nat_stats.ns_added); ! ATOMIC_INC(nat_stats.ns_inuse); ! ATOMIC_INC(np->in_use); return nat; } *************** *** 992,1005 **** ipa = ip->ip_src.s_addr; ! MUTEX_ENTER(&ipf_nat); if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && (nat = ipfr_nat_knownfrag(ip, fin))) natadd = 0; else if ((nat = nat_outlookup(ifp, nflags, ip->ip_src, sport, ip->ip_dst, dport))) ; ! else /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). --- 1002,1017 ---- ipa = ip->ip_src.s_addr; ! READ_ENTER(&ipf_nat); if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && (nat = ipfr_nat_knownfrag(ip, fin))) natadd = 0; else if ((nat = nat_outlookup(ifp, nflags, ip->ip_src, sport, ip->ip_dst, dport))) ; ! else { ! RWLOCK_EXIT(&ipf_nat); ! WRITE_ENTER(&ipf_nat); /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). *************** *** 1029,1042 **** #endif break; } if (nat) { if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); - nat->nat_age = fr_defnatage; ip->ip_src = nat->nat_outip; nat->nat_bytes += ip->ip_len; nat->nat_pkts++; /* * Fix up checksums, not by recalculating them, but --- 1041,1058 ---- #endif break; } + MUTEX_DOWNGRADE(&ipf_nat); + } if (nat) { if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); ip->ip_src = nat->nat_outip; + MUTEX_ENTER(&ipf_rw); + nat->nat_age = fr_defnatage; nat->nat_bytes += ip->ip_len; nat->nat_pkts++; + MUTEX_EXIT(&ipf_rw); /* * Fix up checksums, not by recalculating them, but *************** *** 1057,1062 **** --- 1073,1079 ---- if (ip->ip_p == IPPROTO_TCP) { csump = &tcp->th_sum; + MUTEX_ENTER(&ipf_rw); fr_tcp_age(&nat->nat_age, nat->nat_state, ip, fin,1); /* *************** *** 1067,1072 **** --- 1084,1090 ---- */ if (nat->nat_age == fr_tcpclosed) nat->nat_age = fr_tcplastack; + MUTEX_EXIT(&ipf_rw); } else if (ip->ip_p == IPPROTO_UDP) { udphdr_t *udp = (udphdr_t *)tcp; *************** *** 1087,1097 **** } } (void) ap_check(ip, tcp, fin, nat); ! nat_stats.ns_mapped[1]++; ! MUTEX_EXIT(&ipf_nat); return -2; } ! MUTEX_EXIT(&ipf_nat); return 0; } --- 1105,1115 ---- } } (void) ap_check(ip, tcp, fin, nat); ! ATOMIC_INC(nat_stats.ns_mapped[1]); ! RWLOCK_EXIT(&ipf_nat); return -2; } ! RWLOCK_EXIT(&ipf_nat); return 0; } *************** *** 1127,1133 **** in = ip->ip_dst; ! MUTEX_ENTER(&ipf_nat); if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags))) ; --- 1145,1151 ---- in = ip->ip_dst; ! READ_ENTER(&ipf_nat); if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags))) ; *************** *** 1137,1143 **** else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport, ip->ip_dst, dport))) ; ! else /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). --- 1155,1163 ---- else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport, ip->ip_dst, dport))) ; ! else { ! RWLOCK_EXIT(&ipf_nat); ! WRITE_ENTER(&ipf_nat); /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). *************** *** 1157,1173 **** #endif break; } if (nat) { if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); (void) ap_check(ip, tcp, fin, nat); if (nflags != IPN_ICMPERR) nat->nat_age = fr_defnatage; - ip->ip_dst = nat->nat_inip; nat->nat_bytes += ip->ip_len; nat->nat_pkts++; /* * Fix up checksums, not by recalculating them, but --- 1177,1197 ---- #endif break; } + MUTEX_DOWNGRADE(&ipf_nat); + } if (nat) { if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); + MUTEX_ENTER(&ipf_rw); (void) ap_check(ip, tcp, fin, nat); if (nflags != IPN_ICMPERR) nat->nat_age = fr_defnatage; nat->nat_bytes += ip->ip_len; nat->nat_pkts++; + MUTEX_EXIT(&ipf_rw); + ip->ip_dst = nat->nat_inip; /* * Fix up checksums, not by recalculating them, but *************** *** 1187,1192 **** --- 1211,1217 ---- if (ip->ip_p == IPPROTO_TCP) { csump = &tcp->th_sum; + MUTEX_ENTER(&ipf_rw); fr_tcp_age(&nat->nat_age, nat->nat_state, ip, fin,0); /* *************** *** 1197,1202 **** --- 1222,1228 ---- */ if (nat->nat_age == fr_tcpclosed) nat->nat_age = fr_tcplastack; + MUTEX_EXIT(&ipf_rw); } else if (ip->ip_p == IPPROTO_UDP) { udphdr_t *udp = (udphdr_t *)tcp; *************** *** 1216,1226 **** nat->nat_sumd); } } ! nat_stats.ns_mapped[0]++; ! MUTEX_EXIT(&ipf_nat); return -2; } ! MUTEX_EXIT(&ipf_nat); return 0; } --- 1242,1252 ---- nat->nat_sumd); } } ! ATOMIC_INC(nat_stats.ns_mapped[0]); ! RWLOCK_EXIT(&ipf_nat); return -2; } ! RWLOCK_EXIT(&ipf_nat); return 0; } *************** *** 1230,1240 **** */ void ip_natunload() { ! MUTEX_ENTER(&ipf_nat); (void) nat_clearlist(); (void) nat_flushtable(); (void) ap_unload(); ! MUTEX_EXIT(&ipf_nat); } --- 1256,1266 ---- */ void ip_natunload() { ! WRITE_ENTER(&ipf_nat); (void) nat_clearlist(); (void) nat_flushtable(); (void) ap_unload(); ! RWLOCK_EXIT(&ipf_nat); } *************** *** 1250,1258 **** #endif SPL_NET(s); ! MUTEX_ENTER(&ipf_nat); for (natp = &nat_instances; (nat = *natp); ) { ! if (--nat->nat_age) { natp = &nat->nat_next; continue; } --- 1276,1285 ---- #endif SPL_NET(s); ! WRITE_ENTER(&ipf_nat); for (natp = &nat_instances; (nat = *natp); ) { ! ATOMIC_DEC(nat->nat_age); ! if (nat->nat_age) { natp = &nat->nat_next; continue; } *************** *** 1261,1272 **** nat_log(nat, NL_EXPIRE); #endif nat_delete(nat); ! nat_stats.ns_expire++; } ap_expire(); ! MUTEX_EXIT(&ipf_nat); SPL_X(s); } --- 1288,1299 ---- nat_log(nat, NL_EXPIRE); #endif nat_delete(nat); ! ATOMIC_INC(nat_stats.ns_expire); } ap_expire(); ! RWLOCK_EXIT(&ipf_nat); SPL_X(s); } *************** *** 1289,1295 **** #endif SPL_NET(s); ! MUTEX_ENTER(&ipf_nat); for (nat = nat_instances; nat; nat = nat->nat_next) if ((ifp == nat->nat_ifp) && (np = nat->nat_ptr)) if ((np->in_outmsk == 0xffffffff) && !np->in_nip) { --- 1316,1322 ---- #endif SPL_NET(s); ! WRITE_ENTER(&ipf_nat); for (nat = nat_instances; nat; nat = nat->nat_next) if ((ifp == nat->nat_ifp) && (np = nat->nat_ptr)) if ((np->in_outmsk == 0xffffffff) && !np->in_nip) { *************** *** 1323,1329 **** sumd += nat->nat_sumd; nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); } ! MUTEX_EXIT(&ipf_nat); SPL_X(s); } --- 1350,1356 ---- sumd += nat->nat_sumd; nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); } ! RWLOCK_EXIT(&ipf_nat); SPL_X(s); } diff -cr ip_fil3.2.7/ip_proxy.c ip_fil3.2.8/ip_proxy.c *** ip_fil3.2.7/ip_proxy.c Mon May 18 21:15:22 1998 --- ip_fil3.2.8/ip_proxy.c Sun Jun 7 00:38:15 1998 *************** *** 6,12 **** * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15:22 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) --- 6,12 ---- * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.9 1998/06/06 14:38:15 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) *************** *** 78,83 **** --- 78,86 ---- static ap_session_t *ap_find __P((ip_t *, tcphdr_t *)); static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *, fr_info_t *, nat_t *)); + static int ap_matchsrcdst __P((ap_session_t *, struct in_addr, + struct in_addr, void *, u_short, u_short)); + #define AP_SESS_SIZE 53 *************** *** 120,132 **** { if (aps->aps_dst.s_addr == dst.s_addr) { if ((aps->aps_src.s_addr == src.s_addr) && ! (!tcp || (sport == aps->aps_sport) && ! (dport == aps->aps_dport))) return 1; } else if (aps->aps_dst.s_addr == src.s_addr) { if ((aps->aps_src.s_addr == dst.s_addr) && ! (!tcp || (sport == aps->aps_dport) && ! (dport == aps->aps_sport))) return 1; } return 0; --- 123,135 ---- { if (aps->aps_dst.s_addr == dst.s_addr) { if ((aps->aps_src.s_addr == src.s_addr) && ! (!tcp || ((sport == aps->aps_sport) && ! (dport == aps->aps_dport)))) return 1; } else if (aps->aps_dst.s_addr == src.s_addr) { if ((aps->aps_src.s_addr == dst.s_addr) && ! (!tcp || ((sport == aps->aps_dport) && ! (dport == aps->aps_sport)))) return 1; } return 0; *************** *** 229,234 **** --- 232,238 ---- { ap_session_t *aps; aproxy_t *apr; + u_32_t sum; int err; if (!(fin->fin_fi.fi_fl & FI_TCPUDP)) *************** *** 241,248 **** * verify that the checksum is correct. If not, then * don't do anything with this packet. */ ! if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp, ! ip, tcp, ip->ip_len)) { frstats[fin->fin_out].fr_tcpbad++; return -1; } --- 245,257 ---- * verify that the checksum is correct. If not, then * don't do anything with this packet. */ ! #if SOLARIS && defined(_KERNEL) ! sum = fr_tcpsum(fin->fin_qfm, ip, tcp, ip->ip_len); ! #else ! sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ! ip, tcp, ip->ip_len); ! #endif ! if (tcp->th_sum != sum) { frstats[fin->fin_out].fr_tcpbad++; return -1; } *************** *** 262,269 **** --- 271,283 ---- aps, nat); } if (err == 2) { + #if SOLARIS && defined(_KERNEL) + tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, + tcp, ip->ip_len); + #else tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp, ip->ip_len); + #endif err = 0; } return err; diff -cr ip_fil3.2.7/ip_sfil.c ip_fil3.2.8/ip_sfil.c *** ip_fil3.2.7/ip_sfil.c Wed Dec 3 00:55:39 1997 --- ip_fil3.2.8/ip_sfil.c Mon Jun 8 17:08:06 1998 *************** *** 9,15 **** */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.0.2.25.2.5 1997/12/02 13:55:39 darrenr Exp $"; #endif #include --- 9,15 ---- */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.0.2.25.2.8 1998/06/08 07:08:06 darrenr Exp $"; #endif #include *************** *** 55,67 **** extern fr_flags, fr_active; int ipfr_timer_id = 0; int ipl_unreach = ICMP_UNREACH_HOST; u_long ipl_frouteok[2] = {0, 0}; static void frzerostats __P((caddr_t)); static int frrequest __P((int, int, caddr_t, int)); ! kmutex_t ipl_mutex, ipf_mutex, ipfs_mutex; ! kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; kcondvar_t iplwait, ipfauthwait; --- 55,69 ---- extern fr_flags, fr_active; int ipfr_timer_id = 0; + int fr_running = 0; int ipl_unreach = ICMP_UNREACH_HOST; u_long ipl_frouteok[2] = {0, 0}; static void frzerostats __P((caddr_t)); static int frrequest __P((int, int, caddr_t, int)); ! kmutex_t ipl_mutex, ipf_authmx, ipf_rw; ! krwlock_t ipf_mutex, ipfs_mutex, ipf_solaris; ! krwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; kcondvar_t iplwait, ipfauthwait; *************** *** 69,74 **** --- 71,80 ---- { int i; + if (!fr_running) + return 0; + fr_running = 0; + rw_enter(&ipf_solaris, RW_WRITER); #ifdef IPFDEBUG cmn_err(CE_CONT, "ipldetach()\n"); #endif *************** *** 82,95 **** ip_natunload(); cv_destroy(&iplwait); cv_destroy(&ipfauthwait); mutex_destroy(&ipl_mutex); ! mutex_destroy(&ipf_mutex); ! mutex_destroy(&ipfs_mutex); ! mutex_destroy(&ipf_frag); ! mutex_destroy(&ipf_state); ! mutex_destroy(&ipf_natfrag); ! mutex_destroy(&ipf_nat); ! mutex_destroy(&ipf_auth); return 0; } --- 88,105 ---- ip_natunload(); cv_destroy(&iplwait); cv_destroy(&ipfauthwait); + mutex_destroy(&ipf_authmx); mutex_destroy(&ipl_mutex); ! mutex_destroy(&ipf_rw); ! rw_destroy(&ipf_mutex); ! rw_destroy(&ipf_frag); ! rw_destroy(&ipf_state); ! rw_destroy(&ipf_natfrag); ! rw_destroy(&ipf_nat); ! rw_destroy(&ipf_auth); ! rw_destroy(&ipfs_mutex); ! rw_exit(&ipf_solaris); ! rw_destroy(&ipf_solaris); return 0; } *************** *** 104,120 **** bzero((char *)nat_table, sizeof(nat_table)); bzero((char *)frcache, sizeof(frcache)); mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_mutex, "ipf filter mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipfs_mutex, "ipf solaris mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_frag, "ipf fragment mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_state, "ipf IP state mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_nat, "ipf IP NAT mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_natfrag, "ipf IP NAT-Frag mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_auth, "ipf IP User-Auth mutex", MUTEX_DRIVER, NULL); cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL); cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); ipflog_init(); return 0; } --- 114,134 ---- bzero((char *)nat_table, sizeof(nat_table)); bzero((char *)frcache, sizeof(frcache)); mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_rw, "ipf rw mutex", MUTEX_DRIVER, NULL); ! mutex_init(&ipf_authmx, "ipf auth log mutex", MUTEX_DRIVER, NULL); ! rw_init(&ipf_solaris, "ipf filter load/unload mutex", RW_DRIVER, NULL); ! rw_init(&ipf_mutex, "ipf filter mutex", RW_DRIVER, NULL); ! rw_init(&ipfs_mutex, "ipf solaris mutex", RW_DRIVER, NULL); ! rw_init(&ipf_frag, "ipf fragment mutex", RW_DRIVER, NULL); ! rw_init(&ipf_state, "ipf IP state mutex", RW_DRIVER, NULL); ! rw_init(&ipf_nat, "ipf IP NAT mutex", RW_DRIVER, NULL); ! rw_init(&ipf_natfrag, "ipf IP NAT-Frag mutex", RW_DRIVER, NULL); ! rw_init(&ipf_auth, "ipf IP User-Auth mutex", RW_DRIVER, NULL); cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL); cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); ipflog_init(); + fr_running = 1; return 0; } *************** *** 163,174 **** --- 177,195 ---- if ((IPL_LOGMAX < unit) || (unit < 0)) return ENXIO; + rw_enter(&ipf_solaris, RW_READER); + if (!fr_running) { + rw_exit(&ipf_solaris); + return 0; + } if (unit == IPL_LOGNAT) { error = nat_ioctl((caddr_t)data, cmd, mode); + rw_exit(&ipf_solaris); return error; } if (unit == IPL_LOGSTATE) { error = fr_state_ioctl((caddr_t)data, cmd, mode); + rw_exit(&ipf_solaris); return error; } *************** *** 185,193 **** case SIOCSETFF : if (!(mode & FWRITE)) return EPERM; ! mutex_enter(&ipf_mutex); IRCOPY((caddr_t)data, (caddr_t)&fr_flags, sizeof(fr_flags)); ! mutex_exit(&ipf_mutex); break; case SIOCGETFF : IWCOPY((caddr_t)&fr_flags, (caddr_t)data, sizeof(fr_flags)); --- 206,214 ---- case SIOCSETFF : if (!(mode & FWRITE)) return EPERM; ! rw_enter(&ipf_mutex, RW_WRITER); IRCOPY((caddr_t)data, (caddr_t)&fr_flags, sizeof(fr_flags)); ! rw_exit(&ipf_mutex); break; case SIOCGETFF : IWCOPY((caddr_t)&fr_flags, (caddr_t)data, sizeof(fr_flags)); *************** *** 198,230 **** case SIOCZRLST : if (!(mode & FWRITE)) return EPERM; ! mutex_enter(&ipf_mutex); error = frrequest(unit, cmd, (caddr_t)data, fr_active); ! mutex_exit(&ipf_mutex); break; case SIOCINIFR : case SIOCRMIFR : case SIOCADIFR : if (!(mode & FWRITE)) return EPERM; ! mutex_enter(&ipf_mutex); error = frrequest(unit, cmd, (caddr_t)data, 1 - fr_active); ! mutex_exit(&ipf_mutex); break; case SIOCSWAPA : if (!(mode & FWRITE)) return EPERM; ! mutex_enter(&ipf_mutex); bzero((char *)frcache, sizeof(frcache[0]) * 2); IWCOPY((caddr_t)&fr_active, (caddr_t)data, sizeof(fr_active)); fr_active = 1 - fr_active; ! mutex_exit(&ipf_mutex); break; case SIOCGETFS : { struct friostat fio; ! mutex_enter(&ipf_mutex); bcopy((char *)frstats, (char *)fio.f_st, sizeof(struct filterstats) * 2); fio.f_fin[0] = ipfilter[0][0]; --- 219,251 ---- case SIOCZRLST : if (!(mode & FWRITE)) return EPERM; ! rw_enter(&ipf_mutex, RW_WRITER); error = frrequest(unit, cmd, (caddr_t)data, fr_active); ! rw_exit(&ipf_mutex); break; case SIOCINIFR : case SIOCRMIFR : case SIOCADIFR : if (!(mode & FWRITE)) return EPERM; ! rw_enter(&ipf_mutex, RW_WRITER); error = frrequest(unit, cmd, (caddr_t)data, 1 - fr_active); ! rw_exit(&ipf_mutex); break; case SIOCSWAPA : if (!(mode & FWRITE)) return EPERM; ! rw_enter(&ipf_mutex, RW_WRITER); bzero((char *)frcache, sizeof(frcache[0]) * 2); IWCOPY((caddr_t)&fr_active, (caddr_t)data, sizeof(fr_active)); fr_active = 1 - fr_active; ! rw_exit(&ipf_mutex); break; case SIOCGETFS : { struct friostat fio; ! rw_enter(&ipf_mutex, RW_READER); bcopy((char *)frstats, (char *)fio.f_st, sizeof(struct filterstats) * 2); fio.f_fin[0] = ipfilter[0][0]; *************** *** 238,244 **** fio.f_active = fr_active; fio.f_froute[0] = ipl_frouteok[0]; fio.f_froute[1] = ipl_frouteok[1]; ! mutex_exit(&ipf_mutex); IWCOPY((caddr_t)&fio, (caddr_t)data, sizeof(fio)); break; } --- 259,265 ---- fio.f_active = fr_active; fio.f_froute[0] = ipl_frouteok[0]; fio.f_froute[1] = ipl_frouteok[1]; ! rw_exit(&ipf_mutex); IWCOPY((caddr_t)&fio, (caddr_t)data, sizeof(fio)); break; } *************** *** 251,259 **** if (!(mode & FWRITE)) return EPERM; IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp)); - mutex_enter(&ipf_mutex); frflush(unit, &tmp); - mutex_exit(&ipf_mutex); IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp)); break; #ifdef IPFILTER_LOG --- 272,278 ---- *************** *** 290,295 **** --- 309,315 ---- error = EINVAL; break; } + rw_exit(&ipf_solaris); return error; } diff -cr ip_fil3.2.7/ip_state.c ip_fil3.2.8/ip_state.c *** ip_fil3.2.7/ip_state.c Sun May 24 13:53:04 1998 --- ip_fil3.2.8/ip_state.c Mon Jun 8 02:27:12 1998 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.14 1998/05/24 03:53:04 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__) --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.17 1998/06/07 16:27:12 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__) *************** *** 82,88 **** int ips_num = 0; ips_stat_t ips_stats; #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern kmutex_t ipf_state; #endif static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr, --- 82,89 ---- int ips_num = 0; ips_stat_t ips_stats; #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) ! extern krwlock_t ipf_state; ! extern kmutex_t ipf_rw; #endif static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr, *************** *** 127,133 **** int delete, removed = 0; SPL_NET(s); ! MUTEX_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) { delete = 0; --- 128,134 ---- int delete, removed = 0; SPL_NET(s); ! WRITE_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) { delete = 0; *************** *** 162,168 **** } else isp = &is->is_next; } ! MUTEX_EXIT(&ipf_state); SPL_X(s); return removed; } --- 163,169 ---- } else isp = &is->is_next; } ! RWLOCK_EXIT(&ipf_state); SPL_X(s); return removed; } *************** *** 254,260 **** default : return -1; } ! ips_stats.iss_icmp++; is->is_age = fr_icmptimeout; break; } --- 255,261 ---- default : return -1; } ! ATOMIC_INC(ips_stats.iss_icmp); is->is_age = fr_icmptimeout; break; } *************** *** 272,278 **** is->is_ack = ntohl(tcp->th_ack); is->is_swin = ntohs(tcp->th_win); is->is_dwin = is->is_swin; /* start them the same */ - ips_stats.iss_tcp++; /* * If we're creating state for a starting connection, start the * timer on it as we'll never see an error if it fails to --- 273,278 ---- *************** *** 280,287 **** --- 280,290 ---- */ if ((tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) is->is_ack = 0; /* Trumpet WinSock 'ism */ + MUTEX_ENTER(&ipf_rw); + ips_stats.iss_tcp++; fr_tcp_age(&is->is_age, is->is_state, ip, fin, tcp->th_sport == is->is_sport); + MUTEX_EXIT(&ipf_rw); break; } case IPPROTO_UDP : *************** *** 290,296 **** hv += (is->is_dport = tcp->th_dport); hv += (is->is_sport = tcp->th_sport); ! ips_stats.iss_udp++; is->is_age = fr_udptimeout; break; } --- 293,299 ---- hv += (is->is_dport = tcp->th_dport); hv += (is->is_sport = tcp->th_sport); ! ATOMIC_INC(ips_stats.iss_udp); is->is_age = fr_udptimeout; break; } *************** *** 300,326 **** KMALLOC(is, ipstate_t *, sizeof(*is)); if (is == NULL) { ! ips_stats.iss_nomem++; return -1; } bcopy((char *)&ips, (char *)is, sizeof(*is)); hv %= IPSTATE_SIZE; ! MUTEX_ENTER(&ipf_state); is->is_pass = pass; is->is_pkts = 1; is->is_bytes = ip->ip_len; /* ! * Copy these from the rule itself. */ ! is->is_opt = fin->fin_fr->fr_ip.fi_optmsk; ! is->is_optmsk = fin->fin_fr->fr_mip.fi_optmsk; ! is->is_sec = fin->fin_fr->fr_ip.fi_secmsk; ! is->is_secmsk = fin->fin_fr->fr_mip.fi_secmsk; ! is->is_auth = fin->fin_fr->fr_ip.fi_auth; ! is->is_authmsk = fin->fin_fr->fr_mip.fi_auth; ! is->is_flags = fin->fin_fr->fr_ip.fi_fl; ! is->is_flags |= fin->fin_fr->fr_mip.fi_fl << 4; /* * add into table. */ --- 303,332 ---- KMALLOC(is, ipstate_t *, sizeof(*is)); if (is == NULL) { ! ATOMIC_INC(ips_stats.iss_nomem); return -1; } bcopy((char *)&ips, (char *)is, sizeof(*is)); hv %= IPSTATE_SIZE; ! WRITE_ENTER(&ipf_state); is->is_pass = pass; is->is_pkts = 1; is->is_bytes = ip->ip_len; /* ! * We want to check everything that is a property of this packet, ! * but we don't (automatically) care about it's fragment status as ! * this may change. */ ! is->is_opt = fin->fin_fi.fi_optmsk; ! is->is_optmsk = 0xffffffff; ! is->is_sec = fin->fin_fi.fi_secmsk; ! is->is_secmsk = 0xffff; ! is->is_auth = fin->fin_fi.fi_auth; ! is->is_authmsk = 0xffff; ! is->is_flags = fin->fin_fi.fi_fl; ! is->is_flags |= FI_OPTIONS|FI_TCPUDP|FI_SHORT; ! is->is_flags |= fin->fin_fi.fi_fl << 4; /* * add into table. */ *************** *** 335,345 **** } if (pass & FR_LOGFIRST) is->is_pass &= ~(FR_LOGFIRST|FR_LOG); ! ips_num++; #ifdef IPFILTER_LOG ipstate_log(is, ISL_NEW); #endif ! MUTEX_EXIT(&ipf_state); if (fin->fin_fi.fi_fl & FI_FRAG) ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); return 0; --- 341,351 ---- } if (pass & FR_LOGFIRST) is->is_pass &= ~(FR_LOGFIRST|FR_LOG); ! ATOMIC_INC(ips_num); #ifdef IPFILTER_LOG ipstate_log(is, ISL_NEW); #endif ! RWLOCK_EXIT(&ipf_state); if (fin->fin_fi.fi_fl & FI_FRAG) ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); return 0; *************** *** 421,433 **** is->is_ack = seq; is->is_dwin = ntohs(tcp->th_win); } ! ips_stats.iss_hits++; is->is_pkts++; is->is_bytes += ip->ip_len; /* * Nearing end of connection, start timeout. */ fr_tcp_age(&is->is_age, is->is_state, ip, fin, source); return 1; } return 0; --- 427,441 ---- is->is_ack = seq; is->is_dwin = ntohs(tcp->th_win); } ! ATOMIC_INC(ips_stats.iss_hits); is->is_pkts++; is->is_bytes += ip->ip_len; /* * Nearing end of connection, start timeout. */ + MUTEX_ENTER(&ipf_rw); fr_tcp_age(&is->is_age, is->is_state, ip, fin, source); + MUTEX_EXIT(&ipf_rw); return 1; } return 0; *************** *** 471,478 **** (!out && is->is_ifpin == ifp)) && (is->is_dst.s_addr == dst.s_addr) && (is->is_src.s_addr == src.s_addr) && ! (!tcp || (sp == is->is_sport) && ! (dp == is->is_dport))) { ret = 1; } } else { --- 479,486 ---- (!out && is->is_ifpin == ifp)) && (is->is_dst.s_addr == dst.s_addr) && (is->is_src.s_addr == src.s_addr) && ! (!tcp || ((sp == is->is_sport) && ! (dp == is->is_dport)))) { ret = 1; } } else { *************** *** 480,487 **** (!out && is->is_ifpout == ifp)) && (is->is_dst.s_addr == src.s_addr) && (is->is_src.s_addr == dst.s_addr) && ! (!tcp || (sp == is->is_dport) && ! (dp == is->is_sport))) { ret = 1; } } --- 488,495 ---- (!out && is->is_ifpout == ifp)) && (is->is_dst.s_addr == src.s_addr) && (is->is_src.s_addr == dst.s_addr) && ! (!tcp || ((sp == is->is_dport) && ! (dp == is->is_sport)))) { ret = 1; } } *************** *** 494,501 **** if (((fin->fin_fi.fi_optmsk & is->is_optmsk) != is->is_opt) || ((fin->fin_fi.fi_secmsk & is->is_secmsk) != is->is_sec) || ((fin->fin_fi.fi_auth & is->is_authmsk) != is->is_auth) || ! ((fin->fin_fi.fi_fl & (is->is_flags >> 4)) != ! (is->is_flags & 0xf))) ret = 0; } return ret; --- 502,509 ---- if (((fin->fin_fi.fi_optmsk & is->is_optmsk) != is->is_opt) || ((fin->fin_fi.fi_secmsk & is->is_secmsk) != is->is_sec) || ((fin->fin_fi.fi_auth & is->is_authmsk) != is->is_auth) || ! ((fin->fin_fi.fi_fl & (is->is_flags & 0xf)) != ! (is->is_flags >> 4))) ret = 0; } return ret; *************** *** 535,541 **** hv += ic->icmp_id; hv += ic->icmp_seq; hv %= IPSTATE_SIZE; ! MUTEX_ENTER(&ipf_state); for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && (ic->icmp_id == is->is_icmp.ics_id) && --- 543,549 ---- hv += ic->icmp_id; hv += ic->icmp_seq; hv %= IPSTATE_SIZE; ! READ_ENTER(&ipf_state); for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && (ic->icmp_id == is->is_icmp.ics_id) && *************** *** 543,557 **** fr_matchsrcdst(is, src, dst, fin, NULL, 0, 0)) { if (is->is_icmp.ics_type != ic->icmp_type) continue; is->is_age = fr_icmptimeout; - is->is_pkts++; is->is_bytes += ip->ip_len; ips_stats.iss_hits++; ! pass = is->is_pass; ! MUTEX_EXIT(&ipf_state); return pass; } ! MUTEX_EXIT(&ipf_state); break; case IPPROTO_TCP : { --- 551,567 ---- fr_matchsrcdst(is, src, dst, fin, NULL, 0, 0)) { if (is->is_icmp.ics_type != ic->icmp_type) continue; + pass = is->is_pass; + RWLOCK_EXIT(&ipf_state); + WRITE_ENTER(&ipf_state); is->is_age = fr_icmptimeout; is->is_bytes += ip->ip_len; ips_stats.iss_hits++; ! is->is_pkts++; ! RWLOCK_EXIT(&ipf_state); return pass; } ! RWLOCK_EXIT(&ipf_state); break; case IPPROTO_TCP : { *************** *** 560,566 **** hv += dport; hv += sport; hv %= IPSTATE_SIZE; ! MUTEX_ENTER(&ipf_state); for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && fr_matchsrcdst(is, src, dst, fin, tcp, --- 570,576 ---- hv += dport; hv += sport; hv %= IPSTATE_SIZE; ! WRITE_ENTER(&ipf_state); for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && fr_matchsrcdst(is, src, dst, fin, tcp, *************** *** 568,574 **** if (fr_tcpstate(is, fin, ip, tcp)) { pass = is->is_pass; #ifdef _KERNEL ! MUTEX_EXIT(&ipf_state); #else if (tcp->th_flags & TCP_CLOSE) { --- 578,584 ---- if (fr_tcpstate(is, fin, ip, tcp)) { pass = is->is_pass; #ifdef _KERNEL ! RWLOCK_EXIT(&ipf_state); #else if (tcp->th_flags & TCP_CLOSE) { *************** *** 580,586 **** return pass; } } ! MUTEX_EXIT(&ipf_state); break; } case IPPROTO_UDP : --- 590,596 ---- return pass; } } ! RWLOCK_EXIT(&ipf_state); break; } case IPPROTO_UDP : *************** *** 593,618 **** /* * Nothing else to match on but ports. and IP#'s */ ! MUTEX_ENTER(&ipf_state); for (is = ips_table[hv]; is; is = is->is_next) if ((is->is_p == pr) && fr_matchsrcdst(is, src, dst, fin, tcp, sport, dport)) { ! ips_stats.iss_hits++; ! is->is_pkts++; is->is_bytes += ip->ip_len; is->is_age = fr_udptimeout; ! pass = is->is_pass; ! MUTEX_EXIT(&ipf_state); return pass; } ! MUTEX_EXIT(&ipf_state); break; } default : break; } ! ips_stats.iss_miss++; return 0; } --- 603,630 ---- /* * Nothing else to match on but ports. and IP#'s */ ! READ_ENTER(&ipf_state); for (is = ips_table[hv]; is; is = is->is_next) if ((is->is_p == pr) && fr_matchsrcdst(is, src, dst, fin, tcp, sport, dport)) { ! pass = is->is_pass; ! MUTEX_ENTER(&ipf_rw); is->is_bytes += ip->ip_len; is->is_age = fr_udptimeout; ! ips_stats.iss_hits++; ! is->is_pkts++; ! MUTEX_EXIT(&ipf_rw); ! RWLOCK_EXIT(&ipf_state); return pass; } ! RWLOCK_EXIT(&ipf_state); break; } default : break; } ! ATOMIC_INC(ips_stats.iss_miss); return 0; } *************** *** 625,637 **** register int i; register ipstate_t *is, **isp; ! MUTEX_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) { *isp = is->is_next; KFREE(is); } ! MUTEX_EXIT(&ipf_state); } --- 637,649 ---- register int i; register ipstate_t *is, **isp; ! WRITE_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) { *isp = is->is_next; KFREE(is); } ! RWLOCK_EXIT(&ipf_state); } *************** *** 648,654 **** #endif SPL_NET(s); ! MUTEX_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) if (is->is_age && !--is->is_age) { --- 660,666 ---- #endif SPL_NET(s); ! WRITE_ENTER(&ipf_state); for (i = 0; i < IPSTATE_SIZE; i++) for (isp = &ips_table[i]; (is = *isp); ) if (is->is_age && !--is->is_age) { *************** *** 664,670 **** ips_num--; } else isp = &is->is_next; ! MUTEX_EXIT(&ipf_state); SPL_X(s); } --- 676,682 ---- ips_num--; } else isp = &is->is_next; ! RWLOCK_EXIT(&ipf_state); SPL_X(s); } diff -cr ip_fil3.2.7/ipl.h ip_fil3.2.8/ipl.h *** ip_fil3.2.7/ipl.h Sun May 24 12:06:47 1998 --- ip_fil3.2.8/ipl.h Mon Jun 8 02:32:09 1998 *************** *** 11,16 **** #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter v3.2.7" #endif --- 11,16 ---- #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter v3.2.8" #endif diff -cr ip_fil3.2.7/ipnat.c ip_fil3.2.8/ipnat.c *** ip_fil3.2.7/ipnat.c Sun May 24 05:07:02 1998 --- ip_fil3.2.8/ipnat.c Sun Jun 7 00:39:56 1998 *************** *** 62,68 **** #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.0.2.21.2.6 1998/05/23 19:07:02 darrenr Exp $"; #endif --- 62,68 ---- #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.0.2.21.2.8 1998/06/06 14:39:56 darrenr Exp $"; #endif *************** *** 369,375 **** ntohs(nat.nat_outport)); printf(" [%s %hu]", inet_ntoa(nat.nat_oip), ntohs(nat.nat_oport)); ! printf(" %ld %hu %lx", nat.nat_age, nat.nat_use, nat.nat_sumd); #if SOLARIS printf(" %lx", nat.nat_ipsumd); --- 369,375 ---- ntohs(nat.nat_outport)); printf(" [%s %hu]", inet_ntoa(nat.nat_oip), ntohs(nat.nat_oport)); ! printf(" %ld %hu %x", nat.nat_age, nat.nat_use, nat.nat_sumd); #if SOLARIS printf(" %lx", nat.nat_ipsumd); *************** *** 700,705 **** --- 700,708 ---- "missing parameter for \"proxy\"\n"); return NULL; } + } else { + fprintf(stderr, "missing keyword \"port\"\n"); + return NULL; } if ((proto = index(s, '/'))) { *proto++ = '\0'; diff -cr ip_fil3.2.7/solaris.c ip_fil3.2.8/solaris.c *** ip_fil3.2.7/solaris.c Sat Feb 28 13:35:21 1998 --- ip_fil3.2.8/solaris.c Mon Jun 8 16:58:54 1998 *************** *** 6,12 **** * 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.0.2.22.2.4 1998/02/28 02:35:21 darrenr Exp $"; #include #include --- 6,12 ---- * 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.0.2.22.2.7 1998/06/08 06:58:54 darrenr Exp $"; #include #include *************** *** 56,62 **** int soldetach __P((void)); extern struct filterstats frstats[]; ! extern kmutex_t ipf_mutex, ipfs_mutex, ipf_nat; extern int fr_flags; extern ipnat_t *nat_list; --- 56,63 ---- int soldetach __P((void)); extern struct filterstats frstats[]; ! extern krwlock_t ipf_mutex, ipfs_mutex, ipf_nat, ipf_solaris; ! extern int fr_running; extern int fr_flags; extern ipnat_t *nat_list; *************** *** 140,153 **** int _fini(void) { ! #ifdef IPFDEBUG ! int ipfinst = mod_remove(&modlink1); cmn_err(CE_NOTE, "IP Filter: _fini() = %d\n", ipfinst); - return ipfinst; - #else - return mod_remove(&modlink1); #endif } --- 141,153 ---- int _fini(void) { ! int ipfinst; + ipfinst = mod_remove(&modlink1); + #ifdef IPFDEBUG cmn_err(CE_NOTE, "IP Filter: _fini() = %d\n", ipfinst); #endif + return ipfinst; } *************** *** 545,568 **** int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0; qif_t qfb, *qif; again: ! mutex_enter(&ipfs_mutex); while (!(qif = qif_from_queue(q))) { for (qif = qif_head; qif; qif = qif->qf_next) if (&qif->qf_rqinit == q->q_qinfo && qif->qf_rqinfo && qif->qf_rqinfo->qi_putp) { pnext = qif->qf_rqinfo->qi_putp; - mutex_exit(&ipfs_mutex); frstats[0].fr_notip++; if (!synced) { ipfsync(); synced = 1; goto again; } /* fr_donotip(0, NULL, q, mb, mb, NULL, 0); */ return (*pnext)(q, mb); } ! mutex_exit(&ipfs_mutex); if (!synced) { ipfsync(); synced = 1; --- 545,574 ---- int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0; qif_t qfb, *qif; + rw_enter(&ipf_solaris, RW_READER); again: ! if (!fr_running) { ! rw_exit(&ipf_solaris); ! return 0; ! } ! rw_enter(&ipfs_mutex, RW_READER); while (!(qif = qif_from_queue(q))) { for (qif = qif_head; qif; qif = qif->qf_next) if (&qif->qf_rqinit == q->q_qinfo && qif->qf_rqinfo && qif->qf_rqinfo->qi_putp) { pnext = qif->qf_rqinfo->qi_putp; frstats[0].fr_notip++; + rw_exit(&ipfs_mutex); if (!synced) { ipfsync(); synced = 1; goto again; } + rw_exit(&ipf_solaris); /* fr_donotip(0, NULL, q, mb, mb, NULL, 0); */ return (*pnext)(q, mb); } ! rw_exit(&ipfs_mutex); if (!synced) { ipfsync(); synced = 1; *************** *** 584,589 **** --- 590,596 ---- #endif ); frstats[0].fr_drop++; + rw_exit(&ipf_solaris); freemsg(mb); return 0; } *************** *** 591,616 **** * So we can be more re-entrant. */ bcopy((char *)qif, (char *)&qfb, sizeof(*qif)); ! mutex_exit(&ipfs_mutex); qif = &qfb; pnext = qif->qf_rqinfo->qi_putp; type = MTYPE(mb); if (type == M_DATA || type == M_PROTO || type == M_PCPROTO) if (fr_precheck(&mb, q, qif, 0)) { if (mb) freemsg(mb); return 0; } if (mb) { ! if (pnext) return (*pnext)(q, mb); cmn_err(CE_WARN, "IP Filter: inp NULL: qif %x %s q %x info %x", qif, qif->qf_name, q, q->q_qinfo); - freemsg(mb); } return 0; } --- 598,628 ---- * So we can be more re-entrant. */ bcopy((char *)qif, (char *)&qfb, sizeof(*qif)); ! rw_exit(&ipfs_mutex); qif = &qfb; pnext = qif->qf_rqinfo->qi_putp; type = MTYPE(mb); if (type == M_DATA || type == M_PROTO || type == M_PCPROTO) if (fr_precheck(&mb, q, qif, 0)) { + rw_exit(&ipf_solaris); if (mb) freemsg(mb); return 0; } if (mb) { ! if (pnext) { ! rw_exit(&ipf_solaris); return (*pnext)(q, mb); + } cmn_err(CE_WARN, "IP Filter: inp NULL: qif %x %s q %x info %x", qif, qif->qf_name, q, q->q_qinfo); } + rw_exit(&ipf_solaris); + if (mb) + freemsg(mb); return 0; } *************** *** 622,635 **** int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0; qif_t qfb, *qif; again: ! mutex_enter(&ipfs_mutex); if (!(qif = qif_from_queue(q))) { for (qif = qif_head; qif; qif = qif->qf_next) if (&qif->qf_wqinit == q->q_qinfo && qif->qf_wqinfo && qif->qf_wqinfo->qi_putp) { pnext = qif->qf_wqinfo->qi_putp; ! mutex_exit(&ipfs_mutex); frstats[1].fr_notip++; if (!synced) { ipfsync(); --- 634,652 ---- int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0; qif_t qfb, *qif; + rw_enter(&ipf_solaris, RW_READER); again: ! if (!fr_running) { ! rw_exit(&ipf_solaris); ! return 0; ! } ! rw_enter(&ipfs_mutex, RW_READER); if (!(qif = qif_from_queue(q))) { for (qif = qif_head; qif; qif = qif->qf_next) if (&qif->qf_wqinit == q->q_qinfo && qif->qf_wqinfo && qif->qf_wqinfo->qi_putp) { pnext = qif->qf_wqinfo->qi_putp; ! rw_exit(&ipfs_mutex); frstats[1].fr_notip++; if (!synced) { ipfsync(); *************** *** 637,645 **** goto again; } /* fr_donotip(0, NULL, q, mb, mb, NULL, 0); */ return (*pnext)(q, mb); } ! mutex_exit(&ipfs_mutex); if (!synced) { ipfsync(); synced = 1; --- 654,663 ---- goto again; } /* fr_donotip(0, NULL, q, mb, mb, NULL, 0); */ + rw_exit(&ipf_solaris); return (*pnext)(q, mb); } ! rw_exit(&ipfs_mutex); if (!synced) { ipfsync(); synced = 1; *************** *** 671,676 **** --- 689,695 ---- q->q_nbsrv->q_qinfo, q->q_nbsrv->q_next, q->q_nbsrv->q_ptr); frstats[1].fr_drop++; + rw_exit(&ipf_solaris); freemsg(mb); return 0; } *************** *** 678,703 **** * So we can be more re-entrant. */ bcopy((char *)qif, (char *)&qfb, sizeof(*qif)); ! mutex_exit(&ipfs_mutex); qif = &qfb; pnext = qif->qf_wqinfo->qi_putp; type = MTYPE(mb); if (type == M_DATA || type == M_PROTO || type == M_PCPROTO) if (fr_precheck(&mb, q, qif, 1)) { if (mb) freemsg(mb); return 0; } if (mb) { ! if (pnext) return (*pnext)(q, mb); cmn_err(CE_WARN, "IP Filter: outp NULL: qif %x %s q %x info %x", qif, qif->qf_name, q, q->q_qinfo); - freemsg(mb); } return 0; } --- 697,727 ---- * So we can be more re-entrant. */ bcopy((char *)qif, (char *)&qfb, sizeof(*qif)); ! rw_exit(&ipfs_mutex); qif = &qfb; pnext = qif->qf_wqinfo->qi_putp; type = MTYPE(mb); if (type == M_DATA || type == M_PROTO || type == M_PCPROTO) if (fr_precheck(&mb, q, qif, 1)) { + rw_exit(&ipf_solaris); if (mb) freemsg(mb); return 0; } if (mb) { ! if (pnext) { ! rw_exit(&ipf_solaris); return (*pnext)(q, mb); + } cmn_err(CE_WARN, "IP Filter: outp NULL: qif %x %s q %x info %x", qif, qif->qf_name, q, q->q_qinfo); } + rw_exit(&ipf_solaris); + if (mb) + freemsg(mb); return 0; } *************** *** 711,720 **** void ipf_synctimeout(arg) caddr_t arg; { ipfsync(); ! mutex_enter(&ipfs_mutex); synctimeoutid = 0; ! mutex_exit(&ipfs_mutex); } static int ipf_ip_qin(q, mp) --- 735,746 ---- void ipf_synctimeout(arg) caddr_t arg; { + rw_enter(&ipf_solaris, RW_READER); ipfsync(); ! rw_enter(&ipfs_mutex, RW_WRITER); synctimeoutid = 0; ! rw_exit(&ipfs_mutex); ! rw_exit(&ipf_solaris); } static int ipf_ip_qin(q, mp) *************** *** 727,732 **** --- 753,763 ---- if (mp->b_datap->db_type != M_IOCTL) return (*ipf_ip_inp)(q, mp); + rw_enter(&ipf_solaris, RW_READER); + if (!fr_running) { + rw_exit(&ipf_solaris); + return 0; + } ioc = (struct iocblk *)mp->b_rptr; switch (ioc->ioc_cmd) { *************** *** 739,759 **** #endif ret = (*ipf_ip_inp)(q, mp); ! mutex_enter(&ipfs_mutex); if (synctimeoutid == 0) { synctimeoutid = timeout( ipf_synctimeout, NULL, drv_usectohz(1000000) /*1 sec*/ ); ! mutex_exit(&ipfs_mutex); ! } else ! mutex_exit(&ipfs_mutex); ! return ret; default: ! return (*ipf_ip_inp)(q, mp); } } static int ipdrvattcnt = 0; --- 770,791 ---- #endif ret = (*ipf_ip_inp)(q, mp); ! rw_enter(&ipfs_mutex, RW_WRITER); if (synctimeoutid == 0) { synctimeoutid = timeout( ipf_synctimeout, NULL, drv_usectohz(1000000) /*1 sec*/ ); ! } ! rw_exit(&ipfs_mutex); ! break; default: ! ret = (*ipf_ip_inp)(q, mp); } + rw_exit(&ipf_solaris); + return ret; } static int ipdrvattcnt = 0; *************** *** 779,797 **** cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() ipinfo=0x%lx\n", &ipinfo); #endif if (--ipdrvattcnt <= 0) { if (ipf_ip_inp && (ipinfo.st_wrinit->qi_putp == ipf_ip_qin)) { ipinfo.st_wrinit->qi_putp = ipf_ip_inp; ipf_ip_inp = NULL; } - mutex_enter(&ipfs_mutex); if (synctimeoutid) { synctimeoutid = 0; - mutex_exit(&ipfs_mutex); untimeout(synctimeoutid); ! } else ! mutex_exit(&ipfs_mutex); } } /* --- 811,828 ---- cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() ipinfo=0x%lx\n", &ipinfo); #endif + rw_enter(&ipfs_mutex, RW_WRITER); if (--ipdrvattcnt <= 0) { if (ipf_ip_inp && (ipinfo.st_wrinit->qi_putp == ipf_ip_qin)) { ipinfo.st_wrinit->qi_putp = ipf_ip_inp; ipf_ip_inp = NULL; } if (synctimeoutid) { synctimeoutid = 0; untimeout(synctimeoutid); ! } } + rw_exit(&ipfs_mutex); } /* *************** *** 816,822 **** out = il->ill_wq->q_next; ! mutex_enter(&ipfs_mutex); /* * Look for entry already setup for this device */ --- 847,853 ---- out = il->ill_wq->q_next; ! rw_enter(&ipfs_mutex, RW_WRITER); /* * Look for entry already setup for this device */ *************** *** 825,831 **** qif->qf_optr == out->q_ptr) break; if (qif) { ! mutex_exit(&ipfs_mutex); continue; } #ifdef IPFDEBUG --- 856,862 ---- qif->qf_optr == out->q_ptr) break; if (qif) { ! rw_exit(&ipfs_mutex); continue; } #ifdef IPFDEBUG *************** *** 855,861 **** il->ill_name, in->q_qinfo->qi_putp, in->q_qinfo); #endif ! mutex_exit(&ipfs_mutex); KFREE(qif); continue; } --- 886,892 ---- il->ill_name, in->q_qinfo->qi_putp, in->q_qinfo); #endif ! rw_exit(&ipfs_mutex); KFREE(qif); continue; } *************** *** 875,881 **** il->ill_name, out->q_qinfo->qi_putp, out->q_qinfo); #endif ! mutex_exit(&ipfs_mutex); KFREE(qif); continue; } --- 906,912 ---- il->ill_name, out->q_qinfo->qi_putp, out->q_qinfo); #endif ! rw_exit(&ipfs_mutex); KFREE(qif); continue; } *************** *** 895,901 **** /* * Activate any rules directly associated with this interface */ ! mutex_enter(&ipf_mutex); for (f = ipfilter[0][fr_active]; f; f = f->fr_next) { if ((f->fr_ifa == (struct ifnet *)-1)) { len = strlen(f->fr_ifname)+1; /* includes \0 */ --- 926,932 ---- /* * Activate any rules directly associated with this interface */ ! rw_enter(&ipf_mutex, RW_WRITER); for (f = ipfilter[0][fr_active]; f; f = f->fr_next) { if ((f->fr_ifa == (struct ifnet *)-1)) { len = strlen(f->fr_ifname)+1; /* includes \0 */ *************** *** 912,919 **** f->fr_ifa = il; } } ! mutex_exit(&ipf_mutex); ! mutex_enter(&ipf_nat); for (np = nat_list; np; np = np->in_next) { if ((np->in_ifp == (struct ifnet *)-1)) { len = strlen(np->in_ifname)+1; /* includes \0 */ --- 943,950 ---- f->fr_ifa = il; } } ! rw_exit(&ipf_mutex); ! rw_enter(&ipf_nat, RW_WRITER); for (np = nat_list; np; np = np->in_next) { if ((np->in_ifp == (struct ifnet *)-1)) { len = strlen(np->in_ifname)+1; /* includes \0 */ *************** *** 922,928 **** np->in_ifp = il; } } ! mutex_exit(&ipf_nat); bcopy((caddr_t)qif->qf_rqinfo, (caddr_t)&qif->qf_rqinit, sizeof(struct qinit)); --- 953,959 ---- np->in_ifp = il; } } ! rw_exit(&ipf_nat); bcopy((caddr_t)qif->qf_rqinfo, (caddr_t)&qif->qf_rqinit, sizeof(struct qinit)); *************** *** 946,952 **** #endif out->q_qinfo = &qif->qf_wqinit; ! mutex_exit(&ipfs_mutex); cmn_err(CE_CONT, "IP Filter: attach to [%s,%d]\n", qif->qf_name, il->ill_ppa); } --- 977,983 ---- #endif out->q_qinfo = &qif->qf_wqinit; ! rw_exit(&ipfs_mutex); cmn_err(CE_CONT, "IP Filter: attach to [%s,%d]\n", qif->qf_name, il->ill_ppa); } *************** *** 968,974 **** register ill_t *il; queue_t *in, *out; ! mutex_enter(&ipfs_mutex); for (qp = &qif_head; (qif = *qp); ) { for (il = ill_g_head; il; il = il->ill_next) if ((qif->qf_ill == il) && --- 999,1005 ---- register ill_t *il; queue_t *in, *out; ! rw_enter(&ipfs_mutex, RW_WRITER); for (qp = &qif_head; (qif = *qp); ) { for (il = ill_g_head; il; il = il->ill_next) if ((qif->qf_ill == il) && *************** *** 991,1002 **** /* * Disable any rules directly associated with this interface */ ! mutex_enter(&ipf_nat); for (np = nat_list; np; np = np->in_next) if (np->in_ifp == (void *)qif->qf_ill) np->in_ifp = (struct ifnet *)-1; ! mutex_exit(&ipf_nat); ! mutex_enter(&ipf_mutex); for (f = ipfilter[0][fr_active]; f; f = f->fr_next) if (f->fr_ifa == (void *)qif->qf_ill) f->fr_ifa = (struct ifnet *)-1; --- 1022,1033 ---- /* * Disable any rules directly associated with this interface */ ! rw_enter(&ipf_nat, RW_WRITER); for (np = nat_list; np; np = np->in_next) if (np->in_ifp == (void *)qif->qf_ill) np->in_ifp = (struct ifnet *)-1; ! rw_exit(&ipf_nat); ! rw_enter(&ipf_mutex, RW_WRITER); for (f = ipfilter[0][fr_active]; f; f = f->fr_next) if (f->fr_ifa == (void *)qif->qf_ill) f->fr_ifa = (struct ifnet *)-1; *************** *** 1031,1042 **** #endif out->q_qinfo = qif->qf_wqinfo; } ! mutex_exit(&ipf_mutex); KFREE(qif); qif = *qp; } ! mutex_exit(&ipfs_mutex); solattach(); /* --- 1062,1073 ---- #endif out->q_qinfo = qif->qf_wqinfo; } ! rw_exit(&ipf_mutex); KFREE(qif); qif = *qp; } ! rw_exit(&ipfs_mutex); solattach(); /* *************** *** 1057,1063 **** qif_t *qif, *qf2, **qp; ill_t *il; ! mutex_enter(&ipfs_mutex); /* * Make two passes, first get rid of all the unknown devices, next * unlink known devices. --- 1088,1094 ---- qif_t *qif, *qf2, **qp; ill_t *il; ! rw_enter(&ipfs_mutex, RW_WRITER); /* * Make two passes, first get rid of all the unknown devices, next * unlink known devices. *************** *** 1105,1111 **** } KFREE(qif); } ! mutex_exit(&ipfs_mutex); return ipldetach(); } --- 1136,1142 ---- } KFREE(qif); } ! rw_exit(&ipfs_mutex); return ipldetach(); } diff -cr ip_fil3.2.7/todo ip_fil3.2.8/todo *** ip_fil3.2.7/todo Thu Apr 9 00:06:01 1998 --- ip_fil3.2.8/todo Sun Jun 7 00:40:22 1998 *************** *** 34,41 **** * ipfsync() should change IP#'s in current mappings as well as what's in rules. ! document bimap ! document NAT rule order processing - add more docs --- 34,45 ---- * ipfsync() should change IP#'s in current mappings as well as what's in rules. ! * document bimap ! * document NAT rule order processing ! ! * add more docs ! ! * add ICMP support to state checking code similar to that used for NAT so that ! the 'right' ICMP packets can get through.