Resolve conflicts

MFC after:	2 weeks
This commit is contained in:
Guido van Rooij 2006-08-16 12:06:35 +00:00
parent ec2c2c379b
commit 4160f4c64e
16 changed files with 507 additions and 367 deletions

View File

@ -142,7 +142,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
/* static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp"; */
/* static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $"; */
#endif
#ifndef _KERNEL
@ -150,12 +150,6 @@ static const char rcsid[] = "@(#)$FreeBSD$";
# include "ipt.h"
# include "bpf-ipf.h"
extern int opts;
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
#else /* #ifndef _KERNEL */
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
#endif /* _KERNEL */
@ -1977,24 +1971,23 @@ u_32_t pass;
* it, except for increasing the hit counter.
*/
if ((passt & FR_CALLNOW) != 0) {
frentry_t *frs;
ATOMIC_INC64(fr->fr_hits);
if ((fr->fr_func != NULL) &&
(fr->fr_func != (ipfunc_t)-1)) {
frentry_t *frs;
(fr->fr_func == (ipfunc_t)-1))
continue;
frs = fin->fin_fr;
fin->fin_fr = fr;
fr = (*fr->fr_func)(fin, &passt);
if (fr == NULL) {
fin->fin_fr = frs;
continue;
}
passt = fr->fr_flags;
fin->fin_fr = fr;
}
} else {
frs = fin->fin_fr;
fin->fin_fr = fr;
fr = (*fr->fr_func)(fin, &passt);
if (fr == NULL) {
fin->fin_fr = frs;
continue;
}
passt = fr->fr_flags;
}
fin->fin_fr = fr;
#ifdef IPFILTER_LOG
/*
@ -2026,18 +2019,20 @@ u_32_t pass;
(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
if (fr->fr_grp != NULL) {
fin->fin_fr = *fr->fr_grp;
pass = fr_scanlist(fin, pass);
passt = fr_scanlist(fin, pass);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
(void) strncpy(fin->fin_group, fr->fr_group,
FR_GROUPLEN);
fin->fin_fr = fr;
passt = pass;
}
if (fin->fin_flx & FI_DONTCACHE)
logged = 1;
pass = passt;
}
if (pass & FR_QUICK) {
if (passt & FR_QUICK) {
/*
* Finally, if we've asked to track state for this
* packet, set it up. Add state for "quick" rules
@ -2049,6 +2044,7 @@ u_32_t pass;
!(fin->fin_flx & FI_STATE)) {
int out = fin->fin_out;
fin->fin_fr = fr;
if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads);
} else {
@ -2198,7 +2194,8 @@ u_32_t *passp;
if (FR_ISAUTH(pass)) {
if (fr_newauth(fin->fin_m, fin) != 0) {
#ifdef _KERNEL
fin->fin_m = *fin->fin_mp = NULL;
if ((pass & FR_RETMASK) == 0)
fin->fin_m = *fin->fin_mp = NULL;
#else
;
#endif
@ -2238,21 +2235,6 @@ u_32_t *passp;
}
}
/*
* Finally, if we've asked to track state for this packet, set it up.
*/
if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) {
if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads);
} else {
ATOMIC_INCL(frstats[out].fr_bads);
if (FR_ISPASS(pass)) {
pass &= ~FR_CMDMASK;
pass |= FR_BLOCK;
}
}
}
fr = fin->fin_fr;
if (passp != NULL)
@ -2318,8 +2300,6 @@ int out;
#ifdef USE_INET6
ip6_t *ip6;
#endif
SPL_INT(s);
/*
* The first part of fr_check() deals with making sure that what goes
* into the filtering engine makes some sense. Information about the
@ -2333,6 +2313,8 @@ int out;
if ((u_int)ip & 0x3)
return 2;
# else
SPL_INT(s);
# endif
READ_ENTER(&ipf_global);
@ -2498,6 +2480,23 @@ int out;
if ((pass & FR_NOMATCH) || (fr == NULL))
fr = fr_firewall(fin, &pass);
/*
* If we've asked to track state for this packet, set it up.
* Here rather than fr_firewall because fr_checkauth may decide
* to return a packet for "keep state"
*/
if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) {
if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads);
} else {
ATOMIC_INCL(frstats[out].fr_bads);
if (FR_ISPASS(pass)) {
pass &= ~FR_CMDMASK;
pass |= FR_BLOCK;
}
}
}
fin->fin_fr = fr;
/*
@ -2552,7 +2551,7 @@ int out;
RWLOCK_EXIT(&ipf_mutex);
if (pass & (FR_RETRST|FR_RETICMP)) {
if ((pass & FR_RETMASK) != 0) {
/*
* Should we return an ICMP packet to indicate error
* status passing through the packet filter ?
@ -2578,6 +2577,14 @@ int out;
ATOMIC_INCL(frstats[1].fr_ret);
}
}
/*
* When using return-* with auth rules, the auth code
* takes over disposing of this packet.
*/
if (FR_ISAUTH(pass) && (fin->fin_m != NULL)) {
fin->fin_m = *fin->fin_mp = NULL;
}
} else {
if (pass & FR_RETRST)
fin->fin_error = ECONNRESET;
@ -2791,10 +2798,10 @@ int len;
/* */
/* Expects ip_len to be in host byte order when called. */
/* ------------------------------------------------------------------------ */
u_short fr_cksum(m, ip, l4proto, l4hdr)
u_short fr_cksum(m, ip, l4proto, l4hdr, l3len)
mb_t *m;
ip_t *ip;
int l4proto;
int l4proto, l3len;
void *l4hdr;
{
u_short *sp, slen, sumsave, l4hlen, *csump;
@ -2819,7 +2826,7 @@ void *l4hdr;
if (IP_V(ip) == 4) {
#endif
hlen = IP_HL(ip) << 2;
slen = ip->ip_len - hlen;
slen = l3len - hlen;
sum = htons((u_short)l4proto);
sum += htons(slen);
sp = (u_short *)&ip->ip_src;
@ -2831,9 +2838,9 @@ void *l4hdr;
} else if (IP_V(ip) == 6) {
ip6 = (ip6_t *)ip;
hlen = sizeof(*ip6);
slen = ntohs(ip6->ip6_plen);
slen = ntohs(l3len);
sum = htons((u_short)l4proto);
sum += htons(slen);
sum += slen;
sp = (u_short *)&ip6->ip6_src;
sum += *sp++; /* ip6_src */
sum += *sp++;
@ -3064,7 +3071,7 @@ void *l4hdr;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $
* $Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@ -3477,7 +3484,7 @@ int proto, flags;
char *memstr(src, dst, slen, dlen)
const char *src;
char *dst;
int slen, dlen;
size_t slen, dlen;
{
char *s = NULL;
@ -3765,13 +3772,7 @@ size_t size;
caddr_t ca;
int err;
# if SOLARIS
err = COPYIN(dst, (caddr_t)&ca, sizeof(ca));
if (err != 0)
return err;
# else
bcopy(dst, (caddr_t)&ca, sizeof(ca));
# endif
err = COPYOUT(src, ca, size);
return err;
}
@ -4891,7 +4892,7 @@ ipftq_t *ifq;
ifq->ifq_next->ifq_pnext = ifq->ifq_pnext;
MUTEX_DESTROY(&ifq->ifq_lock);
fr_userifqs--;
ATOMIC_DEC(fr_userifqs);
KFREE(ifq);
}
@ -4913,8 +4914,6 @@ ipftqent_t *tqe;
ipftq_t *ifq;
ifq = tqe->tqe_ifq;
if (ifq == NULL)
return;
MUTEX_ENTER(&ifq->ifq_lock);
@ -4986,24 +4985,21 @@ ipftqent_t *tqe;
tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
MUTEX_ENTER(&ifq->ifq_lock);
if (tqe->tqe_next == NULL) { /* at the end already ? */
MUTEX_EXIT(&ifq->ifq_lock);
return;
if (tqe->tqe_next != NULL) { /* at the end already ? */
/*
* Remove from list
*/
*tqe->tqe_pnext = tqe->tqe_next;
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
/*
* Make it the last entry.
*/
tqe->tqe_next = NULL;
tqe->tqe_pnext = ifq->ifq_tail;
*ifq->ifq_tail = tqe;
ifq->ifq_tail = &tqe->tqe_next;
}
/*
* Remove from list
*/
*tqe->tqe_pnext = tqe->tqe_next;
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
/*
* Make it the last entry.
*/
tqe->tqe_next = NULL;
tqe->tqe_pnext = ifq->ifq_tail;
*ifq->ifq_tail = tqe;
ifq->ifq_tail = &tqe->tqe_next;
MUTEX_EXIT(&ifq->ifq_lock);
}
@ -5055,46 +5051,44 @@ ipftq_t *oifq, *nifq;
* Is the operation here going to be a no-op ?
*/
MUTEX_ENTER(&oifq->ifq_lock);
if (oifq == nifq && *oifq->ifq_tail == tqe) {
MUTEX_EXIT(&oifq->ifq_lock);
return;
if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) {
/*
* Remove from the old queue
*/
*tqe->tqe_pnext = tqe->tqe_next;
if (tqe->tqe_next)
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
else
oifq->ifq_tail = tqe->tqe_pnext;
tqe->tqe_next = NULL;
/*
* If we're moving from one queue to another, release the
* lock on the old queue and get a lock on the new queue.
* For user defined queues, if we're moving off it, call
* delete in case it can now be freed.
*/
if (oifq != nifq) {
tqe->tqe_ifq = NULL;
(void) fr_deletetimeoutqueue(oifq);
MUTEX_EXIT(&oifq->ifq_lock);
MUTEX_ENTER(&nifq->ifq_lock);
tqe->tqe_ifq = nifq;
nifq->ifq_ref++;
}
/*
* Add to the bottom of the new queue
*/
tqe->tqe_die = fr_ticks + nifq->ifq_ttl;
tqe->tqe_pnext = nifq->ifq_tail;
*nifq->ifq_tail = tqe;
nifq->ifq_tail = &tqe->tqe_next;
}
/*
* Remove from the old queue
*/
*tqe->tqe_pnext = tqe->tqe_next;
if (tqe->tqe_next)
tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
else
oifq->ifq_tail = tqe->tqe_pnext;
tqe->tqe_next = NULL;
/*
* If we're moving from one queue to another, release the lock on the
* old queue and get a lock on the new queue. For user defined queues,
* if we're moving off it, call delete in case it can now be freed.
*/
if (oifq != nifq) {
tqe->tqe_ifq = NULL;
(void) fr_deletetimeoutqueue(oifq);
MUTEX_EXIT(&oifq->ifq_lock);
MUTEX_ENTER(&nifq->ifq_lock);
tqe->tqe_ifq = nifq;
nifq->ifq_ref++;
}
/*
* Add to the bottom of the new queue
*/
tqe->tqe_die = fr_ticks + nifq->ifq_ttl;
tqe->tqe_pnext = nifq->ifq_tail;
*nifq->ifq_tail = tqe;
nifq->ifq_tail = &tqe->tqe_next;
MUTEX_EXIT(&nifq->ifq_lock);
}
@ -5578,7 +5572,7 @@ fr_info_t *fin;
if (dosum)
sum = fr_cksum(fin->fin_m, fin->fin_ip,
fin->fin_p, fin->fin_dp);
fin->fin_p, fin->fin_dp, fin->fin_plen);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID)
}
#endif

