Import IP Filter 4.1.13

This commit is contained in:
guido 2006-08-16 11:51:32 +00:00
parent 74f74123f3
commit 83043906d8
21 changed files with 563 additions and 408 deletions

View File

@ -1,28 +1,29 @@
Copyright (C) 1993-2002 by Darren Reed.
The author accepts no responsibility for the use of this software and
provides it on an ``as is'' basis without express or implied warranty.
Redistribution and use, with or without modification, in source and binary
forms, are permitted provided that this notice is preserved in its entirety
and due credit is given to the original author and the contributors.
The licence and distribution terms for any publically available version or
derivative of this code cannot be changed. i.e. this code cannot simply be
copied, in part or in whole, and put under another distribution licence
[including the GNU Public Licence.]
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
I hate legalese, don't you ?
/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* The author accepts no responsibility for the use of this software and
* provides it on an ``as is'' basis without express or implied warranty.
*
* Redistribution and use, with or without modification, in source and binary
* forms, are permitted provided that this notice is preserved in its entirety
* and due credit is given to the original author and the contributors.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied, in part or in whole, and put under another distribution licence
* [including the GNU Public Licence.]
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* I hate legalese, don't you ?
*/

View File

@ -137,7 +137,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[] = "@(#)$Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 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
@ -145,12 +145,6 @@ static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 dar
# 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 */
@ -1972,24 +1966,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
/*
@ -2021,18 +2014,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
@ -2044,6 +2039,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 {
@ -2193,7 +2189,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
@ -2233,21 +2230,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)
@ -2313,8 +2295,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
@ -2328,6 +2308,8 @@ int out;
if ((u_int)ip & 0x3)
return 2;
# else
SPL_INT(s);
# endif
READ_ENTER(&ipf_global);
@ -2493,6 +2475,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;
/*
@ -2547,7 +2546,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 ?
@ -2573,6 +2572,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;
@ -2786,10 +2793,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;
@ -2814,7 +2821,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;
@ -2826,9 +2833,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++;
@ -3059,7 +3066,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,
@ -3472,7 +3479,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;
@ -3760,13 +3767,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;
}
@ -4886,7 +4887,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);
}
@ -4908,8 +4909,6 @@ ipftqent_t *tqe;
ipftq_t *ifq;
ifq = tqe->tqe_ifq;
if (ifq == NULL)
return;
MUTEX_ENTER(&ifq->ifq_lock);
@ -4981,24 +4980,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);
}
@ -5050,46 +5046,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);
}
@ -5573,7 +5567,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

@ -117,12 +117,13 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
/* END OF INCLUDES */
#if !defined(lint)
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.5 2005/06/12 07:18:14 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;
@ -317,7 +318,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)
@ -339,17 +340,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
@ -362,15 +361,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)
{
@ -399,10 +398,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
@ -416,11 +419,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);
@ -473,10 +477,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:
@ -487,6 +489,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);
@ -501,7 +504,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
@ -521,7 +528,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
@ -552,10 +563,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.
@ -579,7 +586,6 @@ int mode;
}
}
}
# endif /* MENTAT */
#endif /* _KERNEL */
SPL_X(s);
break;
@ -794,3 +800,9 @@ int fr_authflush()
return num_flushed;
}
int fr_auth_waiting()
{
return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext];
}

View File

@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $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__
@ -20,6 +20,7 @@ typedef struct frauth {
char *fra_buf;
#ifdef MENTAT
queue_t *fra_q;
mb_t *fra_m;
#endif
} frauth_t;
@ -60,5 +61,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

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.142.2.33 2005/12/04 23:40:17 darrenr Exp $
* $Id: ip_compat.h,v 2.142.2.36 2006/03/26 05:50:29 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -441,6 +441,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)))
@ -578,6 +579,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)
@ -659,6 +661,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))
@ -1029,6 +1032,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"); }
@ -1074,6 +1078,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
@ -1265,6 +1270,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))
@ -1429,6 +1435,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) ;
@ -1451,6 +1458,7 @@ typedef struct mb_s {
# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
extern int bcopywrap __P((void *, void *, size_t));
# ifndef CACHE_HASH
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
@ -1529,6 +1537,9 @@ typedef struct ip6_hdr ip6_t;
#endif
#if defined(_KERNEL)
# ifdef BSD
extern struct selinfo ipfselwait[];
# endif
# ifdef MENTAT
# define COPYDATA mb_copydata
# define COPYBACK mb_copyback
@ -1578,6 +1589,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

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_fil.h,v 2.170.2.23 2005/12/04 23:39:28 darrenr Exp $
* $Id: ip_fil.h,v 2.170.2.29 2006/03/29 11:19:55 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -305,6 +305,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;
@ -1133,6 +1134,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 **));
@ -1148,6 +1160,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));
@ -1259,7 +1272,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 *));
@ -1316,6 +1329,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));
@ -1324,7 +1338,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

