Resolve conflicts from the import.

This commit is contained in:
veego 1998-07-12 15:23:59 +00:00
parent 6f2f0bef2f
commit 97ab1bd53b
10 changed files with 342 additions and 225 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fil.c,v 1.22 1998/05/31 19:39:13 cgd Exp $ */
/* $NetBSD: fil.c,v 1.23 1998/07/12 15:23:59 veego Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
@ -9,7 +9,7 @@
*/
#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 ";
static const char rcsid[] = "@(#)Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 darrenr Exp ";
#endif
#include <sys/errno.h>
@ -78,7 +78,7 @@ extern int opts;
# 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)
# 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
@ -90,9 +90,15 @@ extern int opts;
# 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)
# 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)
@ -515,13 +521,14 @@ void *m;
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++;
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));
fr->fr_hits++;
ATOMIC_INC(fr->fr_hits);
if (pass & FR_ACCOUNT)
fr->fr_bytes += (U_QUAD_T)ip->ip_len;
else
@ -582,14 +589,14 @@ int out;
# endif
int up;
#ifdef M_CANFASTFWD
# 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 */
# endif /* M_CANFASTFWD */
if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
ip->ip_p == IPPROTO_ICMP)) {
@ -611,41 +618,44 @@ int out;
up = MIN(hlen + plen, ip->ip_len);
if (up > m->m_len) {
#ifdef __sgi /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
# ifdef __sgi
/* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
frstats[out].fr_pull[1]++;
ATOMIC_INC(frstats[out].fr_pull[1]);
return -1;
}
m_copydata(m, 0, up, hbuf);
frstats[out].fr_pull[0]++;
ATOMIC_INC(frstats[out].fr_pull[0]);
ip = (ip_t *)hbuf;
#else
# ifndef linux
# else /* __ sgi */
# ifndef linux
if ((*mp = m_pullup(m, up)) == 0) {
frstats[out].fr_pull[1]++;
ATOMIC_INC(frstats[out].fr_pull[1]);
return -1;
} else {
frstats[out].fr_pull[0]++;
ATOMIC_INC(frstats[out].fr_pull[0]);
m = *mp;
ip = mtod(m, ip_t *);
}
# endif
#endif
# endif /* !linux */
# endif /* __sgi */
} else
up = 0;
} else
up = 0;
# endif
# endif /* !defined(__SVR4) && !defined(__svr4__) */
# if SOLARIS
mb_t *m = qif->qf_m;
fin->fin_qfm = m;
# endif
#endif
#endif /* _KERNEL */
fr_makefrip(hlen, ip, fin);
fin->fin_ifp = ifp;
fin->fin_out = out;
fin->fin_mp = mp;
MUTEX_ENTER(&ipf_mutex);
READ_ENTER(&ipf_mutex);
/*
* Check auth now. This, combined with the check below to see if apass
@ -659,8 +669,9 @@ int out;
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++;
(FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
ATOMIC_INC(frstats[0].fr_acct);
}
}
if (apass || (!(pass = ipfr_knownfrag(ip, fin)) &&
@ -678,9 +689,9 @@ int out;
* earlier.
*/
bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
frstats[out].fr_chit++;
ATOMIC_INC(frstats[out].fr_chit);
if ((fr = fin->fin_fr)) {
fr->fr_hits++;
ATOMIC_INC(fr->fr_hits);
pass = fr->fr_flags;
} else
pass = fr_pass;
@ -689,8 +700,9 @@ int out;
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++;
if (pass & FR_NOMATCH) {
ATOMIC_INC(frstats[out].fr_nom);
}
}
fr = fin->fin_fr;
} else
@ -710,29 +722,33 @@ int out;
#endif
if (pass & FR_PREAUTH) {
MUTEX_ENTER(&ipf_auth);
READ_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);
(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)
frstats[out].fr_bnfr++;
else
frstats[out].fr_nfr++;
} else
frstats[out].fr_cfr++;
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)
frstats[out].fr_bads++;
else
frstats[out].fr_ads++;
if (fr_addstate(ip, fin, pass) == -1) {
ATOMIC_INC(frstats[out].fr_bads);
} else {
ATOMIC_INC(frstats[out].fr_ads);
}
}
}
@ -745,34 +761,35 @@ int out;
*/
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++;
(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;
MUTEX_EXIT(&ipf_mutex);
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;
frstats[out].fr_npkl++;
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;
frstats[out].fr_ppkl++;
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;
frstats[out].fr_bpkl++;
ATOMIC_INC(frstats[out].fr_bpkl);
logit:
if (!IPLLOG(pass, ip, fin, m)) {
frstats[out].fr_skip++;
ATOMIC_INC(frstats[out].fr_skip);
if ((pass & (FR_PASS|FR_LOGORBLOCK)) ==
(FR_PASS|FR_LOGORBLOCK))
pass ^= FR_PASS|FR_BLOCK;
@ -797,10 +814,10 @@ logit:
# endif
# endif
#endif
if (pass & FR_PASS)
frstats[out].fr_pass++;
else if (pass & FR_BLOCK) {
frstats[out].fr_block++;
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 ?
@ -821,20 +838,21 @@ logit:
m = *mp = NULL; /* freed by icmp_error() */
# endif
frstats[0].fr_ret++;
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)
frstats[1].fr_ret++;
if (SEND_RESET(ip, qif, ifp) == 0) {
ATOMIC_INC(frstats[1].fr_ret);
}
}
#else
if (pass & FR_RETICMP) {
verbose("- ICMP unreachable sent\n");
frstats[0].fr_ret++;
ATOMIC_INC(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++;
ATOMIC_INC(frstats[1].fr_ret);
}
#endif
} else {
@ -946,13 +964,6 @@ int len;
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
*/
@ -1093,7 +1104,7 @@ nodata:
* 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
* 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,
@ -1298,6 +1309,7 @@ int *result;
{
int flags = *result, flushed = 0, set = fr_active;
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (flags & FR_INACTIVE)
@ -1319,6 +1331,6 @@ int *result;
ipacct[0][set], &ipacct[0][set]);
}
}
RWLOCK_EXIT(&ipf_mutex);
*result = flushed;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_auth.c,v 1.7 1998/05/17 17:07:25 veego Exp $ */
/* $NetBSD: ip_auth.c,v 1.8 1998/07/12 15:23:59 veego Exp $ */
/*
* Copyright (C) 1997 by Darren Reed & Guido van Rooij.
@ -8,7 +8,7 @@
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:29 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.0.2.21.2.5 1998/06/13 13:40:49 darrenr Exp ";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@ -95,7 +95,8 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_auth;
extern krwlock_t ipf_auth;
extern kmutex_t ipf_authmx;
# if SOLARIS
extern kcondvar_t ipfauthwait;
# endif
@ -128,7 +129,7 @@ fr_info_t *fin;
u_32_t pass;
int i;
MUTEX_ENTER(&ipf_auth);
READ_ENTER(&ipf_auth);
for (i = fr_authstart; i != fr_authend; ) {
/*
* index becomes -2 only after an SIOCAUTHW. Check this in
@ -143,6 +144,8 @@ fr_info_t *fin;
*/
if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH))
pass = FR_BLOCK;
RWLOCK_EXIT(&ipf_auth);
WRITE_ENTER(&ipf_auth);
fr_authstats.fas_hits++;
fr_auth[i].fra_index = -1;
fr_authused--;
@ -160,7 +163,7 @@ fr_info_t *fin;
fr_authstart = fr_authend = 0;
}
}
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return pass;
}
i++;
@ -168,7 +171,7 @@ fr_info_t *fin;
i = 0;
}
fr_authstats.fas_miss++;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
@ -191,15 +194,15 @@ ip_t *ip;
{
int i;
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) {
fr_authstats.fas_nospace++;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
if (fr_authend - fr_authstart == FR_NUMAUTH - 1) {
fr_authstats.fas_nospace++;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
@ -208,7 +211,7 @@ ip_t *ip;
i = fr_authend++;
if (fr_authend == FR_NUMAUTH)
fr_authend = 0;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
fr_auth[i].fra_index = i;
fr_auth[i].fra_pass = 0;
fr_auth[i].fra_age = fr_defaultauthage;
@ -290,8 +293,10 @@ frentry_t *fr, **frptr;
if (!fae)
error = ESRCH;
else {
WRITE_ENTER(&ipf_auth);
*faep = fae->fae_next;
*frptr = fr->fr_next;
RWLOCK_EXIT(&ipf_auth);
KFREE(fae);
}
} else {
@ -299,6 +304,7 @@ frentry_t *fr, **frptr;
if (fae != NULL) {
IRCOPY((char *)data, (char *)&fae->fae_fr,
sizeof(fae->fae_fr));
WRITE_ENTER(&ipf_auth);
if (!fae->fae_age)
fae->fae_age = fr_defaultauthage;
fae->fae_fr.fr_hits = 0;
@ -306,6 +312,7 @@ frentry_t *fr, **frptr;
*frptr = &fae->fae_fr;
fae->fae_next = *faep;
*faep = fae;
RWLOCK_EXIT(&ipf_auth);
} else
error = ENOMEM;
}
@ -315,21 +322,26 @@ frentry_t *fr, **frptr;
break;
case SIOCAUTHW:
fr_authioctlloop:
MUTEX_ENTER(&ipf_auth);
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
IWCOPY((char *)&fr_auth[fr_authnext++], data,
IWCOPY((char *)&fr_auth[fr_authnext], data,
sizeof(fr_info_t));
RWLOCK_EXIT(&ipf_auth);
WRITE_ENTER(&ipf_auth);
fr_authnext++;
if (fr_authnext == FR_NUMAUTH)
fr_authnext = 0;
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
#ifdef _KERNEL
# if SOLARIS
if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) {
mutex_exit(&ipf_auth);
mutex_enter(&ipf_authmx);
if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) {
mutex_exit(&ipf_authmx);
return EINTR;
}
mutex_exit(&ipf_authmx);
# else
# ifdef linux
interruptible_sleep_on(&ipfauthwait);
@ -340,17 +352,17 @@ fr_authioctlloop:
# endif
# endif
#endif
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
if (!error)
goto fr_authioctlloop;
break;
case SIOCAUTHR:
IRCOPY(data, (caddr_t)&auth, sizeof(auth));
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
i = au->fra_index;
if ((i < 0) || (i > FR_NUMAUTH) ||
(fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) {
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
return EINVAL;
}
m = fr_authpkts[i];
@ -358,7 +370,7 @@ fr_authioctlloop:
fr_auth[i].fra_pass = au->fra_pass;
fr_authpkts[i] = NULL;
#ifdef _KERNEL
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
SPL_NET(s);
# ifndef linux
if (m && au->fra_info.fin_out) {
@ -441,7 +453,7 @@ void fr_authunload()
register frauthent_t *fae, **faep;
mb_t *m;
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
for (i = 0; i < FR_NUMAUTH; i++) {
if ((m = fr_authpkts[i])) {
FREE_MB_T(m);
@ -455,7 +467,7 @@ void fr_authunload()
*faep = fae->fae_next;
KFREE(fae);
}
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
}
@ -474,7 +486,7 @@ void fr_authexpire()
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_auth);
WRITE_ENTER(&ipf_auth);
for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
FREE_MB_T(m);
@ -493,7 +505,7 @@ void fr_authexpire()
} else
faep = &fae->fae_next;
}
MUTEX_EXIT(&ipf_auth);
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_compat.h,v 1.14 1998/05/29 20:24:36 veego Exp $ */
/* $NetBSD: ip_compat.h,v 1.15 1998/07/12 15:23:59 veego Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
@ -8,7 +8,7 @@
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* Id: ip_compat.h,v 2.0.2.31.2.11 1998/05/23 14:29:36 darrenr Exp
* Id: ip_compat.h,v 2.0.2.31.2.12 1998/06/06 14:36:38 darrenr Exp
*/
#ifndef _NETINET_IP_COMPAT_H_
@ -203,7 +203,15 @@ typedef unsigned long u_32_t;
*/
#ifdef KERNEL
# if SOLARIS
# define MUTEX_ENTER(x) mutex_enter(x)
# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
mutex_exit(&ipf_rw); }
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
mutex_exit(&ipf_rw); }
# define MUTEX_ENTER(x) mutex_enter(x)
# 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))
@ -255,10 +263,24 @@ typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
(x)--; MUTEX_EXIT(&ipf_rw); }
# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
# define 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 MUTEX_ENTER(x) ;
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# endif /* __sgi */
# ifndef linux
@ -341,7 +363,13 @@ extern vm_map_t kmem_map;
# define SLEEP(x,y) ;
# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--
# define MUTEX_ENTER(x) ;
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) ;
# define MUTEX_EXIT(x) ;
# define SPL_NET(x) ;
# define SPL_IMP(x) ;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.h,v 1.25 1998/05/29 20:24:37 veego Exp $ */
/* $NetBSD: ip_fil.h,v 1.26 1998/07/12 15:23:59 veego Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
@ -8,7 +8,7 @@
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
* Id: ip_fil.h,v 2.0.2.39.2.11 1998/05/23 14:29:37 darrenr Exp
* Id: ip_fil.h,v 2.0.2.39.2.12 1998/06/06 14:36:49 darrenr Exp
*/
#ifndef _NETINET_IP_FIL_H_
@ -116,6 +116,9 @@ typedef struct fr_info {
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;
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_frag.c,v 1.11 1997/11/14 12:47:00 mrg Exp $ */
/* $NetBSD: ip_frag.c,v 1.12 1998/07/12 15:24:00 veego Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:21 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.0.2.19.2.2 1998/06/06 14:37:02 darrenr Exp ";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@ -78,9 +78,8 @@ int ipfr_inuse = 0,
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;
extern krwlock_t ipf_frag, ipf_natfrag, ipf_nat;
extern kmutex_t ipf_rw;
#endif
@ -128,7 +127,7 @@ ipfr_t *table[];
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++;
ATOMIC_INC(ipfr_stats.ifs_exists);
return NULL;
}
@ -138,7 +137,7 @@ ipfr_t *table[];
*/
KMALLOC(fr, ipfr_t *, sizeof(*fr));
if (fr == NULL) {
ipfr_stats.ifs_nomem++;
ATOMIC_INC(ipfr_stats.ifs_nomem);
return NULL;
}
@ -159,8 +158,8 @@ ipfr_t *table[];
* 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++;
ATOMIC_INC(ipfr_stats.ifs_new);
ATOMIC_INC(ipfr_inuse);
return fr;
}
@ -172,9 +171,9 @@ int pass;
{
ipfr_t *ipf;
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
return ipf ? 0 : -1;
}
@ -187,12 +186,12 @@ nat_t *nat;
{
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_natfrag);
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
ipf->ipfr_data = nat;
nat->nat_data = ipf;
}
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
return ipf ? 0 : -1;
}
@ -259,7 +258,7 @@ ipfr_t *table[];
else
f->ipfr_off = atoff;
}
ipfr_stats.ifs_hits++;
ATOMIC_INC(ipfr_stats.ifs_hits);
return f;
}
return NULL;
@ -276,7 +275,7 @@ fr_info_t *fin;
nat_t *nat;
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf) {
nat = ipf->ipfr_data;
@ -289,7 +288,7 @@ fr_info_t *fin;
}
} else
nat = NULL;
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
return nat;
}
@ -304,10 +303,10 @@ fr_info_t *fin;
int ret;
ipfr_t *ipf;
MUTEX_ENTER(&ipf_frag);
READ_ENTER(&ipf_frag);
ipf = ipfr_lookup(ip, fin, ipfr_heads);
ret = ipf ? ipf->ipfr_pass : 0;
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
return ret;
}
@ -321,13 +320,13 @@ void *nat;
ipfr_t *fr;
int idx;
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
if (fr->ipfr_data == nat)
fr->ipfr_data = NULL;
MUTEX_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_natfrag);
}
@ -340,16 +339,16 @@ void ipfr_unload()
nat_t *nat;
int idx;
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
KFREE(fr);
}
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
MUTEX_ENTER(&ipf_nat);
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
@ -359,8 +358,8 @@ void ipfr_unload()
}
KFREE(fr);
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
}
@ -384,7 +383,7 @@ int ipfr_slowtimer()
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_frag);
WRITE_ENTER(&ipf_frag);
/*
* Go through the entire table, looking for entries to expire,
@ -402,13 +401,13 @@ int ipfr_slowtimer()
fr->ipfr_next->ipfr_prev =
fr->ipfr_prev;
*fp = fr->ipfr_next;
ipfr_stats.ifs_expire++;
ipfr_inuse--;
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
KFREE(fr);
} else
fp = &fr->ipfr_next;
}
MUTEX_EXIT(&ipf_frag);
RWLOCK_EXIT(&ipf_frag);
/*
* Same again for the NAT table, except that if the structure also
@ -417,8 +416,8 @@ int ipfr_slowtimer()
* NOTE: We need to grab both mutex's early, and in this order so as
* to prevent a deadlock if both try to expire at the same time.
*/
MUTEX_ENTER(&ipf_nat);
MUTEX_ENTER(&ipf_natfrag);
WRITE_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
--fr->ipfr_ttl;
@ -430,8 +429,8 @@ int ipfr_slowtimer()
fr->ipfr_next->ipfr_prev =
fr->ipfr_prev;
*fp = fr->ipfr_next;
ipfr_stats.ifs_expire++;
ipfr_inuse--;
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;
@ -440,8 +439,8 @@ int ipfr_slowtimer()
} else
fp = &fr->ipfr_next;
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
fr_timeoutstate();
ip_natexpire();

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_ftp_pxy.c,v 1.8 1998/05/29 20:24:37 veego Exp $ */
/* $NetBSD: ip_ftp_pxy.c,v 1.9 1998/07/12 15:27:46 veego Exp $ */
/*
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
@ -128,10 +128,7 @@ nat_t *nat;
#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"));
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_log.c,v 1.4 1998/05/17 17:07:25 veego Exp $ */
/* $NetBSD: ip_log.c,v 1.5 1998/07/12 15:24:00 veego Exp $ */
/*
* Copyright (C) 1997 by Darren Reed.
@ -7,7 +7,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: ip_log.c,v 2.0.2.13.2.3 1997/11/20 12:41:40 darrenr Exp
* Id: ip_log.c,v 2.0.2.13.2.4 1998/06/07 16:27:09 darrenr Exp
*/
#ifdef IPFILTER_LOG
# ifndef SOLARIS
@ -462,6 +462,7 @@ int unit;
iplog_t *ipl;
int used;
MUTEX_ENTER(&ipl_mutex);
while ((ipl = iplt[unit])) {
iplt[unit] = ipl->ipl_next;
KFREES((caddr_t)ipl, ipl->ipl_dsize);
@ -470,6 +471,7 @@ int unit;
used = iplused[unit];
iplused[unit] = 0;
iplcrc[unit] = 0;
MUTEX_EXIT(&ipl_mutex);
return used;
}
#endif /* IPFILTER_LOG */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_nat.c,v 1.19 1998/05/29 20:24:37 veego Exp $ */
/* $NetBSD: ip_nat.c,v 1.20 1998/07/12 15:24:00 veego Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
@ -11,7 +11,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.0.2.44.2.10 1998/05/23 19:05:29 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.0.2.44.2.13 1998/06/13 13:42:47 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -107,7 +107,8 @@ u_long fr_defnatage = 1200, /* 10 minutes (600 seconds) */
fr_defnaticmpage = 6; /* 3 seconds */
natstat_t nat_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_nat;
extern kmutex_t ipf_rw;
extern krwlock_t ipf_nat;
#endif
static int nat_flushtable __P((void));
@ -205,7 +206,7 @@ int cmd;
caddr_t data;
int mode;
{
register ipnat_t *nat, *n = NULL, **np = NULL;
register ipnat_t *nat, *nt, *n = NULL, **np = NULL;
ipnat_t natd;
int error = 0, ret;
#if defined(_KERNEL) && !SOLARIS
@ -213,14 +214,16 @@ int mode;
#endif
nat = NULL; /* XXX gcc -Wuninitialized */
KMALLOC(nt, ipnat_t *, sizeof(*nt));
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);
MUTEX_ENTER(&ipf_nat);
WRITE_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;
@ -241,7 +244,8 @@ int mode;
error = EEXIST;
break;
}
KMALLOC(n, ipnat_t *, sizeof(*n));
n = nt;
nt = NULL;
if (n == NULL) {
error = ENOMEM;
break;
@ -273,11 +277,13 @@ int mode;
}
/* Otherwise, these fields are preset */
*np = n;
nat_stats.ns_rules++;
n = NULL;
ATOMIC_INC(nat_stats.ns_rules);
break;
case SIOCRMNAT :
if (!(mode & FWRITE)) {
error = EPERM;
n = NULL;
break;
}
if (!n) {
@ -289,13 +295,15 @@ int mode;
if (n->in_apr)
ap_free(n->in_apr);
KFREE(n);
nat_stats.ns_rules--;
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;
@ -305,6 +313,7 @@ int mode;
{
natlookup_t nl;
MUTEX_DOWNGRADE(&ipf_nat);
IRCOPY((char *)data, (char *)&nl, sizeof(nl));
if (nat_lookupredir(&nl)) {
@ -320,6 +329,7 @@ int mode;
}
ret = nat_flushtable();
(void) ap_unload();
MUTEX_DOWNGRADE(&ipf_nat);
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case SIOCCNATL :
@ -328,17 +338,21 @@ int mode;
break;
}
ret = nat_clearlist();
MUTEX_DOWNGRADE(&ipf_nat);
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case FIONREAD :
#ifdef IPFILTER_LOG
MUTEX_DOWNGRADE(&ipf_nat);
IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data,
sizeof(iplused[IPL_LOGNAT]));
#endif
break;
}
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
if (nt)
KFREE(nt);
return error;
}
@ -372,7 +386,7 @@ struct nat *natd;
* longer being used.
*/
if ((ipn = natd->nat_ptr)) {
ipn->in_space++;
ATOMIC_INC(ipn->in_space);
ipn->in_use--;
if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) {
if (ipn->in_apr)
@ -430,7 +444,7 @@ static int nat_clearlist()
if (n->in_apr)
ap_free(n->in_apr);
KFREE(n);
nat_stats.ns_rules--;
ATOMIC_DEC(nat_stats.ns_rules);
i++;
} else {
n->in_flags |= IPN_DELETE;
@ -699,9 +713,9 @@ int direction;
if (flags & IPN_TCPUDP)
tcp->th_dport = nport;
}
nat_stats.ns_added++;
nat_stats.ns_inuse++;
np->in_use++;
ATOMIC_INC(nat_stats.ns_added);
ATOMIC_INC(nat_stats.ns_inuse);
ATOMIC_INC(np->in_use);
return nat;
}
@ -994,14 +1008,16 @@ fr_info_t *fin;
ipa = ip->ip_src.s_addr;
MUTEX_ENTER(&ipf_nat);
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
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).
@ -1031,14 +1047,18 @@ fr_info_t *fin;
#endif
break;
}
MUTEX_DOWNGRADE(&ipf_nat);
}
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;
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
@ -1059,6 +1079,7 @@ fr_info_t *fin;
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);
/*
@ -1069,6 +1090,7 @@ fr_info_t *fin;
*/
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;
@ -1089,11 +1111,11 @@ fr_info_t *fin;
}
}
(void) ap_check(ip, tcp, fin, nat);
nat_stats.ns_mapped[1]++;
MUTEX_EXIT(&ipf_nat);
ATOMIC_INC(nat_stats.ns_mapped[1]);
RWLOCK_EXIT(&ipf_nat);
return -2;
}
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
return 0;
}
@ -1129,7 +1151,7 @@ fr_info_t *fin;
in = ip->ip_dst;
MUTEX_ENTER(&ipf_nat);
READ_ENTER(&ipf_nat);
if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags)))
;
@ -1139,7 +1161,9 @@ fr_info_t *fin;
else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport,
ip->ip_dst, dport)))
;
else
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).
@ -1159,17 +1183,21 @@ fr_info_t *fin;
#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;
ip->ip_dst = nat->nat_inip;
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
@ -1189,6 +1217,7 @@ fr_info_t *fin;
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);
/*
@ -1199,6 +1228,7 @@ fr_info_t *fin;
*/
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;
@ -1218,11 +1248,11 @@ fr_info_t *fin;
nat->nat_sumd);
}
}
nat_stats.ns_mapped[0]++;
MUTEX_EXIT(&ipf_nat);
ATOMIC_INC(nat_stats.ns_mapped[0]);
RWLOCK_EXIT(&ipf_nat);
return -2;
}
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
return 0;
}
@ -1232,11 +1262,11 @@ fr_info_t *fin;
*/
void ip_natunload()
{
MUTEX_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_nat);
(void) nat_clearlist();
(void) nat_flushtable();
(void) ap_unload();
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
}
@ -1252,9 +1282,10 @@ void ip_natexpire()
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_nat);
WRITE_ENTER(&ipf_nat);
for (natp = &nat_instances; (nat = *natp); ) {
if (--nat->nat_age) {
ATOMIC_DEC(nat->nat_age);
if (nat->nat_age) {
natp = &nat->nat_next;
continue;
}
@ -1263,12 +1294,12 @@ void ip_natexpire()
nat_log(nat, NL_EXPIRE);
#endif
nat_delete(nat);
nat_stats.ns_expire++;
ATOMIC_INC(nat_stats.ns_expire);
}
ap_expire();
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}
@ -1291,7 +1322,7 @@ void *ifp;
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_nat);
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) {
@ -1325,7 +1356,7 @@ void *ifp;
sumd += nat->nat_sumd;
nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16);
}
MUTEX_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_proxy.c,v 1.13 1998/05/29 20:27:18 veego Exp $ */
/* $NetBSD: ip_proxy.c,v 1.14 1998/07/12 15:24:00 veego Exp $ */
/*
* Copyright (C) 1997 by Darren Reed.
@ -8,7 +8,7 @@
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15:22 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.9 1998/06/06 14:38:15 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -81,7 +81,8 @@ 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));
struct in_addr, void *, u_short, u_short));
#define AP_SESS_SIZE 53
@ -233,6 +234,7 @@ nat_t *nat;
{
ap_session_t *aps;
aproxy_t *apr;
u_32_t sum;
int err;
if (!(fin->fin_fi.fi_fl & FI_TCPUDP))
@ -245,8 +247,13 @@ nat_t *nat;
* verify that the checksum is correct. If not, then
* don't do anything with this packet.
*/
if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp,
ip, tcp, ip->ip_len)) {
#if SOLARIS && defined(_KERNEL)
sum = fr_tcpsum(fin->fin_qfm, ip, tcp, 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;
}
@ -266,8 +273,13 @@ nat_t *nat;
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;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_state.c,v 1.14 1998/05/29 20:28:17 veego Exp $ */
/* $NetBSD: ip_state.c,v 1.15 1998/07/12 15:24:00 veego Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
@ -9,7 +9,7 @@
*/
#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 ";
static const char rcsid[] = "@(#)Id: ip_state.c,v 2.0.2.24.2.18 1998/06/12 16:31:29 darrenr Exp ";
#endif
#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__)
@ -84,7 +84,8 @@ ipstate_t *ips_table[IPSTATE_SIZE];
int ips_num = 0;
ips_stat_t ips_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_state;
extern krwlock_t ipf_state;
extern kmutex_t ipf_rw;
#endif
static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr,
@ -129,7 +130,7 @@ int which;
int delete, removed = 0;
SPL_NET(s);
MUTEX_ENTER(&ipf_state);
WRITE_ENTER(&ipf_state);
for (i = 0; i < IPSTATE_SIZE; i++)
for (isp = &ips_table[i]; (is = *isp); ) {
delete = 0;
@ -164,7 +165,7 @@ int which;
} else
isp = &is->is_next;
}
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
return removed;
}
@ -256,7 +257,7 @@ u_int pass;
default :
return -1;
}
ips_stats.iss_icmp++;
ATOMIC_INC(ips_stats.iss_icmp);
is->is_age = fr_icmptimeout;
break;
}
@ -274,7 +275,6 @@ u_int pass;
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
@ -282,8 +282,11 @@ u_int pass;
*/
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 :
@ -292,7 +295,7 @@ u_int pass;
hv += (is->is_dport = tcp->th_dport);
hv += (is->is_sport = tcp->th_sport);
ips_stats.iss_udp++;
ATOMIC_INC(ips_stats.iss_udp);
is->is_age = fr_udptimeout;
break;
}
@ -302,27 +305,30 @@ u_int pass;
KMALLOC(is, ipstate_t *, sizeof(*is));
if (is == NULL) {
ips_stats.iss_nomem++;
ATOMIC_INC(ips_stats.iss_nomem);
return -1;
}
bcopy((char *)&ips, (char *)is, sizeof(*is));
hv %= IPSTATE_SIZE;
MUTEX_ENTER(&ipf_state);
WRITE_ENTER(&ipf_state);
is->is_pass = pass;
is->is_pkts = 1;
is->is_bytes = ip->ip_len;
/*
* Copy these from the rule itself.
* 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_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;
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.
*/
@ -337,11 +343,11 @@ u_int pass;
}
if (pass & FR_LOGFIRST)
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
ips_num++;
ATOMIC_INC(ips_num);
#ifdef IPFILTER_LOG
ipstate_log(is, ISL_NEW);
#endif
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
if (fin->fin_fi.fi_fl & FI_FRAG)
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
return 0;
@ -423,13 +429,15 @@ tcphdr_t *tcp;
is->is_ack = seq;
is->is_dwin = ntohs(tcp->th_win);
}
ips_stats.iss_hits++;
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;
@ -496,8 +504,8 @@ u_short sp, dp;
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)))
((fin->fin_fi.fi_fl & (is->is_flags & 0xf)) !=
(is->is_flags >> 4)))
ret = 0;
}
return ret;
@ -537,7 +545,7 @@ fr_info_t *fin;
hv += ic->icmp_id;
hv += ic->icmp_seq;
hv %= IPSTATE_SIZE;
MUTEX_ENTER(&ipf_state);
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) &&
@ -545,15 +553,20 @@ fr_info_t *fin;
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);
if (fin->fin_fi.fi_fl & FI_FRAG)
ipfr_newfrag(ip, fin,
pass ^ FR_KEEPSTATE);
WRITE_ENTER(&ipf_state);
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);
is->is_pkts++;
RWLOCK_EXIT(&ipf_state);
return pass;
}
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
break;
case IPPROTO_TCP :
{
@ -562,7 +575,7 @@ fr_info_t *fin;
hv += dport;
hv += sport;
hv %= IPSTATE_SIZE;
MUTEX_ENTER(&ipf_state);
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,
@ -570,7 +583,7 @@ fr_info_t *fin;
if (fr_tcpstate(is, fin, ip, tcp)) {
pass = is->is_pass;
#ifdef _KERNEL
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
#else
if (tcp->th_flags & TCP_CLOSE) {
@ -579,10 +592,13 @@ fr_info_t *fin;
KFREE(is);
}
#endif
if (fin->fin_fi.fi_fl & FI_FRAG)
ipfr_newfrag(ip, fin,
pass ^ FR_KEEPSTATE);
return pass;
}
}
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
break;
}
case IPPROTO_UDP :
@ -595,26 +611,31 @@ fr_info_t *fin;
/*
* Nothing else to match on but ports. and IP#'s
*/
MUTEX_ENTER(&ipf_state);
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)) {
ips_stats.iss_hits++;
is->is_pkts++;
pass = is->is_pass;
MUTEX_ENTER(&ipf_rw);
is->is_bytes += ip->ip_len;
is->is_age = fr_udptimeout;
pass = is->is_pass;
MUTEX_EXIT(&ipf_state);
ips_stats.iss_hits++;
is->is_pkts++;
MUTEX_EXIT(&ipf_rw);
RWLOCK_EXIT(&ipf_state);
if (fin->fin_fi.fi_fl & FI_FRAG)
ipfr_newfrag(ip, fin,
pass ^ FR_KEEPSTATE);
return pass;
}
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
break;
}
default :
break;
}
ips_stats.iss_miss++;
ATOMIC_INC(ips_stats.iss_miss);
return 0;
}
@ -627,13 +648,13 @@ void fr_stateunload()
register int i;
register ipstate_t *is, **isp;
MUTEX_ENTER(&ipf_state);
WRITE_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);
RWLOCK_EXIT(&ipf_state);
}
@ -650,7 +671,7 @@ void fr_timeoutstate()
#endif
SPL_NET(s);
MUTEX_ENTER(&ipf_state);
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) {
@ -666,7 +687,7 @@ void fr_timeoutstate()
ips_num--;
} else
isp = &is->is_next;
MUTEX_EXIT(&ipf_state);
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
}