View File

@ -121,12 +121,13 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#if !defined(lint)
static const char rcsid[] = "@(#)$FreeBSD$";
/* static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp"; */
/* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.13 2006/03/29 11:19:55 darrenr Exp $"; */
#endif
#if SOLARIS
#if SOLARIS && defined(_KERNEL)
extern kcondvar_t ipfauthwait;
extern struct pollhead iplpollhead[IPL_LOGSIZE];
#endif /* SOLARIS */
#if defined(linux) && defined(_KERNEL)
wait_queue_head_t fr_authnext_linux;
@ -321,7 +322,7 @@ fr_info_t *fin;
fra = fr_auth + i;
fra->fra_index = i;
fra->fra_pass = 0;
fra->fra_pass = fin->fin_fr->fr_flags;
fra->fra_age = fr_defaultauthage;
bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
#if !defined(sparc) && !defined(m68k)
@ -343,17 +344,15 @@ fr_info_t *fin;
}
#endif
#if SOLARIS && defined(_KERNEL)
COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname);
m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
fra->fra_m = *fin->fin_mp;
fra->fra_info.fin_mp = &fra->fra_m;
cv_signal(&ipfauthwait);
pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM);
#else
# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
if (!fin->fin_out) {
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
}
# endif
fr_authpkts[i] = m;
WAKEUP(&fr_authnext,0);
#endif
@ -366,15 +365,15 @@ caddr_t data;
ioctlcmd_t cmd;
int mode;
{
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
char *t;
mb_t *m;
#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq;
SPL_INT(s);
#endif
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
char *t;
switch (cmd)
{
@ -403,10 +402,14 @@ int mode;
case SIOCAUTHW:
fr_authioctlloop:
error = fr_inobj(data, au, IPFOBJ_FRAUTH);
if (error != 0)
break;
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
error = fr_outobj(data, &fr_auth[fr_authnext],
IPFOBJ_FRAUTH);
if (error != 0)
break;
if (auth.fra_len != 0 && auth.fra_buf != NULL) {
/*
* Copy packet contents out to user space if
@ -420,11 +423,12 @@ int mode;
for (t = auth.fra_buf; m && (len > 0); ) {
i = MIN(M_LEN(m), len);
error = copyoutptr(MTOD(m, char *),
t, i);
&t, i);
len -= i;
t += i;
if (error != 0)
break;
m = m->m_next;
}
}
RWLOCK_EXIT(&ipf_auth);
@ -477,10 +481,8 @@ int mode;
#endif
MUTEX_EXIT(&ipf_authmx);
READ_ENTER(&ipf_global);
if (error == 0) {
READ_ENTER(&ipf_auth);
if (error == 0)
goto fr_authioctlloop;
}
break;
case SIOCAUTHR:
@ -491,6 +493,7 @@ int mode;
WRITE_ENTER(&ipf_auth);
i = au->fra_index;
fra = fr_auth + i;
error = 0;
if ((i < 0) || (i >= fr_authsize) ||
(fra->fra_info.fin_id != au->fra_info.fin_id)) {
RWLOCK_EXIT(&ipf_auth);
@ -505,7 +508,11 @@ int mode;
#ifdef _KERNEL
if ((m != NULL) && (au->fra_info.fin_out != 0)) {
# ifdef MENTAT
error = !putq(fra->fra_q, m);
error = ipf_inject(&fra->fra_info);
if (error != 0) {
FREE_MB_T(m);
error = ENOBUFS;
}
# else /* MENTAT */
# if defined(linux) || defined(AIX)
# else
@ -526,7 +533,11 @@ int mode;
fr_authstats.fas_sendok++;
} else if (m) {
# ifdef MENTAT
error = !putq(fra->fra_q, m);
error = ipf_inject(&fra->fra_info);
if (error != 0) {
FREE_MB_T(m);
error = ENOBUFS;
}
# else /* MENTAT */
# if defined(linux) || defined(AIX)
# else
@ -557,10 +568,6 @@ int mode;
fr_authstats.fas_queok++;
} else
error = EINVAL;
# ifdef MENTAT
if (error != 0)
error = EINVAL;
# else /* MENTAT */
/*
* If we experience an error which will result in the packet
* not being processed, make sure we advance to the next one.
@ -584,7 +591,6 @@ int mode;
}
}
}
# endif /* MENTAT */
#endif /* _KERNEL */
SPL_X(s);
break;
@ -799,3 +805,9 @@ int fr_authflush()
return num_flushed;
}
int fr_auth_waiting()
{
return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext];
}

