summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorguido <guido@FreeBSD.org>2006-08-16 12:06:35 +0000
committerguido <guido@FreeBSD.org>2006-08-16 12:06:35 +0000
commitfcfb8e57499dfda26645e92a1b5ad74c6f35ee92 (patch)
tree8fc6773c550cc36aed09bf86acc757851b98c4b8 /sys
parent3a3876540a6f01df3188a20c19dfe3a6b63aa6e0 (diff)
downloadFreeBSD-src-fcfb8e57499dfda26645e92a1b5ad74c6f35ee92.zip
FreeBSD-src-fcfb8e57499dfda26645e92a1b5ad74c6f35ee92.tar.gz
Resolve conflicts
MFC after: 2 weeks
Diffstat (limited to 'sys')
-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.h10
-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_log.c27
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c215
-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_state.c120
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.c23
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h6
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c62
16 files changed, 501 insertions, 361 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index a13441c..ee21a94 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -142,7 +142,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp"; */
+/* static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $"; */
#endif
#ifndef _KERNEL
@@ -150,12 +150,6 @@ static const char rcsid[] = "@(#)$FreeBSD$";
# include "ipt.h"
# include "bpf-ipf.h"
extern int opts;
-
-# define FR_VERBOSE(verb_pr) verbose verb_pr
-# define FR_DEBUG(verb_pr) debug verb_pr
-#else /* #ifndef _KERNEL */
-# define FR_VERBOSE(verb_pr)
-# define FR_DEBUG(verb_pr)
#endif /* _KERNEL */
@@ -1977,24 +1971,23 @@ u_32_t pass;
* it, except for increasing the hit counter.
*/
if ((passt & FR_CALLNOW) != 0) {
+ frentry_t *frs;
+
ATOMIC_INC64(fr->fr_hits);
if ((fr->fr_func != NULL) &&
- (fr->fr_func != (ipfunc_t)-1)) {
- frentry_t *frs;
+ (fr->fr_func == (ipfunc_t)-1))
+ continue;
- frs = fin->fin_fr;
- fin->fin_fr = fr;
- fr = (*fr->fr_func)(fin, &passt);
- if (fr == NULL) {
- fin->fin_fr = frs;
- continue;
- }
- passt = fr->fr_flags;
- fin->fin_fr = fr;
- }
- } else {
+ frs = fin->fin_fr;
fin->fin_fr = fr;
+ fr = (*fr->fr_func)(fin, &passt);
+ if (fr == NULL) {
+ fin->fin_fr = frs;
+ continue;
+ }
+ passt = fr->fr_flags;
}
+ fin->fin_fr = fr;
#ifdef IPFILTER_LOG
/*
@@ -2026,18 +2019,20 @@ u_32_t pass;
(void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
if (fr->fr_grp != NULL) {
fin->fin_fr = *fr->fr_grp;
- pass = fr_scanlist(fin, pass);
+ passt = fr_scanlist(fin, pass);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
(void) strncpy(fin->fin_group, fr->fr_group,
FR_GROUPLEN);
fin->fin_fr = fr;
+ passt = pass;
}
if (fin->fin_flx & FI_DONTCACHE)
logged = 1;
+ pass = passt;
}
- if (pass & FR_QUICK) {
+ if (passt & FR_QUICK) {
/*
* Finally, if we've asked to track state for this
* packet, set it up. Add state for "quick" rules
@@ -2049,6 +2044,7 @@ u_32_t pass;
!(fin->fin_flx & FI_STATE)) {
int out = fin->fin_out;
+ fin->fin_fr = fr;
if (fr_addstate(fin, NULL, 0) != NULL) {
ATOMIC_INCL(frstats[out].fr_ads);
} else {
@@ -2198,7 +2194,8 @@ u_32_t *passp;
if (FR_ISAUTH(pass)) {
if (fr_newauth(fin->fin_m, fin) != 0) {
#ifdef _KERNEL
- fin->fin_m = *fin->fin_mp = NULL;
+ if ((pass & FR_RETMASK) == 0)
+ fin->fin_m = *fin->fin_mp = NULL;
#else
;
#endif
@@ -2238,21 +2235,6 @@ u_32_t *passp;
}
}
- /*
- * Finally, if we've asked to track state for this packet, set it up.
- */
- if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) {
- if (fr_addstate(fin, NULL, 0) != NULL) {
- ATOMIC_INCL(frstats[out].fr_ads);
- } else {
- ATOMIC_INCL(frstats[out].fr_bads);
- if (FR_ISPASS(pass)) {
- pass &= ~FR_CMDMASK;
- pass |= FR_BLOCK;
- }
- }
- }
-
fr = fin->fin_fr;
if (passp != NULL)
@@ -2318,8 +2300,6 @@ int out;
#ifdef USE_INET6
ip6_t *ip6;
#endif
- SPL_INT(s);
-
/*
* The first part of fr_check() deals with making sure that what goes
* into the filtering engine makes some sense. Information about the
@@ -2333,6 +2313,8 @@ int out;
if ((u_int)ip & 0x3)
return 2;
+# else
+ SPL_INT(s);
# endif
READ_ENTER(&ipf_global);
@@ -2498,6 +2480,23 @@ int out;
if ((pass & FR_NOMATCH) || (fr == NULL))
fr = fr_firewall(fin, &pass);
+ /*
+ * If we've asked to track state for this packet, set it up.
+ * Here rather than fr_firewall because fr_checkauth may decide
+ * to return a packet for "keep state"
+ */
+ if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) {
+ if (fr_addstate(fin, NULL, 0) != NULL) {
+ ATOMIC_INCL(frstats[out].fr_ads);
+ } else {
+ ATOMIC_INCL(frstats[out].fr_bads);
+ if (FR_ISPASS(pass)) {
+ pass &= ~FR_CMDMASK;
+ pass |= FR_BLOCK;
+ }
+ }
+ }
+
fin->fin_fr = fr;
/*
@@ -2552,7 +2551,7 @@ int out;
RWLOCK_EXIT(&ipf_mutex);
- if (pass & (FR_RETRST|FR_RETICMP)) {
+ if ((pass & FR_RETMASK) != 0) {
/*
* Should we return an ICMP packet to indicate error
* status passing through the packet filter ?
@@ -2578,6 +2577,14 @@ int out;
ATOMIC_INCL(frstats[1].fr_ret);
}
}
+
+ /*
+ * When using return-* with auth rules, the auth code
+ * takes over disposing of this packet.
+ */
+ if (FR_ISAUTH(pass) && (fin->fin_m != NULL)) {
+ fin->fin_m = *fin->fin_mp = NULL;
+ }
} else {
if (pass & FR_RETRST)
fin->fin_error = ECONNRESET;
@@ -2791,10 +2798,10 @@ int len;
/* */
/* Expects ip_len to be in host byte order when called. */
/* ------------------------------------------------------------------------ */
-u_short fr_cksum(m, ip, l4proto, l4hdr)
+u_short fr_cksum(m, ip, l4proto, l4hdr, l3len)
mb_t *m;
ip_t *ip;
-int l4proto;
+int l4proto, l3len;
void *l4hdr;
{
u_short *sp, slen, sumsave, l4hlen, *csump;
@@ -2819,7 +2826,7 @@ void *l4hdr;
if (IP_V(ip) == 4) {
#endif
hlen = IP_HL(ip) << 2;
- slen = ip->ip_len - hlen;
+ slen = l3len - hlen;
sum = htons((u_short)l4proto);
sum += htons(slen);
sp = (u_short *)&ip->ip_src;
@@ -2831,9 +2838,9 @@ void *l4hdr;
} else if (IP_V(ip) == 6) {
ip6 = (ip6_t *)ip;
hlen = sizeof(*ip6);
- slen = ntohs(ip6->ip6_plen);
+ slen = ntohs(l3len);
sum = htons((u_short)l4proto);
- sum += htons(slen);
+ sum += slen;
sp = (u_short *)&ip6->ip6_src;
sum += *sp++; /* ip6_src */
sum += *sp++;
@@ -3064,7 +3071,7 @@ 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,
@@ -3477,7 +3484,7 @@ int proto, flags;
char *memstr(src, dst, slen, dlen)
const char *src;
char *dst;
-int slen, dlen;
+size_t slen, dlen;
{
char *s = NULL;
@@ -3765,13 +3772,7 @@ size_t size;
caddr_t ca;
int err;
-# if SOLARIS
- err = COPYIN(dst, (caddr_t)&ca, sizeof(ca));
- if (err != 0)
- return err;
-# else
bcopy(dst, (caddr_t)&ca, sizeof(ca));
-# endif
err = COPYOUT(src, ca, size);
return err;
}
@@ -4891,7 +4892,7 @@ ipftq_t *ifq;
ifq->ifq_next->ifq_pnext = ifq->ifq_pnext;
MUTEX_DESTROY(&ifq->ifq_lock);
- fr_userifqs--;
+ ATOMIC_DEC(fr_userifqs);
KFREE(ifq);
}
@@ -4913,8 +4914,6 @@ ipftqent_t *tqe;
ipftq_t *ifq;
ifq = tqe->tqe_ifq;
- if (ifq == NULL)
- return;
MUTEX_ENTER(&ifq->ifq_lock);
@@ -4986,24 +4985,21 @@ ipftqent_t *tqe;
tqe->tqe_die = fr_ticks + ifq->ifq_ttl;
MUTEX_ENTER(&ifq->ifq_lock);
- if (tqe->tqe_next == NULL) { /* at the end already ? */
- MUTEX_EXIT(&ifq->ifq_lock);
- return;
- }
-
- /*
- * 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);
}
@@ -5055,46 +5051,44 @@ ipftq_t *oifq, *nifq;
* Is the operation here going to be a no-op ?
*/
MUTEX_ENTER(&oifq->ifq_lock);
- if (oifq == nifq && *oifq->ifq_tail == tqe) {
- MUTEX_EXIT(&oifq->ifq_lock);
- return;
- }
+ if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) {
+ /*
+ * Remove from the old queue
+ */
+ *tqe->tqe_pnext = tqe->tqe_next;
+ if (tqe->tqe_next)
+ tqe->tqe_next->tqe_pnext = tqe->tqe_pnext;
+ else
+ oifq->ifq_tail = tqe->tqe_pnext;
+ tqe->tqe_next = NULL;
- /*
- * 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);
}
@@ -5578,7 +5572,7 @@ fr_info_t *fin;
if (dosum)
sum = fr_cksum(fin->fin_m, fin->fin_ip,
- fin->fin_p, fin->fin_dp);
+ fin->fin_p, fin->fin_dp, fin->fin_plen);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID)
}
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index c4341df..3f82d25 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -121,12 +121,13 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#if !defined(lint)
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp"; */
+/* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.13 2006/03/29 11:19:55 darrenr Exp $"; */
#endif
-#if SOLARIS
+#if SOLARIS && defined(_KERNEL)
extern kcondvar_t ipfauthwait;
+extern struct pollhead iplpollhead[IPL_LOGSIZE];
#endif /* SOLARIS */
#if defined(linux) && defined(_KERNEL)
wait_queue_head_t fr_authnext_linux;
@@ -321,7 +322,7 @@ fr_info_t *fin;
fra = fr_auth + i;
fra->fra_index = i;
- fra->fra_pass = 0;
+ fra->fra_pass = fin->fin_fr->fr_flags;
fra->fra_age = fr_defaultauthage;
bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
#if !defined(sparc) && !defined(m68k)
@@ -343,17 +344,15 @@ fr_info_t *fin;
}
#endif
#if SOLARIS && defined(_KERNEL)
+ COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname);
m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
+ fra->fra_m = *fin->fin_mp;
+ fra->fra_info.fin_mp = &fra->fra_m;
cv_signal(&ipfauthwait);
+ pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM);
#else
-# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
- if (!fin->fin_out) {
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
- }
-# endif
fr_authpkts[i] = m;
WAKEUP(&fr_authnext,0);
#endif
@@ -366,15 +365,15 @@ caddr_t data;
ioctlcmd_t cmd;
int mode;
{
+ frauth_t auth, *au = &auth, *fra;
+ int i, error = 0, len;
+ char *t;
mb_t *m;
#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq;
SPL_INT(s);
#endif
- frauth_t auth, *au = &auth, *fra;
- int i, error = 0, len;
- char *t;
switch (cmd)
{
@@ -403,10 +402,14 @@ int mode;
case SIOCAUTHW:
fr_authioctlloop:
error = fr_inobj(data, au, IPFOBJ_FRAUTH);
+ if (error != 0)
+ break;
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
error = fr_outobj(data, &fr_auth[fr_authnext],
IPFOBJ_FRAUTH);
+ if (error != 0)
+ break;
if (auth.fra_len != 0 && auth.fra_buf != NULL) {
/*
* Copy packet contents out to user space if
@@ -420,11 +423,12 @@ 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);
@@ -477,10 +481,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:
@@ -491,6 +493,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);
@@ -505,7 +508,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
@@ -526,7 +533,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
@@ -557,10 +568,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.
@@ -584,7 +591,6 @@ fr_authioctlloop:
}
}
}
-# endif /* MENTAT */
#endif /* _KERNEL */
SPL_X(s);
break;
@@ -799,3 +805,9 @@ int fr_authflush()
return num_flushed;
}
+
+
+int fr_auth_waiting()
+{
+ return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext];
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 5c93610..a480c5d 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* $FreeBSD$
- * Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp
+ * Id: ip_auth.h,v 2.16.2.2 2006/03/16 06:45:49 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@@ -23,6 +23,7 @@ typedef struct frauth {
char *fra_buf;
#ifdef MENTAT
queue_t *fra_q;
+ mb_t *fra_m;
#endif
} frauth_t;
@@ -63,5 +64,6 @@ extern mb_t **fr_authpkts;
extern int fr_newauth __P((mb_t *, fr_info_t *));
extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **));
extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int));
+extern int fr_auth_waiting __P((void));
#endif /* __IP_AUTH_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index cc69245..ebf8fbe 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -5,7 +5,7 @@
*
* @(#)ip_compat.h 1.8 1/14/96
* $FreeBSD$
- * Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp
+ * Id: ip_compat.h,v 2.142.2.36 2006/03/26 05:50:29 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -442,6 +442,7 @@ extern void *get_unit __P((char *, int));
wakeup(id + x); \
spinunlock(_l); \
}
+# define POLLWAKEUP(x) ;
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT)
# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IOSYS, M_NOWAIT)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
@@ -579,6 +580,7 @@ typedef struct {
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id+x)
+# define POLLWAKEUP(x) ;
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define GETIFP(n,v) ifunit(n)
@@ -660,6 +662,7 @@ typedef struct mbuf mb_t;
# define GETIFP(n, v) ifunit(n)
# define GET_MINOR getminor
# define WAKEUP(id,x) wakeup(id + x)
+# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
@@ -1030,6 +1033,7 @@ typedef u_int32_t u_32_t;
# define KFREES(x,s) kmem_free((char *)(x), (s))
# define SLEEP(id, n) sleep((id), PZERO+1)
# define WAKEUP(id,x) wakeup(id + x)
+# define POLLWAKEUP(x) ;
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -1075,6 +1079,7 @@ struct ip6_ext {
# define FREE_MB_T(m) kfree_skb(m)
# define GETKTIME(x) do_gettimeofday((struct timeval *)x)
# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
+# define POLLWAKEUP(x) ;
# define WAKEUP(x,y) wake_up(x##_linux + y)
# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
# define USE_MUTEXES
@@ -1266,6 +1271,7 @@ extern void* getifp __P((char *, int));
# define GET_MINOR minor
# define SLEEP(id, n) sleepx((id), PZERO+1, 0)
# define WAKEUP(id,x) wakeup(id)
+# define POLLWAKEUP(x) ;
# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
@@ -1430,6 +1436,7 @@ typedef struct mb_s {
# define FREE_MB_T(x)
# define SLEEP(x,y) 1;
# define WAKEUP(x,y) ;
+# define POLLWAKEUP(y) ;
# define IPF_PANIC(x,y) ;
# define PANIC(x,y) ;
# define SPL_NET(x) ;
@@ -1580,6 +1587,7 @@ MALLOC_DECLARE(M_IPFILTER);
# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id,x) wakeup(id+x)
+# define POLLWAKEUP(x) selwakeup(ipfselwait+x)
# define GETIFP(n, v) ifunit(n)
# endif /* (Free)BSD */
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index a061ede..568453d 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -5,7 +5,7 @@
*
* @(#)ip_fil.h 1.35 6/5/96
* $FreeBSD$
- * Id: ip_fil.h,v 2.170.2.18 2005/03/28 10:47:52 darrenr Exp
+ * Id: ip_fil.h,v 2.170.2.29 2006/03/29 11:19:55 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -306,6 +306,7 @@ typedef struct fr_info {
#ifdef MENTAT
mb_t *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qpi;
+ char fin_ifname[LIFNAMSIZ];
#endif
#ifdef __sgi
void *fin_hbuf;
@@ -1134,6 +1135,17 @@ typedef struct ipftune {
# endif
#endif
+#ifdef _KERNEL
+# define FR_VERBOSE(verb_pr)
+# define FR_DEBUG(verb_pr)
+#else
+extern void debug __P((char *, ...));
+extern void verbose __P((char *, ...));
+# define FR_VERBOSE(verb_pr) verbose verb_pr
+# define FR_DEBUG(verb_pr) debug verb_pr
+#endif
+
+
#ifndef _KERNEL
extern int fr_check __P((struct ip *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
@@ -1149,6 +1161,7 @@ extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int));
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
extern void m_freem __P((mb_t *));
+extern int bcopywrap __P((void *, void *, size_t));
#else /* #ifndef _KERNEL */
# if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern void ipfilterattach __P((int));
@@ -1262,7 +1275,7 @@ extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag;
extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
extern ipfrwlock_t ipf_frcache;
-extern char *memstr __P((const char *, char *, int, int));
+extern char *memstr __P((const char *, char *, size_t, size_t));
extern int count4bits __P((u_32_t));
extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int));
extern char *getifname __P((struct ifnet *));
@@ -1319,6 +1332,7 @@ extern void fr_delgroup __P((char *, minor_t, int));
extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***));
extern int fr_loginit __P((void));
+extern int ipflog_canread __P((int));
extern int ipflog_clear __P((minor_t));
extern int ipflog_read __P((minor_t, uio_t *));
extern int ipflog __P((fr_info_t *, u_int));
@@ -1327,7 +1341,7 @@ extern void fr_logunload __P((void));
extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *));
extern int fr_copytolog __P((int, char *, int));
-extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *));
+extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *, int));
extern void fr_deinitialise __P((void));
extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *));
extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *));
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 0e81251..d278781 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.27 2005/08/20 13:48:19 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.32 2006/03/25 13:03:01 darrenr Exp $";
#endif
#if defined(KERNEL) || defined(_KERNEL)
@@ -57,6 +57,7 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.27 2005/08/20 13
#endif
#include <sys/protosw.h>
#include <sys/socket.h>
+#include <sys/selinfo.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
@@ -133,6 +134,7 @@ int ipf_locks_done = 0;
#if (__FreeBSD_version >= 300000)
struct callout_handle fr_slowtimer_ch;
#endif
+struct selinfo ipfselwait[IPL_LOGSIZE];
#if (__FreeBSD_version >= 500011)
# include <sys/conf.h>
@@ -302,6 +304,7 @@ pfil_error:
fr_checkp = fr_check;
}
+ bzero((char *)ipfselwait, sizeof(ipfselwait));
bzero((char *)frcache, sizeof(frcache));
fr_running = 1;
@@ -478,9 +481,11 @@ int mode;
}
SPL_NET(s);
+ READ_ENTER(&ipf_global);
error = fr_ioctlswitch(unit, data, cmd, mode);
if (error != -1) {
+ RWLOCK_EXIT(&ipf_global);
SPL_X(s);
return error;
}
@@ -621,7 +626,10 @@ int mode;
error = EINVAL;
break;
}
+
+ RWLOCK_EXIT(&ipf_global);
SPL_X(s);
+
return error;
}
@@ -744,14 +752,18 @@ dev_t dev;
#endif
register struct uio *uio;
{
+ u_int xmin = GET_MINOR(dev);
+
+ if (xmin < 0)
+ return ENXIO;
# ifdef IPFILTER_SYNC
- if (GET_MINOR(dev) == IPL_LOGSYNC)
+ if (xmin == IPL_LOGSYNC)
return ipfsync_read(uio);
# endif
#ifdef IPFILTER_LOG
- return ipflog_read(GET_MINOR(dev), uio);
+ return ipflog_read(xmin, uio);
#else
return ENXIO;
#endif
@@ -1157,6 +1169,8 @@ frdest_t *fdp;
u_short ip_off;
frentry_t *fr;
+ ro = NULL;
+
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@@ -1170,15 +1184,15 @@ frdest_t *fdp;
* problem.
*/
if (M_WRITABLE(m) == 0) {
- if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
+ m0 = m_dup(m, M_DONTWAIT);
+ if (m0 != 0) {
FREE_MB_T(m);
m = m0;
*mpp = m;
} else {
error = ENOBUFS;
FREE_MB_T(m);
- *mpp = NULL;
- fr_frouteok[1]++;
+ goto done;
}
}
#endif
@@ -1220,18 +1234,8 @@ frdest_t *fdp;
goto bad;
}
- /*
- * In case we're here due to "to <if>" being used with "keep state",
- * check that we're going in the correct direction.
- */
- if ((fr != NULL) && (fin->fin_rev != 0)) {
- if ((ifp != NULL) && (fdp == &fr->fr_tif))
- return -1;
- }
- if (fdp != NULL) {
- if (fdp->fd_ip.s_addr != 0)
- dst->sin_addr = fdp->fd_ip;
- }
+ if ((fdp != NULL) && (fdp->fd_ip.s_addr != 0))
+ dst->sin_addr = fdp->fd_ip;
dst->sin_len = sizeof(*dst);
rtalloc(ro);
@@ -1348,6 +1352,7 @@ frdest_t *fdp;
else
mhip->ip_off |= IP_MF;
mhip->ip_len = htons((u_short)(len + mhlen));
+ *mnext = m;
m->m_next = m_copy(m0, off, len);
if (m->m_next == 0) {
error = ENOBUFS; /* ??? */
@@ -1358,7 +1363,6 @@ frdest_t *fdp;
mhip->ip_off = htons((u_short)mhip->ip_off);
mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen);
- *mnext = m;
mnext = &m->m_act;
}
/*
@@ -1387,7 +1391,7 @@ done:
else
fr_frouteok[1]++;
- if (ro->ro_rt) {
+ if ((ro != NULL) && (ro->ro_rt != NULL)) {
RTFREE(ro->ro_rt);
}
*mpp = NULL;
@@ -1490,6 +1494,9 @@ struct in_addr *inp, *inpmask;
else if (atype == FRI_PEERADDR)
sock = ifa->ifa_dstaddr;
+ if (sock == NULL)
+ return -1;
+
#ifdef USE_INET6
if (v == 6) {
return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock,
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index f1754ca..5a93295 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -103,7 +103,7 @@ extern struct timeout fr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77 2004/01/27 00:24:54 darrenr Exp"; */
+/* static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.5 2006/02/26 08:26:54 darrenr Exp $";*/
#endif
@@ -227,6 +227,7 @@ ipfr_t *table[];
{
ipfr_t *fra, frag;
u_int idx, off;
+ frentry_t *fr;
ip_t *ip;
if (ipfr_inuse >= IPFT_SIZE)
@@ -278,12 +279,9 @@ ipfr_t *table[];
return NULL;
}
- fra->ipfr_rule = fin->fin_fr;
- if (fra->ipfr_rule != NULL) {
-
- frentry_t *fr;
-
- fr = fin->fin_fr;
+ fr = fin->fin_fr;
+ fra->ipfr_rule = fr;
+ if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
fr->fr_ref++;
MUTEX_EXIT(&fr->fr_lock);
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index 9e628a6..6718f85 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -9,7 +9,7 @@
* code.
*
* $FreeBSD$
- * Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp
+ * Id: ip_ftp_pxy.c,v 2.88.2.19 2006/04/01 10:14:53 darrenr Exp $
*/
#define IPF_FTP_PROXY
@@ -369,7 +369,7 @@ int dlen;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
- (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
+ (void) fr_addstate(&fi, NULL, SI_W_DPORT);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
@@ -731,7 +731,7 @@ u_int data_ip;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
- (void) fr_addstate(&fi, &nat2->nat_state, sflags);
+ (void) fr_addstate(&fi, NULL, sflags);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
@@ -1030,13 +1030,14 @@ int rv;
if (ippr_ftp_debug > 4)
printf("ippr_ftp_process: mlen %d\n", mlen);
- if (mlen <= 0) {
- if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
- f->ftps_seq[0] = thseq + 1;
- t->ftps_seq[0] = thack;
- }
+ if ((mlen == 0) && ((tcp->th_flags & TH_OPENING) == TH_OPENING)) {
+ f->ftps_seq[0] = thseq + 1;
+ t->ftps_seq[0] = thack;
+ return 0;
+ } else if (mlen < 0) {
return 0;
}
+
aps = nat->nat_aps;
sel = aps->aps_sel[1 - rv];
@@ -1426,7 +1427,7 @@ int dlen;
ap += *s++ - '0';
}
- if (!s)
+ if (!*s)
return 0;
if (*s == '|')
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 36901ac..83dcb70 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* $FreeBSD$
- * Id: ip_log.c,v 2.75.2.6 2004/10/16 07:59:27 darrenr Exp
+ * Id: ip_log.c,v 2.75.2.11 2006/03/26 13:50:47 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL)
@@ -70,6 +70,10 @@ struct file;
# include <sys/dir.h>
# endif
# include <sys/mbuf.h>
+# include <sys/select.h>
+# if __FreeBSD_version >= 500000
+# include <sys/selinfo.h>
+# endif
#else
# if !defined(__hpux) && defined(_KERNEL)
# include <sys/filio.h>
@@ -144,12 +148,14 @@ iplog_select_t iplog_ss[IPL_LOGMAX+1];
extern int selwait;
# endif /* IPL_SELECT */
+extern struct selinfo ipfselwait[IPL_LOGSIZE];
# if defined(linux) && defined(_KERNEL)
wait_queue_head_t iplh_linux[IPL_LOGSIZE];
# endif
# if SOLARIS
extern kcondvar_t iplwait;
+extern struct pollhead iplpollhead[IPL_LOGSIZE];
# endif
iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE];
@@ -508,9 +514,11 @@ int *types, cnt;
# if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait);
MUTEX_EXIT(&ipl_mutex);
+ pollwakeup(&iplpollhead[dev], POLLRDNORM);
# else
MUTEX_EXIT(&ipl_mutex);
- WAKEUP(iplh,dev);
+ WAKEUP(iplh, dev);
+ POLLWAKEUP(dev);
# endif
SPL_X(s);
# ifdef IPL_SELECT
@@ -668,4 +676,19 @@ minor_t unit;
SPL_X(s);
return used;
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: ipflog_canread */
+/* Returns: int - 0 == no data to read, 1 = data present */
+/* Parameters: unit(I) - device we are reading from */
+/* */
+/* Returns an indication of whether or not there is data present in the */
+/* current buffer for the selected ipf device. */
+/* ------------------------------------------------------------------------ */
+int ipflog_canread(unit)
+int unit;
+{
+ return iplt[unit] != NULL;
+}
#endif /* IPFILTER_LOG */
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 1b69f85..063f557 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -110,7 +110,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$FreeBSD$";
-/* static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.38 2005/03/28 11:09:54 darrenr Exp"; */
+/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.56 2006/04/01 10:15:34 darrenr Exp $";*/
#endif
@@ -194,7 +194,7 @@ static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int));
static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int));
static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
tcphdr_t *, nat_t **, int));
-static void nat_resolverule __P((ipnat_t *));
+static int nat_resolverule __P((ipnat_t *));
static nat_t *fr_natclone __P((fr_info_t *, nat_t *));
static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
static int nat_wildok __P((nat_t *, int, int, int, int));
@@ -868,11 +868,8 @@ int getlock;
{
int error = 0, i, j;
- nat_resolverule(n);
- if (n->in_plabel[0] != '\0') {
- if (n->in_apr == NULL)
- return ENOENT;
- }
+ if (nat_resolverule(n) != 0)
+ return ENOENT;
if ((n->in_age[0] == 0) && (n->in_age[1] != 0))
return EINVAL;
@@ -997,7 +994,7 @@ int getlock;
/* from information passed to the kernel, then add it to the appropriate */
/* NAT rule table(s). */
/* ------------------------------------------------------------------------ */
-static void nat_resolverule(n)
+static int nat_resolverule(n)
ipnat_t *n;
{
n->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
@@ -1008,12 +1005,15 @@ ipnat_t *n;
(void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ);
n->in_ifps[1] = n->in_ifps[0];
} else {
- n->in_ifps[1] = fr_resolvenic(n->in_ifnames[0], 4);
+ n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4);
}
if (n->in_plabel[0] != '\0') {
n->in_apr = appr_lookup(n->in_p, n->in_plabel);
+ if (n->in_apr == NULL)
+ return -1;
}
+ return 0;
}
@@ -1341,23 +1341,31 @@ int getlock;
ATOMIC_INC(nat_stats.ns_rules);
- nat_resolverule(in);
+ if (nat_resolverule(in) != 0) {
+ error = ESRCH;
+ goto junkput;
+ }
}
/*
* Check that the NAT entry doesn't already exist in the kernel.
+ *
+ * For NAT_OUTBOUND, we're lookup for a duplicate MAP entry. To do
+ * this, we check to see if the inbound combination of addresses and
+ * ports is already known. Similar logic is applied for NAT_INBOUND.
+ *
*/
bzero((char *)&fin, sizeof(fin));
fin.fin_p = nat->nat_p;
+ fin.fin_ifp = nat->nat_ifps[0];
if (nat->nat_dir == NAT_OUTBOUND) {
fin.fin_data[0] = ntohs(nat->nat_oport);
fin.fin_data[1] = ntohs(nat->nat_outport);
- fin.fin_ifp = nat->nat_ifps[1];
if (getlock) {
READ_ENTER(&ipf_nat);
}
- n = nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip,
- nat->nat_inip);
+ n = nat_inlookup(&fin, nat->nat_flags, fin.fin_p,
+ nat->nat_oip, nat->nat_inip);
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
@@ -1368,12 +1376,11 @@ int getlock;
} else if (nat->nat_dir == NAT_INBOUND) {
fin.fin_data[0] = ntohs(nat->nat_outport);
fin.fin_data[1] = ntohs(nat->nat_oport);
- fin.fin_ifp = nat->nat_ifps[0];
if (getlock) {
READ_ENTER(&ipf_nat);
}
- n = nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip,
- nat->nat_oip);
+ n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p,
+ nat->nat_outip, nat->nat_oip);
if (getlock) {
RWLOCK_EXIT(&ipf_nat);
}
@@ -1438,6 +1445,12 @@ int getlock;
fr->fr_ref = 1;
(void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE);
bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr));
+
+ fr->fr_ref = 1;
+ fr->fr_dsize = 0;
+ fr->fr_data = NULL;
+ fr->fr_type = FR_T_NONE;
+
MUTEX_NUKE(&fr->fr_lock);
MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
} else {
@@ -1577,6 +1590,9 @@ int logtype;
MUTEX_EXIT(&ipf_nat_new);
return;
}
+ /*
+ * At this point, nat_ref can be either 0 or -1
+ */
#ifdef IPFILTER_SYNC
if (nat->nat_sync)
@@ -2155,6 +2171,9 @@ natinfo_t *ni;
/* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */
/* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */
/* and (3) building that structure and putting it into the NAT table(s). */
+/* */
+/* NOTE: natsave should NOT be used top point back to an ipstate_t struct */
+/* as it can result in memory being corrupted. */
/* ------------------------------------------------------------------------ */
nat_t *nat_new(fin, np, natsave, flags, direction)
fr_info_t *fin;
@@ -2248,6 +2267,7 @@ int direction;
natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
+ KFREE(nat);
nat = natl;
goto done;
}
@@ -2265,6 +2285,7 @@ int direction;
natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p,
fin->fin_src, fin->fin_dst);
if (natl != NULL) {
+ KFREE(nat);
nat = natl;
goto done;
}
@@ -2378,7 +2399,12 @@ int direction;
np = ni->nai_np;
- COPYIFNAME(fin->fin_ifp, nat->nat_ifnames[0]);
+ if (np->in_ifps[0] != NULL) {
+ COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]);
+ }
+ if (np->in_ifps[1] != NULL) {
+ COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]);
+ }
#ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0)
nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat);
@@ -2386,7 +2412,8 @@ int direction;
nat->nat_me = natsave;
nat->nat_dir = direction;
- nat->nat_ifps[0] = fin->fin_ifp;
+ nat->nat_ifps[0] = np->in_ifps[0];
+ nat->nat_ifps[1] = np->in_ifps[1];
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
@@ -2473,7 +2500,7 @@ int rev;
nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4);
- if (nat->nat_ifnames[1][0] !='\0') {
+ if (nat->nat_ifnames[1][0] != '\0') {
nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4);
} else {
@@ -2821,8 +2848,9 @@ int dir;
*
* Since the port fields are part of the TCP/UDP checksum
* of the offending IP packet, you need to adjust that checksum
- * as well... but, if you change, you must change the icmp
- * checksum *again*, to reflect that change.
+ * as well... except that the change in the port numbers should
+ * be offset by the checksum change, so we only need to change
+ * the ICMP checksum if we only change the ports.
*
* To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not
@@ -2857,21 +2885,14 @@ int dir;
* The UDP checksum is optional, only adjust it if
* it has been set.
*/
- if ((oip->ip_p == IPPROTO_UDP) &&
- (dlen >= 8) && (*csump != 0)) {
+ if (oip->ip_p == IPPROTO_UDP) {
sumd = sum1 - sum2;
- sumd2 += sumd;
- sum1 = ntohs(*csump);
- fix_datacksum(csump, sumd);
- sum2 = ntohs(*csump);
-
- /*
- * Fix ICMP checksum to compenstate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
+ if ((dlen >= 8) && (*csump != 0)) {
+ fix_datacksum(csump, sumd);
+ } else {
+ sumd2 += sumd;
+ }
}
/*
@@ -2880,20 +2901,10 @@ int dir;
* the other direction compared to the ICMP message.
*/
if (oip->ip_p == IPPROTO_TCP) {
- 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;
@@ -2913,21 +2924,14 @@ int dir;
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
- if ((oip->ip_p == IPPROTO_UDP) &&
- (dlen >= 8) && (*csump != 0)) {
+ if (oip->ip_p == IPPROTO_UDP) {
sumd = sum1 - sum2;
- sumd2 += sumd;
-
- sum1 = ntohs(*csump);
- fix_datacksum(csump, sumd);
- sum2 = ntohs(*csump);
- /*
- * Fix ICMP checksum to compensate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
+ if ((dlen >= 8) && (*csump != 0)) {
+ fix_datacksum(csump, sumd);
+ } else {
+ sumd2 += sumd;
+ }
}
/*
@@ -2936,20 +2940,10 @@ int dir;
* the other direction compared to the ICMP message.
*/
if (oip->ip_p == IPPROTO_TCP) {
- 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;
@@ -3042,10 +3036,7 @@ struct in_addr src , mapdst;
void *ifp;
u_int hv;
- if (fin != NULL)
- ifp = fin->fin_ifp;
- else
- ifp = NULL;
+ ifp = fin->fin_ifp;
sport = 0;
dport = 0;
gre = NULL;
@@ -3077,17 +3068,13 @@ struct in_addr src , mapdst;
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
- nflags = nat->nat_flags;
+ if (nat->nat_ifps[0] != NULL) {
+ if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
+ continue;
+ } else if (ifp != NULL)
+ nat->nat_ifps[0] = ifp;
- if (ifp != NULL) {
- if (nat->nat_dir == NAT_REDIRECT) {
- if (ifp != nat->nat_ifps[0])
- continue;
- } else {
- if (ifp != nat->nat_ifps[1])
- continue;
- }
- }
+ nflags = nat->nat_flags;
if (nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst &&
@@ -3152,15 +3139,11 @@ 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;
@@ -3327,17 +3310,13 @@ struct in_addr src , dst;
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
- nflags = nat->nat_flags;
+ if (nat->nat_ifps[1] != NULL) {
+ if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
+ continue;
+ } else if (ifp != NULL)
+ nat->nat_ifps[1] = ifp;
- if (ifp != NULL) {
- if (nat->nat_dir == NAT_REDIRECT) {
- if (ifp != nat->nat_ifps[1])
- continue;
- } else {
- if (ifp != nat->nat_ifps[0])
- continue;
- }
- }
+ nflags = nat->nat_flags;
if (nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
@@ -3392,15 +3371,11 @@ 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;
@@ -3449,6 +3424,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;
@@ -3710,7 +3695,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;
@@ -4349,8 +4334,8 @@ void fr_natexpire()
{
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
- SPL_INT(s);
int i;
+ SPL_INT(s);
SPL_NET(s);
WRITE_ENTER(&ipf_nat);
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 8fae312..eb84cd1 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -104,7 +104,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.14 2005/06/18 02:41:33 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.16 2006/03/29 11:19:56 darrenr Exp $";
#endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
@@ -324,8 +324,7 @@ int mode;
if (error == 0)
error = appr_ctl(&ctl);
- if ((ctl.apc_dsize > 0) && (ptr != NULL) &&
- (ctl.apc_data == ptr)) {
+ if (ptr != NULL) {
KFREES(ptr, ctl.apc_dsize);
}
break;
@@ -564,8 +563,8 @@ nat_t *nat;
if (err != 0) {
short adjlen = err & 0xffff;
- s1 = LONG_SUM(ip->ip_len - adjlen);
- s2 = LONG_SUM(ip->ip_len);
+ s1 = LONG_SUM(fin->fin_plen - adjlen);
+ s2 = LONG_SUM(fin->fin_plen);
CALC_SUMD(s1, s2, sd);
fix_outcksum(fin, &ip->ip_sum, sd);
}
@@ -585,19 +584,23 @@ nat_t *nat;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum)
tcp->th_sum = fr_cksum(fin->fin_qfm, ip,
- IPPROTO_TCP, tcp);
+ IPPROTO_TCP, tcp,
+ fin->fin_plen);
#else
tcp->th_sum = fr_cksum(fin->fin_m, ip,
- IPPROTO_TCP, tcp);
+ IPPROTO_TCP, tcp,
+ fin->fin_plen);
#endif
} else if ((udp != NULL) && (udp->uh_sum != 0)) {
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if (dosum)
udp->uh_sum = fr_cksum(fin->fin_qfm, ip,
- IPPROTO_UDP, udp);
+ IPPROTO_UDP, udp,
+ fin->fin_plen);
#else
udp->uh_sum = fr_cksum(fin->fin_m, ip,
- IPPROTO_UDP, udp);
+ IPPROTO_UDP, udp,
+ fin->fin_plen);
#endif
}
aps->aps_bytes += fin->fin_plen;
@@ -688,9 +691,9 @@ int inc;
tcp = (tcphdr_t *)fin->fin_dp;
out = fin->fin_out;
/*
- * ip_len has already been adjusted by 'inc'.
+ * fin->fin_plen has already been adjusted by 'inc'.
*/
- nlen = ip->ip_len;
+ nlen = fin->fin_plen;
nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2);
inc2 = inc;
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 01b2d89..c0d755a 100644
--- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
@@ -5,7 +5,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_rcmd_pxy.c,v 1.41.2.5 2005/10/02 04:20:07 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.41.2.6 2006/04/01 10:14:54 darrenr Exp $
*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code.
@@ -205,7 +205,7 @@ nat_t *nat;
fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
ip->ip_dst = nat->nat_inip;
}
- (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
+ (void) fr_addstate(&fi, NULL, SI_W_DPORT);
if (fi.fin_state != NULL)
fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index ab42da0..5a877a6 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -109,7 +109,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.36 2005/12/04 22:25:36 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.41 2006/04/01 10:16:28 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@@ -670,6 +670,7 @@ caddr_t data;
fr->fr_ref = 0;
fr->fr_dsize = 0;
fr->fr_data = NULL;
+ fr->fr_type = FR_T_NONE;
fr_resolvedest(&fr->fr_tif, fr->fr_v);
fr_resolvedest(&fr->fr_dif, fr->fr_v);
@@ -803,6 +804,11 @@ int rev;
/* Inserts it into the state table and appends to the bottom of the active */
/* list. If the capacity of the table has reached the maximum allowed then */
/* the call will fail and a flush is scheduled for the next timeout call. */
+/* */
+/* NOTE: The use of stsave to point to nat_state will result in memory */
+/* corruption. It should only be used to point to objects that will */
+/* either outlive this (not expired) or will deref the ip_state_t */
+/* when they are deleted. */
/* ------------------------------------------------------------------------ */
ipstate_t *fr_addstate(fin, stsave, flags)
fr_info_t *fin;
@@ -825,28 +831,30 @@ u_int flags;
if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN))
return NULL;
- fr = fin->fin_fr;
- if ((fr->fr_statemax == 0) && (ips_num == fr_statemax)) {
- ATOMIC_INCL(ips_stats.iss_max);
- fr_state_doflush = 1;
- return NULL;
- }
-
/*
* If a "keep state" rule has reached the maximum number of references
* to it, then schedule an automatic flush in case we can clear out
- * some "dead old wood".
+ * some "dead old wood". Note that because the lock isn't held on
+ * fr it is possible that we could overflow. The cost of overflowing
+ * is being ignored here as the number by which it can overflow is
+ * a product of the number of simultaneous threads that could be
+ * executing in here, so a limit of 100 won't result in 200, but could
+ * result in 101 or 102.
*/
- MUTEX_ENTER(&fr->fr_lock);
- if ((fr != NULL) && (fr->fr_statemax != 0) &&
- (fr->fr_statecnt >= fr->fr_statemax)) {
- MUTEX_EXIT(&fr->fr_lock);
- ATOMIC_INCL(ips_stats.iss_maxref);
- fr_state_doflush = 1;
- return NULL;
+ fr = fin->fin_fr;
+ if (fr != NULL) {
+ if ((ips_num == fr_statemax) && (fr->fr_statemax == 0)) {
+ ATOMIC_INCL(ips_stats.iss_max);
+ fr_state_doflush = 1;
+ return NULL;
+ }
+ if ((fr->fr_statemax != 0) &&
+ (fr->fr_statecnt >= fr->fr_statemax)) {
+ ATOMIC_INCL(ips_stats.iss_maxref);
+ fr_state_doflush = 1;
+ return NULL;
+ }
}
- fr->fr_statecnt++;
- MUTEX_EXIT(&fr->fr_lock);
pass = (fr == NULL) ? 0 : fr->fr_flags;
@@ -1048,16 +1056,16 @@ u_int flags;
break;
}
if (is != NULL)
- goto cantaddstate;
+ return NULL;
if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) {
ATOMIC_INCL(ips_stats.iss_bucketfull);
- goto cantaddstate;
+ return NULL;
}
KMALLOC(is, ipstate_t *);
if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_nomem);
- goto cantaddstate;
+ return NULL;
}
bcopy((char *)&ips, (char *)is, sizeof(*is));
/*
@@ -1142,6 +1150,7 @@ u_int flags;
is->is_optmsk[0] &= ~0x8;
is->is_optmsk[1] &= ~0x8;
}
+ is->is_me = stsave;
is->is_sec = fin->fin_secmsk;
is->is_secmsk = 0xffff;
is->is_auth = fin->fin_auth;
@@ -1156,7 +1165,6 @@ u_int flags;
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
READ_ENTER(&ipf_state);
- is->is_me = stsave;
fr_stinsert(is, fin->fin_rev);
@@ -1190,14 +1198,6 @@ u_int flags;
(void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
return is;
-
-cantaddstate:
- if (fr != NULL) {
- MUTEX_ENTER(&fr->fr_lock);
- fr->fr_statecnt--;
- MUTEX_EXIT(&fr->fr_lock);
- }
- return NULL;
}
@@ -1457,18 +1457,6 @@ int flags;
win = ntohs(tcp->th_win);
else
win = ntohs(tcp->th_win) << fdata->td_winscale;
-#if 0
- /*
- * XXX - This is a kludge is here because IPFilter doesn't track SACK
- * options in TCP packets. This is not a trivial to do if one is to
- * consider the performance impact of it. So instead, if the
- * receiver has said SACK is ok, double the allowed window size.
- * This is disabled for testing of another workaround for a problem
- * with Microsoft Windows - see below.
- */
- if ((tdata->td_winflags & TCP_SACK_PERMIT) != 0)
- win *= 2;
-#endif
/*
* A window of 0 produces undesirable behaviour from this function.
@@ -1555,6 +1543,39 @@ int flags;
(fdata->td_winflags & TCP_SACK_PERMIT) &&
(tdata->td_winflags & TCP_SACK_PERMIT)) {
inseq = 1;
+ /*
+ * Sometimes a TCP RST will be generated with only the ACK field
+ * set to non-zero.
+ */
+ } else if ((seq == 0) && (tcpflags == (TH_RST|TH_ACK)) &&
+ (ackskew >= -1) && (ackskew <= 1)) {
+ inseq = 1;
+ } else if (!(flags & IS_TCPFSM)) {
+ int i;
+
+ i = (fin->fin_rev << 1) + fin->fin_out;
+
+#if 0
+ if (is_pkts[i]0 == 0) {
+ /*
+ * Picking up a connection in the middle, the "next"
+ * packet seen from a direction that is new should be
+ * accepted, even if it appears out of sequence.
+ */
+ inseq = 1;
+ } else
+#endif
+ if (!(fdata->td_winflags &
+ (TCP_WSCALE_SEEN|TCP_WSCALE_FIRST))) {
+ /*
+ * No TCPFSM and no window scaling, so make some
+ * extra guesses.
+ */
+ if ((seq == fdata->td_maxend) && (ackskew == 0))
+ inseq = 1;
+ else if (SEQ_GE(seq + maxwin, fdata->td_end - maxwin))
+ inseq = 1;
+ }
}
if (inseq) {
@@ -2341,7 +2362,8 @@ 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)
@@ -2434,11 +2456,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 e96b651..d41091a 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.c
+++ b/sys/contrib/ipfilter/netinet/ip_sync.c
@@ -98,7 +98,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.5 2005/09/04 12:51:12 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.7 2006/03/19 14:59:39 darrenr Exp $";
#endif
#define SYNC_STATETABSZ 256
@@ -704,7 +704,6 @@ int ipfsync_nat(sp, data)
synchdr_t *sp;
void *data;
{
- synclogent_t sle;
syncupdent_t su;
nat_t *n, *nat;
synclist_t *sl;
@@ -716,8 +715,6 @@ void *data;
switch (sp->sm_cmd)
{
case SMC_CREATE :
- bcopy(data, &sle, sizeof(sle));
-
KMALLOC(n, nat_t *);
if (n == NULL) {
err = ENOMEM;
@@ -731,9 +728,7 @@ void *data;
break;
}
- WRITE_ENTER(&ipf_nat);
-
- nat = &sle.sle_un.sleu_ipn;
+ nat = (nat_t *)data;
bzero((char *)n, offsetof(nat_t, nat_age));
bcopy((char *)&nat->nat_age, (char *)&n->nat_age,
sizeof(*n) - offsetof(nat_t, nat_age));
@@ -743,6 +738,8 @@ void *data;
sl->sl_idx = -1;
sl->sl_ipn = n;
sl->sl_num = ntohl(sp->sm_num);
+
+ WRITE_ENTER(&ipf_nat);
sl->sl_pnext = syncstatetab + hv;
sl->sl_next = syncstatetab[hv];
if (syncstatetab[hv] != NULL)
@@ -1007,4 +1004,16 @@ int mode;
{
return EINVAL;
}
+
+
+int ipfsync_canread()
+{
+ return !((sl_tail == sl_idx) && (su_tail == su_idx));
+}
+
+
+int ipfsync_canwrite()
+{
+ return 1;
+}
#endif /* IPFILTER_SYNC */
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 906b2ef..cdbf3d0 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -7,14 +7,14 @@
*
* @(#)ipl.h 1.21 6/5/96
* $FreeBSD$
- * Id: ipl.h,v 2.52.2.9 2005/03/30 14:14:05 darrenr Exp
+ * Id: ipl.h,v 2.52.2.14 2006/04/01 20:09:42 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v4.1.10"
+#define IPL_VERSION "IP Filter: v4.1.13"
-#define IPFILTER_VERSION 4011000
+#define IPFILTER_VERSION 4011300
#endif
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 3c23266..2048df4 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -15,6 +15,10 @@
#include <sys/conf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
+#include <sys/select.h>
+#if __FreeBSD_version >= 500000
+# include <sys/selinfo.h>
+#endif
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
@@ -27,6 +31,9 @@
#include <netinet/ip_nat.h>
#include <netinet/ip_auth.h>
#include <netinet/ip_frag.h>
+#include <netinet/ip_sync.h>
+
+extern struct selinfo ipfselwait[IPL_LOGSIZE];
#if __FreeBSD_version >= 502116
static struct cdev *ipf_devs[IPL_LOGSIZE];
@@ -95,6 +102,10 @@ SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
#define CDEV_MAJOR 79
#if __FreeBSD_version >= 501000
+# include <sys/poll.h>
+# include <sys/select.h>
+static int iplpoll(struct cdev *dev, int events, struct thread *td);
+
static struct cdevsw ipl_cdevsw = {
# if __FreeBSD_version >= 502103
.d_version = D_VERSION,
@@ -106,6 +117,7 @@ static struct cdevsw ipl_cdevsw = {
.d_write = iplwrite,
.d_ioctl = iplioctl,
.d_name = "ipl",
+ .d_poll = iplpoll,
# if __FreeBSD_version < 600000
.d_maj = CDEV_MAJOR,
# endif
@@ -117,7 +129,7 @@ static struct cdevsw ipl_cdevsw = {
/* read */ iplread,
/* write */ iplwrite,
/* ioctl */ iplioctl,
- /* poll */ nopoll,
+ /* poll */ iplpoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "ipl",
@@ -273,3 +285,51 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
return (error);
}
#endif
+
+
+#if __FreeBSD_version >= 501000
+static int
+iplpoll(struct cdev *dev, int events, struct thread *td)
+{
+ u_int xmin = GET_MINOR(dev);
+ int revents;
+
+ if (xmin < 0 || xmin > IPL_LOGMAX)
+ return 0;
+
+ revents = 0;
+
+ switch (xmin)
+ {
+ case IPL_LOGIPF :
+ case IPL_LOGNAT :
+ case IPL_LOGSTATE :
+#ifdef IPFILTER_LOG
+ if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin))
+ revents |= events & (POLLIN | POLLRDNORM);
+#endif
+ break;
+ case IPL_LOGAUTH :
+ if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting())
+ revents |= events & (POLLIN | POLLRDNORM);
+ break;
+ case IPL_LOGSYNC :
+#ifdef IPFILTER_SYNC
+ if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread())
+ revents |= events & (POLLIN | POLLRDNORM);
+ if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite())
+ revents |= events & (POLLOUT | POLLWRNORM);
+#endif
+ break;
+ case IPL_LOGSCAN :
+ case IPL_LOGLOOKUP :
+ default :
+ break;
+ }
+
+ if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
+ selrecord(td, &ipfselwait[xmin]);
+
+ return revents;
+}
+#endif
OpenPOWER on IntegriCloud