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. /*
* 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. * 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 * Redistribution and use, with or without modification, in source and binary
and due credit is given to the original author and the contributors. * 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 * The licence and distribution terms for any publically available version or
copied, in part or in whole, and put under another distribution licence * derivative of this code cannot be changed. i.e. this code cannot simply be
[including the GNU Public Licence.] * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
SUCH DAMAGE. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
I hate legalese, don't you ? *
* I hate legalese, don't you ?
*/

View File

@ -137,7 +137,7 @@ struct file;
#if !defined(lint) #if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; 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 #endif
#ifndef _KERNEL #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 "ipt.h"
# include "bpf-ipf.h" # include "bpf-ipf.h"
extern int opts; 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 */ #endif /* _KERNEL */
@ -1972,24 +1966,23 @@ u_32_t pass;
* it, except for increasing the hit counter. * it, except for increasing the hit counter.
*/ */
if ((passt & FR_CALLNOW) != 0) { if ((passt & FR_CALLNOW) != 0) {
frentry_t *frs;
ATOMIC_INC64(fr->fr_hits); ATOMIC_INC64(fr->fr_hits);
if ((fr->fr_func != NULL) && if ((fr->fr_func != NULL) &&
(fr->fr_func != (ipfunc_t)-1)) { (fr->fr_func == (ipfunc_t)-1))
frentry_t *frs; continue;
frs = fin->fin_fr; 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 {
fin->fin_fr = 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 #ifdef IPFILTER_LOG
/* /*
@ -2021,18 +2014,20 @@ u_32_t pass;
(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
if (fr->fr_grp != NULL) { if (fr->fr_grp != NULL) {
fin->fin_fr = *fr->fr_grp; fin->fin_fr = *fr->fr_grp;
pass = fr_scanlist(fin, pass); passt = fr_scanlist(fin, pass);
if (fin->fin_fr == NULL) { if (fin->fin_fr == NULL) {
fin->fin_rule = rulen; fin->fin_rule = rulen;
(void) strncpy(fin->fin_group, fr->fr_group, (void) strncpy(fin->fin_group, fr->fr_group,
FR_GROUPLEN); FR_GROUPLEN);
fin->fin_fr = fr; fin->fin_fr = fr;
passt = pass;
} }
if (fin->fin_flx & FI_DONTCACHE) if (fin->fin_flx & FI_DONTCACHE)
logged = 1; logged = 1;
pass = passt;
} }
if (pass & FR_QUICK) { if (passt & FR_QUICK) {
/* /*
* Finally, if we've asked to track state for this * Finally, if we've asked to track state for this
* packet, set it up. Add state for "quick" rules * packet, set it up. Add state for "quick" rules
@ -2044,6 +2039,7 @@ u_32_t pass;
!(fin->fin_flx & FI_STATE)) { !(fin->fin_flx & FI_STATE)) {
int out = fin->fin_out; int out = fin->fin_out;
fin->fin_fr = fr;
if (fr_addstate(fin, NULL, 0) != NULL) { if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads); ATOMIC_INCL(frstats[out].fr_ads);
} else { } else {
@ -2193,7 +2189,8 @@ u_32_t *passp;
if (FR_ISAUTH(pass)) { if (FR_ISAUTH(pass)) {
if (fr_newauth(fin->fin_m, fin) != 0) { if (fr_newauth(fin->fin_m, fin) != 0) {
#ifdef _KERNEL #ifdef _KERNEL
fin->fin_m = *fin->fin_mp = NULL; if ((pass & FR_RETMASK) == 0)
fin->fin_m = *fin->fin_mp = NULL;
#else #else
; ;
#endif #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; fr = fin->fin_fr;
if (passp != NULL) if (passp != NULL)
@ -2313,8 +2295,6 @@ int out;
#ifdef USE_INET6 #ifdef USE_INET6
ip6_t *ip6; ip6_t *ip6;
#endif #endif
SPL_INT(s);
/* /*
* The first part of fr_check() deals with making sure that what goes * The first part of fr_check() deals with making sure that what goes
* into the filtering engine makes some sense. Information about the * into the filtering engine makes some sense. Information about the
@ -2328,6 +2308,8 @@ int out;
if ((u_int)ip & 0x3) if ((u_int)ip & 0x3)
return 2; return 2;
# else
SPL_INT(s);
# endif # endif
READ_ENTER(&ipf_global); READ_ENTER(&ipf_global);
@ -2493,6 +2475,23 @@ int out;
if ((pass & FR_NOMATCH) || (fr == NULL)) if ((pass & FR_NOMATCH) || (fr == NULL))
fr = fr_firewall(fin, &pass); 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; fin->fin_fr = fr;
/* /*
@ -2547,7 +2546,7 @@ int out;
RWLOCK_EXIT(&ipf_mutex); RWLOCK_EXIT(&ipf_mutex);
if (pass & (FR_RETRST|FR_RETICMP)) { if ((pass & FR_RETMASK) != 0) {
/* /*
* Should we return an ICMP packet to indicate error * Should we return an ICMP packet to indicate error
* status passing through the packet filter ? * status passing through the packet filter ?
@ -2573,6 +2572,14 @@ int out;
ATOMIC_INCL(frstats[1].fr_ret); 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 { } else {
if (pass & FR_RETRST) if (pass & FR_RETRST)
fin->fin_error = ECONNRESET; fin->fin_error = ECONNRESET;
@ -2786,10 +2793,10 @@ int len;
/* */ /* */
/* Expects ip_len to be in host byte order when called. */ /* 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; mb_t *m;
ip_t *ip; ip_t *ip;
int l4proto; int l4proto, l3len;
void *l4hdr; void *l4hdr;
{ {
u_short *sp, slen, sumsave, l4hlen, *csump; u_short *sp, slen, sumsave, l4hlen, *csump;
@ -2814,7 +2821,7 @@ void *l4hdr;
if (IP_V(ip) == 4) { if (IP_V(ip) == 4) {
#endif #endif
hlen = IP_HL(ip) << 2; hlen = IP_HL(ip) << 2;
slen = ip->ip_len - hlen; slen = l3len - hlen;
sum = htons((u_short)l4proto); sum = htons((u_short)l4proto);
sum += htons(slen); sum += htons(slen);
sp = (u_short *)&ip->ip_src; sp = (u_short *)&ip->ip_src;
@ -2826,9 +2833,9 @@ void *l4hdr;
} else if (IP_V(ip) == 6) { } else if (IP_V(ip) == 6) {
ip6 = (ip6_t *)ip; ip6 = (ip6_t *)ip;
hlen = sizeof(*ip6); hlen = sizeof(*ip6);
slen = ntohs(ip6->ip6_plen); slen = ntohs(l3len);
sum = htons((u_short)l4proto); sum = htons((u_short)l4proto);
sum += htons(slen); sum += slen;
sp = (u_short *)&ip6->ip6_src; sp = (u_short *)&ip6->ip6_src;
sum += *sp++; /* ip6_src */ sum += *sp++; /* ip6_src */
sum += *sp++; sum += *sp++;
@ -3059,7 +3066,7 @@ void *l4hdr;
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 * @(#)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, * 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) char *memstr(src, dst, slen, dlen)
const char *src; const char *src;
char *dst; char *dst;
int slen, dlen; size_t slen, dlen;
{ {
char *s = NULL; char *s = NULL;
@ -3760,13 +3767,7 @@ size_t size;
caddr_t ca; caddr_t ca;
int err; 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)); bcopy(dst, (caddr_t)&ca, sizeof(ca));
# endif
err = COPYOUT(src, ca, size); err = COPYOUT(src, ca, size);
return err; return err;
} }
@ -4886,7 +4887,7 @@ ipftq_t *ifq;
ifq->ifq_next->ifq_pnext = ifq->ifq_pnext; ifq->ifq_next->ifq_pnext = ifq->ifq_pnext;
MUTEX_DESTROY(&ifq->ifq_lock); MUTEX_DESTROY(&ifq->ifq_lock);
fr_userifqs--; ATOMIC_DEC(fr_userifqs);
KFREE(ifq); KFREE(ifq);
} }
@ -4908,8 +4909,6 @@ ipftqent_t *tqe;
ipftq_t *ifq; ipftq_t *ifq;
ifq = tqe->tqe_ifq; ifq = tqe->tqe_ifq;
if (ifq == NULL)
return;
MUTEX_ENTER(&ifq->ifq_lock); MUTEX_ENTER(&ifq->ifq_lock);
@ -4981,24 +4980,21 @@ ipftqent_t *tqe;
tqe->tqe_die = fr_ticks + ifq->ifq_ttl; tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
MUTEX_ENTER(&ifq->ifq_lock); MUTEX_ENTER(&ifq->ifq_lock);
if (tqe->tqe_next == NULL) { /* at the end already ? */ if (tqe->tqe_next != NULL) { /* at the end already ? */
MUTEX_EXIT(&ifq->ifq_lock); /*
return; * 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); MUTEX_EXIT(&ifq->ifq_lock);
} }
@ -5050,46 +5046,44 @@ ipftq_t *oifq, *nifq;
* Is the operation here going to be a no-op ? * Is the operation here going to be a no-op ?
*/ */
MUTEX_ENTER(&oifq->ifq_lock); MUTEX_ENTER(&oifq->ifq_lock);
if (oifq == nifq && *oifq->ifq_tail == tqe) { if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) {
MUTEX_EXIT(&oifq->ifq_lock); /*
return; * 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); MUTEX_EXIT(&nifq->ifq_lock);
} }
@ -5573,7 +5567,7 @@ fr_info_t *fin;
if (dosum) if (dosum)
sum = fr_cksum(fin->fin_m, fin->fin_ip, 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) #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID)
} }
#endif #endif

View File

@ -117,12 +117,13 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
/* END OF INCLUDES */ /* END OF INCLUDES */
#if !defined(lint) #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 #endif
#if SOLARIS #if SOLARIS && defined(_KERNEL)
extern kcondvar_t ipfauthwait; extern kcondvar_t ipfauthwait;
extern struct pollhead iplpollhead[IPL_LOGSIZE];
#endif /* SOLARIS */ #endif /* SOLARIS */
#if defined(linux) && defined(_KERNEL) #if defined(linux) && defined(_KERNEL)
wait_queue_head_t fr_authnext_linux; wait_queue_head_t fr_authnext_linux;
@ -317,7 +318,7 @@ fr_info_t *fin;
fra = fr_auth + i; fra = fr_auth + i;
fra->fra_index = i; fra->fra_index = i;
fra->fra_pass = 0; fra->fra_pass = fin->fin_fr->fr_flags;
fra->fra_age = fr_defaultauthage; fra->fra_age = fr_defaultauthage;
bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin)); bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
#if !defined(sparc) && !defined(m68k) #if !defined(sparc) && !defined(m68k)
@ -339,17 +340,15 @@ fr_info_t *fin;
} }
#endif #endif
#if SOLARIS && defined(_KERNEL) #if SOLARIS && defined(_KERNEL)
COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname);
m->b_rptr -= qpi->qpi_off; m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp; fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
fra->fra_q = qpi->qpi_q; /* The queue can disappear! */ 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); cv_signal(&ipfauthwait);
pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM);
#else #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; fr_authpkts[i] = m;
WAKEUP(&fr_authnext,0); WAKEUP(&fr_authnext,0);
#endif #endif
@ -362,15 +361,15 @@ caddr_t data;
ioctlcmd_t cmd; ioctlcmd_t cmd;
int mode; int mode;
{ {
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
char *t;
mb_t *m; mb_t *m;
#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ #if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 501000)) (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq; struct ifqueue *ifq;
SPL_INT(s); SPL_INT(s);
#endif #endif
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
char *t;
switch (cmd) switch (cmd)
{ {
@ -399,10 +398,14 @@ int mode;
case SIOCAUTHW: case SIOCAUTHW:
fr_authioctlloop: fr_authioctlloop:
error = fr_inobj(data, au, IPFOBJ_FRAUTH); error = fr_inobj(data, au, IPFOBJ_FRAUTH);
if (error != 0)
break;
READ_ENTER(&ipf_auth); READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
error = fr_outobj(data, &fr_auth[fr_authnext], error = fr_outobj(data, &fr_auth[fr_authnext],
IPFOBJ_FRAUTH); IPFOBJ_FRAUTH);
if (error != 0)
break;
if (auth.fra_len != 0 && auth.fra_buf != NULL) { if (auth.fra_len != 0 && auth.fra_buf != NULL) {
/* /*
* Copy packet contents out to user space if * Copy packet contents out to user space if
@ -416,11 +419,12 @@ int mode;
for (t = auth.fra_buf; m && (len > 0); ) { for (t = auth.fra_buf; m && (len > 0); ) {
i = MIN(M_LEN(m), len); i = MIN(M_LEN(m), len);
error = copyoutptr(MTOD(m, char *), error = copyoutptr(MTOD(m, char *),
t, i); &t, i);
len -= i; len -= i;
t += i; t += i;
if (error != 0) if (error != 0)
break; break;
m = m->m_next;
} }
} }
RWLOCK_EXIT(&ipf_auth); RWLOCK_EXIT(&ipf_auth);
@ -473,10 +477,8 @@ int mode;
#endif #endif
MUTEX_EXIT(&ipf_authmx); MUTEX_EXIT(&ipf_authmx);
READ_ENTER(&ipf_global); READ_ENTER(&ipf_global);
if (error == 0) { if (error == 0)
READ_ENTER(&ipf_auth);
goto fr_authioctlloop; goto fr_authioctlloop;
}
break; break;
case SIOCAUTHR: case SIOCAUTHR:
@ -487,6 +489,7 @@ int mode;
WRITE_ENTER(&ipf_auth); WRITE_ENTER(&ipf_auth);
i = au->fra_index; i = au->fra_index;
fra = fr_auth + i; fra = fr_auth + i;
error = 0;
if ((i < 0) || (i >= fr_authsize) || if ((i < 0) || (i >= fr_authsize) ||
(fra->fra_info.fin_id != au->fra_info.fin_id)) { (fra->fra_info.fin_id != au->fra_info.fin_id)) {
RWLOCK_EXIT(&ipf_auth); RWLOCK_EXIT(&ipf_auth);
@ -501,7 +504,11 @@ int mode;
#ifdef _KERNEL #ifdef _KERNEL
if ((m != NULL) && (au->fra_info.fin_out != 0)) { if ((m != NULL) && (au->fra_info.fin_out != 0)) {
# ifdef MENTAT # 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 */ # else /* MENTAT */
# if defined(linux) || defined(AIX) # if defined(linux) || defined(AIX)
# else # else
@ -521,7 +528,11 @@ int mode;
fr_authstats.fas_sendok++; fr_authstats.fas_sendok++;
} else if (m) { } else if (m) {
# ifdef MENTAT # 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 */ # else /* MENTAT */
# if defined(linux) || defined(AIX) # if defined(linux) || defined(AIX)
# else # else
@ -552,10 +563,6 @@ int mode;
fr_authstats.fas_queok++; fr_authstats.fas_queok++;
} else } else
error = EINVAL; error = EINVAL;
# ifdef MENTAT
if (error != 0)
error = EINVAL;
# else /* MENTAT */
/* /*
* If we experience an error which will result in the packet * If we experience an error which will result in the packet
* not being processed, make sure we advance to the next one. * not being processed, make sure we advance to the next one.
@ -579,7 +586,6 @@ int mode;
} }
} }
} }
# endif /* MENTAT */
#endif /* _KERNEL */ #endif /* _KERNEL */
SPL_X(s); SPL_X(s);
break; break;
@ -794,3 +800,9 @@ int fr_authflush()
return num_flushed; 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. * 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__ #ifndef __IP_AUTH_H__
@ -20,6 +20,7 @@ typedef struct frauth {
char *fra_buf; char *fra_buf;
#ifdef MENTAT #ifdef MENTAT
queue_t *fra_q; queue_t *fra_q;
mb_t *fra_m;
#endif #endif
} frauth_t; } frauth_t;
@ -60,5 +61,6 @@ extern mb_t **fr_authpkts;
extern int fr_newauth __P((mb_t *, fr_info_t *)); extern int fr_newauth __P((mb_t *, fr_info_t *));
extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_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_ioctl __P((caddr_t, ioctlcmd_t, int));
extern int fr_auth_waiting __P((void));
#endif /* __IP_AUTH_H__ */ #endif /* __IP_AUTH_H__ */

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing. * See the IPFILTER.LICENCE file for details on licencing.
* *
* @(#)ip_compat.h 1.8 1/14/96 * @(#)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__ #ifndef __IP_COMPAT_H__
@ -441,6 +441,7 @@ extern void *get_unit __P((char *, int));
wakeup(id + x); \ wakeup(id + x); \
spinunlock(_l); \ spinunlock(_l); \
} }
# define POLLWAKEUP(x) ;
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT) # 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 KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IOSYS, M_NOWAIT)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) # 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 UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) sleep((id), PZERO+1) # define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id+x) # define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) ;
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) # define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s)) # define KFREES(x,s) kmem_free((char *)(x), (s))
# define GETIFP(n,v) ifunit(n) # define GETIFP(n,v) ifunit(n)
@ -659,6 +661,7 @@ typedef struct mbuf mb_t;
# define GETIFP(n, v) ifunit(n) # define GETIFP(n, v) ifunit(n)
# define GET_MINOR getminor # define GET_MINOR getminor
# define WAKEUP(id,x) wakeup(id + x) # define WAKEUP(id,x) wakeup(id + x)
# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) # 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 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)) # 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 KFREES(x,s) kmem_free((char *)(x), (s))
# define SLEEP(id, n) sleep((id), PZERO+1) # define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id + x) # define WAKEUP(id,x) wakeup(id + x)
# define POLLWAKEUP(x) ;
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) # 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"); } # 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 FREE_MB_T(m) kfree_skb(m)
# define GETKTIME(x) do_gettimeofday((struct timeval *)x) # define GETKTIME(x) do_gettimeofday((struct timeval *)x)
# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux) # define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
# define POLLWAKEUP(x) ;
# define WAKEUP(x,y) wake_up(x##_linux + y) # define WAKEUP(x,y) wake_up(x##_linux + y)
# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d) # define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
# define USE_MUTEXES # define USE_MUTEXES
@ -1265,6 +1270,7 @@ extern void* getifp __P((char *, int));
# define GET_MINOR minor # define GET_MINOR minor
# define SLEEP(id, n) sleepx((id), PZERO+1, 0) # define SLEEP(id, n) sleepx((id), PZERO+1, 0)
# define WAKEUP(id,x) wakeup(id) # define WAKEUP(id,x) wakeup(id)
# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) # 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 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)) # 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 FREE_MB_T(x)
# define SLEEP(x,y) 1; # define SLEEP(x,y) 1;
# define WAKEUP(x,y) ; # define WAKEUP(x,y) ;
# define POLLWAKEUP(y) ;
# define IPF_PANIC(x,y) ; # define IPF_PANIC(x,y) ;
# define PANIC(x,y) ; # define PANIC(x,y) ;
# define SPL_NET(x) ; # define SPL_NET(x) ;
@ -1451,6 +1458,7 @@ typedef struct mb_s {
# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d) # define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
extern void m_copydata __P((mb_t *, int, int, caddr_t)); extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *)); extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
extern int bcopywrap __P((void *, void *, size_t));
# ifndef CACHE_HASH # ifndef CACHE_HASH
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ # define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7) ((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
@ -1529,6 +1537,9 @@ typedef struct ip6_hdr ip6_t;
#endif #endif
#if defined(_KERNEL) #if defined(_KERNEL)
# ifdef BSD
extern struct selinfo ipfselwait[];
# endif
# ifdef MENTAT # ifdef MENTAT
# define COPYDATA mb_copydata # define COPYDATA mb_copydata
# define COPYBACK mb_copyback # define COPYBACK mb_copyback
@ -1578,6 +1589,7 @@ MALLOC_DECLARE(M_IPFILTER);
# define UIOMOVE(a,b,c,d) uiomove(a,b,d) # define UIOMOVE(a,b,c,d) uiomove(a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0) # define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id,x) wakeup(id+x) # define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) selwakeup(ipfselwait+x)
# define GETIFP(n, v) ifunit(n) # define GETIFP(n, v) ifunit(n)
# endif /* (Free)BSD */ # endif /* (Free)BSD */

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing. * See the IPFILTER.LICENCE file for details on licencing.
* *
* @(#)ip_fil.h 1.35 6/5/96 * @(#)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__ #ifndef __IP_FIL_H__
@ -305,6 +305,7 @@ typedef struct fr_info {
#ifdef MENTAT #ifdef MENTAT
mb_t *fin_qfm; /* pointer to mblk where pkt starts */ mb_t *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qpi; void *fin_qpi;
char fin_ifname[LIFNAMSIZ];
#endif #endif
#ifdef __sgi #ifdef __sgi
void *fin_hbuf; void *fin_hbuf;
@ -1133,6 +1134,17 @@ typedef struct ipftune {
# endif # endif
#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 #ifndef _KERNEL
extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); extern int fr_check __P((struct ip *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, 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 iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int)); extern int iplclose __P((dev_t, int));
extern void m_freem __P((mb_t *)); extern void m_freem __P((mb_t *));
extern int bcopywrap __P((void *, void *, size_t));
#else /* #ifndef _KERNEL */ #else /* #ifndef _KERNEL */
# if defined(__NetBSD__) && defined(PFIL_HOOKS) # if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern void ipfilterattach __P((int)); 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_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
extern ipfrwlock_t ipf_frcache; 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 count4bits __P((u_32_t));
extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int)); extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int));
extern char *getifname __P((struct ifnet *)); 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 frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***));
extern int fr_loginit __P((void)); extern int fr_loginit __P((void));
extern int ipflog_canread __P((int));
extern int ipflog_clear __P((minor_t)); extern int ipflog_clear __P((minor_t));
extern int ipflog_read __P((minor_t, uio_t *)); extern int ipflog_read __P((minor_t, uio_t *));
extern int ipflog __P((fr_info_t *, u_int)); 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 frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *));
extern int fr_copytolog __P((int, char *, int)); 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 void fr_deinitialise __P((void));
extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *)); extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *));
extern frentry_t *fr_dstgrpmap __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) #if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 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 #endif
#if defined(KERNEL) || defined(_KERNEL) #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 #endif
#include <sys/protosw.h> #include <sys/protosw.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/selinfo.h>
#include <net/if.h> #include <net/if.h>
#if __FreeBSD_version >= 300000 #if __FreeBSD_version >= 300000
@ -131,6 +132,7 @@ int ipf_locks_done = 0;
#if (__FreeBSD_version >= 300000) #if (__FreeBSD_version >= 300000)
struct callout_handle fr_slowtimer_ch; struct callout_handle fr_slowtimer_ch;
#endif #endif
struct selinfo ipfselwait[IPL_LOGSIZE];
#if (__FreeBSD_version >= 500011) #if (__FreeBSD_version >= 500011)
# include <sys/conf.h> # include <sys/conf.h>
@ -300,6 +302,7 @@ int iplattach()
fr_checkp = fr_check; fr_checkp = fr_check;
} }
bzero((char *)ipfselwait, sizeof(ipfselwait));
bzero((char *)frcache, sizeof(frcache)); bzero((char *)frcache, sizeof(frcache));
fr_running = 1; fr_running = 1;
@ -476,9 +479,11 @@ int mode;
} }
SPL_NET(s); SPL_NET(s);
READ_ENTER(&ipf_global);
error = fr_ioctlswitch(unit, data, cmd, mode); error = fr_ioctlswitch(unit, data, cmd, mode);
if (error != -1) { if (error != -1) {
RWLOCK_EXIT(&ipf_global);
SPL_X(s); SPL_X(s);
return error; return error;
} }
@ -619,7 +624,10 @@ int mode;
error = EINVAL; error = EINVAL;
break; break;
} }
RWLOCK_EXIT(&ipf_global);
SPL_X(s); SPL_X(s);
return error; return error;
} }
@ -742,14 +750,18 @@ dev_t dev;
#endif #endif
register struct uio *uio; register struct uio *uio;
{ {
u_int xmin = GET_MINOR(dev);
if (xmin < 0)
return ENXIO;
# ifdef IPFILTER_SYNC # ifdef IPFILTER_SYNC
if (GET_MINOR(dev) == IPL_LOGSYNC) if (xmin == IPL_LOGSYNC)
return ipfsync_read(uio); return ipfsync_read(uio);
# endif # endif
#ifdef IPFILTER_LOG #ifdef IPFILTER_LOG
return ipflog_read(GET_MINOR(dev), uio); return ipflog_read(xmin, uio);
#else #else
return ENXIO; return ENXIO;
#endif #endif
@ -1155,6 +1167,8 @@ frdest_t *fdp;
u_short ip_off; u_short ip_off;
frentry_t *fr; frentry_t *fr;
ro = NULL;
#ifdef M_WRITABLE #ifdef M_WRITABLE
/* /*
* HOT FIX/KLUDGE: * HOT FIX/KLUDGE:
@ -1168,15 +1182,15 @@ frdest_t *fdp;
* problem. * problem.
*/ */
if (M_WRITABLE(m) == 0) { 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); FREE_MB_T(m);
m = m0; m = m0;
*mpp = m; *mpp = m;
} else { } else {
error = ENOBUFS; error = ENOBUFS;
FREE_MB_T(m); FREE_MB_T(m);
*mpp = NULL; goto done;
fr_frouteok[1]++;
} }
} }
#endif #endif
@ -1218,18 +1232,8 @@ frdest_t *fdp;
goto bad; goto bad;
} }
/* if ((fdp != NULL) && (fdp->fd_ip.s_addr != 0))
* In case we're here due to "to <if>" being used with "keep state", dst->sin_addr = fdp->fd_ip;
* 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;
}
dst->sin_len = sizeof(*dst); dst->sin_len = sizeof(*dst);
rtalloc(ro); rtalloc(ro);
@ -1346,6 +1350,7 @@ frdest_t *fdp;
else else
mhip->ip_off |= IP_MF; mhip->ip_off |= IP_MF;
mhip->ip_len = htons((u_short)(len + mhlen)); mhip->ip_len = htons((u_short)(len + mhlen));
*mnext = m;
m->m_next = m_copy(m0, off, len); m->m_next = m_copy(m0, off, len);
if (m->m_next == 0) { if (m->m_next == 0) {
error = ENOBUFS; /* ??? */ error = ENOBUFS; /* ??? */
@ -1356,7 +1361,6 @@ frdest_t *fdp;
mhip->ip_off = htons((u_short)mhip->ip_off); mhip->ip_off = htons((u_short)mhip->ip_off);
mhip->ip_sum = 0; mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen); mhip->ip_sum = in_cksum(m, mhlen);
*mnext = m;
mnext = &m->m_act; mnext = &m->m_act;
} }
/* /*
@ -1385,7 +1389,7 @@ frdest_t *fdp;
else else
fr_frouteok[1]++; fr_frouteok[1]++;
if (ro->ro_rt) { if ((ro != NULL) && (ro->ro_rt != NULL)) {
RTFREE(ro->ro_rt); RTFREE(ro->ro_rt);
} }
*mpp = NULL; *mpp = NULL;
@ -1488,6 +1492,9 @@ struct in_addr *inp, *inpmask;
else if (atype == FRI_PEERADDR) else if (atype == FRI_PEERADDR)
sock = ifa->ifa_dstaddr; sock = ifa->ifa_dstaddr;
if (sock == NULL)
return -1;
#ifdef USE_INET6 #ifdef USE_INET6
if (v == 6) { if (v == 6) {
return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock, return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock,

View File

@ -100,7 +100,7 @@ extern struct timeout fr_slowtimer_ch;
#if !defined(lint) #if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; 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 #endif
@ -224,6 +224,7 @@ ipfr_t *table[];
{ {
ipfr_t *fra, frag; ipfr_t *fra, frag;
u_int idx, off; u_int idx, off;
frentry_t *fr;
ip_t *ip; ip_t *ip;
if (ipfr_inuse >= IPFT_SIZE) if (ipfr_inuse >= IPFT_SIZE)
@ -275,12 +276,9 @@ ipfr_t *table[];
return NULL; return NULL;
} }
fra->ipfr_rule = fin->fin_fr; fr = fin->fin_fr;
if (fra->ipfr_rule != NULL) { fra->ipfr_rule = fr;
if (fr != NULL) {
frentry_t *fr;
fr = fin->fin_fr;
MUTEX_ENTER(&fr->fr_lock); MUTEX_ENTER(&fr->fr_lock);
fr->fr_ref++; fr->fr_ref++;
MUTEX_EXIT(&fr->fr_lock); MUTEX_EXIT(&fr->fr_lock);

View File

@ -6,7 +6,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT * Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code. * 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 #define IPF_FTP_PROXY
@ -366,7 +366,7 @@ int dlen;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip; 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) if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state); 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; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip; 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) if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state); fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
} }
@ -1027,13 +1027,14 @@ int rv;
if (ippr_ftp_debug > 4) if (ippr_ftp_debug > 4)
printf("ippr_ftp_process: mlen %d\n", mlen); printf("ippr_ftp_process: mlen %d\n", mlen);
if (mlen <= 0) { if ((mlen == 0) && ((tcp->th_flags & TH_OPENING) == TH_OPENING)) {
if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { f->ftps_seq[0] = thseq + 1;
f->ftps_seq[0] = thseq + 1; t->ftps_seq[0] = thack;
t->ftps_seq[0] = thack; return 0;
} } else if (mlen < 0) {
return 0; return 0;
} }
aps = nat->nat_aps; aps = nat->nat_aps;
sel = aps->aps_sel[1 - rv]; sel = aps->aps_sel[1 - rv];
@ -1423,7 +1424,7 @@ int dlen;
ap += *s++ - '0'; ap += *s++ - '0';
} }
if (!s) if (!*s)
return 0; return 0;
if (*s == '|') if (*s == '|')

View File

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

View File

@ -3,7 +3,7 @@
* *
* See the IPFILTER.LICENCE file for details on licencing. * 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> #include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL) #if defined(KERNEL) || defined(_KERNEL)
@ -65,6 +65,10 @@ struct file;
# include <sys/dir.h> # include <sys/dir.h>
# endif # endif
# include <sys/mbuf.h> # include <sys/mbuf.h>
# include <sys/select.h>
# if __FreeBSD_version >= 500000
# include <sys/selinfo.h>
# endif
#else #else
# if !defined(__hpux) && defined(_KERNEL) # if !defined(__hpux) && defined(_KERNEL)
# include <sys/filio.h> # include <sys/filio.h>
@ -145,6 +149,7 @@ wait_queue_head_t iplh_linux[IPL_LOGSIZE];
# endif # endif
# if SOLARIS # if SOLARIS
extern kcondvar_t iplwait; extern kcondvar_t iplwait;
extern struct pollhead iplpollhead[IPL_LOGSIZE];
# endif # endif
iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE]; iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE];
@ -503,9 +508,11 @@ int *types, cnt;
# if SOLARIS && defined(_KERNEL) # if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait); cv_signal(&iplwait);
MUTEX_EXIT(&ipl_mutex); MUTEX_EXIT(&ipl_mutex);
pollwakeup(&iplpollhead[dev], POLLRDNORM);
# else # else
MUTEX_EXIT(&ipl_mutex); MUTEX_EXIT(&ipl_mutex);
WAKEUP(iplh,dev); WAKEUP(iplh, dev);
POLLWAKEUP(dev);
# endif # endif
SPL_X(s); SPL_X(s);
# ifdef IPL_SELECT # ifdef IPL_SELECT
@ -663,4 +670,19 @@ minor_t unit;
SPL_X(s); SPL_X(s);
return used; 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 */ #endif /* IPFILTER_LOG */

