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

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Darren Reed 2000-08-13 04:58:02 +00:00
commit 3002dee911
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64589
18 changed files with 432 additions and 142 deletions

View File

@ -20,6 +20,32 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.4.9 08/08/2000 - Released
implement new aging mechanism in fr_tcp_age()
fix icmp state checking bug
revamp buildsunos script and build both sparcv7/sparcv9 for Solaris
if on an Ultra with a 64bit system & compiler (Caseper Dik)
open ipfilter device read only if we know we can
print out better information for ICMP packets in ipmon
move checking for source spoofed packets to a point where we can generate
logs of them
return EFAULT from ircopyptr/iwcopyptr
don't do ioctl(SIOCGETFS) for auth stats
fix up freeing mbufs for post-4.3BSD
fix returning of inc from ftp proxy
fix bugs with ipfs -R/-W (Caseper Dik)
3.4.8 19/07/2000 - Released
create fake opt_inet6.h for FreeBSD-4 compile as LKM

View File

@ -5,7 +5,7 @@
# provided that this notice is preserved and due credit is given
# to the original author and the contributors.
#
# $Id: Makefile,v 2.11.2.2 2000/07/18 13:58:10 darrenr Exp $
# $Id: Makefile,v 2.11.2.3 2000/08/05 14:50:00 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@ -15,6 +15,7 @@ CC=gcc -Wstrict-prototypes -Wmissing-prototypes
#CC=gcc
#CC=cc -Dconst=
DEBUG=-g
TOP=../..
CFLAGS=-I$$(TOP) -g
CPU=`uname -m`
CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`
@ -63,7 +64,8 @@ MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
"CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \
'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)'
'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)' \
"BITS=$(BITS)" "OBJ=$(OBJ)"
DEST="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)"
MFLAGS=$(MFLAGS1) "IPFLKM=$(IPFLKM)"
#
@ -105,7 +107,7 @@ include:
fi
sunos solaris: include
./buildsunos
./buildsunos $(MFLAGS)
freebsd22: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
@ -132,7 +134,7 @@ freebsd4: include
echo "#define INET6" > opt_inet6.h; \
fi
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 build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "DLKM=-DKLD_MODULE -I/sys"; cd ..)
(cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..)
freebsd3 freebsd30: include
@ -186,7 +188,8 @@ setup:
clean: clean-include
${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \
vnode_if.h $(LKM) *~ opt_inet6.h
vnode_if.h $(LKM) *~
${RM} -rf sparcv7 sparcv9
(cd SunOS4; make clean)
(cd SunOS5; make clean)
(cd BSD; make clean)

View File

@ -65,7 +65,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.4 2000/05/22 12:47:38 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.5 2000/07/20 14:13:30 darrenr Exp $";
#endif
extern char *optarg;
@ -209,6 +209,7 @@ char *argv[];
opts |= OPT_ACCNT|OPT_SHOWLIST;
break;
case 'A' :
device = IPAUTH_NAME;
opts |= OPT_AUTHSTATS;
break;
case 'C' :
@ -297,7 +298,7 @@ char *argv[];
bzero((char *)&ipsst, sizeof(ipsst));
bzero((char *)&ifrst, sizeof(ifrst));
if (ioctl(fd, SIOCGETFS, &fiop) == -1) {
if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) {
perror("ioctl(ipf:SIOCGETFS)");
exit(-1);
}

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.3 2000/06/17 06:24:31 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.4 2000/08/05 14:48:50 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -46,7 +46,7 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.3 2000/06/17 06:24:31 d
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#if (_BSDI_VERSION >= 199802) || (__FreeBSD_Version >= 400000)
#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000)
# include <sys/queue.h>
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi)

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.26.2.3 2000/04/28 14:56:49 darrenr Exp $
* $Id: ip_compat.h,v 2.26.2.4 2000/08/13 03:51:03 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -126,6 +126,10 @@ typedef int minor_t;
#endif /* SOLARIS */
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
#if defined(__FreeBSD__) && (__FreeBSD__ >= 5) && defined(_KERNEL)
# include <machine/in_cksum.h>
#endif
#ifndef IP_OFFMASK
#define IP_OFFMASK 0x1fff
#endif

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.14 2000/07/18 13:57:55 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.15 2000/08/05 14:49:08 darrenr Exp $";
#endif
#ifndef SOLARIS
@ -1139,8 +1139,10 @@ int dst;
return ENOBUFS;
MCLGET(m, M_DONTWAIT);
if (!m)
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
return ENOBUFS;
}
avail = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
xtra = MIN(ntohs(oip6->ip6_plen) + sizeof(ip6_t),
avail - hlen - sizeof(*icmp) - max_linkhdr);

View File

@ -2,7 +2,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_ftp_pxy.c,v 2.7.2.12 2000/07/19 13:06:13 darrenr Exp $
* $Id: ip_ftp_pxy.c,v 2.7.2.13 2000/08/07 12:35:27 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@ -263,7 +263,7 @@ int dlen;
ip->ip_len = slen;
ip->ip_src = swip;
}
return inc;
return APR_INC(inc);
}
@ -703,7 +703,7 @@ int rv;
t->ftps_seq = ntohl(tcp->th_ack);
f->ftps_rptr = rptr;
f->ftps_wptr = wptr;
return inc;
return APR_INC(inc);
}

View File

@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.16 2000/07/18 13:57:40 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.21 2000/08/12 07:32:40 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -126,7 +126,7 @@ hostmap_t **maptable = NULL;
u_long fr_defnatage = DEF_NAT_AGE,
fr_defnaticmpage = 6; /* 3 seconds */
static natstat_t nat_stats;
natstat_t nat_stats;
int fr_nat_lock = 0;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_rw, ipf_hostmap;
@ -403,8 +403,11 @@ int mode;
KMALLOC(nt, ipnat_t *);
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT))
error = IRCOPYPTR(data, (char *)&natd, sizeof(natd));
else if (cmd == SIOCIPFFL) /* SIOCFLNAT & SIOCCNATL */
else if (cmd == SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
error = IRCOPY(data, (char *)&arg, sizeof(arg));
if (error)
error = EFAULT;
}
if (error)
goto done;
@ -498,7 +501,7 @@ int mode;
* mapping range. In all cases, the range is inclusive of
* the start and ending IP addresses.
* If to a CIDR address, lose 2: broadcast + network address
* (so subtract 1)
* (so subtract 1)
* If to a range, add one.
* If to a single IP address, set to 1.
*/
@ -641,7 +644,8 @@ int mode;
sizeof(fr_nat_lock));
if (!error)
fr_nat_lock = arg;
}
} else
error = EFAULT;
break;
case SIOCSTPUT :
if (fr_nat_lock)
@ -666,6 +670,8 @@ int mode;
MUTEX_DOWNGRADE(&ipf_nat);
error = IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data,
sizeof(iplused[IPL_LOGNAT]));
if (error)
error = EFAULT;
#endif
break;
default :
@ -732,7 +738,7 @@ caddr_t data;
static int fr_natgetent(data)
caddr_t data;
{
nat_save_t ipn, *ipnp, *ipnn;
nat_save_t ipn, *ipnp, *ipnn = NULL;
register nat_t *n, *nat;
ap_session_t *aps;
int error;
@ -785,33 +791,33 @@ caddr_t data;
ipn.ipn_dsize += aps->aps_psiz;
KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
if (ipnn == NULL)
return NULL;
return ENOMEM;
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
bcopy((char *)aps, ipn.ipn_data, sizeof(*aps));
bcopy((char *)aps, ipnn->ipn_data, sizeof(*aps));
if (aps->aps_data) {
bcopy(aps->aps_data, ipn.ipn_data + sizeof(*aps),
bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
aps->aps_psiz);
ipn.ipn_dsize += aps->aps_psiz;
ipnn->ipn_dsize += aps->aps_psiz;
}
error = IWCOPY((caddr_t)ipnn, ipnp,
sizeof(ipn) + ipn.ipn_dsize);
if (error)
return EFAULT;
error = EFAULT;
KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
} else {
error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
if (error)
return EFAULT;
error = EFAULT;
}
return 0;
return error;
}
static int fr_natputent(data)
caddr_t data;
{
nat_save_t ipn, *ipnp, *ipnn;
nat_save_t ipn, *ipnp, *ipnn = NULL;
register nat_t *n, *nat;
ap_session_t *aps;
frentry_t *fr;
@ -825,6 +831,7 @@ caddr_t data;
error = IRCOPY((caddr_t)ipnp, (caddr_t)&ipn, sizeof(ipn));
if (error)
return EFAULT;
nat = NULL;
if (ipn.ipn_dsize) {
KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
if (ipnn == NULL)
@ -832,14 +839,18 @@ caddr_t data;
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
ipn.ipn_dsize);
if (error)
return EFAULT;
if (error) {
error = EFAULT;
goto junkput;
}
} else
ipnn = NULL;
KMALLOC(nat, nat_t *);
if (nat == NULL)
return ENOMEM;
if (nat == NULL) {
error = EFAULT;
goto junkput;
}
bcopy((char *)&ipn.ipn_nat, (char *)nat, sizeof(*nat));
/*
@ -1458,7 +1469,7 @@ int dir;
icmphdr_t *icmp;
tcphdr_t *tcp = NULL;
ip_t *oip;
int flags = 0, type;
int flags = 0, type, minlen;
icmp = (icmphdr_t *)fin->fin_dp;
/*
@ -1478,13 +1489,45 @@ int dir;
return NULL;
oip = (ip_t *)((char *)fin->fin_dp + 8);
if (ip->ip_len < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2))
minlen = (oip->ip_hl << 2);
if (minlen < sizeof(ip_t))
return NULL;
if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
return NULL;
/*
* Is the buffer big enough for all of it ? It's the size of the IP
* header claimed in the encapsulated part which is of concern. It
* may be too big to be in this buffer but not so big that it's
* outside the ICMP packet, leading to TCP deref's causing problems.
* This is possible because we don't know how big oip_hl is when we
* do the pullup early in fr_check() and thus can't gaurantee it is
* all here now.
*/
#ifdef _KERNEL
{
mb_t *m;
# if SOLARIS
m = fin->fin_qfm;
if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr)
return NULL;
# else
m = *(mb_t **)fin->fin_mp;
if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN >
(char *)ip + m->m_len)
return NULL;
# endif
}
#endif
if (oip->ip_p == IPPROTO_TCP)
flags = IPN_TCP;
else if (oip->ip_p == IPPROTO_UDP)
flags = IPN_UDP;
if (flags & IPN_TCPUDP) {
minlen += 8; /* + 64bits of data to get ports */
if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
return NULL;
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
if (dir == NAT_INBOUND)
return nat_inlookup(fin->fin_ifp, flags,
@ -1576,7 +1619,10 @@ int dir;
if ((flags & IPN_TCPUDP) != 0) {
tcphdr_t *tcp;
/* XXX - what if this is bogus hl and we go off the end ? */
/*
* XXX - what if this is bogus hl and we go off the end ?
* In this case, nat_icmpinlookup() will have returned NULL.
*/
tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
if (nat->nat_dir == NAT_OUTBOUND) {

View File

@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.3 2000/07/08 02:20:14 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.6 2000/08/07 12:36:19 darrenr Exp $";
#endif
#include <sys/types.h>
@ -50,6 +50,7 @@ static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.3 2000/07/08 02:20:14 d
#include "ip_nat.h"
#include "ip_frag.h"
#include "ip_auth.h"
#include "ip_proxy.h"
#include <inet/ip_ire.h>
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@ -64,6 +65,7 @@ u_long ipl_frouteok[2] = {0, 0};
static int frzerostats __P((caddr_t));
static int frrequest __P((minor_t, int, caddr_t, int));
static int send_ip __P((fr_info_t *fin, mblk_t *m));
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;
@ -148,7 +150,7 @@ caddr_t data;
fr_getstat(&fio);
error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
if (error)
return EFAULT;
return error;
bzero((char *)frstats, sizeof(*frstats) * 2);
@ -227,6 +229,8 @@ int *rp;
case SIOCGETFF :
error = IWCOPY((caddr_t)&fr_flags, (caddr_t)data,
sizeof(fr_flags));
if (error)
error = EFAULT;
break;
case SIOCINAFR :
case SIOCRMAFR :
@ -254,6 +258,8 @@ int *rp;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
error = IWCOPY((caddr_t)&fr_active, (caddr_t)data,
sizeof(fr_active));
if (error)
error = EFAULT;
fr_active = 1 - fr_active;
RWLOCK_EXIT(&ipf_mutex);
}
@ -286,6 +292,8 @@ int *rp;
tmp = frflush(unit, tmp);
error = IWCOPY((caddr_t)&tmp, (caddr_t)data,
sizeof(tmp));
if (error)
error = EFAULT;
}
}
break;
@ -307,6 +315,8 @@ int *rp;
tmp = ipflog_clear(unit);
error = IWCOPY((caddr_t)&tmp, (caddr_t)data,
sizeof(tmp));
if (error)
error = EFAULT;
}
break;
#endif /* IPFILTER_LOG */
@ -319,8 +329,6 @@ int *rp;
case SIOCGFRST :
error = IWCOPYPTR((caddr_t)ipfr_fragstats(), (caddr_t)data,
sizeof(ipfrstat_t));
if (error)
error = EFAULT;
break;
case FIONREAD :
{
@ -328,6 +336,8 @@ int *rp;
int copy = (int)iplused[IPL_LOGIPF];
error = IWCOPY((caddr_t)&copy, (caddr_t)data, sizeof(copy));
if (error)
error = EFAULT;
#endif
break;
}
@ -533,10 +543,8 @@ caddr_t data;
}
MUTEX_DOWNGRADE(&ipf_mutex);
error = IWCOPYPTR((caddr_t)f, data, sizeof(*f));
if (error) {
error = EFAULT;
if (error)
goto out;
}
f->fr_hits = 0;
f->fr_bytes = 0;
goto out;
@ -741,7 +749,7 @@ fr_info_t *fin;
}
int send_ip(fin, m)
int static send_ip(fin, m)
fr_info_t *fin;
mblk_t *m;
{
@ -749,6 +757,7 @@ mblk_t *m;
RWLOCK_EXIT(&ipf_solaris);
#ifdef USE_INET6
if (fin->fin_v == 6) {
extern void ip_wput_v6 __P((queue_t *, mblk_t *));
ip6_t *ip6;
ip6 = (ip6_t *)m->b_rptr;

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.12 2000/06/19 02:38:37 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.17 2000/08/08 16:01:03 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -180,7 +180,7 @@ static ips_stat_t *fr_statetstats()
* flush state tables. two actions currently defined:
* which == 0 : flush all state table entries
* which == 1 : flush TCP connections which have started to close but are
* stuck for some reason.
* stuck for some reason.
*/
static int fr_state_flush(which)
int which;
@ -371,8 +371,8 @@ caddr_t data;
sizeof(ips.ips_fr));
error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
if (error)
return EFAULT;
return 0;
error = EFAULT;
return error;
}
@ -477,6 +477,7 @@ register ipstate_t *is;
is->is_phnext = ips_table + hv;
is->is_hnext = ips_table[hv];
ips_table[hv] = is;
ips_num++;
}
@ -557,7 +558,6 @@ u_int flags;
case ND_NEIGHBOR_SOLICIT :
is->is_icmp.ics_type = ic->icmp_type + 1;
break;
break;
#endif
case ICMP_ECHO :
case ICMP_TSTAMP :
@ -669,11 +669,10 @@ u_int flags;
if (pass & FR_LOGFIRST)
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
fr_stinsert(is);
ips_num++;
if (is->is_p == IPPROTO_TCP) {
MUTEX_ENTER(&is->is_lock);
fr_tcp_age(&is->is_age, is->is_state, fin,
tcp->th_sport == is->is_sport);
0); /* 0 = packet from the source */
MUTEX_EXIT(&is->is_lock);
}
#ifdef IPFILTER_LOG
@ -785,7 +784,8 @@ tcphdr_t *tcp;
* Nearing end of connection, start timeout.
*/
MUTEX_ENTER(&is->is_lock);
fr_tcp_age(&is->is_age, is->is_state, fin, source);
/* source ? 0 : 1 -> !source */
fr_tcp_age(&is->is_age, is->is_state, fin, !source);
MUTEX_EXIT(&is->is_lock);
ret = 1;
}
@ -970,12 +970,12 @@ fr_info_t *fin;
union i6addr dst, src;
struct icmp *ic;
u_short savelen;
fr_info_t ofin;
tcphdr_t *tcp;
icmphdr_t *icmp;
fr_info_t ofin;
int type, len;
tcphdr_t *tcp;
frentry_t *fr;
ip_t *oip;
int type;
u_int hv;
/*
@ -1000,6 +1000,46 @@ fr_info_t *fin;
if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2))
return NULL;
/*
* Sanity checks.
*/
len = fin->fin_dlen - ICMPERR_ICMPHLEN;
if ((len <= 0) || ((oip->ip_hl << 2) > len))
return NULL;
/*
* Is the buffer big enough for all of it ? It's the size of the IP
* header claimed in the encapsulated part which is of concern. It
* may be too big to be in this buffer but not so big that it's
* outside the ICMP packet, leading to TCP deref's causing problems.
* This is possible because we don't know how big oip_hl is when we
* do the pullup early in fr_check() and thus can't gaurantee it is
* all here now.
*/
#ifdef _KERNEL
{
mb_t *m;
# if SOLARIS
m = fin->fin_qfm;
if ((char *)oip + len > (char *)m->b_wptr)
return NULL;
# else
m = *(mb_t **)fin->fin_mp;
if ((char *)oip + len > (char *)ip + m->m_len)
return NULL;
# endif
}
#endif
/*
* in the IPv4 case we must zero the i6addr union otherwise
* the IP6EQ and IP6NEQ macros produce the wrong results because
* of the 'junk' in the unused part of the union
*/
bzero(&src, sizeof(src));
bzero(&dst, sizeof(dst));
if (oip->ip_p == IPPROTO_ICMP) {
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
@ -1028,9 +1068,11 @@ fr_info_t *fin;
hv += icmp->icmp_seq;
hv %= fr_statesize;
oip->ip_len = ntohs(oip->ip_len);
savelen = oip->ip_len;
oip->ip_len = len;
ofin.fin_v = 4;
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
oip->ip_len = htons(oip->ip_len);
oip->ip_len = savelen;
ofin.fin_ifp = fin->fin_ifp;
ofin.fin_out = !fin->fin_out;
ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
@ -1077,7 +1119,8 @@ fr_info_t *fin;
* order. Any change we make must be undone afterwards.
*/
savelen = oip->ip_len;
oip->ip_len = ip->ip_len - (ip->ip_hl << 2) - ICMPERR_ICMPHLEN;
oip->ip_len = len;
ofin.fin_v = 4;
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
oip->ip_len = savelen;
ofin.fin_ifp = fin->fin_ifp;
@ -1198,7 +1241,15 @@ fr_info_t *fin;
case IPPROTO_TCP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
register int i;
i = tcp->th_flags;
/*
* Just plain ignore RST flag set with either FIN or SYN.
*/
if ((i & TH_RST) &&
((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
break;
tryagain = 0;
retry_tcp:
hvm = hv % fr_statesize;
@ -1384,6 +1435,27 @@ void fr_timeoutstate()
/*
* Original idea freom Pradeep Krishnan for use primarily with NAT code.
* (pkrishna@netcom.com)
*
* Rewritten by Arjan de Vet <Arjan.deVet@adv.iae.nl>, 2000-07-29:
*
* - (try to) base state transitions on real evidence only,
* i.e. packets that are sent and have been received by ipfilter;
* diagram 18.12 of TCP/IP volume 1 by W. Richard Stevens was used.
*
* - deal with half-closed connections correctly;
*
* - store the state of the source in state[0] such that ipfstat
* displays the state as source/dest instead of dest/source; the calls
* to fr_tcp_age have been changed accordingly.
*
* Parameters:
*
* state[0] = state of source (host that initiated connection)
* state[1] = state of dest (host that accepted the connection)
*
* dir == 0 : a packet from source to dest
* dir == 1 : a packet from dest to source
*
*/
void fr_tcp_age(age, state, fin, dir)
u_long *age;
@ -1410,68 +1482,193 @@ int dir;
return;
}
*age = fr_tcptimeout; /* 1 min */
*age = fr_tcptimeout; /* default 4 mins */
switch(state[dir])
{
case TCPS_CLOSED:
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
}
case TCPS_FIN_WAIT_2:
if ((flags & TH_OPENING) == TH_OPENING)
case TCPS_CLOSED: /* 0 */
if ((flags & TH_OPENING) == TH_OPENING) {
/*
* 'dir' received an S and sends SA in response,
* CLOSED -> SYN_RECEIVED
*/
state[dir] = TCPS_SYN_RECEIVED;
else if (flags & TH_SYN)
*age = fr_tcptimeout;
} else if ((flags & (TH_SYN|TH_ACK)) == TH_SYN) {
/* 'dir' sent S, CLOSED -> SYN_SENT */
state[dir] = TCPS_SYN_SENT;
break;
case TCPS_SYN_RECEIVED:
case TCPS_SYN_SENT:
if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) {
*age = fr_tcptimeout;
}
/*
* The next piece of code makes it possible to get
* already established connections into the state table
* after a restart or reload of the filter rules; this
* does not work when a strict 'flags S keep state' is
* used for tcp connections of course
*/
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
} else if ((flags & (TH_FIN|TH_ACK)) == (TH_FIN|TH_ACK)) {
state[dir] = TCPS_CLOSE_WAIT;
if (!(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED)
*age = fr_tcplastack;
else
*age = fr_tcpclosewait;
}
/*
* TODO: besides regular ACK packets we can have other
* packets as well; it is yet to be determined how we
* should initialize the states in those cases
*/
break;
case TCPS_LISTEN: /* 1 */
/* NOT USED */
break;
case TCPS_SYN_SENT: /* 2 */
if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
/*
* We see an A from 'dir' which is in SYN_SENT
* state: 'dir' sent an A in response to an SA
* which it received, SYN_SENT -> ESTABLISHED
*/
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
} else if (flags & TH_FIN) {
/*
* We see an F from 'dir' which is in SYN_SENT
* state and wants to close its side of the
* connection; SYN_SENT -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout; /* or fr_tcptimeout? */
} else if ((flags & TH_OPENING) == TH_OPENING) {
/*
* We see an SA from 'dir' which is already in
* SYN_SENT state, this means we have a
* simultaneous open; SYN_SENT -> SYN_RECEIVED
*/
state[dir] = TCPS_SYN_RECEIVED;
*age = fr_tcptimeout;
}
break;
case TCPS_ESTABLISHED:
case TCPS_SYN_RECEIVED: /* 3 */
if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
/*
* We see an A from 'dir' which was in SYN_RECEIVED
* state so it must now be in established state,
* SYN_RECEIVED -> ESTABLISHED
*/
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
} else if (flags & TH_FIN) {
/*
* We see an F from 'dir' which is in SYN_RECEIVED
* state and wants to close its side of the connection;
* SYN_RECEIVED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout; /* or fr_tcptimeout? */
}
break;
case TCPS_ESTABLISHED: /* 4 */
if (flags & TH_FIN) {
state[dir] = TCPS_CLOSE_WAIT;
if (!(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED)
*age = fr_tcplastack;
else
*age = fr_tcpclosewait;
} else {
if (ostate < TCPS_CLOSE_WAIT)
/*
* 'dir' closed its side of the connection; this
* gives us a half-closed connection;
* ESTABLISHED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout;
} else if (flags & TH_ACK) {
/* an ACK, should we exclude other flags here? */
if (ostate == TCPS_FIN_WAIT_1) {
/*
* We know the other side did an active close,
* so we are ACKing the recvd FIN packet (does
* the window matching code guarantee this?)
* and go into CLOSE_WAIT state; this gives us
* a half-closed connection
*/
state[dir] = TCPS_CLOSE_WAIT;
*age = fr_tcpidletimeout;
} else if (ostate < TCPS_CLOSE_WAIT)
/*
* Still a fully established connection,
* reset timeout
*/
*age = fr_tcpidletimeout;
}
break;
case TCPS_CLOSE_WAIT:
if ((flags & TH_FIN) && !(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED) {
case TCPS_CLOSE_WAIT: /* 5 */
if (flags & TH_FIN) {
/*
* Application closed and 'dir' sent a FIN, we're now
* going into LAST_ACK state
*/
*age = fr_tcplastack;
state[dir] = TCPS_LAST_ACK;
} else
*age = fr_tcpclosewait;
break;
case TCPS_LAST_ACK:
if (flags & TH_ACK) {
state[dir] = TCPS_FIN_WAIT_2;
if (!(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED)
*age = fr_tcplastack;
else {
*age = fr_tcpclosewait;
state[dir] = TCPS_CLOSE_WAIT;
}
} else {
/*
* We remain in CLOSE_WAIT because the other side has
* closed already and we did not close our side yet;
* reset timeout
*/
*age = fr_tcpidletimeout;
}
break;
case TCPS_FIN_WAIT_1: /* 6 */
if ((flags & TH_ACK) && ostate > TCPS_CLOSE_WAIT) {
/*
* If the other side is not active anymore it has sent
* us a FIN packet that we are ack'ing now with an ACK;
* this means both sides have now closed the connection
* and we go into TIME_WAIT
*/
/*
* XXX: how do we know we really are ACKing the FIN
* packet here? does the window code guarantee that?
*/
state[dir] = TCPS_TIME_WAIT;
*age = fr_tcptimeout;
} else
/*
* We closed our side of the connection already but the
* other side is still active (ESTABLISHED/CLOSE_WAIT);
* continue with this half-closed connection
*/
*age = fr_tcpidletimeout;
break;
case TCPS_CLOSING: /* 7 */
/* NOT USED */
break;
case TCPS_LAST_ACK: /* 8 */
if (flags & TH_ACK) {
if ((flags & TH_PUSH) || dlen)
/*
* There is still data to be delivered, reset
* timeout
*/
*age = fr_tcplastack;
}
/*
* We cannot detect when we go out of LAST_ACK state to CLOSED
* because that is based on the reception of ACK packets;
* ipfilter can only detect that a packet has been sent by a
* host
*/
break;
case TCPS_FIN_WAIT_2: /* 9 */
/* NOT USED */
break;
case TCPS_TIME_WAIT: /* 10 */
/* we're in 2MSL timeout now */
break;
}
}
@ -1579,6 +1776,7 @@ fr_info_t *fin;
hv %= fr_statesize;
oip->ip6_plen = ntohs(oip->ip6_plen);
ofin.fin_v = 6;
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
oip->ip6_plen = htons(oip->ip6_plen);
ofin.fin_ifp = fin->fin_ifp;

View File

@ -43,7 +43,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.1 2000/07/08 02:19:46 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.3 2000/08/07 14:54:05 darrenr Exp $";
#endif
#if SOLARIS
@ -558,13 +558,21 @@ static void showversion()
struct friostat *fiop=&fio;
u_32_t flags;
char *s;
int vfd;
printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fiop)) {
perror("ioctl(SIOCGETFS");
if ((vfd = open(ipfname, O_RDONLY)) == -1) {
perror("open device");
return;
}
if (ioctl(vfd, SIOCGETFS, &fiop)) {
perror("ioctl(SIOCGETFS");
close(vfd);
return;
}
close(vfd);
flags = get_flags();
printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),

View File

@ -6,12 +6,12 @@
* to the original author and the contributors.
*
* @(#)ipl.h 1.21 6/5/96
* $Id: ipl.h,v 2.15.2.9 2000/07/19 13:40:04 darrenr Exp $
* $Id: ipl.h,v 2.15.2.10 2000/08/07 15:10:09 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.4.8"
#define IPL_VERSION "IP Filter: v3.4.9"
#endif

View File

@ -57,7 +57,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.2 2000/05/15 06:54:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.3 2000/07/27 13:07:13 darrenr Exp $";
#endif
@ -111,7 +111,7 @@ int argc;
char *argv[];
{
char *file = NULL;
int fd = -1, opts = 0, c;
int fd = -1, opts = 0, c, mode = O_RDWR;
while ((c = getopt(argc, argv, "CdFf:hlnrsv")) != -1)
switch (c)
@ -133,15 +133,18 @@ char *argv[];
break;
case 'l' :
opts |= OPT_LIST;
mode = O_RDONLY;
break;
case 'n' :
opts |= OPT_NODO;
mode = O_RDONLY;
break;
case 'r' :
opts |= OPT_REMOVE;
break;
case 's' :
opts |= OPT_STAT;
mode = O_RDONLY;
break;
case 'v' :
opts |= OPT_VERBOSE;
@ -153,7 +156,7 @@ char *argv[];
gethostname(thishost, sizeof(thishost));
thishost[sizeof(thishost) - 1] = '\0';
if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, O_RDWR)) == -1) &&
if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, mode)) == -1) &&
((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
(void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
STRERROR(errno));

View File

@ -96,7 +96,7 @@ Set the protocol to TCP.
.B \-U
Set the protocol to UDP.
.TP
.BR \-d
.BR \-v
enable verbose mode.
.DT
.SH SEE ALSO

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mlfk_ipl.c,v 2.1.2.1 2000/04/26 12:17:24 darrenr Exp $
* $Id: mlfk_ipl.c,v 2.1.2.3 2000/08/13 03:42:42 darrenr Exp $
*/
@ -37,6 +37,7 @@
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ipl.h>
@ -82,6 +83,7 @@ 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, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
#define CDEV_MAJOR 79
static struct cdevsw ipl_cdevsw = {

View File

@ -0,0 +1 @@
#define INET6

View File

@ -320,8 +320,7 @@ while (defined ($_ = shift))
defined ($arg) || &usage (1, qq{-$flag requires an argument});
if ($flag eq 's')
{
defined ($services) && &usage (1, qq{too many service maps}
);
defined ($services) && &usage (1, qq{too many service maps});
$services = $arg;
}
elsif ($flag eq 'A')
@ -433,8 +432,7 @@ while (<STDIN>)
# dd/mm/yyyy (no y2k problem here!). Both formats then have a packet
# timestamp and the log info.
my ($log);
if (s/^\w+\s+\d+\s+\d+:\d+:\d+\s+(?:\d\w:)?[\w\.\-]+\s+\S*ipmon\[\d+\]:\s+(
?:\[ID\s+\d+\s+[\w\.]+\]\s+)?\d+:\d+:\d+\.\d+\s+//)
if (s/^\w+\s+\d+\s+\d+:\d+:\d+\s+(?:\d\w:)?[\w\.\-]+\s+\S*ipmon\[\d+\]:\s+(?:\[ID\s+\d+\s+[\w\.]+\]\s+)?\d+:\d+:\d+\.\d+\s+//)
{
$log = $_;
}
@ -457,15 +455,13 @@ while (<STDIN>)
# number, "PR", a protocol name or number, "len", a header length, a
# packet length (which will be in parentheses for protocols other than
# TCP, UDP, or ICMP), and maybe some additional info.
my @fields = ($log =~ /^(?:(\d+)x)?\s*(\w+)\s+@(\d+):(\d+)\s+(\w)\s+([\w\-\
..,]+)\s+->\s+([\w\-\.,]+)\s+PR\s+(\w+)\s+len\s+(\d+)\s+\(?(\d+)\)?\s*(.*)$/ox);
my @fields = ($log =~ /^(?:(\d+)x)?\s*(\w+)\s+@(\d+):(\d+)\s+(\w)\s+([\w\-\..,]+)\s+->\s+([\w\-\.,]+)\s+PR\s+(\w+)\s+len\s+(\d+)\s+\(?(\d+)\)?\s*(.*)$/ox);
unless (scalar (@fields))
{
print STDERR "$me:$.: cannot parse: $_\n";
next;
}
my ($count, $if, $group, $rule, $act, $src, $dest, $proto, $hlen, $len, $mo
re) = @fields;
my ($count, $if, $group, $rule, $act, $src, $dest, $proto, $hlen, $len, $more) = @fields;
# Skip actions we're not interested in.
next unless (exists ($selectActs{$act}));
@ -530,8 +526,7 @@ re) = @fields;
$dest = $x;
# Skip hosts we're not interested in.
next if ($selectHosts && !(exists ($selectHosts{$src}) || exists ($selectHo
sts{$dest})));
next if ($selectHosts && !(exists ($selectHosts{$src}) || exists ($selectHosts{$dest})));
# Convert proto to proto number.
$proto = &protoNumber ($proto);
@ -566,12 +561,10 @@ sts{$dest})));
}
# Count the packet as outgoing traffic from the source address.
&countPacket ($src, 's', $dest, $proto, $count, "$sport:$dport:$if:$act") i
f ($sTable);
&countPacket ($src, 's', $dest, $proto, $count, "$sport:$dport:$if:$act") if ($sTable);
# Count the packet as incoming traffic to the destination address.
&countPacket ($dest, 'd', $src, $proto, $count, "$dport:$sport:$if:$act") i
f ($dTable);
&countPacket ($dest, 'd', $src, $proto, $count, "$dport:$sport:$if:$act") if ($dTable);
}
my $dir;
@ -588,16 +581,14 @@ foreach $dir (@dirs)
{
my @a = split (/\./, $a);
my @b = split (/\./, $b);
$a[0] <=> $b[0] || $a[1] <=> $b[1] || $a[2] <=> $b[2] || $a[3] <=> $b[3
];
$a[0] <=> $b[0] || $a[1] <=> $b[1] || $a[2] <=> $b[2] || $a[3] <=> $b[3];
}
sub packetSort
{
my ($asport, $adport, $aif, $aact) = split (/:/, $a);
my ($bsport, $bdport, $bif, $bact) = split (/:/, $b);
$bact cmp $aact || $aif cmp $bif || $asport <=> $bsport || $adport <=>
$bdport;
$bact cmp $aact || $aif cmp $bif || $asport <=> $bsport || $adport <=> $bdport;
}
my $host;
@ -636,19 +627,15 @@ $bdport;
$act = '?' unless (defined ($act = $acts{$act}));
if (($protoName eq 'tcp') || ($protoName eq 'udp'))
{
printf (" %-6s %7s %4d %4s %16s %2s %s.%s\n", $if, $
act, $count, $protoName, &portName ($sport, $protoName), $arrow, $peerName, &po
rtName ($dport, $protoName));
printf (" %-6s %7s %4d %4s %16s %2s %s.%s\n", $if, $act, $count, $protoName, &portName ($sport, $protoName), $arrow, $peerName, &portName ($dport, $protoName));
}
elsif ($protoName eq 'icmp')
{
printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act
, $count, $protoName, &icmpType ($sport), $arrow, $peerName);
printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act, $count, $protoName, &icmpType ($sport), $arrow, $peerName);
}
else
{
printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act
, $count, $protoName, '', $arrow, $peerName);
printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act, $count, $protoName, '', $arrow, $peerName);
}
}
}
@ -672,8 +659,7 @@ sub portName
unless (exists ($pn{$pname}))
{
my $name = getservbyport ($port, $proto);
$pn{$pname} = (defined ($name) ? $name : ($port <= 1023 ? $port : '<hig
h>'));
$pn{$pname} = (defined ($name) ? $name : ($port <= 1023 ? $port : '<high>'));
}
return $pn{$pname};
}

View File

@ -6,7 +6,7 @@
* 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.15.2.6 2000/07/18 13:56:33 darrenr Exp $"
#pragma ident "@(#)$Id: solaris.c,v 2.15.2.7 2000/08/05 14:50:30 darrenr Exp $"
#include <sys/systm.h>
#include <sys/types.h>
@ -51,6 +51,7 @@
#include "ipl.h"
#include "ip_fil.h"
#include "ip_nat.h"
#include "ip_state.h"
char _depends_on[] = "drv/ip";
@ -683,7 +684,7 @@ int out;
s = m->b_rptr;
}
*mp = m2;
MTYPE(m2) = MTYPE(mt);
MTYPE(m2) = M_DATA;
freemsg(mt);
mt = m2;