View File

@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* $FreeBSD$
* Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp
* Id: ip_auth.h,v 2.16.2.2 2006/03/16 06:45:49 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@ -23,6 +23,7 @@ typedef struct frauth {
char *fra_buf;
#ifdef MENTAT
queue_t *fra_q;
mb_t *fra_m;
#endif
} frauth_t;
@ -63,5 +64,6 @@ extern mb_t **fr_authpkts;
extern int fr_newauth __P((mb_t *, fr_info_t *));
extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **));
extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int));
extern int fr_auth_waiting __P((void));
#endif /* __IP_AUTH_H__ */

View File

@ -5,7 +5,7 @@
*
* @(#)ip_compat.h 1.8 1/14/96
* $FreeBSD$
* Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp
* Id: ip_compat.h,v 2.142.2.36 2006/03/26 05:50:29 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -442,6 +442,7 @@ extern void *get_unit __P((char *, int));
wakeup(id + x); \
spinunlock(_l); \
}
# define POLLWAKEUP(x) ;
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT)
# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IOSYS, M_NOWAIT)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
@ -579,6 +580,7 @@ typedef struct {
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) ;
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define GETIFP(n,v) ifunit(n)
@ -660,6 +662,7 @@ typedef struct mbuf mb_t;
# define GETIFP(n, v) ifunit(n)
# define GET_MINOR getminor
# define WAKEUP(id,x) wakeup(id + x)
# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
@ -1030,6 +1033,7 @@ typedef u_int32_t u_32_t;
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id + x)
# define POLLWAKEUP(x) ;
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@ -1075,6 +1079,7 @@ struct ip6_ext {
# define FREE_MB_T(m) kfree_skb(m)
# define GETKTIME(x) do_gettimeofday((struct timeval *)x)
# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
# define POLLWAKEUP(x) ;
# define WAKEUP(x,y) wake_up(x##_linux + y)
# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
# define USE_MUTEXES
@ -1266,6 +1271,7 @@ extern void* getifp __P((char *, int));
# define GET_MINOR minor
# define SLEEP(id, n) sleepx((id), PZERO+1, 0)
# define WAKEUP(id,x) wakeup(id)
# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
@ -1430,6 +1436,7 @@ typedef struct mb_s {
# define FREE_MB_T(x)
# define SLEEP(x,y) 1;
# define WAKEUP(x,y) ;
# define POLLWAKEUP(y) ;
# define IPF_PANIC(x,y) ;
# define PANIC(x,y) ;
# define SPL_NET(x) ;
@ -1580,6 +1587,7 @@ MALLOC_DECLARE(M_IPFILTER);
# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) selwakeup(ipfselwait+x)
# define GETIFP(n, v) ifunit(n)
# endif /* (Free)BSD */

View File

@ -5,7 +5,7 @@
*
* @(#)ip_fil.h 1.35 6/5/96
* $FreeBSD$
* Id: ip_fil.h,v 2.170.2.18 2005/03/28 10:47:52 darrenr Exp
* Id: ip_fil.h,v 2.170.2.29 2006/03/29 11:19:55 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -306,6 +306,7 @@ typedef struct fr_info {
#ifdef MENTAT
mb_t *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qpi;
char fin_ifname[LIFNAMSIZ];
#endif
#ifdef __sgi
void *fin_hbuf;
@ -1134,6 +1135,17 @@ typedef struct ipftune {
# endif
#endif
#ifdef _KERNEL
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
#else
extern void debug __P((char *, ...));
extern void verbose __P((char *, ...));
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
#endif
#ifndef _KERNEL
extern int fr_check __P((struct ip *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
@ -1149,6 +1161,7 @@ extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int));
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
extern void m_freem __P((mb_t *));
extern int bcopywrap __P((void *, void *, size_t));
#else /* #ifndef _KERNEL */
# if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern void ipfilterattach __P((int));
@ -1262,7 +1275,7 @@ extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag;
extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
extern ipfrwlock_t ipf_frcache;
extern char *memstr __P((const char *, char *, int, int));
extern char *memstr __P((const char *, char *, size_t, size_t));
extern int count4bits __P((u_32_t));
extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int));
extern char *getifname __P((struct ifnet *));
@ -1319,6 +1332,7 @@ extern void fr_delgroup __P((char *, minor_t, int));
extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***));
extern int fr_loginit __P((void));
extern int ipflog_canread __P((int));
extern int ipflog_clear __P((minor_t));
extern int ipflog_read __P((minor_t, uio_t *));
extern int ipflog __P((fr_info_t *, u_int));
@ -1327,7 +1341,7 @@ extern void fr_logunload __P((void));
extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *));
extern int fr_copytolog __P((int, char *, int));
extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *));
extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *, int));
extern void fr_deinitialise __P((void));
extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *));
extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *));

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_freebsd.c,v 2.53.2.27 2005/08/20 13:48:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.32 2006/03/25 13:03:01 darrenr Exp $";
#endif
#if defined(KERNEL) || defined(_KERNEL)
@ -57,6 +57,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.27 2005/08/20 13
#endif
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/selinfo.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
@ -133,6 +134,7 @@ int ipf_locks_done = 0;
#if (__FreeBSD_version >= 300000)
struct callout_handle fr_slowtimer_ch;
#endif
struct selinfo ipfselwait[IPL_LOGSIZE];
#if (__FreeBSD_version >= 500011)
# include <sys/conf.h>
@ -302,6 +304,7 @@ int iplattach()
fr_checkp = fr_check;
}
bzero((char *)ipfselwait, sizeof(ipfselwait));
bzero((char *)frcache, sizeof(frcache));
fr_running = 1;
@ -478,9 +481,11 @@ int mode;
}
SPL_NET(s);
READ_ENTER(&ipf_global);
error = fr_ioctlswitch(unit, data, cmd, mode);
if (error != -1) {
RWLOCK_EXIT(&ipf_global);
SPL_X(s);
return error;
}
@ -621,7 +626,10 @@ int mode;
error = EINVAL;
break;
}
RWLOCK_EXIT(&ipf_global);
SPL_X(s);
return error;
}
@ -744,14 +752,18 @@ dev_t dev;
#endif
register struct uio *uio;
{
u_int xmin = GET_MINOR(dev);
if (xmin < 0)
return ENXIO;
# ifdef IPFILTER_SYNC
if (GET_MINOR(dev) == IPL_LOGSYNC)
if (xmin == IPL_LOGSYNC)
return ipfsync_read(uio);
# endif
#ifdef IPFILTER_LOG
return ipflog_read(GET_MINOR(dev), uio);
return ipflog_read(xmin, uio);
#else
return ENXIO;
#endif
@ -1157,6 +1169,8 @@ frdest_t *fdp;
u_short ip_off;
frentry_t *fr;
ro = NULL;
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@ -1170,15 +1184,15 @@ frdest_t *fdp;
* problem.
*/
if (M_WRITABLE(m) == 0) {
if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
m0 = m_dup(m, M_DONTWAIT);
if (m0 != 0) {
FREE_MB_T(m);
m = m0;
*mpp = m;
} else {
error = ENOBUFS;
FREE_MB_T(m);
*mpp = NULL;
fr_frouteok[1]++;
goto done;
}
}
#endif
@ -1220,18 +1234,8 @@ frdest_t *fdp;
goto bad;
}
/*
* In case we're here due to "to <if>" being used with "keep state",
* check that we're going in the correct direction.
*/
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return -1;
}
if (fdp != NULL) {
if (fdp->fd_ip.s_addr != 0)
dst->sin_addr = fdp->fd_ip;
}
if ((fdp != NULL) && (fdp->fd_ip.s_addr != 0))
dst->sin_addr = fdp->fd_ip;
dst->sin_len = sizeof(*dst);
rtalloc(ro);
@ -1348,6 +1352,7 @@ frdest_t *fdp;
else
mhip->ip_off |= IP_MF;
mhip->ip_len = htons((u_short)(len + mhlen));
*mnext = m;
m->m_next = m_copy(m0, off, len);
if (m->m_next == 0) {
error = ENOBUFS; /* ??? */
@ -1358,7 +1363,6 @@ frdest_t *fdp;
mhip->ip_off = htons((u_short)mhip->ip_off);
mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen);
*mnext = m;
mnext = &m->m_act;
}
/*
@ -1387,7 +1391,7 @@ frdest_t *fdp;
else
fr_frouteok[1]++;
if (ro->ro_rt) {
if ((ro != NULL) && (ro->ro_rt != NULL)) {
RTFREE(ro->ro_rt);
}
*mpp = NULL;
@ -1490,6 +1494,9 @@ struct in_addr *inp, *inpmask;
else if (atype == FRI_PEERADDR)
sock = ifa->ifa_dstaddr;
if (sock == NULL)
return -1;
#ifdef USE_INET6
if (v == 6) {
return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock,

View File

@ -103,7 +103,7 @@ extern struct timeout fr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
/* static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77 2004/01/27 00:24:54 darrenr Exp"; */
/* static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.5 2006/02/26 08:26:54 darrenr Exp $";*/
#endif
@ -227,6 +227,7 @@ ipfr_t *table[];
{
ipfr_t *fra, frag;
u_int idx, off;
frentry_t *fr;
ip_t *ip;
if (ipfr_inuse >= IPFT_SIZE)
@ -278,12 +279,9 @@ ipfr_t *table[];
return NULL;
}
fra->ipfr_rule = fin->fin_fr;
if (fra->ipfr_rule != NULL) {
frentry_t *fr;
fr = fin->fin_fr;
fr = fin->fin_fr;
fra->ipfr_rule = fr;
if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
fr->fr_ref++;
MUTEX_EXIT(&fr->fr_lock);

View File

@ -9,7 +9,7 @@
* code.
*
* $FreeBSD$
* Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp
* Id: ip_ftp_pxy.c,v 2.88.2.19 2006/04/01 10:14:53 darrenr Exp $
*/
#define IPF_FTP_PROXY
@ -369,7 +369,7 @@ int dlen;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
(void) fr_addstate(&fi, NULL, SI_W_DPORT);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
@ -731,7 +731,7 @@ u_int data_ip;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, sflags);
(void) fr_addstate(&fi, NULL, sflags);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
@ -1030,13 +1030,14 @@ int rv;
if (ippr_ftp_debug > 4)
printf("ippr_ftp_process: mlen %d\n", mlen);
if (mlen <= 0) {
if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
f->ftps_seq[0] = thseq + 1;
t->ftps_seq[0] = thack;
}
if ((mlen == 0) && ((tcp->th_flags & TH_OPENING) == TH_OPENING)) {
f->ftps_seq[0] = thseq + 1;
t->ftps_seq[0] = thack;
return 0;
} else if (mlen < 0) {
return 0;
}
aps = nat->nat_aps;
sel = aps->aps_sel[1 - rv];
@ -1426,7 +1427,7 @@ int dlen;
ap += *s++ - '0';
}
if (!s)
if (!*s)
return 0;
if (*s == '|')

