aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rooij <guido@FreeBSD.org>2006-08-16 11:51:32 +0000
committerGuido van Rooij <guido@FreeBSD.org>2006-08-16 11:51:32 +0000
commit0be1832174307c242b42db3dac9d7e762f0c693b (patch)
tree4b016f8ad91729ff411fb356068d1ae475e0bd91
parentfc79eaf127b2927f108bf1971bfb850f7dabea63 (diff)
downloadsrc-0be1832174307c242b42db3dac9d7e762f0c693b.tar.gz
src-0be1832174307c242b42db3dac9d7e762f0c693b.zip
Import IP Filter 4.1.13
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=161351
-rw-r--r--sys/contrib/ipfilter/netinet/IPFILTER.LICENCE57
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c210
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c58
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h14
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h20
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c47
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c12
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c19
-rw-r--r--sys/contrib/ipfilter/netinet/ip_h323_pxy.c4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c26
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c215
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pptp_pxy.c18
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c25
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_scan.c11
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c120
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.c23
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h6
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c62
21 files changed, 557 insertions, 402 deletions
diff --git a/sys/contrib/ipfilter/netinet/IPFILTER.LICENCE b/sys/contrib/ipfilter/netinet/IPFILTER.LICENCE
index 2b4b67e86fd9..41c151ccdedb 100644
--- a/sys/contrib/ipfilter/netinet/IPFILTER.LICENCE
+++ b/sys/contrib/ipfilter/netinet/IPFILTER.LICENCE
@@ -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 ?
+ */
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index c8c1b55074f4..8f911e6043c2 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -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 @@ nodata:
* 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;
- }
-
- /*
- * Remove from list
- */
- *tqe->tqe_pnext = tqe->tqe_next;
- tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
+ 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;
+ /*
+ * 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;
- /*
- * 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;
- /*
- * 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);
- (void) fr_deletetimeoutqueue(oifq);
+ MUTEX_EXIT(&oifq->ifq_lock);
- MUTEX_EXIT(&oifq->ifq_lock);
+ MUTEX_ENTER(&nifq->ifq_lock);
- MUTEX_ENTER(&nifq->ifq_lock);
+ tqe->tqe_ifq = nifq;
+ nifq->ifq_ref++;
+ }
- 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;
}
-
- /*
- * 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
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index b6f0844354bf..0f0c2ff8007d 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -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 @@ fr_authioctlloop:
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 @@ fr_authioctlloop:
#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 @@ fr_authioctlloop:
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 @@ fr_authioctlloop:
#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 @@ fr_authioctlloop:
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 @@ fr_authioctlloop:
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 @@ fr_authioctlloop:
}
}
}
-# 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];
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 389277827009..22c69b77c684 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -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__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index f48a98dbfda3..0a294cff58d8 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -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 */
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index 45d5bb4734c8..5a13993d4168 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -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 *));
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 760122e393b3..d361beaa5710 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -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 @@ pfil_error:
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 @@ done:
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,
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index db1a0afbd8db..18360cee09c6 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -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);
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index 860d75ecb80d..e72d6fec2280 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -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 == '|')
diff --git a/sys/contrib/ipfilter/netinet/ip_h323_pxy.c b/sys/contrib/ipfilter/netinet/ip_h323_pxy.c
index 1933203e05cd..7fc62276c597 100644
--- a/sys/contrib/ipfilter/netinet/ip_h323_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_h323_pxy.c
@@ -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;
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 6618c6d6d841..550855709d02 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -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 */
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 30bba0787643..af73ebf03643 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -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) {
- if (dlen >= 18) {
- sumd = sum1 - sum2;
- sumd2 += sumd;
+ sumd = sum1 - sum2;
- sum1 = ntohs(*csump);
+ if (dlen >= 18) {
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) {
- if (dlen >= 18) {
- sumd = sum1 - sum2;
- sumd2 += sumd;
+ sumd = sum1 - sum2;
- sum1 = ntohs(*csump);
+ if (dlen >= 18) {
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 @@ find_in_wild_ports:
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 @@ find_out_wild_ports:
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 @@ find_out_wild_ports:
/* 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 @@ maskloop:
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);
diff --git a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
index 0047e1032acf..2ef2e17dc5dc 100644
--- a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
@@ -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);
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 60b6ac04af21..8fdd98cc3984 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -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;
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 1782064ed0a2..c93207e006e1 100644
--- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
@@ -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);
}
diff --git a/sys/contrib/ipfilter/netinet/ip_scan.c b/sys/contrib/ipfilter/netinet/ip_scan.c
index 73977c7d224e..13a5a60210e1 100644
--- a/sys/contrib/ipfilter/netinet/ip_scan.c
+++ b/sys/contrib/ipfilter/netinet/ip_scan.c
@@ -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
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index b0bf74245f2a..32aa80591ded 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -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 @@ icmp6again:
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 @@ retry_tcpudp:
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;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.c b/sys/contrib/ipfilter/netinet/ip_sync.c
index 768d1c538e60..b5b811b7619c 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.c
+++ b/sys/contrib/ipfilter/netinet/ip_sync.c
@@ -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 */
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.h b/sys/contrib/ipfilter/netinet/ip_sync.h
index 8a62192dbfb0..76862f7534a1 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.h
+++ b/sys/contrib/ipfilter/netinet/ip_sync.h
@@ -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 */
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index ee9a9550b884..28b9e0cfdfe3 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -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
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 26a51aa69feb..e4c5ccb9e146 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -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