@ -5,7 +5,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)
@ -55,6 +55,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
@ -131,6 +132,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>
@ -300,6 +302,7 @@ int iplattach()
fr_checkp = fr_check;
}
bzero((char *)ipfselwait, sizeof(ipfselwait));
bzero((char *)frcache, sizeof(frcache));
fr_running = 1;
@ -476,9 +479,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;
}
@ -619,7 +624,10 @@ int mode;
error = EINVAL;
break;
}
RWLOCK_EXIT(&ipf_global);
SPL_X(s);
return error;
}
@ -742,14 +750,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
@ -1155,6 +1167,8 @@ frdest_t *fdp;
u_short ip_off;
frentry_t *fr;
ro = NULL;
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@ -1168,15 +1182,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
@ -1218,18 +1232,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);
@ -1346,6 +1350,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; /* ??? */
@ -1356,7 +1361,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;
}
/*
@ -1385,7 +1389,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;
@ -1488,6 +1492,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

@ -100,7 +100,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[] = "@(#)$Id: ip_frag.c,v 2.77.2.4 2005/08/20 13:48:21 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.5 2006/02/26 08:26:54 darrenr Exp $";
#endif
@ -224,6 +224,7 @@ ipfr_t *table[];
{
ipfr_t *fra, frag;
u_int idx, off;
frentry_t *fr;
ip_t *ip;
if (ipfr_inuse >= IPFT_SIZE)
@ -275,12 +276,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

@ -6,7 +6,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_ftp_pxy.c,v 2.88.2.16 2005/12/04 23:39:27 darrenr Exp $
* $Id: ip_ftp_pxy.c,v 2.88.2.19 2006/04/01 10:14:53 darrenr Exp $
*/
#define IPF_FTP_PROXY
@ -366,7 +366,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);
}
@ -728,7 +728,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);
}
@ -1027,13 +1027,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];
@ -1423,7 +1424,7 @@ int dlen;
ap += *s++ - '0';
}
if (!s)
if (!*s)
return 0;
if (*s == '|')

View File

@ -1,5 +1,3 @@
/* $FreeBSD$ */
/*
* Copyright 2001, QNX Software Systems Ltd. All Rights Reserved
*
@ -248,7 +246,7 @@ nat_t *nat;
tcp = (tcphdr_t *)fin->fin_dp;
ipaddr = nat->nat_inip.s_addr;
data = (caddr_t)tcp + (TCP_OFF(tcp) << 2);
datlen = ip->ip_len - fin->fin_hlen - (TCP_OFF(tcp) << 2);
datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
if (find_port(ipaddr, data, datlen, &off, &port) == 0) {
fr_info_t fi;
nat_t *nat2;

View File

@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_log.c,v 2.75.2.7 2005/06/11 07:47:44 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)
@ -65,6 +65,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>
@ -145,6 +149,7 @@ 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];
@ -503,9 +508,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
@ -663,4 +670,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

@ -107,7 +107,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[] = "@(#)$Id: ip_nat.c,v 2.195.2.47 2005/11/14 17:13:35 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.56 2006/04/01 10:15:34 darrenr Exp $";
#endif
@ -191,7 +191,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));
@ -865,11 +865,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;
@ -994,7 +991,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';
@ -1005,12 +1002,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;
}
@ -1338,23 +1338,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);
}
@ -1365,12 +1373,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);
}
@ -1435,6 +1442,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 {
@ -1574,6 +1587,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)
@ -2152,6 +2168,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;
@ -2245,6 +2264,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;
}
@ -2262,6 +2282,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;
}
@ -2375,7 +2396,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);
@ -2383,7 +2409,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;
@ -2470,7 +2497,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 {
@ -2818,8 +2845,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
@ -2854,21 +2882,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;
}
}
/*
@ -2877,20 +2898,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;
@ -2910,21 +2921,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;
}
}
/*
@ -2933,20 +2937,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;
@ -3039,10 +3033,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;
@ -3074,17 +3065,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 &&
@ -3149,15 +3136,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;
@ -3324,17 +3307,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 &&
@ -3389,15 +3368,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;
@ -3446,6 +3421,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;
@ -3707,7 +3692,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;
@ -4346,8 +4331,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

@ -4,7 +4,7 @@
* Simple PPTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_pptp_pxy.c,v 2.10.2.11 2005/12/04 23:39:27 darrenr Exp $
* $Id: ip_pptp_pxy.c,v 2.10.2.13 2006/03/17 10:40:05 darrenr Exp $
*
*/
#define IPF_PPTP_PROXY
@ -93,7 +93,8 @@ nat_t *nat;
if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
ip->ip_dst) != NULL) {
if (ippr_pptp_debug > 0)
printf("ippr_pptp_new: GRE session already exists\n");
printf("ippr_pptp_new: GRE session %s\n",
"already exists");
return -1;
}
@ -101,7 +102,8 @@ nat_t *nat;
KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
if (aps->aps_data == NULL) {
if (ippr_pptp_debug > 0)
printf("ippr_pptp_new: malloc for aps_data failed\n");
printf("ippr_pptp_new: malloc for aps_data %s\n",
"failed");
return -1;
}
@ -208,10 +210,12 @@ pptp_pxy_t *pptp;
RWLOCK_EXIT(&ipf_state);
} else {
RWLOCK_EXIT(&ipf_state);
if (nat->nat_dir == NAT_INBOUND)
fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr;
else
fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr;
if (nat2 != NULL) {
if (nat->nat_dir == NAT_INBOUND)
fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr;
else
fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr;
}
fi.fin_ifp = NULL;
pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state,
0);