View File

@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* $FreeBSD$
* Id: ip_log.c,v 2.75.2.6 2004/10/16 07:59:27 darrenr Exp
* Id: ip_log.c,v 2.75.2.11 2006/03/26 13:50:47 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL)
@ -70,6 +70,10 @@ struct file;
# include <sys/dir.h>
# endif
# include <sys/mbuf.h>
# include <sys/select.h>
# if __FreeBSD_version >= 500000
# include <sys/selinfo.h>
# endif
#else
# if !defined(__hpux) && defined(_KERNEL)
# include <sys/filio.h>
@ -144,12 +148,14 @@ iplog_select_t iplog_ss[IPL_LOGMAX+1];
extern int selwait;
# endif /* IPL_SELECT */
extern struct selinfo ipfselwait[IPL_LOGSIZE];
# if defined(linux) && defined(_KERNEL)
wait_queue_head_t iplh_linux[IPL_LOGSIZE];
# endif
# if SOLARIS
extern kcondvar_t iplwait;
extern struct pollhead iplpollhead[IPL_LOGSIZE];
# endif
iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE];
@ -508,9 +514,11 @@ int *types, cnt;
# if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait);
MUTEX_EXIT(&ipl_mutex);
pollwakeup(&iplpollhead[dev], POLLRDNORM);
# else
MUTEX_EXIT(&ipl_mutex);
WAKEUP(iplh,dev);
WAKEUP(iplh, dev);
POLLWAKEUP(dev);
# endif
SPL_X(s);
# ifdef IPL_SELECT
@ -668,4 +676,19 @@ minor_t unit;
SPL_X(s);
return used;
}
/* ------------------------------------------------------------------------ */
/* Function: ipflog_canread */
/* Returns: int - 0 == no data to read, 1 = data present */
/* Parameters: unit(I) - device we are reading from */
/* */
/* Returns an indication of whether or not there is data present in the */
/* current buffer for the selected ipf device. */
/* ------------------------------------------------------------------------ */
int ipflog_canread(unit)
int unit;
{
return iplt[unit] != NULL;
}
#endif /* IPFILTER_LOG */