View File

@ -107,7 +107,7 @@ extern struct ifnet vpnif;
#if !defined(lint) #if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; 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 #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 void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int));
static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
tcphdr_t *, nat_t **, int)); 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 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 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)); static int nat_wildok __P((nat_t *, int, int, int, int));
@ -865,11 +865,8 @@ int getlock;
{ {
int error = 0, i, j; int error = 0, i, j;
nat_resolverule(n); if (nat_resolverule(n) != 0)
if (n->in_plabel[0] != '\0') { return ENOENT;
if (n->in_apr == NULL)
return ENOENT;
}
if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) if ((n->in_age[0] == 0) && (n->in_age[1] != 0))
return EINVAL; return EINVAL;
@ -994,7 +991,7 @@ int getlock;
/* from information passed to the kernel, then add it to the appropriate */ /* from information passed to the kernel, then add it to the appropriate */
/* NAT rule table(s). */ /* NAT rule table(s). */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
static void nat_resolverule(n) static int nat_resolverule(n)
ipnat_t *n; ipnat_t *n;
{ {
n->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; 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); (void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ);
n->in_ifps[1] = n->in_ifps[0]; n->in_ifps[1] = n->in_ifps[0];
} else { } 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') { if (n->in_plabel[0] != '\0') {
n->in_apr = appr_lookup(n->in_p, n->in_plabel); 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); 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. * 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)); bzero((char *)&fin, sizeof(fin));
fin.fin_p = nat->nat_p; fin.fin_p = nat->nat_p;
fin.fin_ifp = nat->nat_ifps[0];
if (nat->nat_dir == NAT_OUTBOUND) { if (nat->nat_dir == NAT_OUTBOUND) {
fin.fin_data[0] = ntohs(nat->nat_oport); fin.fin_data[0] = ntohs(nat->nat_oport);
fin.fin_data[1] = ntohs(nat->nat_outport); fin.fin_data[1] = ntohs(nat->nat_outport);
fin.fin_ifp = nat->nat_ifps[1];
if (getlock) { if (getlock) {
READ_ENTER(&ipf_nat); READ_ENTER(&ipf_nat);
} }
n = nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip, n = nat_inlookup(&fin, nat->nat_flags, fin.fin_p,
nat->nat_inip); nat->nat_oip, nat->nat_inip);
if (getlock) { if (getlock) {
RWLOCK_EXIT(&ipf_nat); RWLOCK_EXIT(&ipf_nat);
} }
@ -1365,12 +1373,11 @@ int getlock;
} else if (nat->nat_dir == NAT_INBOUND) { } else if (nat->nat_dir == NAT_INBOUND) {
fin.fin_data[0] = ntohs(nat->nat_outport); fin.fin_data[0] = ntohs(nat->nat_outport);
fin.fin_data[1] = ntohs(nat->nat_oport); fin.fin_data[1] = ntohs(nat->nat_oport);
fin.fin_ifp = nat->nat_ifps[0];
if (getlock) { if (getlock) {
READ_ENTER(&ipf_nat); READ_ENTER(&ipf_nat);
} }
n = nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip, n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p,
nat->nat_oip); nat->nat_outip, nat->nat_oip);
if (getlock) { if (getlock) {
RWLOCK_EXIT(&ipf_nat); RWLOCK_EXIT(&ipf_nat);
} }
@ -1435,6 +1442,12 @@ int getlock;
fr->fr_ref = 1; fr->fr_ref = 1;
(void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE); (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE);
bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr)); 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_NUKE(&fr->fr_lock);
MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
} else { } else {
@ -1574,6 +1587,9 @@ int logtype;
MUTEX_EXIT(&ipf_nat_new); MUTEX_EXIT(&ipf_nat_new);
return; return;
} }
/*
* At this point, nat_ref can be either 0 or -1
*/
#ifdef IPFILTER_SYNC #ifdef IPFILTER_SYNC
if (nat->nat_sync) if (nat->nat_sync)
@ -2152,6 +2168,9 @@ natinfo_t *ni;
/* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */ /* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */
/* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */ /* 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). */ /* 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) nat_t *nat_new(fin, np, natsave, flags, direction)
fr_info_t *fin; fr_info_t *fin;
@ -2245,6 +2264,7 @@ int direction;
natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p, natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst); fin->fin_src, fin->fin_dst);
if (natl != NULL) { if (natl != NULL) {
KFREE(nat);
nat = natl; nat = natl;
goto done; goto done;
} }
@ -2262,6 +2282,7 @@ int direction;
natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p, natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst); fin->fin_src, fin->fin_dst);
if (natl != NULL) { if (natl != NULL) {
KFREE(nat);
nat = natl; nat = natl;
goto done; goto done;
} }
@ -2375,7 +2396,12 @@ int direction;
np = ni->nai_np; 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 #ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0) if ((nat->nat_flags & SI_CLONE) == 0)
nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat); nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat);
@ -2383,7 +2409,8 @@ int direction;
nat->nat_me = natsave; nat->nat_me = natsave;
nat->nat_dir = direction; 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_ptr = np;
nat->nat_p = fin->fin_p; nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp; nat->nat_mssclamp = np->in_mssclamp;
@ -2470,7 +2497,7 @@ int rev;
nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0'; nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4); 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_ifnames[1][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4); nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4);
} else { } else {
@ -2818,8 +2845,9 @@ int dir;
* *
* Since the port fields are part of the TCP/UDP checksum * Since the port fields are part of the TCP/UDP checksum
* of the offending IP packet, you need to adjust that checksum * of the offending IP packet, you need to adjust that checksum
* as well... but, if you change, you must change the icmp * as well... except that the change in the port numbers should
* checksum *again*, to reflect that change. * 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 * To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not * 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 * The UDP checksum is optional, only adjust it if
* it has been set. * it has been set.
*/ */
if ((oip->ip_p == IPPROTO_UDP) && if (oip->ip_p == IPPROTO_UDP) {
(dlen >= 8) && (*csump != 0)) {
sumd = sum1 - sum2; sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump); if ((dlen >= 8) && (*csump != 0)) {
fix_datacksum(csump, sumd); fix_datacksum(csump, sumd);
sum2 = ntohs(*csump); } else {
sumd2 += sumd;
/* }
* Fix ICMP checksum to compenstate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} }
/* /*
@ -2877,20 +2898,10 @@ int dir;
* the other direction compared to the ICMP message. * the other direction compared to the ICMP message.
*/ */
if (oip->ip_p == IPPROTO_TCP) { if (oip->ip_p == IPPROTO_TCP) {
sumd = sum1 - sum2;
if (dlen >= 18) { if (dlen >= 18) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd); fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
* TCP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} else { } else {
sumd = sum2 - sum1 + 1; sumd = sum2 - sum1 + 1;
sumd2 += sumd; sumd2 += sumd;
@ -2910,21 +2921,14 @@ int dir;
* The UDP checksum is optional, only adjust * The UDP checksum is optional, only adjust
* it if it has been set. * it if it has been set.
*/ */
if ((oip->ip_p == IPPROTO_UDP) && if (oip->ip_p == IPPROTO_UDP) {
(dlen >= 8) && (*csump != 0)) {
sumd = sum1 - sum2; sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump); if ((dlen >= 8) && (*csump != 0)) {
fix_datacksum(csump, sumd); fix_datacksum(csump, sumd);
sum2 = ntohs(*csump); } else {
sumd2 += sumd;
/* }
* Fix ICMP checksum to compensate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} }
/* /*
@ -2933,20 +2937,10 @@ int dir;
* the other direction compared to the ICMP message. * the other direction compared to the ICMP message.
*/ */
if (oip->ip_p == IPPROTO_TCP) { if (oip->ip_p == IPPROTO_TCP) {
sumd = sum1 - sum2;
if (dlen >= 18) { if (dlen >= 18) {
sumd = sum1 - sum2;
sumd2 += sumd;
sum1 = ntohs(*csump);
fix_datacksum(csump, sumd); fix_datacksum(csump, sumd);
sum2 = ntohs(*csump);
/*
* Fix ICMP checksum to compensate
* TCP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
} else { } else {
if (nat->nat_dir == NAT_INBOUND) if (nat->nat_dir == NAT_INBOUND)
sumd = sum2 - sum1; sumd = sum2 - sum1;
@ -3039,10 +3033,7 @@ struct in_addr src , mapdst;
void *ifp; void *ifp;
u_int hv; u_int hv;
if (fin != NULL) ifp = fin->fin_ifp;
ifp = fin->fin_ifp;
else
ifp = NULL;
sport = 0; sport = 0;
dport = 0; dport = 0;
gre = NULL; gre = NULL;
@ -3074,17 +3065,13 @@ struct in_addr src , mapdst;
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz); hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
nat = nat_table[1][hv]; nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) { 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) { nflags = nat->nat_flags;
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[0])
continue;
} else {
if (ifp != nat->nat_ifps[1])
continue;
}
}
if (nat->nat_oip.s_addr == src.s_addr && if (nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst && nat->nat_outip.s_addr == dst &&
@ -3149,15 +3136,11 @@ struct in_addr src , mapdst;
nat = nat_table[1][hv]; nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) { for (; nat; nat = nat->nat_hnext[1]) {
if (ifp != NULL) { if (nat->nat_ifps[0] != NULL) {
if (nat->nat_dir == NAT_REDIRECT) { if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
if (ifp != nat->nat_ifps[0]) continue;
continue; } else if (ifp != NULL)
} else { nat->nat_ifps[0] = ifp;
if (ifp != nat->nat_ifps[1])
continue;
}
}
if (nat->nat_p != fin->fin_p) if (nat->nat_p != fin->fin_p)
continue; continue;
@ -3324,17 +3307,13 @@ struct in_addr src , dst;
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz); hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
nat = nat_table[0][hv]; nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) { 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) { nflags = nat->nat_flags;
if (nat->nat_dir == NAT_REDIRECT) {
if (ifp != nat->nat_ifps[1])
continue;
} else {
if (ifp != nat->nat_ifps[0])
continue;
}
}
if (nat->nat_inip.s_addr == srcip && if (nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr && nat->nat_oip.s_addr == dst.s_addr &&
@ -3389,15 +3368,11 @@ struct in_addr src , dst;
nat = nat_table[0][hv]; nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) { for (; nat; nat = nat->nat_hnext[0]) {
if (ifp != NULL) { if (nat->nat_ifps[1] != NULL) {
if (nat->nat_dir == NAT_REDIRECT) { if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
if (ifp != nat->nat_ifps[1]) continue;
continue; } else if (ifp != NULL)
} else { nat->nat_ifps[1] = ifp;
if (ifp != nat->nat_ifps[0])
continue;
}
}
if (nat->nat_p != fin->fin_p) if (nat->nat_p != fin->fin_p)
continue; continue;
@ -3446,6 +3421,16 @@ struct in_addr src , dst;
/* entry for. */ /* entry for. */
/* */ /* */
/* Lookup the NAT tables to search for a matching redirect */ /* 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) nat_t *nat_lookupredir(np)
natlookup_t *np; natlookup_t *np;
@ -3707,7 +3692,7 @@ u_32_t *passp;
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz); hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
for (np = nat_rules[hv]; np; np = np->in_mnext) 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; continue;
if (np->in_v != fin->fin_v) if (np->in_v != fin->fin_v)
continue; continue;
@ -4346,8 +4331,8 @@ void fr_natexpire()
{ {
ipftq_t *ifq, *ifqnext; ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn; ipftqent_t *tqe, *tqn;
SPL_INT(s);
int i; int i;
SPL_INT(s);
SPL_NET(s); SPL_NET(s);
WRITE_ENTER(&ipf_nat); WRITE_ENTER(&ipf_nat);

View File

@ -4,7 +4,7 @@
* Simple PPTP transparent proxy for in-kernel use. For use with the NAT * Simple PPTP transparent proxy for in-kernel use. For use with the NAT
* code. * 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 #define IPF_PPTP_PROXY
@ -93,7 +93,8 @@ nat_t *nat;
if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
ip->ip_dst) != NULL) { ip->ip_dst) != NULL) {
if (ippr_pptp_debug > 0) 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; return -1;
} }
@ -101,7 +102,8 @@ nat_t *nat;
KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp)); KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
if (aps->aps_data == NULL) { if (aps->aps_data == NULL) {
if (ippr_pptp_debug > 0) 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; return -1;
} }
@ -208,10 +210,12 @@ pptp_pxy_t *pptp;
RWLOCK_EXIT(&ipf_state); RWLOCK_EXIT(&ipf_state);
} else { } else {
RWLOCK_EXIT(&ipf_state); RWLOCK_EXIT(&ipf_state);
if (nat->nat_dir == NAT_INBOUND) if (nat2 != NULL) {
fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; if (nat->nat_dir == NAT_INBOUND)
else fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr;
fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; else
fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr;
}
fi.fin_ifp = NULL; fi.fin_ifp = NULL;
pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state,
0); 0);

View File

@ -103,7 +103,7 @@ struct file;
/* END OF INCLUDES */ /* END OF INCLUDES */
#if !defined(lint) #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 #endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
@ -323,8 +323,7 @@ int mode;
if (error == 0) if (error == 0)
error = appr_ctl(&ctl); error = appr_ctl(&ctl);
if ((ctl.apc_dsize > 0) && (ptr != NULL) && if (ptr != NULL) {
(ctl.apc_data == ptr)) {
KFREES(ptr, ctl.apc_dsize); KFREES(ptr, ctl.apc_dsize);
} }
break; break;
@ -563,8 +562,8 @@ nat_t *nat;
if (err != 0) { if (err != 0) {
short adjlen = err & 0xffff; short adjlen = err & 0xffff;
s1 = LONG_SUM(ip->ip_len - adjlen); s1 = LONG_SUM(fin->fin_plen - adjlen);
s2 = LONG_SUM(ip->ip_len); s2 = LONG_SUM(fin->fin_plen);
CALC_SUMD(s1, s2, sd); CALC_SUMD(s1, s2, sd);
fix_outcksum(fin, &ip->ip_sum, sd); fix_outcksum(fin, &ip->ip_sum, sd);
} }
@ -584,19 +583,23 @@ nat_t *nat;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum) if (dosum)
tcp->th_sum = fr_cksum(fin->fin_qfm, ip, tcp->th_sum = fr_cksum(fin->fin_qfm, ip,
IPPROTO_TCP, tcp); IPPROTO_TCP, tcp,
fin->fin_plen);
#else #else
tcp->th_sum = fr_cksum(fin->fin_m, ip, tcp->th_sum = fr_cksum(fin->fin_m, ip,
IPPROTO_TCP, tcp); IPPROTO_TCP, tcp,
fin->fin_plen);
#endif #endif
} else if ((udp != NULL) && (udp->uh_sum != 0)) { } else if ((udp != NULL) && (udp->uh_sum != 0)) {
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum) if (dosum)
udp->uh_sum = fr_cksum(fin->fin_qfm, ip, udp->uh_sum = fr_cksum(fin->fin_qfm, ip,
IPPROTO_UDP, udp); IPPROTO_UDP, udp,
fin->fin_plen);
#else #else
udp->uh_sum = fr_cksum(fin->fin_m, ip, udp->uh_sum = fr_cksum(fin->fin_m, ip,
IPPROTO_UDP, udp); IPPROTO_UDP, udp,
fin->fin_plen);
#endif #endif
} }
aps->aps_bytes += fin->fin_plen; aps->aps_bytes += fin->fin_plen;
@ -687,9 +690,9 @@ int inc;
tcp = (tcphdr_t *)fin->fin_dp; tcp = (tcphdr_t *)fin->fin_dp;
out = fin->fin_out; 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); nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2);
inc2 = inc; inc2 = inc;

View File

@ -3,7 +3,7 @@
* *
* See the IPFILTER.LICENCE file for details on licencing. * 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 * Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code. * code.
@ -202,7 +202,7 @@ nat_t *nat;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip; 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) if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state); fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
} }