View File

@ -103,7 +103,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 ));
@ -323,8 +323,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;
@ -563,8 +562,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);
}
@ -584,19 +583,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;
@ -687,9 +690,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

@ -3,7 +3,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.
@ -202,7 +202,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

@ -58,7 +58,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_scan.c,v 2.40.2.4 2005/08/20 13:48:24 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.6 2006/03/26 23:06:49 darrenr Exp $";
#endif
#ifdef IPFILTER_SCAN /* endif at bottom of file */
@ -84,18 +84,23 @@ int ipsc_matchstr __P((sinfo_t *, char *, int));
int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *));
int ipsc_match __P((ipstate_t *));
static int ipsc_inited = 0;
int ipsc_init()
{
RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock");
ipsc_inited = 1;
return 0;
}
void fr_scanunload()
{
RW_DESTROY(&ipsc_rwlock);
if (ipsc_inited == 1) {
RW_DESTROY(&ipsc_rwlock);
ipsc_inited = 0;
}
}
@ -431,6 +436,8 @@ ipstate_t *is;
}
if (k == 1)
isc = lm;
if (isc == NULL)
return 0;
/*
* No matches or partial matches, so reset the respective

View File

@ -107,7 +107,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;
@ -668,6 +668,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);
@ -801,6 +802,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;
@ -823,28 +829,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;
@ -1046,16 +1054,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));
/*
@ -1140,6 +1148,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;
@ -1154,7 +1163,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);
@ -1188,14 +1196,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;
}
@ -1455,18 +1455,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.
@ -1553,6 +1541,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) {
@ -2339,7 +2360,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)
@ -2432,11 +2454,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

@ -96,7 +96,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
@ -702,7 +702,6 @@ int ipfsync_nat(sp, data)
synchdr_t *sp;
void *data;
{
synclogent_t sle;
syncupdent_t su;
nat_t *n, *nat;
synclist_t *sl;
@ -714,8 +713,6 @@ void *data;
switch (sp->sm_cmd)
{
case SMC_CREATE :
bcopy(data, &sle, sizeof(sle));
KMALLOC(n, nat_t *);
if (n == NULL) {
err = ENOMEM;
@ -729,9 +726,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));
@ -741,6 +736,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)
@ -1005,4 +1002,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

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp $
* $Id: ip_sync.h,v 2.11.2.3 2006/03/19 14:59:39 darrenr Exp $
*/
#ifndef __IP_SYNC_H__
@ -111,5 +111,7 @@ extern int ipfsync_nat __P((synchdr_t *sp, void *data));
extern int ipfsync_state __P((synchdr_t *sp, void *data));
extern int ipfsync_read __P((struct uio *uio));
extern int ipfsync_write __P((struct uio *uio));
extern int ipfsync_canread __P((void));
extern int ipfsync_canwrite __P((void));
#endif /* IP_SYNC */

View File

@ -4,14 +4,14 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
* $Id: ipl.h,v 2.52.2.11 2005/12/04 22:37:24 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

@ -12,6 +12,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>
@ -24,6 +28,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];
@ -92,6 +99,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,
@ -103,6 +114,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
@ -114,7 +126,7 @@ static struct cdevsw ipl_cdevsw = {
/* read */ iplread,
/* write */ iplwrite,
/* ioctl */ iplioctl,
/* poll */ nopoll,
/* poll */ iplpoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "ipl",
@ -270,3 +282,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