View File

@ -110,7 +110,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
/* static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.38 2005/03/28 11:09:54 darrenr Exp"; */
/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.56 2006/04/01 10:15:34 darrenr Exp $";*/
#endif
@ -194,7 +194,7 @@ static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int));
static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int));
static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
tcphdr_t *, nat_t **, int));
static void nat_resolverule __P((ipnat_t *));
static int nat_resolverule __P((ipnat_t *));
static nat_t *fr_natclone __P((fr_info_t *, nat_t *));
static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
static int nat_wildok __P((nat_t *, int, int, int, int));
@ -868,11 +868,8 @@ int getlock;
{
int error = 0, i, j;
nat_resolverule(n);
if (n->in_plabel[0] != '\0') {
if (n->in_apr == NULL)
return ENOENT;
}
if (nat_resolverule(n) != 0)
return ENOENT;
if ((n->in_age[0] == 0) && (n->in_age[1] != 0))
return EINVAL;
@ -997,7 +994,7 @@ int getlock;
/* from information passed to the kernel, then add it to the appropriate */
/* NAT rule table(s). */
/* ------------------------------------------------------------------------ */
static void nat_resolverule(n)
static int nat_resolverule(n)
ipnat_t *n;
{
n->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
@ -1008,12 +1005,15 @@ ipnat_t *n;
(void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ);
n->in_ifps[1] = n->in_ifps[0];
} else {
n->in_ifps[1] = fr_resolvenic(n->in_ifnames[0], 4);
n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4);
}
if (n->in_plabel[0] != '\0') {
n->in_apr = appr_lookup(n->in_p, n->in_plabel);
if (n->in_apr == NULL)
return -1;
}
return 0;
}
@ -1341,23 +1341,31 @@ int getlock;
ATOMIC_INC(nat_stats.ns_rules);
nat_resolverule(in);
if (nat_resolverule(in) != 0) {
error = ESRCH;
goto junkput;
}
}
/*
* Check that the NAT entry doesn't already exist in the kernel.
*
* For NAT_OUTBOUND, we're lookup for a duplicate MAP entry. To do
* this, we check to see if the inbound combination of addresses and
* ports is already known. Similar logic is applied for NAT_INBOUND.
*
*/
bzero((char *)&fin, sizeof(fin));
fin.fin_p = nat->nat_p;
fin.fin_ifp = nat->nat_ifps[0];
if (nat->nat_dir == NAT_OUTBOUND) {
fin.fin_data[0] = ntohs(nat->nat_oport);
fin.fin_data[1] = ntohs(nat->nat_outport);
fin.fin_ifp = nat->nat_ifps[1];
if (getlock) {
READ_ENTER(&ipf_nat);
}
n = nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip,
nat->nat_inip);
n = nat_inlookup(&fin, nat->nat_flags, fin.fin_p,
nat->nat_oip, nat->nat_inip);
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
@ -1368,12 +1376,11 @@ int getlock;
} else if (nat->nat_dir == NAT_INBOUND) {
fin.fin_data[0] = ntohs(nat->nat_outport);
fin.fin_data[1] = ntohs(nat->nat_oport);
fin.fin_ifp = nat->nat_ifps[0];
if (getlock) {
READ_ENTER(&ipf_nat);
}
n = nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip,
nat->nat_oip);
n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p,
nat->nat_outip, nat->nat_oip);
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
@ -1438,6 +1445,12 @@ int getlock;
fr->fr_ref = 1;
(void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE);
bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr));
fr->fr_ref = 1;
fr->fr_dsize = 0;
fr->fr_data = NULL;
fr->fr_type = FR_T_NONE;
MUTEX_NUKE(&fr->fr_lock);
MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
} else {
@ -1577,6 +1590,9 @@ int logtype;
MUTEX_EXIT(&ipf_nat_new);
return;
}
/*
* At this point, nat_ref can be either 0 or -1
*/
#ifdef IPFILTER_SYNC
if (nat->nat_sync)
@ -2155,6 +2171,9 @@ natinfo_t *ni;
/* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */
/* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */
/* and (3) building that structure and putting it into the NAT table(s). */
/* */
/* NOTE: natsave should NOT be used top point back to an ipstate_t struct */
/* as it can result in memory being corrupted. */
/* ------------------------------------------------------------------------ */
nat_t *nat_new(fin, np, natsave, flags, direction)
fr_info_t *fin;
@ -2248,6 +2267,7 @@ int direction;
natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
KFREE(nat);
nat = natl;
goto done;
}
@ -2265,6 +2285,7 @@ int direction;
natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
KFREE(nat);
nat = natl;
goto done;
}
@ -2378,7 +2399,12 @@ int direction;
np = ni->nai_np;
COPYIFNAME(fin->fin_ifp, nat->nat_ifnames[0]);
if (np->in_ifps[0] != NULL) {
COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]);
}
if (np->in_ifps[1] != NULL) {
COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]);
}
#ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0)
nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat);
@ -2386,7 +2412,8 @@ int direction;
nat->nat_me = natsave;
nat->nat_dir = direction;
nat->nat_ifps[0] = fin->fin_ifp;
nat->nat_ifps[0] = np->in_ifps[0];
nat->nat_ifps[1] = np->in_ifps[1];
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
@ -2473,7 +2500,7 @@ int rev;
nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4);
if (nat->nat_ifnames[1][0] !='\0') {
if (nat->nat_ifnames[1][0] != '\0') {
nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4);
} else {
@ -2821,8 +2848,9 @@ int dir;
*
* Since the port fields are part of the TCP/UDP checksum
* of the offending IP packet, you need to adjust that checksum
* as well... but, if you change, you must change the icmp
* checksum *again*, to reflect that change.
* as well... except that the change in the port numbers should
* be offset by the checksum change, so we only need to change
* the ICMP checksum if we only change the ports.
*
* To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not
@ -2857,21 +2885,14 @@ int dir;
* The UDP checksum is optional, only adjust it if
* it has been set.
*/
if ((oip->ip_p == IPPROTO_UDP) &&
(dlen >= 8) && (*csump != 0)) {
if (oip->ip_p == IPPROTO_UDP) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compenstate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
if ((dlen >= 8) && (*csump != 0)) {
fix_datacksum(csump, sumd);
} else {
sumd2 += sumd;
}
}
/*
@ -2880,20 +2901,10 @@ int dir;
* the other direction compared to the ICMP message.
*/
if (oip->ip_p == IPPROTO_TCP) {
sumd = sum1 - sum2;
if (dlen >= 18) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
* TCP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} else {
sumd = sum2 - sum1 + 1;
sumd2 += sumd;
@ -2913,21 +2924,14 @@ int dir;
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
if ((oip->ip_p == IPPROTO_UDP) &&
(dlen >= 8) && (*csump != 0)) {
if (oip->ip_p == IPPROTO_UDP) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
if ((dlen >= 8) && (*csump != 0)) {
fix_datacksum(csump, sumd);
} else {
sumd2 += sumd;
}
}
/*
@ -2936,20 +2940,10 @@ int dir;
* the other direction compared to the ICMP message.
*/
if (oip->ip_p == IPPROTO_TCP) {
sumd = sum1 - sum2;
if (dlen >= 18) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
* TCP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} else {
if (nat->nat_dir == NAT_INBOUND)
sumd = sum2 - sum1;
@ -3042,10 +3036,7 @@ struct in_addr src , mapdst;
void *ifp;
u_int hv;
if (fin != NULL)
ifp = fin->fin_ifp;
else
ifp = NULL;
ifp = fin->fin_ifp;
sport = 0;
dport = 0;
gre = NULL;
@ -3077,17 +3068,13 @@ struct in_addr src , mapdst;
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
if (nat->nat_ifps[0] != NULL) {
if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
continue;
} else if (ifp != NULL)
nat->nat_ifps[0] = ifp;
if (ifp != NULL) {
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[0])
continue;
} else {
if (ifp != nat->nat_ifps[1])
continue;
}
}
nflags = nat->nat_flags;
if (nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst &&
@ -3152,15 +3139,11 @@ struct in_addr src , mapdst;
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
if (ifp != NULL) {
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[0])
continue;
} else {
if (ifp != nat->nat_ifps[1])
continue;
}
}
if (nat->nat_ifps[0] != NULL) {
if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
continue;
} else if (ifp != NULL)
nat->nat_ifps[0] = ifp;
if (nat->nat_p != fin->fin_p)
continue;
@ -3327,17 +3310,13 @@ struct in_addr src , dst;
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
if (nat->nat_ifps[1] != NULL) {
if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
continue;
} else if (ifp != NULL)
nat->nat_ifps[1] = ifp;
if (ifp != NULL) {
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[1])
continue;
} else {
if (ifp != nat->nat_ifps[0])
continue;
}
}
nflags = nat->nat_flags;
if (nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
@ -3392,15 +3371,11 @@ struct in_addr src , dst;
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
if (ifp != NULL) {
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[1])
continue;
} else {
if (ifp != nat->nat_ifps[0])
continue;
}
}
if (nat->nat_ifps[1] != NULL) {
if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
continue;
} else if (ifp != NULL)
nat->nat_ifps[1] = ifp;
if (nat->nat_p != fin->fin_p)
continue;
@ -3449,6 +3424,16 @@ struct in_addr src , dst;
/* entry for. */
/* */
/* Lookup the NAT tables to search for a matching redirect */
/* The contents of natlookup_t should imitate those found in a packet that */
/* would be translated - ie a packet coming in for RDR or going out for MAP.*/
/* We can do the lookup in one of two ways, imitating an inbound or */
/* outbound packet. By default we assume outbound, unless IPN_IN is set. */
/* For IN, the fields are set as follows: */
/* nl_real* = source information */
/* nl_out* = destination information (translated) */
/* For an out packet, the fields are set like this: */
/* nl_in* = source information (untranslated) */
/* nl_out* = destination information (translated) */
/* ------------------------------------------------------------------------ */
nat_t *nat_lookupredir(np)
natlookup_t *np;
@ -3710,7 +3695,7 @@ u_32_t *passp;
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
for (np = nat_rules[hv]; np; np = np->in_mnext)
{
if ((np->in_ifps[0] && (np->in_ifps[0] != ifp)))
if ((np->in_ifps[1] && (np->in_ifps[1] != ifp)))
continue;
if (np->in_v != fin->fin_v)
continue;
@ -4349,8 +4334,8 @@ void fr_natexpire()
{
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
SPL_INT(s);
int i;
SPL_INT(s);
SPL_NET(s);
WRITE_ENTER(&ipf_nat);

View File

@ -104,7 +104,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.14 2005/06/18 02:41:33 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.16 2006/03/29 11:19:56 darrenr Exp $";
#endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
@ -324,8 +324,7 @@ int mode;
if (error == 0)
error = appr_ctl(&ctl);
if ((ctl.apc_dsize > 0) && (ptr != NULL) &&
(ctl.apc_data == ptr)) {
if (ptr != NULL) {
KFREES(ptr, ctl.apc_dsize);
}
break;
@ -564,8 +563,8 @@ nat_t *nat;
if (err != 0) {
short adjlen = err & 0xffff;
s1 = LONG_SUM(ip->ip_len - adjlen);
s2 = LONG_SUM(ip->ip_len);
s1 = LONG_SUM(fin->fin_plen - adjlen);
s2 = LONG_SUM(fin->fin_plen);
CALC_SUMD(s1, s2, sd);
fix_outcksum(fin, &ip->ip_sum, sd);
}
@ -585,19 +584,23 @@ nat_t *nat;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum)
tcp->th_sum = fr_cksum(fin->fin_qfm, ip,
IPPROTO_TCP, tcp);
IPPROTO_TCP, tcp,
fin->fin_plen);
#else
tcp->th_sum = fr_cksum(fin->fin_m, ip,
IPPROTO_TCP, tcp);
IPPROTO_TCP, tcp,
fin->fin_plen);
#endif
} else if ((udp != NULL) && (udp->uh_sum != 0)) {
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum)
udp->uh_sum = fr_cksum(fin->fin_qfm, ip,
IPPROTO_UDP, udp);
IPPROTO_UDP, udp,
fin->fin_plen);
#else
udp->uh_sum = fr_cksum(fin->fin_m, ip,
IPPROTO_UDP, udp);
IPPROTO_UDP, udp,
fin->fin_plen);
#endif
}
aps->aps_bytes += fin->fin_plen;
@ -688,9 +691,9 @@ int inc;
tcp = (tcphdr_t *)fin->fin_dp;
out = fin->fin_out;
/*
* ip_len has already been adjusted by 'inc'.
* fin->fin_plen has already been adjusted by 'inc'.
*/
nlen = ip->ip_len;
nlen = fin->fin_plen;
nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2);
inc2 = inc;