View File

@ -58,7 +58,7 @@ struct file;
#if !defined(lint) #if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; 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 #endif
#ifdef IPFILTER_SCAN /* endif at bottom of file */ #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_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *));
int ipsc_match __P((ipstate_t *)); int ipsc_match __P((ipstate_t *));
static int ipsc_inited = 0;
int ipsc_init() int ipsc_init()
{ {
RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock");
ipsc_inited = 1;
return 0; return 0;
} }
void fr_scanunload() 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) if (k == 1)
isc = lm; isc = lm;
if (isc == NULL)
return 0;
/* /*
* No matches or partial matches, so reset the respective * No matches or partial matches, so reset the respective

View File

@ -107,7 +107,7 @@ struct file;
#if !defined(lint) #if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; 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 #endif
static ipstate_t **ips_table = NULL; static ipstate_t **ips_table = NULL;
@ -668,6 +668,7 @@ caddr_t data;
fr->fr_ref = 0; fr->fr_ref = 0;
fr->fr_dsize = 0; fr->fr_dsize = 0;
fr->fr_data = NULL; fr->fr_data = NULL;
fr->fr_type = FR_T_NONE;
fr_resolvedest(&fr->fr_tif, fr->fr_v); fr_resolvedest(&fr->fr_tif, fr->fr_v);
fr_resolvedest(&fr->fr_dif, 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 */ /* 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 */ /* 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. */ /* 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) ipstate_t *fr_addstate(fin, stsave, flags)
fr_info_t *fin; fr_info_t *fin;
@ -823,28 +829,30 @@ u_int flags;
if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN)) if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN))
return NULL; 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 * 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 * 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); fr = fin->fin_fr;
if ((fr != NULL) && (fr->fr_statemax != 0) && if (fr != NULL) {
(fr->fr_statecnt >= fr->fr_statemax)) { if ((ips_num == fr_statemax) && (fr->fr_statemax == 0)) {
MUTEX_EXIT(&fr->fr_lock); ATOMIC_INCL(ips_stats.iss_max);
ATOMIC_INCL(ips_stats.iss_maxref); fr_state_doflush = 1;
fr_state_doflush = 1; return NULL;
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; pass = (fr == NULL) ? 0 : fr->fr_flags;
@ -1046,16 +1054,16 @@ u_int flags;
break; break;
} }
if (is != NULL) if (is != NULL)
goto cantaddstate; return NULL;
if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) { if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) {
ATOMIC_INCL(ips_stats.iss_bucketfull); ATOMIC_INCL(ips_stats.iss_bucketfull);
goto cantaddstate; return NULL;
} }
KMALLOC(is, ipstate_t *); KMALLOC(is, ipstate_t *);
if (is == NULL) { if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_nomem); ATOMIC_INCL(ips_stats.iss_nomem);
goto cantaddstate; return NULL;
} }
bcopy((char *)&ips, (char *)is, sizeof(*is)); bcopy((char *)&ips, (char *)is, sizeof(*is));
/* /*
@ -1140,6 +1148,7 @@ u_int flags;
is->is_optmsk[0] &= ~0x8; is->is_optmsk[0] &= ~0x8;
is->is_optmsk[1] &= ~0x8; is->is_optmsk[1] &= ~0x8;
} }
is->is_me = stsave;
is->is_sec = fin->fin_secmsk; is->is_sec = fin->fin_secmsk;
is->is_secmsk = 0xffff; is->is_secmsk = 0xffff;
is->is_auth = fin->fin_auth; is->is_auth = fin->fin_auth;
@ -1154,7 +1163,6 @@ u_int flags;
is->is_pass &= ~(FR_LOGFIRST|FR_LOG); is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
READ_ENTER(&ipf_state); READ_ENTER(&ipf_state);
is->is_me = stsave;
fr_stinsert(is, fin->fin_rev); fr_stinsert(is, fin->fin_rev);
@ -1188,14 +1196,6 @@ u_int flags;
(void) fr_newfrag(fin, pass ^ FR_KEEPSTATE); (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
return is; 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); win = ntohs(tcp->th_win);
else else
win = ntohs(tcp->th_win) << fdata->td_winscale; 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. * A window of 0 produces undesirable behaviour from this function.
@ -1553,6 +1541,39 @@ int flags;
(fdata->td_winflags & TCP_SACK_PERMIT) && (fdata->td_winflags & TCP_SACK_PERMIT) &&
(tdata->td_winflags & TCP_SACK_PERMIT)) { (tdata->td_winflags & TCP_SACK_PERMIT)) {
inseq = 1; 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) { if (inseq) {
@ -2339,7 +2360,8 @@ ipftq_t **ifqp;
if ((is->is_p != pr) || (is->is_v != v)) if ((is->is_p != pr) || (is->is_v != v))
continue; continue;
is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); 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, fr_matchicmpqueryreply(v, &is->is_icmp,
ic, fin->fin_rev)) { ic, fin->fin_rev)) {
if (fin->fin_rev) if (fin->fin_rev)
@ -2432,11 +2454,13 @@ ipftq_t **ifqp;
break; break;
} }
if ((is != NULL) && ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) && if (is != NULL) {
(is->is_tqehead[fin->fin_rev] != NULL)) if (((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) &&
ifq = is->is_tqehead[fin->fin_rev]; (is->is_tqehead[fin->fin_rev] != NULL))
if (ifq != NULL && ifqp != NULL) ifq = is->is_tqehead[fin->fin_rev];
*ifqp = ifq; if (ifq != NULL && ifqp != NULL)
*ifqp = ifq;
}
return is; return is;
} }

View File

@ -96,7 +96,7 @@ struct file;
/* END OF INCLUDES */ /* END OF INCLUDES */
#if !defined(lint) #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 #endif
#define SYNC_STATETABSZ 256 #define SYNC_STATETABSZ 256
@ -702,7 +702,6 @@ int ipfsync_nat(sp, data)
synchdr_t *sp; synchdr_t *sp;
void *data; void *data;
{ {
synclogent_t sle;
syncupdent_t su; syncupdent_t su;
nat_t *n, *nat; nat_t *n, *nat;
synclist_t *sl; synclist_t *sl;
@ -714,8 +713,6 @@ void *data;
switch (sp->sm_cmd) switch (sp->sm_cmd)
{ {
case SMC_CREATE : case SMC_CREATE :
bcopy(data, &sle, sizeof(sle));
KMALLOC(n, nat_t *); KMALLOC(n, nat_t *);
if (n == NULL) { if (n == NULL) {
err = ENOMEM; err = ENOMEM;
@ -729,9 +726,7 @@ void *data;
break; break;
} }
WRITE_ENTER(&ipf_nat); nat = (nat_t *)data;
nat = &sle.sle_un.sleu_ipn;
bzero((char *)n, offsetof(nat_t, nat_age)); bzero((char *)n, offsetof(nat_t, nat_age));
bcopy((char *)&nat->nat_age, (char *)&n->nat_age, bcopy((char *)&nat->nat_age, (char *)&n->nat_age,
sizeof(*n) - offsetof(nat_t, nat_age)); sizeof(*n) - offsetof(nat_t, nat_age));
@ -741,6 +736,8 @@ void *data;
sl->sl_idx = -1; sl->sl_idx = -1;
sl->sl_ipn = n; sl->sl_ipn = n;
sl->sl_num = ntohl(sp->sm_num); sl->sl_num = ntohl(sp->sm_num);
WRITE_ENTER(&ipf_nat);
sl->sl_pnext = syncstatetab + hv; sl->sl_pnext = syncstatetab + hv;
sl->sl_next = syncstatetab[hv]; sl->sl_next = syncstatetab[hv];
if (syncstatetab[hv] != NULL) if (syncstatetab[hv] != NULL)
@ -1005,4 +1002,16 @@ int mode;
{ {
return EINVAL; return EINVAL;
} }
int ipfsync_canread()
{
return !((sl_tail == sl_idx) && (su_tail == su_idx));
}
int ipfsync_canwrite()
{
return 1;
}
#endif /* IPFILTER_SYNC */ #endif /* IPFILTER_SYNC */

View File

@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing. * See the IPFILTER.LICENCE file for details on licencing.
* *
* @(#)ip_fil.h 1.35 6/5/96 * @(#)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__ #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_state __P((synchdr_t *sp, void *data));
extern int ipfsync_read __P((struct uio *uio)); extern int ipfsync_read __P((struct uio *uio));
extern int ipfsync_write __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 */ #endif /* IP_SYNC */

View File

@ -4,14 +4,14 @@
* See the IPFILTER.LICENCE file for details on licencing. * See the IPFILTER.LICENCE file for details on licencing.
* *
* @(#)ipl.h 1.21 6/5/96 * @(#)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__ #ifndef __IPL_H__
#define __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 #endif

View File

@ -12,6 +12,10 @@
#include <sys/conf.h> #include <sys/conf.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/select.h>
#if __FreeBSD_version >= 500000
# include <sys/selinfo.h>
#endif
#include <net/if.h> #include <net/if.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -24,6 +28,9 @@
#include <netinet/ip_nat.h> #include <netinet/ip_nat.h>
#include <netinet/ip_auth.h> #include <netinet/ip_auth.h>
#include <netinet/ip_frag.h> #include <netinet/ip_frag.h>
#include <netinet/ip_sync.h>
extern struct selinfo ipfselwait[IPL_LOGSIZE];
#if __FreeBSD_version >= 502116 #if __FreeBSD_version >= 502116
static struct cdev *ipf_devs[IPL_LOGSIZE]; 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 #define CDEV_MAJOR 79
#if __FreeBSD_version >= 501000 #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 = { static struct cdevsw ipl_cdevsw = {
# if __FreeBSD_version >= 502103 # if __FreeBSD_version >= 502103
.d_version = D_VERSION, .d_version = D_VERSION,
@ -103,6 +114,7 @@ static struct cdevsw ipl_cdevsw = {
.d_write = iplwrite, .d_write = iplwrite,
.d_ioctl = iplioctl, .d_ioctl = iplioctl,
.d_name = "ipl", .d_name = "ipl",
.d_poll = iplpoll,
# if __FreeBSD_version < 600000 # if __FreeBSD_version < 600000
.d_maj = CDEV_MAJOR, .d_maj = CDEV_MAJOR,
# endif # endif
@ -114,7 +126,7 @@ static struct cdevsw ipl_cdevsw = {
/* read */ iplread, /* read */ iplread,
/* write */ iplwrite, /* write */ iplwrite,
/* ioctl */ iplioctl, /* ioctl */ iplioctl,
/* poll */ nopoll, /* poll */ iplpoll,
/* mmap */ nommap, /* mmap */ nommap,
/* strategy */ nostrategy, /* strategy */ nostrategy,
/* name */ "ipl", /* name */ "ipl",
@ -270,3 +282,51 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
return (error); return (error);
} }
#endif #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