aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2001-07-28 11:42:17 +0000
committerDarren Reed <darrenr@FreeBSD.org>2001-07-28 11:42:17 +0000
commit49ca0189911a484818dacff8a69106cc39f73315 (patch)
treec1372cea73bd44a9c1a188aecc172f1b6b8a45ce
parentd42c04169ee9ec41cadf0b90e80130d6d165c4ee (diff)
downloadsrc-49ca0189911a484818dacff8a69106cc39f73315.tar.gz
src-49ca0189911a484818dacff8a69106cc39f73315.zip
Import version 3.4.20 of IPFiltervendor/ipfilter-sys/3-4-20
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=80479 svn path=/vendor-sys/ipfilter/3-4-20/; revision=80480; tag=vendor/ipfilter-sys/3-4-20
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c144
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c217
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.h12
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h97
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.c215
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h29
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c107
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.h17
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c110
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c67
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c154
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h33
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h11
-rw-r--r--sys/contrib/ipfilter/netinet/ip_raudio_pxy.c22
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c77
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h16
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h10
18 files changed, 862 insertions, 510 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index 02f075b1c6c5..c4cd2e041168 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -1,15 +1,8 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#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.35.2.30 2000/12/17 05:49:22 darrenr Exp $";
-#endif
-
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -100,6 +93,11 @@ static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darr
#endif
#include "netinet/ipl.h"
+#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.35.2.39 2001/07/18 13:30:32 darrenr Exp $";
+#endif
+
#ifndef _KERNEL
# include "ipf.h"
# include "ipt.h"
@@ -115,12 +113,6 @@ extern int opts;
# if SOLARIS || defined(__sgi)
extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat;
extern kmutex_t ipf_rw;
-# endif
-# if SOLARIS
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \
- ip, qif)
-# else /* SOLARIS */
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
# endif /* SOLARIS || __sgi */
#endif /* _KERNEL */
@@ -226,7 +218,7 @@ fr_info_t *fin;
if (v == 4) {
fin->fin_id = ip->ip_id;
fi->fi_tos = ip->ip_tos;
- off = (ip->ip_off & IP_OFFMASK) << 3;
+ off = (ip->ip_off & IP_OFFMASK);
tcp = (tcphdr_t *)((char *)ip + hlen);
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
fi->fi_src.i6[1] = 0;
@@ -239,7 +231,7 @@ fr_info_t *fin;
fi->fi_daddr = ip->ip_dst.s_addr;
p = ip->ip_p;
fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
- if (ip->ip_off & 0x3fff)
+ if (ip->ip_off & (IP_MF|IP_OFFMASK))
fi->fi_fl |= FI_FRAG;
plen = ip->ip_len;
fin->fin_dlen = plen - hlen;
@@ -260,6 +252,7 @@ fr_info_t *fin;
fi->fi_fl = 0;
plen = ntohs(ip6->ip6_plen);
fin->fin_dlen = plen;
+ plen += sizeof(*ip6);
}
#endif
else
@@ -268,6 +261,7 @@ fr_info_t *fin;
fin->fin_off = off;
fin->fin_plen = plen;
fin->fin_dp = (void *)tcp;
+ off <<= 3;
switch (p)
{
@@ -315,25 +309,34 @@ fr_info_t *fin;
icmp = (icmphdr_t *)tcp;
- if (icmp->icmp_type == ICMP_ECHOREPLY ||
- icmp->icmp_type == ICMP_ECHO)
+ switch (icmp->icmp_type)
+ {
+ case ICMP_ECHOREPLY :
+ case ICMP_ECHO :
+ /* Router discovery messages - RFC 1256 */
+ case ICMP_ROUTERADVERT :
+ case ICMP_ROUTERSOLICIT :
minicmpsz = ICMP_MINLEN;
-
+ break;
/*
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
* 3*timestamp(3*4)
*/
- else if (icmp->icmp_type == ICMP_TSTAMP ||
- icmp->icmp_type == ICMP_TSTAMPREPLY)
+ case ICMP_TSTAMP :
+ case ICMP_TSTAMPREPLY :
minicmpsz = 20;
-
+ break;
/*
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
* mask(4)
*/
- else if (icmp->icmp_type == ICMP_MASKREQ ||
- icmp->icmp_type == ICMP_MASKREPLY)
+ case ICMP_MASKREQ :
+ case ICMP_MASKREPLY :
minicmpsz = 12;
+ break;
+ default :
+ break;
+ }
}
if ((!(plen >= hlen + minicmpsz) && !off) ||
@@ -522,7 +525,7 @@ fr_info_t *fin;
* satisfy the "short" class too).
*/
if (err && (fin->fin_fi.fi_p == IPPROTO_TCP)) {
- if (fin->fin_fi.fi_fl & FI_SHORT)
+ if (fin->fin_fl & FI_SHORT)
return !(ft->ftu_tcpf | ft->ftu_tcpfm);
/*
* Match the flags ? If not, abort this match.
@@ -557,10 +560,7 @@ void *m;
fin->fin_fr = NULL;
fin->fin_rule = 0;
fin->fin_group = 0;
- if (fin->fin_v == 4)
- off = ip->ip_off & IP_OFFMASK;
- else
- off = 0;
+ off = fin->fin_off;
pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
@@ -787,7 +787,7 @@ int out;
mb_t *mc = NULL;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
- char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
+ char hbuf[128];
# endif
int up;
@@ -812,6 +812,9 @@ int out;
# ifdef USE_INET6
if (v == 6) {
len = ntohs(((ip6_t*)ip)->ip6_plen);
+ if (!len)
+ return -1; /* potential jumbo gram */
+ len += sizeof(ip6_t);
p = ((ip6_t *)ip)->ip6_nxt;
} else
# endif
@@ -820,7 +823,8 @@ int out;
len = ip->ip_len;
}
- if ((p == IPPROTO_TCP || p == IPPROTO_UDP || p == IPPROTO_ICMP
+ if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
+ (v == 4 && p == IPPROTO_ICMP)
# ifdef USE_INET6
|| (v == 6 && p == IPPROTO_ICMPV6)
# endif
@@ -889,13 +893,6 @@ int out;
# endif
#endif /* _KERNEL */
- /*
- * Be careful here: ip_id is in network byte order when called
- * from ip_output()
- */
- if ((out) && (v == 4))
- ip->ip_id = ntohs(ip->ip_id);
-
changed = 0;
fin->fin_ifp = ifp;
fin->fin_v = v;
@@ -940,15 +937,12 @@ int out;
}
#endif
pass = fr_pass;
- if (fin->fin_fi.fi_fl & FI_SHORT) {
+ if (fin->fin_fl & FI_SHORT) {
ATOMIC_INCL(frstats[out].fr_short);
}
READ_ENTER(&ipf_mutex);
- if (fin->fin_fi.fi_fl & FI_SHORT)
- ATOMIC_INCL(frstats[out].fr_short);
-
/*
* Check auth now. This, combined with the check below to see if apass
* is 0 is to ensure that we don't count the packet twice, which can
@@ -972,8 +966,18 @@ int out;
}
}
- if (apass || (!(fr = ipfr_knownfrag(ip, fin)) &&
- !(fr = fr_checkstate(ip, fin)))) {
+ if (!apass) {
+ if ((fin->fin_fl & FI_FRAG) == FI_FRAG)
+ fr = ipfr_knownfrag(ip, fin);
+ if (!fr && !(fin->fin_fl & FI_SHORT))
+ fr = fr_checkstate(ip, fin);
+ if (fr != NULL)
+ pass = fr->fr_flags;
+ if (fr && (pass & FR_LOGFIRST))
+ pass &= ~(FR_LOGFIRST|FR_LOG);
+ }
+
+ if (apass || !fr) {
/*
* If a packet is found in the auth table, then skip checking
* the access lists for permission but we do need to consider
@@ -1008,22 +1012,26 @@ int out;
ATOMIC_INCL(frstats[out].fr_nom);
}
}
- fr = fin->fin_fr;
} else
pass = apass;
+ fr = fin->fin_fr;
/*
* If we fail to add a packet to the authorization queue,
* then we drop the packet later. However, if it was added
* then pretend we've dropped it already.
*/
- if ((pass & FR_AUTH))
- if (fr_newauth((mb_t *)m, fin, ip) != 0)
+ if ((pass & FR_AUTH)) {
+ if (fr_newauth((mb_t *)m, fin, ip) != 0) {
#ifdef _KERNEL
m = *mp = NULL;
#else
;
#endif
+ error = 0;
+ } else
+ error = ENOSPC;
+ }
if (pass & FR_PREAUTH) {
READ_ENTER(&ipf_auth);
@@ -1038,7 +1046,7 @@ int out;
fin->fin_fr = fr;
if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) {
- if (fin->fin_fi.fi_fl & FI_FRAG) {
+ if (fin->fin_fl & FI_FRAG) {
if (ipfr_newfrag(ip, fin, pass) == -1) {
ATOMIC_INCL(frstats[out].fr_bnfr);
} else {
@@ -1116,9 +1124,6 @@ logit:
}
#endif /* IPFILTER_LOG */
- if ((out) && (v == 4))
- ip->ip_id = htons(ip->ip_id);
-
#ifdef _KERNEL
/*
* Only allow FR_DUP to work if a rule matched - it makes no sense to
@@ -1160,7 +1165,7 @@ logit:
send_icmp_err(ip, ICMP_UNREACH, fin, dst);
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ !(fin->fin_fl & FI_SHORT)) {
if (send_reset(ip, fin) == 0) {
ATOMIC_INCL(frstats[1].fr_ret);
}
@@ -1173,7 +1178,7 @@ logit:
verbose("- forged ICMP unreachable sent\n");
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ !(fin->fin_fl & FI_SHORT)) {
verbose("- TCP RST sent\n");
ATOMIC_INCL(frstats[1].fr_ret);
}
@@ -1202,15 +1207,17 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(m, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(mc, fin, &fr->fr_dif);
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (void) ipfr_fastroute(m, mp, fin, fdp);
+
+ if (mc != NULL)
+ (void) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
}
- if (!(pass & FR_PASS) && m)
+
+ if (!(pass & FR_PASS) && m) {
m_freem(m);
+ m = *mp = NULL;
+ }
# ifdef __sgi
else if (changed && up && m)
m_copyback(m, 0, up, hbuf);
@@ -1221,12 +1228,11 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(ip, m, mp, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(ip, mc, mp, fin, &fr->fr_dif);
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (void) ipfr_fastroute(ip, m, mp, fin, fdp);
+
+ if (mc != NULL)
+ (void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
}
# endif /* !SOLARIS */
return (pass & FR_PASS) ? 0 : error;
@@ -1458,7 +1464,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1907,7 +1913,7 @@ void frsync()
ip_statesync(ifp);
}
ip_natsync((struct ifnet *)-1);
-# endif
+# endif /* !SOLARIS */
WRITE_ENTER(&ipf_mutex);
frsynclist(ipacct[0][fr_active]);
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index a4536105819c..b22d470b6095 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -1,14 +1,8 @@
/*
- * Copyright (C) 1998-2000 by Darren Reed & Guido van Rooij.
+ * Copyright (C) 1998-2001 by Darren Reed & Guido van Rooij.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.5 2001/01/10 06:18:35 darrenr Exp $";
-#endif
-
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -77,7 +71,7 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.5 2001/01/10 06:18:35 d
#endif
#include <netinet/tcp.h>
#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
-extern struct ifqueue ipintrq; /* ip packet input queue */
+extern struct ifqueue ipintrq; /* ip packet input queue */
#else
# ifndef linux
# if __FreeBSD_version >= 300000
@@ -107,10 +101,13 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
# endif
#endif
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.12 2001/07/18 14:57:08 darrenr Exp $";
+#endif
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern KRWLOCK_T ipf_auth;
+extern KRWLOCK_T ipf_auth, ipf_mutex;
extern kmutex_t ipf_authmx;
# if SOLARIS
extern kcondvar_t ipfauthwait;
@@ -129,7 +126,8 @@ static frauth_t fr_auth[FR_NUMAUTH];
mb_t *fr_authpkts[FR_NUMAUTH];
static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
static frauthent_t *fae_list = NULL;
-frentry_t *ipauth = NULL;
+frentry_t *ipauth = NULL,
+ *fr_authlist = NULL;
/*
@@ -142,10 +140,12 @@ ip_t *ip;
fr_info_t *fin;
{
u_short id = ip->ip_id;
+ frentry_t *fr;
+ frauth_t *fra;
u_32_t pass;
int i;
- if (fr_auth_lock)
+ if (fr_auth_lock || !fr_authused)
return 0;
READ_ENTER(&ipf_auth);
@@ -155,24 +155,54 @@ fr_info_t *fin;
* case the same packet gets sent again and it hasn't yet been
* auth'd.
*/
- if ((fr_auth[i].fra_index == -2) &&
- (id == fr_auth[i].fra_info.fin_id) &&
- !bcmp((char *)fin,(char *)&fr_auth[i].fra_info,FI_CSIZE)) {
+ fra = fr_auth + i;
+ if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) &&
+ !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) {
/*
* Avoid feedback loop.
*/
- if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH))
+ if (!(pass = fra->fra_pass) || (pass & FR_AUTH))
pass = FR_BLOCK;
+ /*
+ * Create a dummy rule for the stateful checking to
+ * use and return. Zero out any values we don't
+ * trust from userland!
+ */
+ if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) &&
+ (fin->fin_fi.fi_fl & FI_FRAG))) {
+ KMALLOC(fr, frentry_t *);
+ if (fr) {
+ bcopy((char *)fra->fra_info.fin_fr,
+ fr, sizeof(*fr));
+ fr->fr_grp = NULL;
+ fr->fr_ifa = fin->fin_ifp;
+ fr->fr_func = NULL;
+ fr->fr_ref = 1;
+ fr->fr_flags = pass;
+#if BSD >= 199306
+ fr->fr_oifa = NULL;
+#endif
+ }
+ } else
+ fr = fra->fra_info.fin_fr;
+ fin->fin_fr = fr;
RWLOCK_EXIT(&ipf_auth);
WRITE_ENTER(&ipf_auth);
+ if (fr && fr != fra->fra_info.fin_fr) {
+ fr->fr_next = fr_authlist;
+ fr_authlist = fr;
+ }
fr_authstats.fas_hits++;
- fr_auth[i].fra_index = -1;
+ fra->fra_index = -1;
fr_authused--;
if (i == fr_authstart) {
- while (fr_auth[i].fra_index == -1) {
+ while (fra->fra_index == -1) {
i++;
- if (i == FR_NUMAUTH)
+ fra++;
+ if (i == FR_NUMAUTH) {
i = 0;
+ fra = fr_auth;
+ }
fr_authstart = i;
if (i == fr_authend)
break;
@@ -208,6 +238,7 @@ ip_t *ip;
#if defined(_KERNEL) && SOLARIS
qif_t *qif = fin->fin_qif;
#endif
+ frauth_t *fra;
int i;
if (fr_auth_lock)
@@ -219,7 +250,7 @@ ip_t *ip;
RWLOCK_EXIT(&ipf_auth);
return 0;
} else {
- if ((fr_authstart == 0) && (fr_authend == FR_NUMAUTH - 1)) {
+ if (fr_authused == FR_NUMAUTH) {
fr_authstats.fas_nospace++;
RWLOCK_EXIT(&ipf_auth);
return 0;
@@ -232,51 +263,48 @@ ip_t *ip;
if (fr_authend == FR_NUMAUTH)
fr_authend = 0;
RWLOCK_EXIT(&ipf_auth);
- fr_auth[i].fra_index = i;
- fr_auth[i].fra_pass = 0;
- fr_auth[i].fra_age = fr_defaultauthage;
- bcopy((char *)fin, (char *)&fr_auth[i].fra_info, sizeof(*fin));
-#if !defined(sparc) && !defined(m68k)
+ fra = fr_auth + i;
+ fra->fra_index = i;
+ fra->fra_pass = 0;
+ fra->fra_age = fr_defaultauthage;
+ bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
+#if SOLARIS && defined(_KERNEL)
+# if !defined(sparc)
/*
* No need to copyback here as we want to undo the changes, not keep
* them.
*/
-# if SOLARIS && defined(_KERNEL)
if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
-# endif
{
register u_short bo;
bo = ip->ip_len;
ip->ip_len = htons(bo);
-# if !SOLARIS && !defined(__NetBSD__)
- /* 4.4BSD converts this ip_input.c, but I don't in solaris.c */
- bo = ip->ip_id;
- ip->ip_id = htons(bo);
-# endif
bo = ip->ip_off;
ip->ip_off = htons(bo);
}
-#endif
-#if SOLARIS && defined(_KERNEL)
+# endif
m->b_rptr -= qif->qf_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
- fr_auth[i].fra_q = qif->qf_q;
+ fra->fra_q = qif->qf_q;
cv_signal(&ipfauthwait);
#else
+# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
+ if (!fin->fin_out) {
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ }
+# endif
fr_authpkts[i] = m;
-# if defined(linux) && defined(_KERNEL)
- wake_up_interruptible(&ipfauthwait);
-# else
WAKEUP(&fr_authnext);
-# endif
#endif
return 1;
}
-int fr_auth_ioctl(data, cmd, fr, frptr)
+int fr_auth_ioctl(data, mode, cmd, fr, frptr)
caddr_t data;
+int mode;
#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
u_long cmd;
#else
@@ -287,8 +315,9 @@ frentry_t *fr, **frptr;
mb_t *m;
#if defined(_KERNEL) && !SOLARIS
struct ifqueue *ifq;
+ int s;
#endif
- frauth_t auth, *au = &auth;
+ frauth_t auth, *au = &auth, *fra;
frauthent_t *fae, **faep;
int i, error = 0;
@@ -313,21 +342,26 @@ frentry_t *fr, **frptr;
else
faep = &fae->fae_next;
if (cmd == SIOCRMAFR) {
- if (!fae)
+ if (!fr || !frptr)
+ error = EINVAL;
+ else if (!fae)
error = ESRCH;
else {
WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
*faep = fae->fae_next;
*frptr = fr->fr_next;
+ SPL_X(s);
RWLOCK_EXIT(&ipf_auth);
KFREE(fae);
}
- } else {
+ } else if (fr && frptr) {
KMALLOC(fae, frauthent_t *);
if (fae != NULL) {
bcopy((char *)fr, (char *)&fae->fae_fr,
sizeof(*fr));
WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
fae->fae_age = fr_defaultauthage;
fae->fae_fr.fr_hits = 0;
fae->fae_fr.fr_next = *frptr;
@@ -335,10 +369,12 @@ frentry_t *fr, **frptr;
fae->fae_next = *faep;
*faep = fae;
ipauth = &fae_list->fae_fr;
+ SPL_X(s);
RWLOCK_EXIT(&ipf_auth);
} else
error = ENOMEM;
- }
+ } else
+ error = EINVAL;
break;
case SIOCATHST:
READ_ENTER(&ipf_auth);
@@ -348,6 +384,10 @@ frentry_t *fr, **frptr;
sizeof(fr_authstats));
break;
case SIOCAUTHW:
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
fr_authioctlloop:
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
@@ -357,9 +397,11 @@ fr_authioctlloop:
if (error)
break;
WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
fr_authnext++;
if (fr_authnext == FR_NUMAUTH)
fr_authnext = 0;
+ SPL_X(s);
RWLOCK_EXIT(&ipf_auth);
return 0;
}
@@ -372,55 +414,62 @@ fr_authioctlloop:
}
mutex_exit(&ipf_authmx);
# else
-# ifdef linux
- interruptible_sleep_on(&ipfauthwait);
- if (current->signal & ~current->blocked)
- error = -EINTR;
-# else
error = SLEEP(&fr_authnext, "fr_authnext");
# endif
-# endif
#endif
RWLOCK_EXIT(&ipf_auth);
if (!error)
goto fr_authioctlloop;
break;
case SIOCAUTHR:
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth));
if (error)
return error;
WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
i = au->fra_index;
+ fra = fr_auth + i;
if ((i < 0) || (i > FR_NUMAUTH) ||
- (fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) {
+ (fra->fra_info.fin_id != au->fra_info.fin_id)) {
+ SPL_X(s);
RWLOCK_EXIT(&ipf_auth);
return EINVAL;
}
m = fr_authpkts[i];
- fr_auth[i].fra_index = -2;
- fr_auth[i].fra_pass = au->fra_pass;
+ fra->fra_index = -2;
+ fra->fra_pass = au->fra_pass;
fr_authpkts[i] = NULL;
-#ifdef _KERNEL
RWLOCK_EXIT(&ipf_auth);
-# ifndef linux
+#ifdef _KERNEL
if (m && au->fra_info.fin_out) {
-# if SOLARIS
- error = fr_qout(fr_auth[i].fra_q, m);
-# else /* SOLARIS */
-# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__)
- error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
+# if SOLARIS
+ error = fr_qout(fra->fra_q, m);
+# else /* SOLARIS */
+ struct route ro;
+
+ bzero((char *)&ro, sizeof(ro));
+# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
+ defined(__OpenBSD__)
+ error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
-# else
- error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
-# endif
-# endif /* SOLARIS */
+# else
+ error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL);
+# endif
+ if (ro.ro_rt) {
+ RTFREE(ro.ro_rt);
+ }
+# endif /* SOLARIS */
if (error)
fr_authstats.fas_sendfail++;
else
fr_authstats.fas_sendok++;
} else if (m) {
# if SOLARIS
- error = fr_qin(fr_auth[i].fra_q, m);
+ error = fr_qin(fra->fra_q, m);
# else /* SOLARIS */
ifq = &ipintrq;
if (IF_QFULL(ifq)) {
@@ -438,7 +487,6 @@ fr_authioctlloop:
fr_authstats.fas_queok++;
} else
error = EINVAL;
-# endif
# if SOLARIS
if (error)
error = EINVAL;
@@ -449,10 +497,10 @@ fr_authioctlloop:
*/
if (error == ENOBUFS) {
fr_authused--;
- fr_auth[i].fra_index = -1;
- fr_auth[i].fra_pass = 0;
+ fra->fra_index = -1;
+ fra->fra_pass = 0;
if (i == fr_authstart) {
- while (fr_auth[i].fra_index == -1) {
+ while (fra->fra_index == -1) {
i++;
if (i == FR_NUMAUTH)
i = 0;
@@ -468,6 +516,7 @@ fr_authioctlloop:
}
# endif
#endif /* _KERNEL */
+ SPL_X(s);
break;
default :
error = EINVAL;
@@ -485,6 +534,7 @@ void fr_authunload()
{
register int i;
register frauthent_t *fae, **faep;
+ frentry_t *fr, **frp;
mb_t *m;
WRITE_ENTER(&ipf_auth);
@@ -503,6 +553,26 @@ void fr_authunload()
}
ipauth = NULL;
RWLOCK_EXIT(&ipf_auth);
+
+ if (fr_authlist) {
+ /*
+ * We *MuST* reget ipf_auth because otherwise we won't get the
+ * locks in the right order and risk deadlock.
+ * We need ipf_mutex here to prevent a rule from using it
+ * inside fr_check().
+ */
+ WRITE_ENTER(&ipf_mutex);
+ WRITE_ENTER(&ipf_auth);
+ for (frp = &fr_authlist; (fr = *frp); ) {
+ if (fr->fr_ref == 1) {
+ *frp = fr->fr_next;
+ KFREE(fr);
+ } else
+ frp = &fr->fr_next;
+ }
+ RWLOCK_EXIT(&ipf_auth);
+ RWLOCK_EXIT(&ipf_mutex);
+ }
}
@@ -515,6 +585,7 @@ void fr_authexpire()
register int i;
register frauth_t *fra;
register frauthent_t *fae, **faep;
+ register frentry_t *fr, **frp;
mb_t *m;
#if !SOLARIS
int s;
@@ -544,6 +615,14 @@ void fr_authexpire()
faep = &fae->fae_next;
}
ipauth = &fae_list->fae_fr;
+
+ for (frp = &fr_authlist; (fr = *frp); ) {
+ if (fr->fr_ref == 1) {
+ *frp = fr->fr_next;
+ KFREE(fr);
+ } else
+ frp = &fr->fr_next;
+ }
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 681a6e53f4c3..7d3e46316d10 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -1,11 +1,9 @@
/*
- * Copyright (C) 1997-2000 by Darren Reed & Guido Van Rooij.
+ * Copyright (C) 1997-2001 by Darren Reed & Guido Van Rooij.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_auth.h,v 2.3.2.2 2000/10/19 15:38:44 darrenr Exp $
+ * $Id: ip_auth.h,v 2.3.2.4 2001/07/18 14:57:08 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@@ -55,8 +53,8 @@ extern void fr_authunload __P((void));
extern mb_t *fr_authpkts[];
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
-extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
+extern int fr_auth_ioctl __P((caddr_t, int, u_long, frentry_t *, frentry_t **));
#else
-extern int fr_auth_ioctl __P((caddr_t, int, frentry_t *, frentry_t **));
+extern int fr_auth_ioctl __P((caddr_t, int, int, frentry_t *, frentry_t **));
#endif
#endif /* __IP_AUTH_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index ed71f36cc021..a7d0db4f07a8 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -1,12 +1,10 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.26.2.9 2001/01/14 14:58:01 darrenr Exp $
+ * $Id: ip_compat.h,v 2.26.2.17 2001/07/23 04:22:48 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -27,6 +25,9 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
+#if SOLARIS && !defined(SOLARIS2)
+# define SOLARIS2 4 /* Pick an old version */
+#endif
#if SOLARIS2 >= 8
# ifndef USE_INET6
# define USE_INET6
@@ -119,10 +120,34 @@ struct ether_addr {
# define V4_PART_OF_V6(v6) v6.s6_addr32[3]
# endif
# endif
-#else
+
+typedef struct qif {
+ struct qif *qf_next;
+ ill_t *qf_ill;
+ kmutex_t qf_lock;
+ void *qf_iptr;
+ void *qf_optr;
+ queue_t *qf_in;
+ queue_t *qf_out;
+ struct qinit *qf_wqinfo;
+ struct qinit *qf_rqinfo;
+ struct qinit qf_wqinit;
+ struct qinit qf_rqinit;
+ mblk_t *qf_m; /* These three fields are for passing data up from */
+ queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
+ size_t qf_off;
+ size_t qf_len; /* this field is used for in ipfr_fastroute */
+ char qf_name[8];
+ /*
+ * in case the ILL has disappeared...
+ */
+ size_t qf_hl; /* header length */
+ int qf_sap;
+} qif_t;
+#else /* SOLARIS */
# if !defined(__sgi)
typedef int minor_t;
-#endif
+# endif
#endif /* SOLARIS */
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
@@ -264,10 +289,26 @@ union i6addr {
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
# ifdef IPFILTER_LKM
-# include <osreldate.h>
+# ifndef __FreeBSD_cc_version
+# include <osreldate.h>
+# else
+# if __FreeBSD_cc_version < 430000
+# include <osreldate.h>
+# else
+# include <sys/param.h>
+# endif
+# endif
# define ACTUALLY_LKM_NOT_KERNEL
# else
-# include <sys/osreldate.h>
+# ifndef __FreeBSD_cc_version
+# include <sys/osreldate.h>
+# else
+# if __FreeBSD_cc_version < 430000
+# include <sys/osreldate.h>
+# else
+# include <sys/param.h>
+# endif
+# endif
# endif
# if __FreeBSD__ < 3
# include <machine/spl.h>
@@ -325,6 +366,7 @@ typedef struct {
# define ATOMIC_DEC32(x) atomic_add_32((uint32_t*)&(x), -1)
# define ATOMIC_DEC16(x) atomic_add_16((uint16_t*)&(x), -1)
# else
+# define IRE_CACHE IRE_ROUTE
# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
mutex_exit(&ipf_rw); }
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
@@ -374,29 +416,6 @@ typedef struct {
# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
-typedef struct qif {
- struct qif *qf_next;
- ill_t *qf_ill;
- kmutex_t qf_lock;
- void *qf_iptr;
- void *qf_optr;
- queue_t *qf_in;
- queue_t *qf_out;
- struct qinit *qf_wqinfo;
- struct qinit *qf_rqinfo;
- struct qinit qf_wqinit;
- struct qinit qf_rqinit;
- mblk_t *qf_m; /* These three fields are for passing data up from */
- queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
- size_t qf_off;
- size_t qf_len; /* this field is used for in ipfr_fastroute */
- char qf_name[8];
- /*
- * in case the ILL has disappeared...
- */
- size_t qf_hl; /* header length */
- int qf_sap;
-} qif_t;
extern ill_t *get_unit __P((char *, int));
# define GETUNIT(n, v) get_unit(n, v)
# define IFNAME(x) ((ill_t *)x)->ill_name
@@ -452,7 +471,9 @@ extern ill_t *get_unit __P((char *, int));
(defined(OpenBSD) && (OpenBSD >= 199603))
# define IFNAME(x) ((struct ifnet *)x)->if_xname
# else
-# define IFNAME(x) ((struct ifnet *)x)->if_name
+# define USE_GETIFNAME 1
+# define IFNAME(x) get_ifname((struct ifnet *)x)
+extern char *get_ifname __P((struct ifnet *));
# endif
# endif
# endif /* sun */
@@ -508,7 +529,8 @@ extern vm_map_t kmem_map;
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id) wakeup(id)
# endif /* BSD */
-# if defined(NetBSD) && NetBSD <= 1991011 && NetBSD >= 199407
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199407)) || \
+ (defined(OpenBSD) && (OpenBSD >= 200006))
# define SPL_NET(x) x = splsoftnet()
# define SPL_X(x) (void) splx(x)
# else
@@ -517,7 +539,7 @@ extern vm_map_t kmem_map;
# define SPL_NET(x) x = splnet()
# define SPL_X(x) (void) splx(x)
# endif
-# endif /* NetBSD && NetBSD <= 1991011 && NetBSD >= 199407 */
+# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
# define PANIC(x,y) if (x) panic y
#else /* KERNEL */
# define SLEEP(x,y) ;
@@ -576,7 +598,6 @@ typedef struct mbuf mb_t;
# endif
#endif /* SOLARIS */
-#if defined(linux) || defined(__sgi)
/*
* These #ifdef's are here mainly for linux, but who knows, they may
* not be in other places or maybe one day linux will grow up and some
@@ -615,6 +636,9 @@ typedef struct mbuf mb_t;
#ifndef ICMP_MASKREPLY
# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
#endif
+#ifndef ICMP_PARAMPROB_OPTABSENT
+# define ICMP_PARAMPROB_OPTABSENT 1
+#endif
#ifndef IPVERSION
# define IPVERSION 4
#endif
@@ -702,7 +726,6 @@ typedef struct mbuf mb_t;
#ifndef IPOPT_OLEN
# define IPOPT_OLEN 1
#endif
-#endif /* linux || __sgi */
#ifdef linux
#include <linux/in_systm.h>
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c
index 92537750b79c..e15ff67b6534 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil.c
@@ -1,15 +1,8 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#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.c,v 2.42.2.17 2000/10/19 15:39:42 darrenr Exp $";
-#endif
-
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
@@ -118,6 +111,11 @@ static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.17 2000/10/19 15:39:42 d
extern int ip_optcopy __P((struct ip *, struct ip *));
#endif
+#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.c,v 2.42.2.34 2001/07/23 13:49:57 darrenr Exp $";
+#endif
+
extern struct protosw inetsw[];
@@ -131,7 +129,11 @@ extern int tcp_ttl;
# endif
#endif
+#ifdef ICMP_UNREACH_FILTER_PROHIB
+int ipl_unreach = ICMP_UNREACH_FILTER_PROHIB;
+#else
int ipl_unreach = ICMP_UNREACH_FILTER;
+#endif
u_long ipl_frouteok[2] = {0, 0};
static int frzerostats __P((caddr_t));
@@ -171,6 +173,10 @@ struct callout_handle ipfr_slowtimer_ch;
# include <sys/callout.h>
struct callout ipfr_slowtimer_ch;
#endif
+#if defined(__OpenBSD__)
+# include <sys/timeout.h>
+struct timeout ipfr_slowtimer_ch;
+#endif
#if defined(__sgi) && defined(_KERNEL)
toid_t ipfr_slowtimer_ch;
#endif
@@ -246,12 +252,18 @@ int iplattach()
# ifdef IPFILTER_LOG
ipflog_init();
# endif
- if (nat_init() == -1)
- return -1;
- if (fr_stateinit() == -1)
- return -1;
- if (appr_init() == -1)
- return -1;
+ if (nat_init() == -1) {
+ SPL_X(s);
+ return EIO;
+ }
+ if (fr_stateinit() == -1) {
+ SPL_X(s);
+ return EIO;
+ }
+ if (appr_init() == -1) {
+ SPL_X(s);
+ return EIO;
+ }
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
@@ -261,6 +273,7 @@ int iplattach()
# ifdef USE_INET6
goto pfil_error;
# else
+ SPL_X(s);
appr_unload();
ip_natunload();
fr_stateunload();
@@ -277,6 +290,7 @@ int iplattach()
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
pfil_error:
+ SPL_X(s);
appr_unload();
ip_natunload();
fr_stateunload();
@@ -321,10 +335,15 @@ pfil_error:
callout_init(&ipfr_slowtimer_ch);
callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
# else
-# if (__FreeBSD_version >= 300000) || defined(__sgi)
- ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
+# if defined(__OpenBSD__)
+ timeout_set(&ipfr_slowtimer_ch, ipfr_slowtimer, NULL);
+ timeout_add(&ipfr_slowtimer_ch, hz/2);
# else
+# if (__FreeBSD_version >= 300000) || defined(__sgi)
+ ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
+# else
timeout(ipfr_slowtimer, NULL, hz/2);
+# endif
# endif
# endif
#endif
@@ -353,8 +372,12 @@ int ipldetach()
# ifdef __sgi
untimeout(ipfr_slowtimer_ch);
# else
+# if defined(__OpenBSD__)
+ timeout_del(&ipfr_slowtimer_ch);
+# else
untimeout(ipfr_slowtimer, NULL);
-# endif
+# endif /* OpenBSD */
+# endif /* __sgi */
# endif /* FreeBSD */
# endif /* NetBSD */
#endif
@@ -376,16 +399,20 @@ int ipldetach()
# if __NetBSD_Version__ >= 104200000
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
- if (error)
+ if (error) {
+ SPL_X(s);
return error;
+ }
# else
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
- if (error)
+ if (error) {
+ SPL_X(s);
return error;
+ }
# endif
# endif
@@ -489,8 +516,9 @@ int mode;
}
if (unit == IPL_LOGAUTH) {
if (!fr_running)
- return EIO;
- error = fr_auth_ioctl(data, cmd, NULL, NULL);
+ error = EIO;
+ else
+ error = fr_auth_ioctl(data, mode, cmd, NULL, NULL);
SPL_X(s);
return error;
}
@@ -564,7 +592,7 @@ int mode;
fr_getstat(&fio);
error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
if (error)
- return EFAULT;
+ error = EFAULT;
break;
}
case SIOCFRZST :
@@ -607,7 +635,7 @@ int mode;
error = IWCOPYPTR((caddr_t)ipfr_fragstats(), data,
sizeof(ipfrstat_t));
if (error)
- return EFAULT;
+ error = EFAULT;
break;
case SIOCAUTHW :
case SIOCAUTHR :
@@ -820,8 +848,6 @@ caddr_t data;
return EBUSY;
if (fg && fg->fg_head)
fg->fg_head->fr_ref--;
- if (unit == IPL_LOGAUTH)
- return fr_auth_ioctl(data, req, f, ftail);
if (f->fr_grhead)
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
unit, set);
@@ -835,8 +861,6 @@ caddr_t data;
if (f)
error = EEXIST;
else {
- if (unit == IPL_LOGAUTH)
- return fr_auth_ioctl(data, req, fp, ftail);
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
@@ -1068,7 +1092,7 @@ struct mbuf *m;
# ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
# endif
- return ipfr_fastroute(m, fin, NULL);
+ return ipfr_fastroute(m, fin->fin_mp, fin, NULL);
}
@@ -1079,6 +1103,7 @@ fr_info_t *fin;
int dst;
{
int err, hlen = 0, xtra = 0, iclen, ohlen = 0, avail, code;
+ u_short shlen, slen = 0, soff = 0;
struct in_addr dst4;
struct icmp *icmp;
struct mbuf *m;
@@ -1220,6 +1245,11 @@ int dst;
} else
#endif
{
+ slen = oip->ip_len;
+ oip->ip_len = htons(oip->ip_len);
+ soff = oip->ip_off;
+ oip->ip_off = htons(ip->ip_off);
+
ip->ip_src.s_addr = dst4.s_addr;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
@@ -1233,7 +1263,18 @@ int dst;
ip->ip_len = iclen;
ip->ip_p = IPPROTO_ICMP;
}
+
+ shlen = fin->fin_hlen;
+ fin->fin_hlen = hlen;
err = send_ip(oip, fin, m);
+ fin->fin_hlen = shlen;
+#ifdef USE_INET6
+ if (fin->fin_v == 4)
+#endif
+ {
+ oip->ip_len = slen;
+ oip->ip_off = soff;
+ }
return err;
}
@@ -1268,8 +1309,8 @@ register struct mbuf *m0;
}
-int ipfr_fastroute(m0, fin, fdp)
-struct mbuf *m0;
+int ipfr_fastroute(m0, mpp, fin, fdp)
+struct mbuf *m0, **mpp;
fr_info_t *fin;
frdest_t *fdp;
{
@@ -1282,16 +1323,49 @@ frdest_t *fdp;
struct route iproute;
frentry_t *fr;
+#ifdef M_WRITABLE
+ /*
+ * HOT FIX/KLUDGE:
+ *
+ * If the mbuf we're about to send is not writable (because of
+ * a cluster reference, for example) we'll need to make a copy
+ * of it since this routine modifies the contents.
+ *
+ * If you have non-crappy network hardware that can transmit data
+ * from the mbuf, rather than making a copy, this is gonna be a
+ * problem.
+ */
+ if (M_WRITABLE(m) == 0) {
+ if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
+ m_freem(m);
+ m = m0;
+ } else {
+ error = ENOBUFS;
+ m_freem(m);
+ ipl_frouteok[1]++;
+ }
+ }
+#endif
+
hlen = fin->fin_hlen;
ip = mtod(m0, struct ip *);
+#if defined(__NetBSD__) && defined(M_CSUM_IPv4)
+ /*
+ * Clear any in-bound checksum flags for this packet.
+ */
+ m0->m_pkthdr.csuminfo = 0;
+#endif /* __NetBSD__ && M_CSUM_IPv4 */
+
#ifdef USE_INET6
if (ip->ip_v == 6) {
/*
* currently "to <if>" and "to <if>:ip#" are not supported
* for IPv6
*/
- return ip6_output(m0, NULL, NULL, 0, NULL, NULL);
+ error = ip6_output(m0, NULL, NULL, 0, NULL, NULL);
+ *mpp = NULL;
+ return error;
}
#endif
/*
@@ -1316,10 +1390,15 @@ frdest_t *fdp;
*/
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
- return -1;
+ return 0;
dst->sin_addr = ip->ip_dst;
- } else if (fdp)
- dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
+ } else if (fdp) {
+ if (fdp->fd_ip.s_addr) {
+ dst->sin_addr = fdp->fd_ip;
+ ip->ip_dst = fdp->fd_ip;
+ } else
+ dst->sin_addr = ip->ip_dst;
+ }
# if BSD >= 199306
dst->sin_len = sizeof(*dst);
@@ -1374,36 +1453,44 @@ frdest_t *fdp;
* If small enough for interface, can just send directly.
*/
if (ip->ip_len <= ifp->if_mtu) {
-# if BSD >= 199306
+# if defined(MCLISREFERENCED) && !defined(sparc)
int i = 0;
-# ifdef MCLISREFERENCED
if ((m->m_flags & M_EXT) && MCLISREFERENCED(m))
-# else
- if (m->m_flags & M_EXT)
-# endif
i = 1;
# endif
# ifndef sparc
+# if !(_BSDI_VERSION >= 199510)
ip->ip_id = htons(ip->ip_id);
+# endif
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
# endif
+# if defined(__NetBSD__) && defined(M_CSUM_IPv4)
+ if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
+ else if (ip->ip_sum == 0)
+ ip->ip_sum = in_cksum(m, hlen);
+# else
if (!ip->ip_sum)
ip->ip_sum = in_cksum(m, hlen);
+# endif /* __NetBSD__ && M_CSUM_IPv4 */
# if BSD >= 199306
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
ro->ro_rt);
+# if defined(MCLISREFERENCED) && !defined(sparc)
if (i) {
ip->ip_id = ntohs(ip->ip_id);
ip->ip_len = ntohs(ip->ip_len);
ip->ip_off = ntohs(ip->ip_off);
}
+# endif
# else
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
# endif
goto done;
}
+
/*
* Too large for interface; fragment if possible.
* Must be able to put at least 8 bytes per fragment.
@@ -1506,9 +1593,11 @@ done:
else
ipl_frouteok[1]++;
- if (ro->ro_rt)
+ if (ro->ro_rt) {
RTFREE(ro->ro_rt);
- return 0;
+ }
+ *mpp = NULL;
+ return error;
bad:
if (error == EMSGSIZE) {
sifp = fin->fin_ifp;
@@ -1550,6 +1639,18 @@ void *ifp;
return (ifp == iproute.ro_rt->rt_ifp);
}
+
+# ifdef USE_GETIFNAME
+char *
+get_ifname(ifp)
+struct ifnet *ifp;
+{
+ static char workbuf[64];
+
+ sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
+ return workbuf;
+}
+# endif
#else /* #ifdef _KERNEL */
@@ -1586,9 +1687,9 @@ ip_t *ip;
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
- sprintf(fname, "/tmp/%s", ifp->if_xname);
+ sprintf(fname, "%s", ifp->if_xname);
# else
- sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
+ sprintf(fname, "%s%d", ifp->if_name, ifp->if_unit);
# endif
fd = open(fname, O_WRONLY|O_APPEND);
if (fd == -1) {
@@ -1605,7 +1706,7 @@ struct ifnet *get_unit(name, v)
char *name;
int v;
{
- struct ifnet *ifp, **ifa;
+ struct ifnet *ifp, **ifa, **old_ifneta;
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
@@ -1634,10 +1735,12 @@ int v;
}
nifs = 1;
} else {
+ old_ifneta = ifneta;
nifs++;
ifneta = (struct ifnet **)realloc(ifneta,
(nifs + 1) * sizeof(*ifa));
if (!ifneta) {
+ free(old_ifneta);
nifs = 0;
return NULL;
}
@@ -1704,28 +1807,6 @@ void init_ifp()
}
-int ipfr_fastroute(ip, fin, fdp)
-ip_t *ip;
-fr_info_t *fin;
-frdest_t *fdp;
-{
- struct ifnet *ifp = fdp->fd_ifp;
-
- if (!ifp)
- return 0; /* no routing table out here */
-
- ip->ip_len = htons((u_short)ip->ip_len);
- ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
-#ifdef __sgi
- (*ifp->if_output)(ifp, (void *)ip, NULL);
-#else
- (*ifp->if_output)(ifp, (void *)ip, NULL, 0);
-#endif
- return 0;
-}
-
-
int ipllog __P((void))
{
verbose("l");
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index ed1cfc4408fb..6d51ced5e0ae 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1,12 +1,10 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ip_fil.h,v 2.29.2.4 2000/11/12 11:54:53 darrenr Exp $
+ * $Id: ip_fil.h,v 2.29.2.10 2001/07/15 13:51:42 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -59,7 +57,7 @@
# define SIOCSTLCK _IOWR('r', 79, u_int)
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
# define SIOCSTGET _IOWR('r', 81, struct ipstate_save *)
-# define SIOCSTGSZ _IOWR('r', 82, struct natget *)
+# define SIOCSTGSZ _IOWR('r', 82, struct natget)
# define SIOCGFRST _IOWR('r', 83, struct ipfrstat *)
#else
# define SIOCADAFR _IOW(r, 60, struct frentry *)
@@ -84,7 +82,7 @@
# define SIOCSTLCK _IOWR(r, 79, u_int)
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
# define SIOCSTGET _IOWR(r, 81, struct ipstate_save *)
-# define SIOCSTGSZ _IOWR(r, 82, struct natget *)
+# define SIOCSTGSZ _IOWR(r, 82, struct natget)
# define SIOCGFRST _IOWR(r, 83, struct ipfrstat *)
#endif
#define SIOCADDFR SIOCADAFR
@@ -152,7 +150,10 @@ typedef struct fr_info {
u_short fin_off;
} fr_info_t;
-#define fin_v fin_fi.fi_v
+#define fin_v fin_fi.fi_v
+#define fin_saddr fin_fi.fi_saddr
+#define fin_daddr fin_fi.fi_daddr
+#define fin_fl fin_fi.fi_fl
/*
* Size for compares on fr_info structures
@@ -168,6 +169,9 @@ typedef struct frdest {
void *fd_ifp;
struct in_addr fd_ip;
char fd_ifname[IFNAMSIZ];
+#if SOLARIS
+ mb_t *fd_mp; /* cache resolver for to/dup-to */
+#endif
} frdest_t;
typedef struct frpcmp {
@@ -192,8 +196,6 @@ typedef struct frtuc {
typedef struct frentry {
struct frentry *fr_next;
- u_32_t fr_group; /* group to which this rule belongs */
- u_32_t fr_grhead; /* group # which this rule starts */
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
void *fr_ifa;
@@ -217,6 +219,8 @@ typedef struct frentry {
u_short fr_icmp;
frtuc_t fr_tuc;
+ u_32_t fr_group; /* group to which this rule belongs */
+ u_32_t fr_grhead; /* group # which this rule starts */
u_32_t fr_flags; /* per-rule flags && options (see below) */
u_int fr_skip; /* # of rules to skip */
u_int fr_loglevel; /* syslog log facility + priority */
@@ -436,6 +440,8 @@ typedef struct ipflog {
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
#define IPLLOGSIZE 8192
+#define IPF_OPTCOPY 0x07ff00 /* bit mask of copied options */
+
/*
* Device filenames for reading log information. Use ipf on Solaris2 because
* ipl is already a name used by something else.
@@ -484,7 +490,6 @@ extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
extern int send_reset __P((ip_t *, struct ifnet *));
extern int icmp_error __P((ip_t *, struct ifnet *));
extern int ipf_log __P((void));
-extern int ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
extern struct ifnet *get_unit __P((char *, int));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
@@ -530,7 +535,7 @@ extern int iplread __P((dev_t, struct uio *, cred_t *));
# else /* SOLARIS */
extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
+extern int ipfr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *));
extern size_t mbufchainlen __P((mb_t *));
# ifdef __sgi
# include <sys/cred.h>
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index 556478d51d0b..b0e63a9f7551 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -1,15 +1,8 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#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.10.2.7 2000/11/27 10:26:56 darrenr Exp $";
-#endif
-
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
@@ -81,7 +74,7 @@ static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.7 2000/11/27 10:26:56 d
# ifndef IPFILTER_LKM
# include <sys/libkern.h>
# include <sys/systm.h>
-# endif
+# endif
extern struct callout_handle ipfr_slowtimer_ch;
# endif
#endif
@@ -89,6 +82,15 @@ extern struct callout_handle ipfr_slowtimer_ch;
# include <sys/callout.h>
extern struct callout ipfr_slowtimer_ch;
#endif
+#if defined(__OpenBSD__)
+# include <sys/timeout.h>
+extern struct timeout ipfr_slowtimer_ch;
+#endif
+
+#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.10.2.14 2001/07/15 22:06:15 darrenr Exp $";
+#endif
static ipfr_t *ipfr_heads[IPFT_SIZE];
@@ -141,12 +143,15 @@ fr_info_t *fin;
u_int pass;
ipfr_t *table[];
{
- ipfr_t **fp, *fra, frag;
- u_int idx;
+ ipfr_t **fp, *fra, frag;
+ u_int idx, off;
if (ipfr_inuse >= IPFT_SIZE)
return NULL;
+ if (!(fin->fin_fl & FI_FRAG))
+ return NULL;
+
frag.ipfr_p = ip->ip_p;
idx = ip->ip_p;
frag.ipfr_id = ip->ip_id;
@@ -160,6 +165,10 @@ ipfr_t *table[];
idx *= 127;
idx %= IPFT_SIZE;
+ frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY;
+ frag.ipfr_secmsk = fin->fin_fi.fi_secmsk;
+ frag.ipfr_auth = fin->fin_fi.fi_auth;
+
/*
* first, make sure it isn't already there...
*/
@@ -200,7 +209,10 @@ ipfr_t *table[];
/*
* Compute the offset of the expected start of the next packet.
*/
- fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
+ off = ip->ip_off & IP_OFFMASK;
+ if (!off)
+ fra->ipfr_seen0 = 1;
+ fra->ipfr_off = off + (fin->fin_dlen >> 3);
ATOMIC_INCL(ipfr_stats.ifs_new);
ATOMIC_INC32(ipfr_inuse);
return fra;
@@ -219,7 +231,12 @@ u_int pass;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
- return ipf ? 0 : -1;
+ if (ipf == NULL) {
+ ATOMIC_INCL(frstats[fin->fin_out].fr_bnfr);
+ return -1;
+ }
+ ATOMIC_INCL(frstats[fin->fin_out].fr_nfr);
+ return 0;
}
@@ -230,9 +247,16 @@ u_int pass;
nat_t *nat;
{
ipfr_t *ipf;
+ int off;
if ((ip->ip_v != 4) || (fr_frag_lock))
return -1;
+
+ off = fin->fin_off;
+ off <<= 3;
+ if ((off + fin->fin_dlen) > 0xffff || (fin->fin_dlen == 0))
+ return NULL;
+
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@@ -254,8 +278,8 @@ fr_info_t *fin;
ipfr_t *table[];
{
ipfr_t *f, frag;
- u_int idx;
-
+ u_int idx;
+
/*
* For fragments, we record protocol, packet id, TOS and both IP#'s
* (these should all be the same for all fragments of a packet).
@@ -275,6 +299,10 @@ ipfr_t *table[];
idx *= 127;
idx %= IPFT_SIZE;
+ frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY;
+ frag.ipfr_secmsk = fin->fin_fi.fi_secmsk;
+ frag.ipfr_auth = fin->fin_fi.fi_auth;
+
/*
* check the table, careful to only compare the right amount of data
*/
@@ -283,6 +311,20 @@ ipfr_t *table[];
IPFR_CMPSZ)) {
u_short atoff, off;
+ off = fin->fin_off;
+
+ /*
+ * XXX - We really need to be guarding against the
+ * retransmission of (src,dst,id,offset-range) here
+ * because a fragmented packet is never resent with
+ * the same IP ID#.
+ */
+ if (f->ipfr_seen0) {
+ if (!off || (fin->fin_fl & FI_SHORT))
+ continue;
+ } else if (!off)
+ f->ipfr_seen0 = 1;
+
if (f != table[idx]) {
/*
* move fragment info. to the top of the list
@@ -295,7 +337,6 @@ ipfr_t *table[];
f->ipfr_prev = NULL;
table[idx] = f;
}
- off = ip->ip_off & IP_OFFMASK;
atoff = off + (fin->fin_dlen >> 3);
/*
* If we've follwed the fragments, and this is the
@@ -321,11 +362,18 @@ nat_t *ipfr_nat_knownfrag(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
- nat_t *nat;
- ipfr_t *ipf;
+ ipfr_t *ipf;
+ nat_t *nat;
+ int off;
- if ((ip->ip_v != 4) || (fr_frag_lock))
+ if ((fin->fin_v != 4) || (fr_frag_lock))
+ return NULL;
+
+ off = fin->fin_off;
+ off <<= 3;
+ if ((off + fin->fin_dlen) > 0xffff || (fin->fin_dlen == 0))
return NULL;
+
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
@@ -351,15 +399,24 @@ frentry_t *ipfr_knownfrag(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
- frentry_t *fr = NULL;
- ipfr_t *fra;
+ frentry_t *fr;
+ ipfr_t *fra;
+ int off;
- if ((ip->ip_v != 4) || (fr_frag_lock))
+ if ((fin->fin_v != 4) || (fr_frag_lock))
+ return NULL;
+
+ off = fin->fin_off;
+ off <<= 3;
+ if ((off + fin->fin_dlen) > 0xffff || (fin->fin_dlen == 0))
return NULL;
+
READ_ENTER(&ipf_frag);
fra = ipfr_lookup(ip, fin, ipfr_heads);
if (fra != NULL)
fr = fra->ipfr_rule;
+ else
+ fr = NULL;
RWLOCK_EXIT(&ipf_frag);
return fr;
}
@@ -544,7 +601,11 @@ int ipfr_slowtimer()
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
+# if defined(__OpenBSD_)
+ timeout_add(&ipfr_slowtimer_ch, hz/2, ipfr_slowtimer, NULL);
+# else
timeout(ipfr_slowtimer, NULL, hz/2);
+# endif
# endif
# if (BSD < 199306) && !defined(__sgi)
return 0;
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h
index 362bcdd120c9..446510f0e965 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.h
+++ b/sys/contrib/ipfilter/netinet/ip_frag.h
@@ -1,12 +1,10 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_frag.h 1.5 3/24/96
- * $Id: ip_frag.h,v 2.4.2.2 2000/11/10 13:10:54 darrenr Exp $
+ * $Id: ip_frag.h,v 2.4.2.5 2001/06/26 10:43:13 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -20,11 +18,15 @@ typedef struct ipfr {
struct in_addr ipfr_src;
struct in_addr ipfr_dst;
void *ipfr_ifp;
+ u_32_t ipfr_optmsk;
+ u_short ipfr_secmsk;
+ u_short ipfr_auth;
u_short ipfr_id;
u_char ipfr_p;
u_char ipfr_tos;
u_short ipfr_off;
- u_short ipfr_ttl;
+ u_char ipfr_ttl;
+ u_char ipfr_seen0;
frentry_t *ipfr_rule;
} ipfr_t;
@@ -40,7 +42,8 @@ typedef struct ipfrstat {
struct ipfr **ifs_nattab;
} ipfrstat_t;
-#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
+#define IPFR_CMPSZ (offsetof(ipfr_t, ipfr_off) - \
+ offsetof(ipfr_t, ipfr_src))
extern int fr_ipfrttl;
extern int fr_frag_lock;
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index ddca8890f0bf..830a4f66c9ec 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -2,7 +2,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * $Id: ip_ftp_pxy.c,v 2.7.2.20 2000/12/02 00:15:06 darrenr Exp $
+ * $Id: ip_ftp_pxy.c,v 2.7.2.26 2001/07/15 13:50:54 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -22,6 +22,22 @@ extern kmutex_t ipf_rw;
#define IPF_MAX227LEN 51
#define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */
+#define FTPXY_GO 0
+#define FTPXY_INIT 1
+#define FTPXY_USER_1 2
+#define FTPXY_USOK_1 3
+#define FTPXY_PASS_1 4
+#define FTPXY_PAOK_1 5
+#define FTPXY_AUTH_1 6
+#define FTPXY_AUOK_1 7
+#define FTPXY_ADAT_1 8
+#define FTPXY_ADOK_1 9
+#define FTPXY_ACCT_1 10
+#define FTPXY_ACOK_1 11
+#define FTPXY_USER_2 12
+#define FTPXY_USOK_2 13
+#define FTPXY_PASS_2 14
+#define FTPXY_PAOK_2 15
int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_complete __P((char *, size_t));
@@ -75,6 +91,7 @@ nat_t *nat;
f = &ftp->ftp_side[1];
f->ftps_rptr = f->ftps_buf;
f->ftps_wptr = f->ftps_buf;
+ ftp->ftp_passok = FTPXY_INIT;
return 0;
}
@@ -215,7 +232,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- fix_outcksum(&ip->ip_sum, sum2);
+ fix_outcksum(fin, &ip->ip_sum, sum2);
#endif
ip->ip_len += inc;
}
@@ -255,6 +272,7 @@ int dlen;
fi.fin_dlen = sizeof(*tcp2);
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
+ fi.fin_out = 1;
swip = ip->ip_src;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_src = nat->nat_inip;
@@ -297,11 +315,36 @@ int dlen;
}
cmd[i] = '\0';
- if ((ftp->ftp_passok == 0) && !strncmp(cmd, "USER ", 5))
- ftp->ftp_passok = 1;
- else if ((ftp->ftp_passok == 2) && !strncmp(cmd, "PASS ", 5))
- ftp->ftp_passok = 3;
- else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly &&
+ ftp->ftp_incok = 0;
+ if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) {
+ if (ftp->ftp_passok == FTPXY_ADOK_1 ||
+ ftp->ftp_passok == FTPXY_AUOK_1) {
+ ftp->ftp_passok = FTPXY_USER_2;
+ ftp->ftp_incok = 1;
+ } else {
+ ftp->ftp_passok = FTPXY_USER_1;
+ ftp->ftp_incok = 1;
+ }
+ } else if (!strncmp(cmd, "AUTH ", 5)) {
+ ftp->ftp_passok = FTPXY_AUTH_1;
+ ftp->ftp_incok = 1;
+ } else if (!strncmp(cmd, "PASS ", 5)) {
+ if (ftp->ftp_passok == FTPXY_USOK_1) {
+ ftp->ftp_passok = FTPXY_PASS_1;
+ ftp->ftp_incok = 1;
+ } else if (ftp->ftp_passok == FTPXY_USOK_2) {
+ ftp->ftp_passok = FTPXY_PASS_2;
+ ftp->ftp_incok = 1;
+ }
+ } else if ((ftp->ftp_passok == FTPXY_AUOK_1) &&
+ !strncmp(cmd, "ADAT ", 5)) {
+ ftp->ftp_passok = FTPXY_ADAT_1;
+ ftp->ftp_incok = 1;
+ } else if ((ftp->ftp_passok == FTPXY_PAOK_2) &&
+ !strncmp(cmd, "ACCT ", 5)) {
+ ftp->ftp_passok = FTPXY_ACCT_1;
+ ftp->ftp_incok = 1;
+ } else if ((ftp->ftp_passok == FTPXY_GO) && !ippr_ftp_pasvonly &&
!strncmp(cmd, "PORT ", 5)) {
inc = ippr_ftp_port(fin, ip, nat, f, dlen);
} else if (ippr_ftp_insecure && !ippr_ftp_pasvonly &&
@@ -332,12 +375,13 @@ int dlen;
int inc;
char *s;
+#define PASV_REPLEN 24
/*
* Check for PASV reply message.
*/
if (dlen < IPF_MIN227LEN)
return 0;
- else if (strncmp(f->ftps_rptr, "227 Entering Passive Mode", 25))
+ else if (strncmp(f->ftps_rptr, "227 Entering Passive Mod", PASV_REPLEN))
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
@@ -345,7 +389,7 @@ int dlen;
/*
* Skip the PORT command + space
*/
- s = f->ftps_rptr + 25;
+ s = f->ftps_rptr + PASV_REPLEN;
while (*s && !isdigit(*s))
s++;
/*
@@ -373,6 +417,8 @@ int dlen;
if (*s == ')')
s++;
+ if (*s == '.')
+ s++;
if (*s == '\n')
s--;
/*
@@ -445,7 +491,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- fix_outcksum(&ip->ip_sum, sum2);
+ fix_outcksum(fin, &ip->ip_sum, sum2);
#endif /* SOLARIS || defined(__sgi) */
ip->ip_len += inc;
}
@@ -469,12 +515,13 @@ int dlen;
tcp2->th_win = htons(8192);
tcp2->th_sport = 0; /* XXX - fake it for nat_new */
tcp2->th_off = 5;
- fi.fin_data[1] = a5 << 8 | a6;
+ fi.fin_data[0] = a5 << 8 | a6;
fi.fin_dlen = sizeof(*tcp2);
- tcp2->th_dport = htons(fi.fin_data[1]);
- fi.fin_data[0] = 0;
+ tcp2->th_dport = htons(fi.fin_data[0]);
+ fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
+ fi.fin_out = 1;
swip = ip->ip_src;
swip2 = ip->ip_dst;
fi.fin_fi.fi_daddr = ip->ip_src.s_addr;
@@ -511,17 +558,38 @@ int dlen;
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
- if ((ftp->ftp_passok == 1) && !strncmp(rptr, "331", 3))
- ftp->ftp_passok = 2;
- else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "230", 3))
- ftp->ftp_passok = 4;
- else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "530", 3))
- ftp->ftp_passok = 0;
- else if ((ftp->ftp_passok == 4) && !strncmp(rptr, "227 ", 4)) {
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ if (!isdigit(*rptr) || !isdigit(*(rptr + 1)) || !isdigit(*(rptr + 2)))
+ return inc;
+ if (ftp->ftp_passok == FTPXY_GO) {
+ if (!strncmp(rptr, "227 ", 4))
+ inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
} else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) {
inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ } else if (*rptr == '5' || *rptr == '4')
+ ftp->ftp_passok = FTPXY_INIT;
+ else if (ftp->ftp_incok) {
+ if (*rptr == '3') {
+ if (ftp->ftp_passok == FTPXY_ACCT_1)
+ ftp->ftp_passok = FTPXY_GO;
+ else
+ ftp->ftp_passok++;
+ } else if (*rptr == '2') {
+ switch (ftp->ftp_passok)
+ {
+ case FTPXY_USER_1 :
+ case FTPXY_USER_2 :
+ case FTPXY_PASS_1 :
+ case FTPXY_PASS_2 :
+ case FTPXY_ACCT_1 :
+ ftp->ftp_passok = FTPXY_GO;
+ break;
+ default :
+ ftp->ftp_passok += 3;
+ break;
+ }
+ }
}
+ ftp->ftp_incok = 0;
while ((*rptr++ != '\n') && (rptr < wptr))
;
f->ftps_rptr = rptr;
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 8adc410e80b7..5968f46ad4b0 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -1,11 +1,9 @@
/*
- * Copyright (C) 1997-2000 by Darren Reed.
+ * Copyright (C) 1997-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_log.c,v 2.5.2.2 2000/08/13 03:50:41 darrenr Exp $
+ * $Id: ip_log.c,v 2.5.2.5 2001/06/26 10:43:14 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@@ -21,7 +19,13 @@
# endif
# else
# ifdef KLD_MODULE
-# include <osreldate.h>
+# ifndef __FreeBSD_cc_version
+# include <osreldate.h>
+# else
+# if __FreeBSD_cc_version < 430000
+# include <osreldate.h>
+# endif
+# endif
# endif
# endif
#endif
@@ -45,7 +49,7 @@
# include <sys/ioctl.h>
# endif
# include <sys/time.h>
-# if defined(_KERNEL) && !defined(linux)
+# if defined(_KERNEL)
# include <sys/systm.h>
# endif
# include <sys/uio.h>
@@ -55,9 +59,7 @@
# else
# include <sys/dir.h>
# endif
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
+# include <sys/mbuf.h>
# else
# include <sys/filio.h>
# include <sys/cred.h>
@@ -69,9 +71,7 @@
# include <sys/dditypes.h>
# include <sys/cmn_err.h>
# endif
-# ifndef linux
-# include <sys/protosw.h>
-# endif
+# include <sys/protosw.h>
# include <sys/socket.h>
# include <net/if.h>
@@ -89,7 +89,7 @@
# include <sys/hashing.h>
# endif
# endif
-# if !defined(linux) && !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
+# if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
# include <netinet/in_var.h>
# endif
# include <netinet/in_systm.h>
@@ -97,9 +97,7 @@
# include <netinet/tcp.h>
# include <netinet/udp.h>
# include <netinet/ip_icmp.h>
-# ifndef linux
-# include <netinet/ip_var.h>
-# endif
+# include <netinet/ip_var.h>
# ifndef _KERNEL
# include <syslog.h>
# endif
@@ -130,9 +128,6 @@ extern kcondvar_t iplwait;
iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1], *ipll[IPL_LOGMAX+1];
size_t iplused[IPL_LOGMAX+1];
static fr_info_t iplcrc[IPL_LOGMAX+1];
-# ifdef linux
-static struct wait_queue *iplwait[IPL_LOGMAX+1];
-# endif
/*
@@ -229,9 +224,7 @@ mb_t *m;
(defined(OpenBSD) && (OpenBSD >= 199603))
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
# else
-# ifndef linux
ipfl.fl_unit = (u_char)ifp->if_unit;
-# endif
if ((ipfl.fl_ifname[0] = ifp->if_name[0]))
if ((ipfl.fl_ifname[1] = ifp->if_name[1]))
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
@@ -337,7 +330,7 @@ int *types, cnt;
ipl->ipl_count = 1;
ipl->ipl_next = NULL;
ipl->ipl_dsize = len;
-# if SOLARIS || defined(sun) || defined(linux)
+# if SOLARIS || defined(sun)
uniqtime((struct timeval *)&ipl->ipl_sec);
# else
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
@@ -370,11 +363,7 @@ int *types, cnt;
mutex_exit(&ipl_mutex);
# else
MUTEX_EXIT(&ipl_mutex);
-# ifdef linux
- wake_up_interruptible(&iplwait[dev]);
-# else
wakeup(&iplh[dev]);
-# endif
# endif
return 1;
}
@@ -399,8 +388,7 @@ struct uio *uio;
return ENXIO;
if (!uio->uio_resid)
return 0;
- if ((uio->uio_resid < sizeof(iplog_t)) ||
- (uio->uio_resid > IPLLOGSIZE))
+ if (uio->uio_resid < sizeof(iplog_t))
return EINVAL;
/*
@@ -417,19 +405,13 @@ struct uio *uio;
return EINTR;
}
# else
-# ifdef linux
- interruptible_sleep_on(&iplwait[unit]);
- if (current->signal & ~current->blocked)
- return -EINTR;
-# else
MUTEX_EXIT(&ipl_mutex);
- SPL_X(s);
error = SLEEP(&iplh[unit], "ipl sleep");
- if (error)
+ if (error) {
+ SPL_X(s);
return error;
- SPL_NET(s);
+ }
MUTEX_ENTER(&ipl_mutex);
-# endif /* linux */
# endif /* SOLARIS */
}
@@ -447,10 +429,8 @@ struct uio *uio;
iplt[unit] = ipl->ipl_next;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
- SPL_X(s);
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
if (error) {
- SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
@@ -458,7 +438,6 @@ struct uio *uio;
break;
}
KFREES((caddr_t)ipl, dlen);
- SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
}
if (!iplt[unit]) {
@@ -469,13 +448,7 @@ struct uio *uio;
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
-# ifdef linux
- if (!error)
- return (int)copied;
- return -error;
-# else
return error;
-# endif
}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index e7e121a0b723..eb6e133bfc0f 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -1,17 +1,10 @@
/*
- * Copyright (C) 1995-2000 by Darren Reed.
+ * Copyright (C) 1995-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com)
*/
-#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.37.2.32 2001/01/10 06:19:11 darrenr Exp $";
-#endif
-
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
#define _KERNEL
#endif
@@ -91,6 +84,7 @@ extern struct ifnet vpnif;
#ifndef linux
# include <netinet/ip_var.h>
+# include <netinet/tcp_fsm.h>
#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
@@ -111,6 +105,11 @@ extern struct ifnet vpnif;
#undef SOCKADDR_IN
#define SOCKADDR_IN struct sockaddr_in
+#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.37.2.44 2001/07/21 07:17:22 darrenr Exp $";
+#endif
+
nat_t **nat_table[2] = { NULL, NULL },
*nat_instances = NULL;
ipnat_t *nat_list = NULL;
@@ -301,7 +300,8 @@ struct hostmap *hm;
}
-void fix_outcksum(sp, n)
+void fix_outcksum(fin, sp, n)
+fr_info_t *fin;
u_short *sp;
u_32_t n;
{
@@ -310,12 +310,13 @@ u_32_t n;
if (!n)
return;
-#if SOLARIS2 >= 6
else if (n & NAT_HW_CKSUM) {
+ n &= 0xffff;
+ n += fin->fin_dlen;
+ n = (n & 0xffff) + (n >> 16);
*sp = n & 0xffff;
return;
}
-#endif
sum1 = (~ntohs(*sp)) & 0xffff;
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
@@ -326,7 +327,8 @@ u_32_t n;
}
-void fix_incksum(sp, n)
+void fix_incksum(fin, sp, n)
+fr_info_t *fin;
u_short *sp;
u_32_t n;
{
@@ -335,12 +337,13 @@ u_32_t n;
if (!n)
return;
-#if SOLARIS2 >= 6
else if (n & NAT_HW_CKSUM) {
+ n &= 0xffff;
+ n += fin->fin_dlen;
+ n = (n & 0xffff) + (n >> 16);
*sp = n & 0xffff;
return;
}
-#endif
#ifdef sparc
sum1 = (~(*sp)) & 0xffff;
#else
@@ -625,9 +628,11 @@ int mode;
nat_stats.ns_table[0] = nat_table[0];
nat_stats.ns_table[1] = nat_table[1];
nat_stats.ns_list = nat_list;
+ nat_stats.ns_maptable = maptable;
nat_stats.ns_nattab_sz = ipf_nattable_sz;
nat_stats.ns_rultab_sz = ipf_natrules_sz;
nat_stats.ns_rdrtab_sz = ipf_rdrrules_sz;
+ nat_stats.ns_hostmap_sz = ipf_hostmap_sz;
nat_stats.ns_instances = nat_instances;
nat_stats.ns_apslist = ap_sess_list;
error = IWCOPYPTR((char *)&nat_stats, (char *)data,
@@ -1395,14 +1400,14 @@ int direction;
CALC_SUMD(sum1, sum2, sumd);
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
- if ((flags == IPN_TCP) && dohwcksum &&
+ if ((flags & IPN_TCPUDP) && dohwcksum &&
(qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
if (direction == NAT_OUTBOUND)
sum1 = LONG_SUM(ntohl(in.s_addr));
else
sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
sum1 += LONG_SUM(ntohl(ip->ip_dst.s_addr));
- sum1 += 30;
+ sum1 += IPPROTO_TCP;
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
nat->nat_sumd[1] = NAT_HW_CKSUM|(sum1 & 0xffff);
} else
@@ -1463,8 +1468,8 @@ badnat:
void nat_insert(nat)
nat_t *nat;
{
+ u_int hv1, hv2;
nat_t **natp;
- u_int hv;
MUTEX_INIT(&nat->nat_lock, "nat entry lock", NULL);
@@ -1477,18 +1482,30 @@ nat_t *nat;
nat->nat_next = nat_instances;
nat_instances = nat;
- hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
- ipf_nattable_sz);
- natp = &nat_table[0][hv];
+ if (!(nat->nat_flags & (FI_W_SPORT|FI_W_DPORT))) {
+ hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
+ 0xffffffff);
+ hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1 + nat->nat_oport,
+ ipf_nattable_sz);
+ hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
+ 0xffffffff);
+ hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2 + nat->nat_oport,
+ ipf_nattable_sz);
+ } else {
+ hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0, 0xffffffff);
+ hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1, ipf_nattable_sz);
+ hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0, 0xffffffff);
+ hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2, ipf_nattable_sz);
+ }
+
+ natp = &nat_table[0][hv1];
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
nat->nat_phnext[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
- hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
- ipf_nattable_sz);
- natp = &nat_table[1][hv];
+ natp = &nat_table[1][hv2];
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
nat->nat_phnext[1] = natp;
@@ -1604,7 +1621,7 @@ int dir;
ip_t *oip;
int flags = 0;
- if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK))
+ if ((fin->fin_fl & FI_SHORT) || (fin->fin_off != 0))
return NULL;
/*
* nat_icmplookup() will return NULL for `defective' packets.
@@ -1878,13 +1895,14 @@ int dir;
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
if (nat->nat_dir == NAT_OUTBOUND) {
- fix_outcksum(&icmp->icmp_cksum, sumd2);
+ fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
} else {
- fix_incksum(&icmp->icmp_cksum, sumd2);
+ fix_incksum(fin, &icmp->icmp_cksum, sumd2);
}
}
}
- nat->nat_age = fr_defnaticmpage;
+ if (oip->ip_p == IPPROTO_ICMP)
+ nat->nat_age = fr_defnaticmpage;
return nat;
}
@@ -1917,7 +1935,8 @@ int rw;
sport = ports & 0xffff;
flags &= IPN_TCPUDP;
- hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
+ hv = NAT_HASH_FN(dst, dport, 0xffffffff);
+ 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;
@@ -1935,7 +1954,8 @@ int rw;
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
- hv = NAT_HASH_FN(dst, 0, ipf_nattable_sz);
+ hv = NAT_HASH_FN(dst, 0, 0xffffffff);
+ hv = NAT_HASH_FN(src.s_addr, hv, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -1999,7 +2019,8 @@ u_32_t ports;
/*
* Add into the NAT table in the new position
*/
- hv = NAT_HASH_FN(nat->nat_inip.s_addr, sport, ipf_nattable_sz);
+ hv = NAT_HASH_FN(nat->nat_inip.s_addr, sport, 0xffffffff);
+ hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + dport, ipf_nattable_sz);
natp = &nat_table[0][hv];
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
@@ -2007,7 +2028,8 @@ u_32_t ports;
nat->nat_hnext[0] = *natp;
*natp = nat;
- hv = NAT_HASH_FN(nat->nat_outip.s_addr, sport, ipf_nattable_sz);
+ hv = NAT_HASH_FN(nat->nat_outip.s_addr, sport, 0xffffffff);
+ hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + dport, ipf_nattable_sz);
natp = &nat_table[1][hv];
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
@@ -2041,7 +2063,8 @@ int rw;
flags &= IPN_TCPUDP;
srcip = src.s_addr;
- hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
+ hv = NAT_HASH_FN(srcip, sport, 0xffffffff);
+ 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;
@@ -2061,6 +2084,7 @@ int rw;
RWLOCK_EXIT(&ipf_nat);
}
hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
+ hv = NAT_HASH_FN(dst.s_addr, hv, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -2145,8 +2169,8 @@ ip_t *ip;
}
ft = &np->in_tuc;
- if (!(fin->fin_fi.fi_fl & FI_TCPUDP) ||
- (fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) {
+ if (!(fin->fin_fl & FI_TCPUDP) ||
+ (fin->fin_fl & FI_SHORT) || (fin->fin_off != 0)) {
if (ft->ftu_scmp || ft->ftu_dcmp)
return 0;
return 1;
@@ -2168,13 +2192,12 @@ fr_info_t *fin;
register u_32_t ipa;
tcphdr_t *tcp = NULL;
u_short sport = 0, dport = 0, *csump = NULL;
+ int natadd = 1, i, icmpset = 1;
+ u_int nflags = 0, hv, msk;
struct ifnet *ifp;
- int natadd = 1;
frentry_t *fr;
- u_int nflags = 0, hv, msk;
u_32_t iph;
nat_t *nat;
- int i;
if (nat_list == NULL || (fr_nat_lock))
return 0;
@@ -2185,7 +2208,7 @@ fr_info_t *fin;
else
ifp = fin->fin_ifp;
- if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
@@ -2203,8 +2226,8 @@ fr_info_t *fin;
if ((ip->ip_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
- ;
- else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
+ icmpset = 1;
+ else if ((fin->fin_fl & FI_FRAG) &&
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p,
@@ -2238,8 +2261,7 @@ maskloop:
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
for (np = nat_rules[hv]; np; np = np->in_mnext)
{
- if ((np->in_ifp && (np->in_ifp != ifp)) ||
- !np->in_space)
+ if (np->in_ifp && (np->in_ifp != ifp))
continue;
if ((np->in_flags & IPN_RF) &&
!(np->in_flags & nflags))
@@ -2283,7 +2305,7 @@ maskloop:
*/
if (nat) {
np = nat->nat_ptr;
- if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
+ if (natadd && (fin->fin_fl & FI_FRAG) && np)
ipfr_nat_newfrag(ip, fin, 0, nat);
MUTEX_ENTER(&nat->nat_lock);
nat->nat_age = fr_defnatage;
@@ -2303,22 +2325,21 @@ maskloop:
CALC_SUMD(s1, s2, sumd);
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(&ip->ip_sum, sumd);
+ fix_incksum(fin, &ip->ip_sum, sumd);
else
- fix_outcksum(&ip->ip_sum, sumd);
+ fix_outcksum(fin, &ip->ip_sum, sumd);
}
#if SOLARIS || defined(__sgi)
else {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
+ fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
else
- fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
+ fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
}
#endif
ip->ip_src = nat->nat_outip;
- if (!(ip->ip_off & IP_OFFMASK) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
tcp->th_sport = nat->nat_outport;
@@ -2351,14 +2372,15 @@ maskloop:
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
- nat->nat_age = fr_defnaticmpage;
+ if (!icmpset)
+ nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(csump, nat->nat_sumd[1]);
+ fix_outcksum(fin, csump, nat->nat_sumd[1]);
else
- fix_incksum(csump, nat->nat_sumd[1]);
+ fix_incksum(fin, csump, nat->nat_sumd[1]);
}
}
@@ -2389,18 +2411,18 @@ fr_info_t *fin;
register struct in_addr src;
register struct in_addr in;
register ipnat_t *np;
+ u_short sport = 0, dport = 0, *csump = NULL;
u_int nflags = 0, natadd = 1, hv, msk;
struct ifnet *ifp = fin->fin_ifp;
tcphdr_t *tcp = NULL;
- u_short sport = 0, dport = 0, *csump = NULL;
+ int i, icmpset = 0;
nat_t *nat;
u_32_t iph;
- int i;
if ((nat_list == NULL) || (ip->ip_v != 4) || (fr_nat_lock))
return 0;
- if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
@@ -2420,8 +2442,8 @@ fr_info_t *fin;
if ((ip->ip_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND)))
- ;
- else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
+ icmpset = 1;
+ else if ((fin->fin_fl & FI_FRAG) &&
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p,
@@ -2488,7 +2510,7 @@ maskloop:
if (nat) {
np = nat->nat_ptr;
fin->fin_fr = nat->nat_fr;
- if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
+ if (natadd && (fin->fin_fl & FI_FRAG) && np)
ipfr_nat_newfrag(ip, fin, 0, nat);
if ((np->in_apr != NULL) && (np->in_dport == 0 ||
(tcp != NULL && sport == np->in_dport))) {
@@ -2515,12 +2537,11 @@ maskloop:
*/
#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
+ fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
else
- fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
+ fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
#endif
- if (!(ip->ip_off & IP_OFFMASK) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) {
tcp->th_dport = nat->nat_inport;
@@ -2553,14 +2574,15 @@ maskloop:
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
- nat->nat_age = fr_defnaticmpage;
+ if (!icmpset)
+ nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(csump, nat->nat_sumd[0]);
+ fix_incksum(fin, csump, nat->nat_sumd[0]);
else
- fix_outcksum(csump, nat->nat_sumd[0]);
+ fix_outcksum(fin, csump, nat->nat_sumd[0]);
}
}
ATOMIC_INCL(nat_stats.ns_mapped[0]);
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 22f8503df113..f712dfcd9c5e 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -1,12 +1,10 @@
/*
- * Copyright (C) 1995-2000 by Darren Reed.
+ * Copyright (C) 1995-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.17.2.14 2000/11/18 03:58:04 darrenr Exp $
+ * $Id: ip_nat.h,v 2.17.2.20 2001/06/26 10:43:15 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -35,10 +33,18 @@
* appropriate sizes. The figures below were used for
* a setup with 1000-2000 networks to NAT.
*/
-#define NAT_SIZE 127
-#define RDR_SIZE 127
-#define HOSTMAP_SIZE 127
-#define NAT_TABLE_SZ 127
+#ifndef NAT_SIZE
+# define NAT_SIZE 127
+#endif
+#ifndef RDR_SIZE
+# define RDR_SIZE 127
+#endif
+#ifndef HOSTMAP_SIZE
+# define HOSTMAP_SIZE 127
+#endif
+#ifndef NAT_TABLE_SZ
+# define NAT_TABLE_SZ 127
+#endif
#ifdef LARGE_NAT
#undef NAT_SIZE
#undef RDR_SIZE
@@ -201,11 +207,13 @@ typedef struct natstat {
u_long ns_memfail;
u_long ns_badnat;
nat_t **ns_table[2];
+ hostmap_t **ns_maptable;
ipnat_t *ns_list;
void *ns_apslist;
u_int ns_nattab_sz;
u_int ns_rultab_sz;
u_int ns_rdrtab_sz;
+ u_int ns_hostmap_sz;
nat_t *ns_instances;
u_int ns_wilds;
} natstat_t;
@@ -220,12 +228,13 @@ typedef struct natstat {
#define IPN_AUTOPORTMAP 0x010
#define IPN_IPRANGE 0x020
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
- IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST)
+ IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|IPN_FRAG)
#define IPN_FILTER 0x040
#define IPN_SPLIT 0x080
#define IPN_ROUNDR 0x100
#define IPN_NOTSRC 0x080000
#define IPN_NOTDST 0x100000
+#define IPN_FRAG 0x200000
typedef struct natlog {
@@ -300,8 +309,8 @@ extern int ip_natout __P((ip_t *, fr_info_t *));
extern int ip_natin __P((ip_t *, fr_info_t *));
extern void ip_natunload __P((void)), ip_natexpire __P((void));
extern void nat_log __P((struct nat *, u_int));
-extern void fix_incksum __P((u_short *, u_32_t));
-extern void fix_outcksum __P((u_short *, u_32_t));
+extern void fix_incksum __P((fr_info_t *, u_short *, u_32_t));
+extern void fix_outcksum __P((fr_info_t *, u_short *, u_32_t));
extern void fix_datacksum __P((u_short *, u_32_t));
#endif /* __IP_NAT_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index e1e55f11acde..325f36259ec2 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -1,14 +1,8 @@
/*
- * Copyright (C) 1997-2000 by Darren Reed.
+ * Copyright (C) 1997-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.1 2000/05/06 12:30:50 darrenr Exp $";
-#endif
-
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
@@ -78,6 +72,10 @@ static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.1 2000/05/06 12:30:50 d
# include <sys/malloc.h>
#endif
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.6 2001/07/15 22:06:15 darrenr Exp $";
+#endif
+
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -216,9 +214,13 @@ ip_t *ip;
fr_info_t *fin;
nat_t *nat;
{
+#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
+ mb_t *m = fin->fin_qfm;
+ int dosum = 1;
+#endif
+ tcphdr_t *tcp = NULL;
ap_session_t *aps;
aproxy_t *apr;
- tcphdr_t *tcp = NULL;
u_32_t sum;
short rv;
int err;
@@ -234,8 +236,13 @@ nat_t *nat;
* verify that the checksum is correct. If not, then
* don't do anything with this packet.
*/
-#if SOLARIS && defined(_KERNEL)
- sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
+#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
+ if (dohwcksum && (m->b_ick_flag == ICK_VALID)) {
+ sum = tcp->th_sum;
+ dosum = 0;
+ }
+ if (dosum)
+ sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
@@ -261,8 +268,9 @@ nat_t *nat;
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, APR_INC(err));
-#if SOLARIS && defined(_KERNEL)
- tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
+#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
+ if (dosum)
+ tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index 212900fbea7e..b8c8eb086cae 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -1,11 +1,9 @@
/*
- * Copyright (C) 1997-2000 by Darren Reed.
+ * Copyright (C) 1997-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_proxy.h,v 2.8.2.4 2000/12/02 00:15:03 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.8.2.7 2001/06/26 10:43:16 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -102,7 +100,8 @@ typedef struct ftpside {
} ftpside_t;
typedef struct ftpinfo {
- u_int ftp_passok;
+ int ftp_passok;
+ int ftp_incok;
ftpside_t ftp_side[2];
} ftpinfo_t;
diff --git a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
index 9ea437c6a4cd..476e15949f35 100644
--- a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
@@ -1,5 +1,5 @@
/*
- * $Id: ip_raudio_pxy.c,v 1.7.2.3 2000/10/27 22:54:04 darrenr Exp $
+ * $Id: ip_raudio_pxy.c,v 1.7.2.6 2001/07/23 04:17:56 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -62,8 +62,8 @@ nat_t *nat;
raudio_t *rap = aps->aps_data;
unsigned char membuf[512 + 1], *s;
u_short id = 0;
- tcphdr_t *tcp;
int off, dlen;
+ tcphdr_t *tcp;
int len = 0;
mb_t *m;
#if SOLARIS
@@ -86,14 +86,16 @@ nat_t *nat;
dlen = msgdsize(m) - off;
if (dlen <= 0)
return 0;
- copyout_mblk(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
+ dlen = MIN(sizeof(membuf), dlen);
+ copyout_mblk(m, off, dlen, (char *)membuf);
#else
m = *(mb_t **)fin->fin_mp;
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
- m_copydata(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
+ dlen = MIN(sizeof(membuf), dlen);
+ m_copydata(m, off, dlen, (char *)membuf);
#endif
/*
* In all the startup parsing, ensure that we don't go outside
@@ -170,8 +172,8 @@ nat_t *nat;
unsigned char membuf[IPF_MAXPORTLEN + 1], *s;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
+ int off, dlen, slen, clen;
struct in_addr swa, swb;
- int off, dlen, slen;
int a1, a2, a3, a4;
u_short sp, dp;
fr_info_t fi;
@@ -202,13 +204,15 @@ nat_t *nat;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
- copyout_mblk(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
+ clen = MIN(sizeof(membuf), dlen);
+ copyout_mblk(m, off, clen, (char *)membuf);
#else
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
- m_copydata(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
+ clen = MIN(sizeof(membuf), dlen);
+ m_copydata(m, off, clen, (char *)membuf);
#endif
seq = ntohl(tcp->th_seq);
@@ -217,7 +221,7 @@ nat_t *nat;
* We only care for the first 19 bytes coming back from the server.
*/
if (rap->rap_sseq == 0) {
- s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
+ s = (u_char *)memstr("PNA", (char *)membuf, 3, clen);
if (s == NULL)
return 0;
a1 = s - membuf;
@@ -278,6 +282,7 @@ nat_t *nat;
tcp2->th_dport = htons(dp);
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
+ fi.fin_out = 0;
ipn = nat_new(nat->nat_ptr, ip, &fi,
IPN_UDP | (sp ? 0 : FI_W_SPORT), NAT_OUTBOUND);
if (ipn != NULL) {
@@ -292,6 +297,7 @@ nat_t *nat;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
+ fi.fin_out = 1;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 5d6396958eb5..649ad939ddf8 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -1,15 +1,8 @@
/*
- * Copyright (C) 1995-2000 by Darren Reed.
+ * Copyright (C) 1995-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#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.30.2.28 2001/01/08 14:04:46 darrenr Exp $";
-#endif
-
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -97,6 +90,11 @@ static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.28 2001/01/08 14:04:46
# endif
#endif
+#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.30.2.38 2001/07/23 13:49:46 darrenr Exp $";
+#endif
+
#ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
#endif
@@ -140,7 +138,9 @@ u_long fr_tcpidletimeout = FIVE_DAYS,
fr_tcpclosed = 120,
fr_tcphalfclosed = 2 * 2 * 3600, /* 2 hours */
fr_udptimeout = 240,
- fr_icmptimeout = 120;
+ fr_udpacktimeout = 24,
+ fr_icmptimeout = 120,
+ fr_icmpacktimeout = 12;
int fr_statemax = IPSTATE_MAX,
fr_statesize = IPSTATE_SIZE;
int fr_state_doflush = 0,
@@ -241,6 +241,7 @@ caddr_t data;
if (error)
return EFAULT;
+ WRITE_ENTER(&ipf_state);
for (sp = ips_list; sp; sp = sp->is_next)
if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
!bcmp((char *)&sp->is_src, (char *)&st.is_src,
@@ -249,7 +250,6 @@ caddr_t data;
sizeof(st.is_dst)) &&
!bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
sizeof(st.is_ps))) {
- WRITE_ENTER(&ipf_state);
#ifdef IPFILTER_LOG
ipstate_log(sp, ISL_REMOVE);
#endif
@@ -257,6 +257,7 @@ caddr_t data;
RWLOCK_EXIT(&ipf_state);
return 0;
}
+ RWLOCK_EXIT(&ipf_state);
return ESRCH;
}
@@ -502,8 +503,7 @@ u_int flags;
u_int pass;
int out;
- if (fr_state_lock || (fin->fin_off & IP_OFFMASK) ||
- (fin->fin_fi.fi_fl & FI_SHORT))
+ if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
return NULL;
if (ips_num == fr_statemax) {
ips_stats.iss_max++;
@@ -663,7 +663,7 @@ u_int flags;
is->is_secmsk = 0xffff;
is->is_auth = fin->fin_fi.fi_auth;
is->is_authmsk = 0xffff;
- is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
+ is->is_flags = fin->fin_fl & FI_CMP;
is->is_flags |= FI_CMP << 4;
is->is_flags |= flags & (FI_WILDP|FI_WILDA);
if (flags & (FI_WILDP|FI_WILDA))
@@ -688,7 +688,7 @@ u_int flags;
#endif
RWLOCK_EXIT(&ipf_state);
fin->fin_rev = IP6NEQ(is->is_dst, fin->fin_fi.fi_dst);
- if (fin->fin_fi.fi_fl & FI_FRAG)
+ if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
return is;
}
@@ -717,6 +717,8 @@ tcphdr_t *tcp;
* Find difference between last checked packet and this packet.
*/
source = IP6EQ(fin->fin_fi.fi_src, is->is_src);
+ if (source && (ntohs(is->is_sport) != fin->fin_data[0]))
+ source = 0;
fdata = &is->is_tcp.ts_data[!source];
tdata = &is->is_tcp.ts_data[source];
seq = ntohl(tcp->th_seq);
@@ -809,7 +811,7 @@ tcphdr_t *tcp;
u_short sp, dp;
void *ifp;
- rev = fin->fin_rev = IP6NEQ(is->is_dst, dst);
+ rev = IP6NEQ(is->is_dst, dst);
ifp = fin->fin_ifp;
out = fin->fin_out;
@@ -817,6 +819,12 @@ tcphdr_t *tcp;
flags = is->is_flags;
sp = tcp->th_sport;
dp = tcp->th_dport;
+ if (!rev) {
+ if (!(flags & FI_W_SPORT) && (sp != is->is_sport))
+ rev = 1;
+ else if (!(flags & FI_W_DPORT) && (dp != is->is_dport))
+ rev = 1;
+ }
} else {
flags = is->is_flags & FI_WILDA;
sp = 0;
@@ -871,10 +879,10 @@ tcphdr_t *tcp;
if (tcp == NULL)
flags = is->is_flags & (FI_CMP|(FI_CMP<<4));
- if (((fin->fin_fi.fi_fl & (flags >> 4)) != (flags & FI_CMP)) ||
- ((fin->fin_fi.fi_optmsk & is->is_optmsk) != is->is_opt) ||
- ((fin->fin_fi.fi_secmsk & is->is_secmsk) != is->is_sec) ||
- ((fin->fin_fi.fi_auth & is->is_authmsk) != is->is_auth))
+ if (((fin->fin_fl & (flags >> 4)) != (flags & FI_CMP)) ||
+ (fin->fin_fi.fi_optmsk != is->is_opt) ||
+ (fin->fin_fi.fi_secmsk != is->is_sec) ||
+ (fin->fin_fi.fi_auth != is->is_auth))
return 0;
if ((flags & (FI_W_SPORT|FI_W_DPORT))) {
@@ -924,16 +932,11 @@ tcphdr_t *tcp;
if (ret >= 0) {
is->is_ifp[ret] = ifp;
#ifdef _KERNEL
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp),
- sizeof(is->is_ifname[1]));
+ strncpy(is->is_ifname[ret], IFNAME(fin->fin_ifp),
+ sizeof(is->is_ifname[ret]));
#endif
}
-#ifdef _KERNEL
- if (ret >= 0) {
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp),
- sizeof(is->is_ifname[1]));
- }
-#endif
+ fin->fin_rev = rev;
return 1;
}
@@ -1209,8 +1212,7 @@ fr_info_t *fin;
frentry_t *fr;
tcphdr_t *tcp;
- if (fr_state_lock || (fin->fin_off & IP_OFFMASK) ||
- (fin->fin_fi.fi_fl & FI_SHORT))
+ if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
return NULL;
is = NULL;
@@ -1254,7 +1256,10 @@ fr_info_t *fin;
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, NULL) &&
fr_matchicmpqueryreply(v, is, ic)) {
- is->is_age = fr_icmptimeout;
+ if (fin->fin_rev)
+ is->is_age = fr_icmpacktimeout;
+ else
+ is->is_age = fr_icmptimeout;
break;
}
}
@@ -1302,6 +1307,11 @@ retry_tcpudp:
if (!fr_tcpstate(is, fin, ip, tcp)) {
continue;
}
+ } else if ((pr == IPPROTO_UDP)) {
+ if (fin->fin_rev)
+ is->is_age = fr_udpacktimeout;
+ else
+ is->is_age = fr_udptimeout;
}
break;
}
@@ -1345,7 +1355,7 @@ retry_tcpudp:
fr_delstate(is);
#endif
RWLOCK_EXIT(&ipf_state);
- if (fin->fin_fi.fi_fl & FI_FRAG)
+ if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
return fr;
}
@@ -1420,7 +1430,8 @@ void fr_stateunload()
ips_stats.iss_inuse = 0;
ips_num = 0;
RWLOCK_EXIT(&ipf_state);
- KFREES(ips_table, fr_statesize * sizeof(ipstate_t *));
+ if (ips_table)
+ KFREES(ips_table, fr_statesize * sizeof(ipstate_t *));
ips_table = NULL;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index 1d1bc0068d8a..b940d774ade6 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.h
+++ b/sys/contrib/ipfilter/netinet/ip_state.h
@@ -1,12 +1,10 @@
/*
- * Copyright (C) 1995-2000 by Darren Reed.
+ * Copyright (C) 1995-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
- * $Id: ip_state.h,v 2.13.2.2 2000/08/23 11:01:31 darrenr Exp $
+ * $Id: ip_state.h,v 2.13.2.4 2001/06/26 10:43:17 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -17,8 +15,12 @@
# define SIOCDELST _IOW(r, 61, struct ipstate *)
#endif
-#define IPSTATE_SIZE 5737
-#define IPSTATE_MAX 4013 /* Maximum number of states held */
+#ifndef IPSTATE_SIZE
+# define IPSTATE_SIZE 5737
+#endif
+#ifndef IPSTATE_MAX
+# define IPSTATE_MAX 4013 /* Maximum number of states held */
+#endif
#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
(((s1) == (d2)) && ((d1) == (s2))))
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 3529d6510143..472bcce2f4f0 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -1,17 +1,15 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 by Darren Reed.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and due credit is given
- * to the original author and the contributors.
+ * See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.15.2.17 2001/01/14 13:47:15 darrenr Exp $
+ * $Id: ipl.h,v 2.15.2.23 2001/07/23 13:52:10 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.16"
+#define IPL_VERSION "IP Filter: v3.4.20"
#endif