View File

@ -5,7 +5,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_rcmd_pxy.c,v 1.41.2.5 2005/10/02 04:20:07 darrenr Exp $
* $Id: ip_rcmd_pxy.c,v 1.41.2.6 2006/04/01 10:14:54 darrenr Exp $
*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code.
@ -205,7 +205,7 @@ nat_t *nat;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
(void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
(void) fr_addstate(&fi, NULL, SI_W_DPORT);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}

View File

@ -109,7 +109,7 @@ struct file;
#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.186.2.36 2005/12/04 22:25:36 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.41 2006/04/01 10:16:28 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@ -670,6 +670,7 @@ caddr_t data;
fr->fr_ref = 0;
fr->fr_dsize = 0;
fr->fr_data = NULL;
fr->fr_type = FR_T_NONE;
fr_resolvedest(&fr->fr_tif, fr->fr_v);
fr_resolvedest(&fr->fr_dif, fr->fr_v);
@ -803,6 +804,11 @@ int rev;
/* Inserts it into the state table and appends to the bottom of the active */
/* list. If the capacity of the table has reached the maximum allowed then */
/* the call will fail and a flush is scheduled for the next timeout call. */
/* */
/* NOTE: The use of stsave to point to nat_state will result in memory */
/* corruption. It should only be used to point to objects that will */
/* either outlive this (not expired) or will deref the ip_state_t */
/* when they are deleted. */
/* ------------------------------------------------------------------------ */
ipstate_t *fr_addstate(fin, stsave, flags)
fr_info_t *fin;
@ -825,28 +831,30 @@ u_int flags;
if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN))
return NULL;
fr = fin->fin_fr;
if ((fr->fr_statemax == 0) && (ips_num == fr_statemax)) {
ATOMIC_INCL(ips_stats.iss_max);
fr_state_doflush = 1;
return NULL;
}
/*
* If a "keep state" rule has reached the maximum number of references
* to it, then schedule an automatic flush in case we can clear out
* some "dead old wood".
* some "dead old wood". Note that because the lock isn't held on
* fr it is possible that we could overflow. The cost of overflowing
* is being ignored here as the number by which it can overflow is
* a product of the number of simultaneous threads that could be
* executing in here, so a limit of 100 won't result in 200, but could
* result in 101 or 102.
*/
MUTEX_ENTER(&fr->fr_lock);
if ((fr != NULL) && (fr->fr_statemax != 0) &&
(fr->fr_statecnt >= fr->fr_statemax)) {
MUTEX_EXIT(&fr->fr_lock);
ATOMIC_INCL(ips_stats.iss_maxref);
fr_state_doflush = 1;
return NULL;
fr = fin->fin_fr;
if (fr != NULL) {
if ((ips_num == fr_statemax) && (fr->fr_statemax == 0)) {
ATOMIC_INCL(ips_stats.iss_max);
fr_state_doflush = 1;
return NULL;
}
if ((fr->fr_statemax != 0) &&
(fr->fr_statecnt >= fr->fr_statemax)) {
ATOMIC_INCL(ips_stats.iss_maxref);
fr_state_doflush = 1;
return NULL;
}
}
fr->fr_statecnt++;
MUTEX_EXIT(&fr->fr_lock);
pass = (fr == NULL) ? 0 : fr->fr_flags;
@ -1048,16 +1056,16 @@ u_int flags;
break;
}
if (is != NULL)
goto cantaddstate;
return NULL;
if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) {
ATOMIC_INCL(ips_stats.iss_bucketfull);
goto cantaddstate;
return NULL;
}
KMALLOC(is, ipstate_t *);
if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_nomem);
goto cantaddstate;
return NULL;
}
bcopy((char *)&ips, (char *)is, sizeof(*is));
/*
@ -1142,6 +1150,7 @@ u_int flags;
is->is_optmsk[0] &= ~0x8;
is->is_optmsk[1] &= ~0x8;
}
is->is_me = stsave;
is->is_sec = fin->fin_secmsk;
is->is_secmsk = 0xffff;
is->is_auth = fin->fin_auth;
@ -1156,7 +1165,6 @@ u_int flags;
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
READ_ENTER(&ipf_state);
is->is_me = stsave;
fr_stinsert(is, fin->fin_rev);
@ -1190,14 +1198,6 @@ u_int flags;
(void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
return is;
cantaddstate:
if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
fr->fr_statecnt--;
MUTEX_EXIT(&fr->fr_lock);
}
return NULL;
}
@ -1457,18 +1457,6 @@ int flags;
win = ntohs(tcp->th_win);
else
win = ntohs(tcp->th_win) << fdata->td_winscale;
#if 0
/*
* XXX - This is a kludge is here because IPFilter doesn't track SACK
* options in TCP packets. This is not a trivial to do if one is to
* consider the performance impact of it. So instead, if the
* receiver has said SACK is ok, double the allowed window size.
* This is disabled for testing of another workaround for a problem
* with Microsoft Windows - see below.
*/
if ((tdata->td_winflags & TCP_SACK_PERMIT) != 0)
win *= 2;
#endif
/*
* A window of 0 produces undesirable behaviour from this function.
@ -1555,6 +1543,39 @@ int flags;
(fdata->td_winflags & TCP_SACK_PERMIT) &&
(tdata->td_winflags & TCP_SACK_PERMIT)) {
inseq = 1;
/*
* Sometimes a TCP RST will be generated with only the ACK field
* set to non-zero.
*/
} else if ((seq == 0) && (tcpflags == (TH_RST|TH_ACK)) &&
(ackskew >= -1) && (ackskew <= 1)) {
inseq = 1;
} else if (!(flags & IS_TCPFSM)) {
int i;
i = (fin->fin_rev << 1) + fin->fin_out;
#if 0
if (is_pkts[i]0 == 0) {
/*
* Picking up a connection in the middle, the "next"
* packet seen from a direction that is new should be
* accepted, even if it appears out of sequence.
*/
inseq = 1;
} else
#endif
if (!(fdata->td_winflags &
(TCP_WSCALE_SEEN|TCP_WSCALE_FIRST))) {
/*
* No TCPFSM and no window scaling, so make some
* extra guesses.
*/
if ((seq == fdata->td_maxend) && (ackskew == 0))
inseq = 1;
else if (SEQ_GE(seq + maxwin, fdata->td_end - maxwin))
inseq = 1;
}
}
if (inseq) {
@ -2341,7 +2362,8 @@ ipftq_t **ifqp;
if ((is->is_p != pr) || (is->is_v != v))
continue;
is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
if (is != NULL &&
if ((is != NULL) &&
(ic->icmp_id == is->is_icmp.ici_id) &&
fr_matchicmpqueryreply(v, &is->is_icmp,
ic, fin->fin_rev)) {
if (fin->fin_rev)
@ -2434,11 +2456,13 @@ ipftq_t **ifqp;
break;
}
if ((is != NULL) && ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) &&
(is->is_tqehead[fin->fin_rev] != NULL))
ifq = is->is_tqehead[fin->fin_rev];
if (ifq != NULL && ifqp != NULL)
*ifqp = ifq;
if (is != NULL) {
if (((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) &&
(is->is_tqehead[fin->fin_rev] != NULL))
ifq = is->is_tqehead[fin->fin_rev];
if (ifq != NULL && ifqp != NULL)
*ifqp = ifq;
}
return is;
}

View File

@ -98,7 +98,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.5 2005/09/04 12:51:12 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.7 2006/03/19 14:59:39 darrenr Exp $";
#endif
#define SYNC_STATETABSZ 256
@ -704,7 +704,6 @@ int ipfsync_nat(sp, data)
synchdr_t *sp;
void *data;
{
synclogent_t sle;
syncupdent_t su;
nat_t *n, *nat;
synclist_t *sl;
@ -716,8 +715,6 @@ void *data;
switch (sp->sm_cmd)
{
case SMC_CREATE :
bcopy(data, &sle, sizeof(sle));
KMALLOC(n, nat_t *);
if (n == NULL) {
err = ENOMEM;
@ -731,9 +728,7 @@ void *data;
break;
}
WRITE_ENTER(&ipf_nat);
nat = &sle.sle_un.sleu_ipn;
nat = (nat_t *)data;
bzero((char *)n, offsetof(nat_t, nat_age));
bcopy((char *)&nat->nat_age, (char *)&n->nat_age,
sizeof(*n) - offsetof(nat_t, nat_age));
@ -743,6 +738,8 @@ void *data;
sl->sl_idx = -1;
sl->sl_ipn = n;
sl->sl_num = ntohl(sp->sm_num);
WRITE_ENTER(&ipf_nat);
sl->sl_pnext = syncstatetab + hv;
sl->sl_next = syncstatetab[hv];
if (syncstatetab[hv] != NULL)
@ -1007,4 +1004,16 @@ int mode;
{
return EINVAL;
}
int ipfsync_canread()
{
return !((sl_tail == sl_idx) && (su_tail == su_idx));
}
int ipfsync_canwrite()
{
return 1;
}
#endif /* IPFILTER_SYNC */

View File

@ -7,14 +7,14 @@
*
* @(#)ipl.h 1.21 6/5/96
* $FreeBSD$
* Id: ipl.h,v 2.52.2.9 2005/03/30 14:14:05 darrenr Exp
* Id: ipl.h,v 2.52.2.14 2006/04/01 20:09:42 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v4.1.10"
#define IPL_VERSION "IP Filter: v4.1.13"
#define IPFILTER_VERSION 4011000
#define IPFILTER_VERSION 4011300
#endif

View File

@ -15,6 +15,10 @@
#include <sys/conf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/select.h>
#if __FreeBSD_version >= 500000
# include <sys/selinfo.h>
#endif
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
@ -27,6 +31,9 @@
#include <netinet/ip_nat.h>
#include <netinet/ip_auth.h>
#include <netinet/ip_frag.h>
#include <netinet/ip_sync.h>
extern struct selinfo ipfselwait[IPL_LOGSIZE];
#if __FreeBSD_version >= 502116
static struct cdev *ipf_devs[IPL_LOGSIZE];
@ -95,6 +102,10 @@ SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
#define CDEV_MAJOR 79
#if __FreeBSD_version >= 501000
# include <sys/poll.h>
# include <sys/select.h>
static int iplpoll(struct cdev *dev, int events, struct thread *td);
static struct cdevsw ipl_cdevsw = {
# if __FreeBSD_version >= 502103
.d_version = D_VERSION,
@ -106,6 +117,7 @@ static struct cdevsw ipl_cdevsw = {
.d_write = iplwrite,
.d_ioctl = iplioctl,
.d_name = "ipl",
.d_poll = iplpoll,
# if __FreeBSD_version < 600000
.d_maj = CDEV_MAJOR,
# endif
@ -117,7 +129,7 @@ static struct cdevsw ipl_cdevsw = {
/* read */ iplread,
/* write */ iplwrite,
/* ioctl */ iplioctl,
/* poll */ nopoll,
/* poll */ iplpoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "ipl",
@ -273,3 +285,51 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
return (error);
}
#endif
#if __FreeBSD_version >= 501000
static int
iplpoll(struct cdev *dev, int events, struct thread *td)
{
u_int xmin = GET_MINOR(dev);
int revents;
if (xmin < 0 || xmin > IPL_LOGMAX)
return 0;
revents = 0;
switch (xmin)
{
case IPL_LOGIPF :
case IPL_LOGNAT :
case IPL_LOGSTATE :
#ifdef IPFILTER_LOG
if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin))
revents |= events & (POLLIN | POLLRDNORM);
#endif
break;
case IPL_LOGAUTH :
if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting())
revents |= events & (POLLIN | POLLRDNORM);
break;
case IPL_LOGSYNC :
#ifdef IPFILTER_SYNC
if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread())
revents |= events & (POLLIN | POLLRDNORM);
if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite())
revents |= events & (POLLOUT | POLLWRNORM);
#endif
break;
case IPL_LOGSCAN :
case IPL_LOGLOOKUP :
default :
break;
}
if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
selrecord(td, &ipfselwait[xmin]);
return revents;
}
#endif