summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2002-03-19 11:30:23 +0000
committerDarren Reed <darrenr@FreeBSD.org>2002-03-19 11:30:23 +0000
commit76531d9f8d54be5c8da482dd6dc247802c602ae9 (patch)
treebe2176e1c1603aa1b8ab85e9da63eb59ef9b81b5
parent28613e558429407a3e0d83210176a075ed6c80c4 (diff)
downloadsrc-test-76531d9f8d54be5c8da482dd6dc247802c602ae9.tar.gz
src-test-76531d9f8d54be5c8da482dd6dc247802c602ae9.zip
Import IPFilter 3.4.25 (last version 3.4.20)
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=92682
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c202
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c18
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.h5
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h448
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.c582
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h89
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c21
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.h18
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c150
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c76
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c468
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h22
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c143
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h24
-rw-r--r--sys/contrib/ipfilter/netinet/ip_raudio_pxy.c17
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c24
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c609
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h18
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h6
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c6
20 files changed, 2077 insertions, 869 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index c4cd2e0411681..06623c357ebb8 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -34,7 +37,6 @@
# include <string.h>
# include <stdlib.h>
#endif
-#include <sys/uio.h>
#if !defined(__SVR4) && !defined(__svr4__)
# ifndef linux
# include <sys/mbuf.h>
@@ -77,10 +79,10 @@
#endif
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@@ -95,7 +97,7 @@
#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 $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $";
#endif
#ifndef _KERNEL
@@ -105,7 +107,7 @@ extern int opts;
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
-# define IPLLOG(a, c, d, e) ipllog()
+# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
#else /* #ifndef _KERNEL */
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
@@ -260,7 +262,7 @@ fr_info_t *fin;
fin->fin_off = off;
fin->fin_plen = plen;
- fin->fin_dp = (void *)tcp;
+ fin->fin_dp = (char *)tcp;
off <<= 3;
switch (p)
@@ -280,7 +282,7 @@ fr_info_t *fin;
{
case ICMP6_ECHO_REPLY :
case ICMP6_ECHO_REQUEST :
- minicmpsz = ICMP6ERR_MINPKTLEN;
+ minicmpsz = ICMP6_MINLEN;
break;
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
@@ -380,6 +382,19 @@ getports:
fin->fin_data[1] = ntohs(tcp->th_dport);
}
break;
+ case IPPROTO_ESP :
+#ifdef USE_INET6
+ if (v == 6) {
+ if (plen < 8)
+ fi->fi_fl |= FI_SHORT;
+ } else
+#endif
+ if (v == 4) {
+ if (((ip->ip_len < hlen + 8) && !off) ||
+ (off && off < 8))
+ fi->fi_fl |= FI_SHORT;
+ }
+ break;
default :
break;
}
@@ -545,8 +560,8 @@ fr_info_t *fin;
* Could be per interface, but this gets real nasty when you don't have
* kernel sauce.
*/
-int fr_scanlist(pass, ip, fin, m)
-u_32_t pass;
+int fr_scanlist(passin, ip, fin, m)
+u_32_t passin;
ip_t *ip;
register fr_info_t *fin;
void *m;
@@ -554,20 +569,21 @@ void *m;
register struct frentry *fr;
register fr_ip_t *fi = &fin->fin_fi;
int rulen, portcmp = 0, off, skip = 0, logged = 0;
- u_32_t passt;
+ u_32_t pass, passt, passl;
+ frentry_t *frl;
+ frl = NULL;
+ pass = passin;
fr = fin->fin_fr;
fin->fin_fr = NULL;
- fin->fin_rule = 0;
- fin->fin_group = 0;
off = fin->fin_off;
- pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
portcmp = 1;
for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
if (skip) {
+ FR_VERBOSE(("%d (%#x)\n", skip, fr->fr_flags));
skip--;
continue;
}
@@ -578,25 +594,28 @@ void *m;
* check that we are working for the right interface
*/
#ifdef _KERNEL
-# if BSD >= 199306
+# if (BSD >= 199306)
if (fin->fin_out != 0) {
if ((fr->fr_oifa &&
- fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif) ||
- (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp))
+ (fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif)))
continue;
- } else
+ }
# endif
- if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
- continue;
#else
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
- FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
- (pass & FR_AUTH) ? 'a' : 'b'));
+#endif
+
+ FR_VERBOSE(("%c", fr->fr_skip ? 's' :
+ (pass & FR_PASS) ? 'p' :
+ (pass & FR_AUTH) ? 'a' :
+ (pass & FR_ACCOUNT) ? 'A' :
+ (pass & FR_NOMATCH) ? 'n' : 'b'));
+
if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
continue;
+
FR_VERBOSE((":i"));
-#endif
{
register u_32_t *ld, *lm, *lip;
register int i;
@@ -618,22 +637,19 @@ void *m;
/*
* Unrolled loops (4 each, for 32 bits).
*/
- i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
FR_DEBUG(("1b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
FR_DEBUG(("1d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 5;
} else {
lip += 3;
lm += 3;
@@ -642,23 +658,19 @@ void *m;
i ^= (fr->fr_flags & FR_NOTSRCIP);
if (i)
continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2a. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
FR_DEBUG(("2b. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2c. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
FR_DEBUG(("2d. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip++ & *lm++) != *ld++) << 6;
} else {
lip += 3;
lm += 3;
@@ -667,14 +679,12 @@ void *m;
i ^= (fr->fr_flags & FR_NOTDSTIP);
if (i)
continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
FR_DEBUG(("3. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
+ i |= ((*lip++ & *lm++) != *ld++);
FR_DEBUG(("4. %#08x & %#08x != %#08x\n",
*lip, *lm, *ld));
+ i |= ((*lip & *lm) != *ld);
if (i)
continue;
}
@@ -701,17 +711,30 @@ void *m;
}
}
FR_VERBOSE(("*"));
- /*
- * Just log this packet...
- */
+
+ if (fr->fr_flags & FR_NOMATCH) {
+ passt = passl;
+ passl = passin;
+ fin->fin_fr = frl;
+ frl = NULL;
+ if (fr->fr_flags & FR_QUICK)
+ break;
+ continue;
+ }
+
+ passl = passt;
passt = fr->fr_flags;
+ frl = fin->fin_fr;
+ fin->fin_fr = fr;
#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
if (securelevel <= 0)
#endif
if ((passt & FR_CALLNOW) && fr->fr_func)
passt = (*fr->fr_func)(passt, ip, fin);
- fin->fin_fr = fr;
#ifdef IPFILTER_LOG
+ /*
+ * Just log this packet...
+ */
if ((passt & FR_LOGMASK) == FR_LOG) {
if (!IPLLOG(passt, ip, fin, m)) {
if (passt & FR_LOGORBLOCK)
@@ -722,32 +745,33 @@ void *m;
logged = 1;
}
#endif /* IPFILTER_LOG */
- if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
- pass = passt;
- FR_DEBUG(("pass %#x\n", pass));
ATOMIC_INCL(fr->fr_hits);
- if (pass & FR_ACCOUNT)
+ if (passt & FR_ACCOUNT)
fr->fr_bytes += (U_QUAD_T)ip->ip_len;
else
fin->fin_icode = fr->fr_icode;
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
- if (fr->fr_grp) {
+ if (fr->fr_grp != NULL) {
fin->fin_fr = fr->fr_grp;
- pass = fr_scanlist(pass, ip, fin, m);
+ passt = fr_scanlist(passt, ip, fin, m);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
fin->fin_group = fr->fr_group;
fin->fin_fr = fr;
}
- if (pass & FR_DONTCACHE)
+ if (passt & FR_DONTCACHE)
logged = 1;
}
- if (pass & FR_QUICK)
+ if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
+ pass = passt;
+ FR_DEBUG(("pass %#x\n", pass));
+ if (passt & FR_QUICK)
break;
}
if (logged)
pass |= FR_DONTCACHE;
+ pass |= (fi->fi_fl << 24);
return pass;
}
@@ -803,7 +827,7 @@ int out;
/*
* disable delayed checksums.
*/
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if ((out != 0) && (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
@@ -844,6 +868,9 @@ int out;
case IPPROTO_ICMP:
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
+ case IPPROTO_ESP:
+ plen = 8;
+ break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
@@ -906,20 +933,26 @@ int out;
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
- logit = -2;
+ if (fr_minttllog & 1)
+ logit = -3;
+ if (fr_minttllog & 2)
+ drop = 1;
}
} else
# endif
if (!out) {
if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
- if (fr_chksrc == 2)
+ if (fr_chksrc & 1)
+ drop = 1;
+ if (fr_chksrc & 2)
logit = -2;
} else if (ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
+ if (fr_minttllog & 1)
logit = -3;
+ if (fr_minttllog & 2)
+ drop = 1;
}
}
if (drop) {
@@ -1010,6 +1043,7 @@ int out;
FI_COPYSIZE);
if (pass & FR_NOMATCH) {
ATOMIC_INCL(frstats[out].fr_nom);
+ fin->fin_fr = NULL;
}
}
} else
@@ -1023,11 +1057,7 @@ int out;
*/
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;
@@ -1057,7 +1087,7 @@ int out;
}
}
if (pass & FR_KEEPSTATE) {
- if (fr_addstate(ip, fin, 0) == NULL) {
+ if (fr_addstate(ip, fin, NULL, 0) == NULL) {
ATOMIC_INCL(frstats[out].fr_bads);
} else {
ATOMIC_INCL(frstats[out].fr_ads);
@@ -1086,11 +1116,19 @@ int out;
else
#endif
list = ipacct[1][fr_active];
- if ((fin->fin_fr = list) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[1].fr_acct);
+ if (list != NULL) {
+ u_32_t sg, sr;
+
+ fin->fin_fr = list;
+ sg = fin->fin_group;
+ sr = fin->fin_rule;
+ if (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT) {
+ ATOMIC_INCL(frstats[1].fr_acct);
+ }
+ fin->fin_group = sg;
+ fin->fin_rule = sr;
+ fin->fin_fr = fr;
}
- fin->fin_fr = fr;
changed = ip_natout(ip, fin);
} else
fin->fin_fr = fr;
@@ -1134,10 +1172,10 @@ logit:
# if SOLARIS
mc = dupmsg(m);
# else
-# ifndef linux
- mc = m_copy(m, 0, M_COPYALL);
+# if defined(__OpenBSD__) && (OpenBSD >= 199905)
+ mc = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
# else
- ;
+ mc = m_copy(m, 0, M_COPYALL);
# endif
# endif
#endif
@@ -1154,7 +1192,6 @@ logit:
* some operating systems.
*/
if (!out) {
-#ifdef _KERNEL
if (pass & FR_RETICMP) {
int dst;
@@ -1170,19 +1207,6 @@ logit:
ATOMIC_INCL(frstats[1].fr_ret);
}
}
-#else
- if ((pass & FR_RETMASK) == FR_RETICMP) {
- verbose("- ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if ((pass & FR_RETMASK) == FR_FAKEICMP) {
- verbose("- forged ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fl & FI_SHORT)) {
- verbose("- TCP RST sent\n");
- ATOMIC_INCL(frstats[1].fr_ret);
- }
-#endif
} else {
if (pass & FR_RETRST)
error = ECONNRESET;
@@ -1207,8 +1231,10 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
(void) ipfr_fastroute(m, mp, fin, fdp);
+ m = *mp;
+ }
if (mc != NULL)
(void) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
@@ -1243,6 +1269,12 @@ logit:
return 0;
if (pass & FR_AUTH)
return -2;
+ if ((pass & FR_RETMASK) == FR_RETRST)
+ return -3;
+ if ((pass & FR_RETMASK) == FR_RETICMP)
+ return -4;
+ if ((pass & FR_RETMASK) == FR_FAKEICMP)
+ return -5;
return -1;
#endif /* _KERNEL */
}
@@ -1464,7 +1496,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index b22d470b6095f..e4ad347280c75 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -3,6 +3,9 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -19,7 +22,6 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -102,7 +104,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#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 $";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.17 2002/03/06 09:44:10 darrenr Exp $";
#endif
@@ -305,7 +307,7 @@ ip_t *ip;
int fr_auth_ioctl(data, mode, cmd, fr, frptr)
caddr_t data;
int mode;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
u_long cmd;
#else
int cmd;
@@ -377,9 +379,7 @@ frentry_t *fr, **frptr;
error = EINVAL;
break;
case SIOCATHST:
- READ_ENTER(&ipf_auth);
fr_authstats.fas_faelist = fae_list;
- RWLOCK_EXIT(&ipf_auth);
error = IWCOPYPTR((char *)&fr_authstats, data,
sizeof(fr_authstats));
break;
@@ -453,7 +453,7 @@ fr_authioctlloop:
bzero((char *)&ro, sizeof(ro));
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
- defined(__OpenBSD__)
+ defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605))
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
# else
@@ -478,7 +478,9 @@ fr_authioctlloop:
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
+# if IRIX < 605
schednetisr(NETISR_IP);
+# endif
}
# endif /* SOLARIS */
if (error)
@@ -526,7 +528,6 @@ fr_authioctlloop:
}
-#ifdef _KERNEL
/*
* Free all network buffer memory used to keep saved packets.
*/
@@ -587,7 +588,7 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
-#if !SOLARIS
+#if !SOLARIS && defined(_KERNEL)
int s;
#endif
@@ -626,4 +627,3 @@ void fr_authexpire()
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
-#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 7d3e46316d10f..cb168c4ca9597 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_auth.h,v 2.3.2.4 2001/07/18 14:57:08 darrenr Exp $
+ * $Id: ip_auth.h,v 2.3.2.5 2001/11/04 13:15:51 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@@ -52,7 +52,8 @@ extern void fr_authexpire __P((void));
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__)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || \
+ (__FreeBSD_version >= 300003)
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, int, frentry_t *, frentry_t **));
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index a7d0db4f07a8c..4eab541231a67 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.26.2.17 2001/07/23 04:22:48 darrenr Exp $
+ * $Id: ip_compat.h,v 2.26.2.39 2002/03/13 03:54:34 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -25,14 +25,21 @@
#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
+#if SOLARIS
+# if !defined(SOLARIS2)
+# define SOLARIS2 3 /* Pick an old version */
+# endif
+# if SOLARIS2 >= 8
+# ifndef USE_INET6
+# define USE_INET6
+# endif
+# else
+# undef USE_INET6
# endif
#endif
+#if defined(sun) && !(defined(__svr4__) || defined(__SVR4))
+# undef USE_INET6
+#endif
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
@@ -62,6 +69,18 @@ struct ether_addr {
};
#endif
+#ifndef LIFNAMSIZ
+# ifdef IF_NAMESIZE
+# define LIFNAMSIZ IF_NAMESIZE
+# else
+# ifdef IFNAMSIZ
+# define LIFNAMSIZ IFNAMSIZ
+# else
+# define LIFNAMSIZ 16
+# endif
+# endif
+#endif
+
#if defined(__sgi) && !defined(IPFILTER_LKM)
# ifdef __STDC__
# define IPL_EXTERN(ep) ipfilter##ep
@@ -76,12 +95,37 @@ struct ether_addr {
# endif
#endif
+#ifdef __sgi
+# include <sys/debug.h>
+#endif
+
#ifdef linux
# include <sys/sysmacros.h>
#endif
+
+
+/*
+ * This is a workaround for <sys/uio.h> troubles on FreeBSD and OpenBSD.
+ */
+#ifndef _KERNEL
+# define ADD_KERNEL
+# define _KERNEL
+# define KERNEL
+#endif
+#ifdef __OpenBSD__
+struct file;
+#endif
+#include <sys/uio.h>
+#ifdef ADD_KERNEL
+# undef _KERNEL
+# undef KERNEL
+#endif
+
#if SOLARIS
# define MTYPE(m) ((m)->b_datap->db_type)
-# include <sys/isa_defs.h>
+# if SOLARIS2 >= 4
+# include <sys/isa_defs.h>
+# endif
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
# include <sys/kmem.h>
@@ -137,12 +181,14 @@ typedef struct qif {
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];
+ char qf_name[LIFNAMSIZ];
/*
* in case the ILL has disappeared...
*/
size_t qf_hl; /* header length */
int qf_sap;
+ size_t qf_incnt;
+ size_t qf_outcnt;
} qif_t;
#else /* SOLARIS */
# if !defined(__sgi)
@@ -210,6 +256,7 @@ typedef unsigned int u_32_t;
# endif
typedef struct ip6_hdr ip6_t;
# endif
+# include <netinet/icmp6.h>
union i6addr {
u_32_t i6[4];
struct in_addr in4;
@@ -225,6 +272,14 @@ union i6addr {
#define IP6CMP(a,b) bcmp((char *)&(a), (char *)&(b), sizeof(a))
#define IP6EQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) == 0)
#define IP6NEQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) != 0)
+#define IP6_ISZERO(a) ((((union i6addr *)(a))->i6[0] | \
+ ((union i6addr *)(a))->i6[1] | \
+ ((union i6addr *)(a))->i6[2] | \
+ ((union i6addr *)(a))->i6[3]) == 0)
+#define IP6_NOTZERO(a) ((((union i6addr *)(a))->i6[0] | \
+ ((union i6addr *)(a))->i6[1] | \
+ ((union i6addr *)(a))->i6[2] | \
+ ((union i6addr *)(a))->i6[3]) != 0)
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -325,6 +380,21 @@ union i6addr {
* Build some macros and #defines to enable the same code to compile anywhere
* Well, that's the idea, anyway :-)
*/
+#if SOLARIS
+typedef mblk_t mb_t;
+# if SOLARIS2 >= 7
+# ifdef lint
+# define ALIGN32(ptr) (ptr ? 0L : 0L)
+# define ALIGN16(ptr) (ptr ? 0L : 0L)
+# else
+# define ALIGN32(ptr) (ptr)
+# define ALIGN16(ptr) (ptr)
+# endif
+# endif
+#else
+typedef struct mbuf mb_t;
+#endif /* SOLARIS */
+
#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
# define ATOMIC_INCL ATOMIC_INC
# define ATOMIC_INC64 ATOMIC_INC
@@ -506,11 +576,19 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# define GET_MINOR(x) minor(x)
# endif
# if (BSD >= 199306) || defined(__FreeBSD__)
-# include <vm/vm.h>
+# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \
+ defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_BSDI_VERSION)
+# include <vm/vm.h>
+# endif
# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
-# include <vm/vm_extern.h>
-# include <sys/proc.h>
+# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \
+ (defined(OpenBSD) && (OpenBSD >= 200111))
+# include <uvm/uvm_extern.h>
+# else
+# include <vm/vm_extern.h>
extern vm_map_t kmem_map;
+# endif
+# include <sys/proc.h>
# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# include <vm/vm_kern.h>
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
@@ -542,7 +620,7 @@ extern vm_map_t kmem_map;
# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
# define PANIC(x,y) if (x) panic y
#else /* KERNEL */
-# define SLEEP(x,y) ;
+# define SLEEP(x,y) 1
# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define ATOMIC_INC(x) (x)++
@@ -564,40 +642,18 @@ extern vm_map_t kmem_map;
# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
+# define FREE_MB_T(x) ;
# define GETUNIT(x, v) get_unit(x,v)
# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
+# define IFNAME(x) get_ifname((struct ifnet *)x)
+# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
+extern void m_copydata __P((mb_t *, int, int, caddr_t));
+extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
#endif /* KERNEL */
-#if SOLARIS
-typedef mblk_t mb_t;
-# if SOLARIS2 >= 7
-# ifdef lint
-# define ALIGN32(ptr) (ptr ? 0L : 0L)
-# define ALIGN16(ptr) (ptr ? 0L : 0L)
-# else
-# define ALIGN32(ptr) (ptr)
-# define ALIGN16(ptr) (ptr)
-# endif
-# endif
-#else
-# ifdef linux
-# ifndef kernel
-typedef struct mb {
- struct mb *next;
- u_int len;
- u_char *data;
-} mb_t;
-# else
-typedef struct sk_buff mb_t;
-# endif
-# else
-typedef struct mbuf mb_t;
-# endif
-#endif /* SOLARIS */
-
/*
* 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
@@ -606,38 +662,152 @@ typedef struct mbuf mb_t;
#ifndef ICMP_MINLEN
# define ICMP_MINLEN 8
#endif
+#ifndef ICMP_ECHOREPLY
+# define ICMP_ECHOREPLY 0
+#endif
#ifndef ICMP_UNREACH
-# define ICMP_UNREACH ICMP_DEST_UNREACH
+# define ICMP_UNREACH 3
+#endif
+#ifndef ICMP_UNREACH_NET
+# define ICMP_UNREACH_NET 0
+#endif
+#ifndef ICMP_UNREACH_HOST
+# define ICMP_UNREACH_HOST 1
+#endif
+#ifndef ICMP_UNREACH_PROTOCOL
+# define ICMP_UNREACH_PROTOCOL 2
+#endif
+#ifndef ICMP_UNREACH_PORT
+# define ICMP_UNREACH_PORT 3
+#endif
+#ifndef ICMP_UNREACH_NEEDFRAG
+# define ICMP_UNREACH_NEEDFRAG 4
+#endif
+#ifndef ICMP_UNREACH_SRCFAIL
+# define ICMP_UNREACH_SRCFAIL 5
+#endif
+#ifndef ICMP_UNREACH_NET_UNKNOWN
+# define ICMP_UNREACH_NET_UNKNOWN 6
+#endif
+#ifndef ICMP_UNREACH_HOST_UNKNOWN
+# define ICMP_UNREACH_HOST_UNKNOWN 7
+#endif
+#ifndef ICMP_UNREACH_ISOLATED
+# define ICMP_UNREACH_ISOLATED 8
+#endif
+#ifndef ICMP_UNREACH_NET_PROHIB
+# define ICMP_UNREACH_NET_PROHIB 9
+#endif
+#ifndef ICMP_UNREACH_HOST_PROHIB
+# define ICMP_UNREACH_HOST_PROHIB 10
+#endif
+#ifndef ICMP_UNREACH_TOSNET
+# define ICMP_UNREACH_TOSNET 11
+#endif
+#ifndef ICMP_UNREACH_TOSHOST
+# define ICMP_UNREACH_TOSHOST 12
+#endif
+#ifndef ICMP_UNREACH_ADMIN_PROHIBIT
+# define ICMP_UNREACH_ADMIN_PROHIBIT 13
+#endif
+#ifndef ICMP_UNREACH_HOST_PRECEDENCE
+# define ICMP_UNREACH_HOST_PRECEDENCE 14
+#endif
+#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
+# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
#endif
#ifndef ICMP_SOURCEQUENCH
-# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+# define ICMP_SOURCEQUENCH 4
+#endif
+#ifndef ICMP_REDIRECT_NET
+# define ICMP_REDIRECT_NET 0
+#endif
+#ifndef ICMP_REDIRECT_HOST
+# define ICMP_REDIRECT_HOST 1
+#endif
+#ifndef ICMP_REDIRECT_TOSNET
+# define ICMP_REDIRECT_TOSNET 2
+#endif
+#ifndef ICMP_REDIRECT_TOSHOST
+# define ICMP_REDIRECT_TOSHOST 3
+#endif
+#ifndef ICMP_ALTHOSTADDR
+# define ICMP_ALTHOSTADDR 6
#endif
#ifndef ICMP_TIMXCEED
-# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+# define ICMP_TIMXCEED 11
+#endif
+#ifndef ICMP_TIMXCEED_INTRANS
+# define ICMP_TIMXCEED_INTRANS 0
+#endif
+#ifndef ICMP_TIMXCEED_REASS
+# define ICMP_TIMXCEED_REASS 1
#endif
#ifndef ICMP_PARAMPROB
-# define ICMP_PARAMPROB ICMP_PARAMETERPROB
+# define ICMP_PARAMPROB 12
+#endif
+#ifndef ICMP_PARAMPROB_ERRATPTR
+# define ICMP_PARAMPROB_ERRATPTR 0
+#endif
+#ifndef ICMP_PARAMPROB_OPTABSENT
+# define ICMP_PARAMPROB_OPTABSENT 1
+#endif
+#ifndef ICMP_PARAMPROB_LENGTH
+# define ICMP_PARAMPROB_LENGTH 2
#endif
#ifndef ICMP_TSTAMP
-# define ICMP_TSTAMP ICMP_TIMESTAMP
+# define ICMP_TSTAMP 13
#endif
#ifndef ICMP_TSTAMPREPLY
-# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
+# define ICMP_TSTAMPREPLY 14
#endif
#ifndef ICMP_IREQ
-# define ICMP_IREQ ICMP_INFO_REQUEST
+# define ICMP_IREQ 15
#endif
#ifndef ICMP_IREQREPLY
-# define ICMP_IREQREPLY ICMP_INFO_REPLY
+# define ICMP_IREQREPLY 16
#endif
#ifndef ICMP_MASKREQ
-# define ICMP_MASKREQ ICMP_ADDRESS
+# define ICMP_MASKREQ 17
#endif
#ifndef ICMP_MASKREPLY
-# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
+# define ICMP_MASKREPLY 18
#endif
-#ifndef ICMP_PARAMPROB_OPTABSENT
-# define ICMP_PARAMPROB_OPTABSENT 1
+#ifndef ICMP_TRACEROUTE
+# define ICMP_TRACEROUTE 30
+#endif
+#ifndef ICMP_DATACONVERR
+# define ICMP_DATACONVERR 31
+#endif
+#ifndef ICMP_MOBILE_REDIRECT
+# define ICMP_MOBILE_REDIRECT 32
+#endif
+#ifndef ICMP_IPV6_WHEREAREYOU
+# define ICMP_IPV6_WHEREAREYOU 33
+#endif
+#ifndef ICMP_IPV6_IAMHERE
+# define ICMP_IPV6_IAMHERE 34
+#endif
+#ifndef ICMP_MOBILE_REGREQUEST
+# define ICMP_MOBILE_REGREQUEST 35
+#endif
+#ifndef ICMP_MOBILE_REGREPLY
+# define ICMP_MOBILE_REGREPLY 36
+#endif
+#ifndef ICMP_SKIP
+# define ICMP_SKIP 39
+#endif
+#ifndef ICMP_PHOTURIS
+# define ICMP_PHOTURIS 40
+#endif
+#ifndef ICMP_PHOTURIS_UNKNOWN_INDEX
+# define ICMP_PHOTURIS_UNKNOWN_INDEX 1
+#endif
+#ifndef ICMP_PHOTURIS_AUTH_FAILED
+# define ICMP_PHOTURIS_AUTH_FAILED 2
+#endif
+#ifndef ICMP_PHOTURIS_DECRYPT_FAILED
+# define ICMP_PHOTURIS_DECRYPT_FAILED 3
#endif
#ifndef IPVERSION
# define IPVERSION 4
@@ -726,6 +896,15 @@ typedef struct mbuf mb_t;
#ifndef IPOPT_OLEN
# define IPOPT_OLEN 1
#endif
+#ifndef IPPROTO_GRE
+# define IPPROTO_GRE 47 /* GRE encaps RFC 1701 */
+#endif
+#ifndef IPPROTO_ESP
+# define IPPROTO_ESP 50
+#endif
+#ifndef IPPROTO_ICMPV6
+# define IPPROTO_ICMPV6 58
+#endif
#ifdef linux
#include <linux/in_systm.h>
@@ -997,6 +1176,10 @@ struct ether_addr {
#define A_A &
#endif
+#if (BSD >= 199306) && !defined(m_act)
+# define m_act m_nextpkt
+#endif
+
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
@@ -1016,9 +1199,170 @@ struct ether_addr {
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
+#define ICMP6_MINLEN 8
#define ICMP6ERR_MINPKTLEN (40 + 8)
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
+#ifndef ICMP6_DST_UNREACH
+# define ICMP6_DST_UNREACH 1
+#endif
+#ifndef ICMP6_PACKET_TOO_BIG
+# define ICMP6_PACKET_TOO_BIG 2
+#endif
+#ifndef ICMP6_TIME_EXCEEDED
+# define ICMP6_TIME_EXCEEDED 3
+#endif
+#ifndef ICMP6_PARAM_PROB
+# define ICMP6_PARAM_PROB 4
+#endif
+
+#ifndef ICMP6_ECHO_REQUEST
+# define ICMP6_ECHO_REQUEST 128
+#endif
+#ifndef ICMP6_ECHO_REPLY
+# define ICMP6_ECHO_REPLY 129
+#endif
+#ifndef ICMP6_MEMBERSHIP_QUERY
+# define ICMP6_MEMBERSHIP_QUERY 130
+#endif
+#ifndef MLD6_LISTENER_QUERY
+# define MLD6_LISTENER_QUERY 130
+#endif
+#ifndef ICMP6_MEMBERSHIP_REPORT
+# define ICMP6_MEMBERSHIP_REPORT 131
+#endif
+#ifndef MLD6_LISTENER_REPORT
+# define MLD6_LISTENER_REPORT 131
+#endif
+#ifndef ICMP6_MEMBERSHIP_REDUCTION
+# define ICMP6_MEMBERSHIP_REDUCTION 132
+#endif
+#ifndef MLD6_LISTENER_DONE
+# define MLD6_LISTENER_DONE 132
+#endif
+#ifndef ND_ROUTER_SOLICIT
+# define ND_ROUTER_SOLICIT 133
+#endif
+#ifndef ND_ROUTER_ADVERT
+# define ND_ROUTER_ADVERT 134
+#endif
+#ifndef ND_NEIGHBOR_SOLICIT
+# define ND_NEIGHBOR_SOLICIT 135
+#endif
+#ifndef ND_NEIGHBOR_ADVERT
+# define ND_NEIGHBOR_ADVERT 136
+#endif
+#ifndef ND_REDIRECT
+# define ND_REDIRECT 137
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING
+# define ICMP6_ROUTER_RENUMBERING 138
+#endif
+#ifndef ICMP6_WRUREQUEST
+# define ICMP6_WRUREQUEST 139
+#endif
+#ifndef ICMP6_WRUREPLY
+# define ICMP6_WRUREPLY 140
+#endif
+#ifndef ICMP6_FQDN_QUERY
+# define ICMP6_FQDN_QUERY 139
+#endif
+#ifndef ICMP6_FQDN_REPLY
+# define ICMP6_FQDN_REPLY 140
+#endif
+#ifndef ICMP6_NI_QUERY
+# define ICMP6_NI_QUERY 139
+#endif
+#ifndef ICMP6_NI_REPLY
+# define ICMP6_NI_REPLY 140
+#endif
+#ifndef MLD6_MTRACE_RESP
+# define MLD6_MTRACE_RESP 200
+#endif
+#ifndef MLD6_MTRACE
+# define MLD6_MTRACE 201
+#endif
+#ifndef ICMP6_HADISCOV_REQUEST
+# define ICMP6_HADISCOV_REQUEST 202
+#endif
+#ifndef ICMP6_HADISCOV_REPLY
+# define ICMP6_HADISCOV_REPLY 203
+#endif
+#ifndef ICMP6_MOBILEPREFIX_SOLICIT
+# define ICMP6_MOBILEPREFIX_SOLICIT 204
+#endif
+#ifndef ICMP6_MOBILEPREFIX_ADVERT
+# define ICMP6_MOBILEPREFIX_ADVERT 205
+#endif
+#ifndef ICMP6_MAXTYPE
+# define ICMP6_MAXTYPE 205
+#endif
+
+#ifndef ICMP6_DST_UNREACH_NOROUTE
+# define ICMP6_DST_UNREACH_NOROUTE 0
+#endif
+#ifndef ICMP6_DST_UNREACH_ADMIN
+# define ICMP6_DST_UNREACH_ADMIN 1
+#endif
+#ifndef ICMP6_DST_UNREACH_NOTNEIGHBOR
+# define ICMP6_DST_UNREACH_NOTNEIGHBOR 2
+#endif
+#ifndef ICMP6_DST_UNREACH_BEYONDSCOPE
+# define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#endif
+#ifndef ICMP6_DST_UNREACH_ADDR
+# define ICMP6_DST_UNREACH_ADDR 3
+#endif
+#ifndef ICMP6_DST_UNREACH_NOPORT
+# define ICMP6_DST_UNREACH_NOPORT 4
+#endif
+#ifndef ICMP6_TIME_EXCEED_TRANSIT
+# define ICMP6_TIME_EXCEED_TRANSIT 0
+#endif
+#ifndef ICMP6_TIME_EXCEED_REASSEMBLY
+# define ICMP6_TIME_EXCEED_REASSEMBLY 1
+#endif
+
+#ifndef ICMP6_NI_SUCCESS
+# define ICMP6_NI_SUCCESS 0
+#endif
+#ifndef ICMP6_NI_REFUSED
+# define ICMP6_NI_REFUSED 1
+#endif
+#ifndef ICMP6_NI_UNKNOWN
+# define ICMP6_NI_UNKNOWN 2
+#endif
+
+#ifndef ICMP6_ROUTER_RENUMBERING_COMMAND
+# define ICMP6_ROUTER_RENUMBERING_COMMAND 0
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING_RESULT
+# define ICMP6_ROUTER_RENUMBERING_RESULT 1
+#endif
+#ifndef ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET
+# define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255
+#endif
+
+#ifndef ICMP6_PARAMPROB_HEADER
+# define ICMP6_PARAMPROB_HEADER 0
+#endif
+#ifndef ICMP6_PARAMPROB_NEXTHEADER
+# define ICMP6_PARAMPROB_NEXTHEADER 1
+#endif
+#ifndef ICMP6_PARAMPROB_OPTION
+# define ICMP6_PARAMPROB_OPTION 2
+#endif
+
+#ifndef ICMP6_NI_SUBJ_IPV6
+# define ICMP6_NI_SUBJ_IPV6 0
+#endif
+#ifndef ICMP6_NI_SUBJ_FQDN
+# define ICMP6_NI_SUBJ_FQDN 1
+#endif
+#ifndef ICMP6_NI_SUBJ_IPV4
+# define ICMP6_NI_SUBJ_IPV4 2
+#endif
+
/*
* ECN is a new addition to TCP - RFC 2481
*/
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c
index e15ff67b65344..1cac072015e65 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil.c
@@ -16,7 +16,7 @@
#endif
#include <sys/param.h>
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
+ defined(_KERNEL) && !defined(_LKM)
# include "opt_ipfilter_log.h"
#endif
#if defined(__FreeBSD__) && !defined(__FreeBSD_version)
@@ -24,6 +24,9 @@
# include <osreldate.h>
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#ifndef _KERNEL
# include <stdio.h>
# include <string.h>
@@ -44,7 +47,6 @@
#ifdef _KERNEL
# include <sys/systm.h>
#endif
-#include <sys/uio.h>
#if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@@ -93,12 +95,16 @@
#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
+# if !SOLARIS
+# include <netinet6/ip6protosw.h>
+# include <netinet6/nd6.h>
+# endif
#endif
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
@@ -113,7 +119,7 @@ extern int ip_optcopy __P((struct ip *, struct ip *));
#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 $";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.53 2002/03/13 02:29:08 darrenr Exp $";
#endif
@@ -144,15 +150,18 @@ static int frrequest __P((int, int, caddr_t, int));
#endif
#ifdef _KERNEL
static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
-static int send_ip __P((ip_t *, fr_info_t *, struct mbuf *));
+static int send_ip __P((ip_t *, fr_info_t *, struct mbuf **));
+# ifdef USE_INET6
+static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **,
+ fr_info_t *, frdest_t *));
+# endif
# ifdef __sgi
extern kmutex_t ipf_rw;
extern KRWLOCK_T ipf_mutex;
# endif
#else
-int ipllog __P((void));
void init_ifp __P((void));
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *));
static int write_output __P((struct ifnet *, struct mbuf *,
@@ -208,6 +217,77 @@ int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
# endif /* NETBSD_PF */
#endif /* __NetBSD__ */
+
+#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000) && \
+ defined(_KERNEL)
+# include <net/pfil.h>
+
+static int fr_check_wrapper(void *, struct mbuf **, struct ifnet *, int );
+
+static int fr_check_wrapper(arg, mp, ifp, dir)
+void *arg;
+struct mbuf **mp;
+struct ifnet *ifp;
+int dir;
+{
+ struct ip *ip = mtod(*mp, struct ip *);
+ int rv, hlen = ip->ip_hl << 2;
+
+#if defined(M_CSUM_TCPv4)
+ /*
+ * If the packet is out-bound, we can't delay checksums
+ * here. For in-bound, the checksum has already been
+ * validated.
+ */
+ if (dir == PFIL_OUT) {
+ if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
+ in_delayed_cksum(*mp);
+ (*mp)->m_pkthdr.csum_flags &=
+ ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
+ }
+ }
+#endif /* M_CSUM_TCPv4 */
+
+ /*
+ * We get the packet with all fields in network byte
+ * order. We expect ip_len and ip_off to be in host
+ * order. We frob them, call the filter, then frob
+ * them back.
+ *
+ * Note, we don't need to update the checksum, because
+ * it has already been verified.
+ */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+
+ rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
+
+ if (rv == 0 && *mp != NULL) {
+ ip = mtod(*mp, struct ip *);
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ }
+
+ return (rv);
+}
+
+# ifdef USE_INET6
+# include <netinet/ip6.h>
+
+static int fr_check_wrapper6(void *, struct mbuf **, struct ifnet *, int );
+
+static int fr_check_wrapper6(arg, mp, ifp, dir)
+void *arg;
+struct mbuf **mp;
+struct ifnet *ifp;
+int dir;
+{
+
+ return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
+ ifp, (dir == PFIL_OUT), mp));
+}
+# endif
+#endif /* __NetBSD_Version >= 105110000 && _KERNEL */
#ifdef _KERNEL
# if defined(IPFILTER_LKM) && !defined(__sgi)
int iplidentify(s)
@@ -228,19 +308,32 @@ void
ipfilterattach(count)
int count;
{
- if (iplattach() != 0)
- printf("IP Filter failed to attach\n");
+
+ /*
+ * Do nothing here, really. The filter will be enabled
+ * by the SIOCFRENB ioctl.
+ */
}
# endif
+# if defined(__NetBSD__)
+int ipl_enable()
+# else
int iplattach()
+# endif
{
char *defpass;
int s;
# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000))
int error = 0;
# endif
+#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000)
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+#endif
SPL_NET(s);
if (fr_running || (fr_checkp == fr_check)) {
@@ -267,8 +360,24 @@ int iplattach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
+# if __NetBSD_Version__ >= 105110000
+ if (
+ !(ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET))
+# ifdef USE_INET6
+ && !(ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6))
+# endif
+ )
+ return ENODEV;
+
+ if (ph_inet != NULL)
+ error = pfil_add_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet);
+ else
+ error = 0;
+# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
if (error) {
# ifdef USE_INET6
goto pfil_error;
@@ -284,11 +393,22 @@ int iplattach()
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet6 != NULL)
+ error = pfil_add_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+ else
+ error = 0;
+ if (error) {
+ pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+# else
error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
if (error) {
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
pfil_error:
SPL_X(s);
appr_unload();
@@ -355,11 +475,21 @@ pfil_error:
* Disable the filter by removing the hooks from the IP input/output
* stream.
*/
+# if defined(__NetBSD__)
+int ipl_disable()
+# else
int ipldetach()
+# endif
{
int s, i = FR_INQUE|FR_OUTQUE;
#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
int error = 0;
+# if __NetBSD_Version__ >= 105150000
+ struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+# endif
+# endif
#endif
#ifdef _KERNEL
@@ -397,8 +527,16 @@ int ipldetach()
# ifdef NETBSD_PF
# if __NetBSD_Version__ >= 104200000
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet != NULL)
+ error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet);
+ else
+ error = 0;
+# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
if (error) {
SPL_X(s);
return error;
@@ -407,8 +545,16 @@ int ipldetach()
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
# endif
# ifdef USE_INET6
+# if __NetBSD_Version__ >= 105110000
+ if (ph_inet6 != NULL)
+ error = pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT, ph_inet6);
+ else
+ error = 0;
+# else
error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
if (error) {
SPL_X(s);
return error;
@@ -530,7 +676,7 @@ int mode;
sizeof(iplused[IPL_LOGIPF]));
#endif
break;
-#if !defined(IPFILTER_LKM) && defined(_KERNEL)
+#if (!defined(IPFILTER_LKM) || defined(__NetBSD__)) && defined(_KERNEL)
case SIOCFRENB :
{
u_int enable;
@@ -542,9 +688,17 @@ int mode;
if (error)
break;
if (enable)
+# if defined(__NetBSD__)
+ error = ipl_enable();
+# else
error = iplattach();
+# endif
else
+# if defined(__NetBSD__)
+ error = ipl_disable();
+# else
error = ipldetach();
+# endif
}
break;
}
@@ -711,11 +865,11 @@ caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
- frentry_t frd;
- frdest_t *fdp;
frgroup_t *fg = NULL;
+ int error = 0, in, i;
u_int *p, *pp;
- int error = 0, in;
+ frentry_t frd;
+ frdest_t *fdp;
u_int group;
fp = &frd;
@@ -764,18 +918,17 @@ caddr_t data;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
- if (*fp->fr_ifname) {
- fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_v);
- if (!fp->fr_ifa)
- fp->fr_ifa = (void *)-1;
- }
-#if BSD >= 199306
- if (*fp->fr_oifname) {
- fp->fr_oifa = GETUNIT(fp->fr_oifname, fp->fr_v);
- if (!fp->fr_oifa)
- fp->fr_oifa = (void *)-1;
+ for (i = 0; i < 4; i++) {
+ if ((fp->fr_ifnames[i][1] == '\0') &&
+ ((fp->fr_ifnames[i][0] == '-') ||
+ (fp->fr_ifnames[i][0] == '*'))) {
+ fp->fr_ifas[i] = NULL;
+ } else if (*fp->fr_ifnames[i]) {
+ fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v);
+ if (!fp->fr_ifas[i])
+ fp->fr_ifas[i] = (void *)-1;
+ }
}
-#endif
fdp = &fp->fr_dif;
fp->fr_flags &= ~FR_DUP;
@@ -854,6 +1007,7 @@ caddr_t data;
fixskip(fprev, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
+ f->fr_ref--;
if (f->fr_ref == 0)
KFREE(f);
}
@@ -1002,7 +1156,7 @@ fr_info_t *fin;
if (m == NULL)
return -1;
- tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
+ tlen = fin->fin_dlen - (tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
@@ -1044,7 +1198,7 @@ fr_info_t *fin;
ip6->ip6_dst = oip6->ip6_src;
tcp2->th_sum = in6_cksum(m, IPPROTO_TCP,
sizeof(*ip6), sizeof(*tcp2));
- return send_ip(oip, fin, m);
+ return send_ip(oip, fin, &m);
}
# endif
ip->ip_p = IPPROTO_TCP;
@@ -1053,17 +1207,25 @@ fr_info_t *fin;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2));
ip->ip_len = hlen + sizeof(*tcp2);
- return send_ip(oip, fin, m);
+ return send_ip(oip, fin, &m);
}
-static int send_ip(oip, fin, m)
+/*
+ * Send an IP(v4/v6) datagram out into the network
+ */
+static int send_ip(oip, fin, mp)
ip_t *oip;
fr_info_t *fin;
-struct mbuf *m;
+struct mbuf **mp;
{
+ struct mbuf *m = *mp;
+ char *dpsave;
+ int error;
ip_t *ip;
+ dpsave = fin->fin_dp;
+
ip = mtod(m, ip_t *);
ip->ip_v = fin->fin_v;
@@ -1079,20 +1241,22 @@ struct mbuf *m;
ip->ip_ttl = ip_defttl;
# endif
ip->ip_sum = 0;
+ fin->fin_dp = (char *)(ip + 1);
}
# ifdef USE_INET6
else if (ip->ip_v == 6) {
ip6_t *ip6 = (ip6_t *)ip;
ip6->ip6_hlim = 127;
-
- return ip6_output(m, NULL, NULL, 0, NULL, NULL);
+ fin->fin_dp = (char *)(ip6 + 1);
}
# endif
# ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
# endif
- return ipfr_fastroute(m, fin->fin_mp, fin, NULL);
+ error = ipfr_fastroute(m, mp, fin, NULL);
+ fin->fin_dp = dpsave;
+ return error;
}
@@ -1266,7 +1430,7 @@ int dst;
shlen = fin->fin_hlen;
fin->fin_hlen = hlen;
- err = send_ip(oip, fin, m);
+ err = send_ip(oip, fin, &m);
fin->fin_hlen = shlen;
#ifdef USE_INET6
if (fin->fin_v == 4)
@@ -1279,7 +1443,8 @@ int dst;
}
-# if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
+# if !defined(IPFILTER_LKM) && !defined(__sgi) && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 300000))
# if (BSD < 199306)
int iplinit __P((void));
@@ -1291,21 +1456,35 @@ void
# endif
iplinit()
{
+
+# if defined(__NetBSD__)
+ if (ipl_enable() != 0)
+# else
if (iplattach() != 0)
+# endif
+ {
printf("IP Filter failed to attach\n");
+ }
ip_init();
}
# endif /* ! __NetBSD__ */
+/*
+ * Return the length of the entire mbuf.
+ */
size_t mbufchainlen(m0)
register struct mbuf *m0;
{
+#if BSD >= 199306
+ return m0->m_pkthdr.len;
+#else
register size_t len = 0;
for (; m0; m0 = m0->m_next)
len += m0->m_len;
return len;
+#endif
}
@@ -1323,6 +1502,24 @@ frdest_t *fdp;
struct route iproute;
frentry_t *fr;
+ ip = NULL;
+ ro = NULL;
+ ifp = NULL;
+ ro = &iproute;
+ ro->ro_rt = NULL;
+
+#ifdef USE_INET6
+ if (fin->fin_v == 6) {
+ error = ipfr_fastroute6(m0, mpp, fin, fdp);
+ if (error != 0)
+ goto bad;
+ goto done;
+ }
+#else
+ if (fin->fin_v == 6)
+ goto bad;
+#endif
+
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@@ -1336,13 +1533,14 @@ frdest_t *fdp;
* problem.
*/
if (M_WRITABLE(m) == 0) {
- if ((m0 = m_dup(m, M_DONTWAIT)) != 0) {
- m_freem(m);
+ if ((m0 = m_dup(m, M_DONTWAIT)) != NULL) {
+ m_freem(*mpp);
+ *mpp = m0;
m = m0;
} else {
error = ENOBUFS;
- m_freem(m);
- ipl_frouteok[1]++;
+ m_freem(*mpp);
+ goto done;
}
}
#endif
@@ -1354,35 +1552,26 @@ frdest_t *fdp;
/*
* Clear any in-bound checksum flags for this packet.
*/
+# if (__NetBSD_Version__ > 105009999)
+ m0->m_pkthdr.csum_flags = 0;
+# else
m0->m_pkthdr.csuminfo = 0;
+# endif
#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
- */
- error = ip6_output(m0, NULL, NULL, 0, NULL, NULL);
- *mpp = NULL;
- return error;
- }
-#endif
/*
* Route packet.
*/
- ro = &iproute;
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
+ dst->sin_addr = ip->ip_dst;
fr = fin->fin_fr;
- if (fdp)
+ if (fdp != NULL)
ifp = fdp->fd_ifp;
- else {
+ else
ifp = fin->fin_ifp;
- dst->sin_addr = ip->ip_dst;
- }
/*
* In case we're here due to "to <if>" being used with "keep state",
@@ -1391,13 +1580,9 @@ frdest_t *fdp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return 0;
- dst->sin_addr = ip->ip_dst;
- } else if (fdp) {
- if (fdp->fd_ip.s_addr) {
+ } else if (fdp != NULL) {
+ if (fdp->fd_ip.s_addr != 0)
dst->sin_addr = fdp->fd_ip;
- ip->ip_dst = fdp->fd_ip;
- } else
- dst->sin_addr = ip->ip_dst;
}
# if BSD >= 199306
@@ -1418,26 +1603,36 @@ frdest_t *fdp;
error = -2;
goto bad;
}
- if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
- if (in_localaddr(ip->ip_dst))
- error = EHOSTUNREACH;
- else
- error = ENETUNREACH;
- goto bad;
- }
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
}
- if (ro->ro_rt)
- ro->ro_rt->rt_use++;
+
+ if ((ifp == NULL) && (ro->ro_rt != NULL))
+ ifp = ro->ro_rt->rt_ifp;
+
+ if ((ro->ro_rt == NULL) || (ifp == NULL)) {
+ if (in_localaddr(ip->ip_dst))
+ error = EHOSTUNREACH;
+ else
+ error = ENETUNREACH;
+ goto bad;
+ }
+
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
+#if BSD >= 199306
+ dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
+#else
+ dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
+#endif
+ }
+ ro->ro_rt->rt_use++;
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
* NAT'd and counted.
*/
- fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
+ sifp = fin->fin_ifp;
+ fin->fin_ifp = ifp;
fin->fin_out = 1;
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
@@ -1447,44 +1642,39 @@ frdest_t *fdp;
if (!fr || !(fr->fr_flags & FR_RETMASK))
(void) fr_checkstate(ip, fin);
(void) ip_natout(ip, fin);
+ fin->fin_ifp = sifp;
} else
ip->ip_sum = 0;
/*
* If small enough for interface, can just send directly.
*/
if (ip->ip_len <= ifp->if_mtu) {
-# if defined(MCLISREFERENCED) && !defined(sparc)
- int i = 0;
-
- if ((m->m_flags & M_EXT) && MCLISREFERENCED(m))
- i = 1;
-# endif
# ifndef sparc
-# if !(_BSDI_VERSION >= 199510)
+# if (!defined(__FreeBSD__) && !(_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 (__NetBSD_Version__ > 105009999)
+ if (ifp->if_csum_flags_tx & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+ else if (ip->ip_sum == 0)
+ ip->ip_sum = in_cksum(m, hlen);
+# else
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);
+# endif
# else
if (!ip->ip_sum)
ip->ip_sum = in_cksum(m, hlen);
# endif /* __NetBSD__ && M_CSUM_IPv4 */
-# if BSD >= 199306
+# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
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
@@ -1554,9 +1744,7 @@ frdest_t *fdp;
m->m_pkthdr.len = mhlen + len;
m->m_pkthdr.rcvif = NULL;
# endif
-# ifndef sparc
mhip->ip_off = htons((u_short)mhip->ip_off);
-# endif
mhip->ip_sum = 0;
mhip->ip_sum = in_cksum(m, mhlen);
*mnext = m;
@@ -1576,7 +1764,7 @@ sendorfree:
m0 = m->m_act;
m->m_act = 0;
if (error == 0)
-# if BSD >= 199306
+# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
# else
@@ -1593,13 +1781,13 @@ done:
else
ipl_frouteok[1]++;
- if (ro->ro_rt) {
+ if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
}
*mpp = NULL;
return error;
bad:
- if (error == EMSGSIZE) {
+ if ((error == EMSGSIZE) && (fin->fin_v == 4)) {
sifp = fin->fin_ifp;
code = fin->fin_icode;
fin->fin_icode = ICMP_UNREACH_NEEDFRAG;
@@ -1613,6 +1801,10 @@ bad:
}
+/*
+ * Return true or false depending on whether the route to the
+ * given IP address uses the same interface as the one passed.
+ */
int fr_verifysrc(ipa, ifp)
struct in_addr ipa;
void *ifp;
@@ -1622,6 +1814,9 @@ void *ifp;
bzero((char *)&iproute, sizeof(iproute));
dst = (struct sockaddr_in *)&iproute.ro_dst;
+# if (BSD >= 199306)
+ dst->sin_len = sizeof(*dst);
+# endif
dst->sin_family = AF_INET;
dst->sin_addr = ipa;
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
@@ -1651,10 +1846,78 @@ struct ifnet *ifp;
return workbuf;
}
# endif
+
+
+# if defined(USE_INET6)
+/*
+ * This is the IPv6 specific fastroute code. It doesn't clean up the mbuf's
+ * or ensure that it is an IPv6 packet that is being forwarded, those are
+ * expected to be done by the called (ipfr_fastroute).
+ */
+static int ipfr_fastroute6(m0, mpp, fin, fdp)
+struct mbuf *m0, **mpp;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+ struct route_in6 ip6route;
+ struct sockaddr_in6 *dst6;
+ struct route_in6 *ro;
+ struct ifnet *ifp;
+ frentry_t *fr;
+ int error;
+
+ ifp = NULL;
+ ro = &ip6route;
+ fr = fin->fin_fr;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(struct sockaddr_in6);
+ dst6->sin6_addr = fin->fin_fi.fi_src.in6;
+
+ if (fdp != NULL)
+ ifp = fdp->fd_ifp;
+
+ if ((fr != NULL) && (fin->fin_rev != 0)) {
+ if ((ifp != NULL) && (fdp == &fr->fr_tif))
+ return 0;
+ } else if (fdp != NULL) {
+ if (IP6_NOTZERO(&fdp->fd_ip6))
+ dst6->sin6_addr = fdp->fd_ip6.in6;
+ }
+ if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
+ return -2;
+
+ rtalloc((struct route *)ro);
+
+ if ((ifp == NULL) && (ro->ro_rt != NULL))
+ ifp = ro->ro_rt->rt_ifp;
+
+ if ((ro->ro_rt == NULL) || (ifp == NULL) ||
+ (ifp != ro->ro_rt->rt_ifp)) {
+ error = EHOSTUNREACH;
+ } else {
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst6 = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
+ ro->ro_rt->rt_use++;
+
+ if (m0->m_pkthdr.len <= nd_ifinfo[ifp->if_index].linkmtu)
+ error = nd6_output(ifp, fin->fin_ifp, m0, dst6,
+ ro->ro_rt);
+ else
+ error = EMSGSIZE;
+ }
+
+ if (ro->ro_rt != NULL) {
+ RTFREE(ro->ro_rt);
+ }
+ return error;
+}
+# endif
#else /* #ifdef _KERNEL */
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@@ -1667,7 +1930,7 @@ static int no_output __P((struct ifnet *ifp, struct mbuf *m,
# ifdef __STDC__
-# ifdef __sgi
+# if defined(__sgi) && (IRIX < 605)
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s))
# else
@@ -1702,26 +1965,39 @@ ip_t *ip;
}
-struct ifnet *get_unit(name, v)
-char *name;
+char *get_ifname(ifp)
+struct ifnet *ifp;
+{
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ return ifp->if_xname;
+# else
+ static char fullifname[LIFNAMSIZ];
+
+ sprintf(fullifname, "%s%d", ifp->if_name, ifp->if_unit);
+ return fullifname;
+# endif
+}
+
+
+struct ifnet *get_unit(ifname, v)
+char *ifname;
int v;
{
struct ifnet *ifp, **ifa, **old_ifneta;
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- if (!strcmp(name, ifp->if_xname))
- return ifp;
- }
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ if (!strncmp(ifname, ifp->if_xname, sizeof(ifp->if_xname)))
# else
- char ifname[32], *s;
+ char fullname[LIFNAMSIZ];
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- (void) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
- if (!strcmp(name, ifname))
+ sprintf(fullname, "%s%d", ifp->if_name, ifp->if_unit);
+ if (!strcmp(ifname, fullname))
+# endif
return ifp;
}
-# endif
if (!ifneta) {
ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
@@ -1754,20 +2030,19 @@ int v;
ifp = ifneta[nifs - 1];
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ strncpy(ifp->if_xname, ifname, sizeof(ifp->if_xname));
# else
- for (s = name; *s && !isdigit(*s); s++)
- ;
- if (*s && isdigit(*s)) {
- ifp->if_unit = atoi(s);
- ifp->if_name = (char *)malloc(s - name + 1);
- strncpy(ifp->if_name, name, s - name);
- ifp->if_name[s - name] = '\0';
- } else {
- ifp->if_name = strdup(name);
+ ifp->if_name = strdup(ifname);
+
+ ifname = ifp->if_name;
+ while (*ifname && !isdigit(*ifname))
+ ifname++;
+ if (*ifname && isdigit(*ifname)) {
+ ifp->if_unit = atoi(ifname);
+ *ifname = '\0';
+ } else
ifp->if_unit = -1;
- }
# endif
ifp->if_output = no_output;
return ifp;
@@ -1807,27 +2082,22 @@ void init_ifp()
}
-int ipllog __P((void))
-{
- verbose("l");
- return 0;
-}
-
-
-int send_reset(ip, ifp)
+int send_reset(ip, fin)
ip_t *ip;
-struct ifnet *ifp;
+fr_info_t *fin;
{
verbose("- TCP RST sent\n");
return 0;
}
-int icmp_error(ip, ifp)
+int send_icmp_err(ip, code, fin, dst)
ip_t *ip;
-struct ifnet *ifp;
+int code;
+fr_info_t *fin;
+int dst;
{
- verbose("- TCP RST sent\n");
+ verbose("- ICMP UNREACHABLE RST sent\n");
return 0;
}
@@ -1836,4 +2106,52 @@ void frsync()
{
return;
}
+
+void m_copydata(m, off, len, cp)
+mb_t *m;
+int off, len;
+caddr_t cp;
+{
+ bcopy((char *)m + off, cp, len);
+}
+
+
+int ipfuiomove(buf, len, rwflag, uio)
+caddr_t buf;
+int len, rwflag;
+struct uio *uio;
+{
+ int left, ioc, num, offset;
+ struct iovec *io;
+ char *start;
+
+ if (rwflag == UIO_READ) {
+ left = len;
+ ioc = 0;
+
+ offset = uio->uio_offset;
+
+ while ((left > 0) && (ioc < uio->uio_iovcnt)) {
+ io = uio->uio_iov + ioc;
+ num = io->iov_len;
+ if (num > left)
+ num = left;
+ start = io->iov_base + offset;
+ if (start > io->iov_base + io->iov_len) {
+ offset -= io->iov_len;
+ ioc++;
+ continue;
+ }
+ bcopy(buf, start, num);
+ uio->uio_resid -= num;
+ uio->uio_offset += num;
+ left -= num;
+ if (left > 0)
+ ioc++;
+ }
+ if (left > 0)
+ return EFAULT;
+ }
+ return 0;
+}
#endif /* _KERNEL */
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index 6d51ced5e0ae2..96a8f4bb8c6ee 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1,10 +1,10 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* 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.10 2001/07/15 13:51:42 darrenr Exp $
+ * $Id: ip_fil.h,v 2.29.2.29 2002/03/13 03:56:46 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -34,6 +34,10 @@
# endif
#endif
+#ifndef offsetof
+# define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+
#if defined(__STDC__) || defined(__GNUC__)
# define SIOCADAFR _IOW('r', 60, struct frentry *)
# define SIOCRMAFR _IOW('r', 61, struct frentry *)
@@ -51,8 +55,8 @@
# define SIOCFRSYN _IOW('r', 73, u_int)
# define SIOCFRZST _IOWR('r', 74, struct friostat *)
# define SIOCZRLST _IOWR('r', 75, struct frentry *)
-# define SIOCAUTHW _IOWR('r', 76, struct fr_info *)
-# define SIOCAUTHR _IOWR('r', 77, struct fr_info *)
+# define SIOCAUTHW _IOWR('r', 76, struct frauth_t *)
+# define SIOCAUTHR _IOWR('r', 77, struct frauth_t *)
# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR('r', 79, u_int)
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
@@ -76,8 +80,8 @@
# define SIOCFRSYN _IOW(r, 73, u_int)
# define SIOCFRZST _IOWR(r, 74, struct friostat *)
# define SIOCZRLST _IOWR(r, 75, struct frentry *)
-# define SIOCAUTHW _IOWR(r, 76, struct fr_info *)
-# define SIOCAUTHR _IOWR(r, 77, struct fr_info *)
+# define SIOCAUTHW _IOWR(r, 76, struct frauth_t *)
+# define SIOCAUTHR _IOWR(r, 77, struct frauth_t *)
# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
# define SIOCSTLCK _IOWR(r, 79, u_int)
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
@@ -123,7 +127,9 @@ typedef struct fr_ip {
#define FI_W_SADDR 0x00000400
#define FI_W_DADDR 0x00000800
#define FI_WILDA (FI_W_SADDR|FI_W_DADDR)
-#define FI_NEWFR 0x00001000
+#define FI_NEWFR 0x00001000 /* Create a filter rule */
+#define FI_IGNOREPKT 0x00002000 /* Do not treat as a real packet */
+#define FI_NORULE 0x00004000 /* Not direct a result of a rule */
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
@@ -135,10 +141,12 @@ typedef struct fr_info {
u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
/* From here on is packet specific */
u_char fin_icode; /* ICMP error to return */
- u_short fin_rule; /* rule # last matched */
+ u_32_t fin_rule; /* rule # last matched */
u_32_t fin_group; /* group number, -1 for none */
struct frentry *fin_fr; /* last matching rule */
char *fin_dp; /* start of data past IP header */
+ u_short fin_plen;
+ u_short fin_off;
u_short fin_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
void *fin_mp; /* pointer to pointer to mbuf */
@@ -146,19 +154,21 @@ typedef struct fr_info {
void *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qif;
#endif
- u_short fin_plen;
- u_short fin_off;
} fr_info_t;
#define fin_v fin_fi.fi_v
+#define fin_p fin_fi.fi_p
#define fin_saddr fin_fi.fi_saddr
+#define fin_src fin_fi.fi_src.in4
#define fin_daddr fin_fi.fi_daddr
+#define fin_dst fin_fi.fi_dst.in4
#define fin_fl fin_fi.fi_fl
/*
* Size for compares on fr_info structures
*/
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
+#define FI_LCSIZE offsetof(fr_info_t, fin_dp)
/*
* Size for copying cache fr_info structure
@@ -167,13 +177,16 @@ typedef struct fr_info {
typedef struct frdest {
void *fd_ifp;
- struct in_addr fd_ip;
- char fd_ifname[IFNAMSIZ];
+ union i6addr fd_ip6;
+ char fd_ifname[LIFNAMSIZ];
#if SOLARIS
mb_t *fd_mp; /* cache resolver for to/dup-to */
#endif
} frdest_t;
+#define fd_ip fd_ip6.in4
+
+
typedef struct frpcmp {
int frp_cmp; /* data for port comparisons */
u_short frp_port; /* top port for <> and >< */
@@ -198,10 +211,7 @@ typedef struct frentry {
struct frentry *fr_next;
struct frentry *fr_grp;
int fr_ref; /* reference count - for grouping */
- void *fr_ifa;
-#if BSD >= 199306
- void *fr_oifa;
-#endif
+ void *fr_ifas[4];
/*
* These are only incremented when a packet matches this rule and
* it is the last match
@@ -218,6 +228,7 @@ typedef struct frentry {
u_short fr_icmpm; /* data for ICMP packets (mask) */
u_short fr_icmp;
+ u_int fr_age[2]; /* aging for state */
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 */
@@ -227,10 +238,7 @@ typedef struct frentry {
int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
int fr_sap; /* For solaris only */
u_char fr_icode; /* return ICMP code */
- char fr_ifname[IFNAMSIZ];
-#if BSD >= 199306
- char fr_oifname[IFNAMSIZ];
-#endif
+ char fr_ifnames[4][LIFNAMSIZ];
struct frdest fr_tif; /* "to" interface */
struct frdest fr_dif; /* duplicate packet interfaces */
u_int fr_cksum; /* checksum on filter rules for performance */
@@ -252,10 +260,11 @@ typedef struct frentry {
#define fr_src fr_ip.fi_src.in4
#define fr_dmsk fr_mip.fi_dst.in4
#define fr_smsk fr_mip.fi_src.in4
+#define fr_ifname fr_ifnames[0]
+#define fr_oifname fr_ifnames[2]
+#define fr_ifa fr_ifas[0]
+#define fr_oifa fr_ifas[2]
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
-#endif
#define FR_CMPSIZ (sizeof(struct frentry) - offsetof(frentry_t, fr_ip))
/*
@@ -268,8 +277,8 @@ typedef struct frentry {
#define FR_LOG 0x00010 /* Log */
#define FR_LOGB 0x00011 /* Log-fail */
#define FR_LOGP 0x00012 /* Log-pass */
-#define FR_LOGBODY 0x00020 /* Log the body */
-#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
+#define FR_NOTSRCIP 0x00020 /* not the src IP# */
+#define FR_NOTDSTIP 0x00040 /* not the dst IP# */
#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
#define FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
@@ -283,8 +292,8 @@ typedef struct frentry {
#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
#define FR_DUP 0x20000 /* duplicate packet */
#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
-#define FR_NOTSRCIP 0x80000 /* not the src IP# */
-#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
+#define FR_LOGBODY 0x80000 /* Log the body */
+#define FR_LOGFIRST 0x100000 /* Log the first byte if state held */
#define FR_AUTH 0x200000 /* use authentication */
#define FR_PREAUTH 0x400000 /* require preauthentication */
#define FR_DONTCACHE 0x800000 /* don't cache the result */
@@ -406,15 +415,16 @@ typedef struct iplog {
struct iplog *ipl_next;
} iplog_t;
-#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+#define IPLOG_SIZE sizeof(iplog_t)
typedef struct ipflog {
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603))
- u_char fl_ifname[IFNAMSIZ];
+ u_char fl_ifname[LIFNAMSIZ];
#else
u_int fl_unit;
- u_char fl_ifname[4];
+ u_char fl_ifname[LIFNAMSIZ];
#endif
u_char fl_plen; /* extra data after hlen */
u_char fl_hlen; /* length of IP headers saved */
@@ -422,7 +432,8 @@ typedef struct ipflog {
u_32_t fl_rule;
u_32_t fl_group;
u_32_t fl_flags;
- u_32_t fl_lflags;
+ u_char fl_dir;
+ u_char fl_pad[3];
} ipflog_t;
@@ -485,10 +496,11 @@ typedef struct ipflog {
#ifndef _KERNEL
+extern char *get_ifname __P((struct ifnet *));
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 send_reset __P((ip_t *, struct ifnet *));
-extern int icmp_error __P((ip_t *, struct ifnet *));
+extern int send_reset __P((ip_t *, fr_info_t *));
+extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int ipf_log __P((void));
extern struct ifnet *get_unit __P((char *, int));
# if defined(__NetBSD__) || defined(__OpenBSD__) || \
@@ -506,11 +518,6 @@ extern void ipfilterattach __P((int));
extern int iplattach __P((void));
extern int ipl_enable __P((void));
extern int ipl_disable __P((void));
-extern void ipflog_init __P((void));
-extern int ipflog_clear __P((minor_t));
-extern int ipflog_read __P((minor_t, struct uio *));
-extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
-extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
extern int send_reset __P((ip_t *, fr_info_t *));
# if SOLARIS
@@ -593,6 +600,12 @@ extern u_short ipf_cksum __P((u_short *, int));
extern int ircopyptr __P((void *, void *, size_t));
extern int iwcopyptr __P((void *, void *, size_t));
+extern void ipflog_init __P((void));
+extern int ipflog_clear __P((minor_t));
+extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
+extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
+extern int ipflog_read __P((minor_t, struct uio *));
+
extern int frflush __P((minor_t, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index b0e63a9f75511..abc0faa8d72a6 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -7,6 +7,9 @@
# define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -23,7 +26,6 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -63,7 +65,6 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
@@ -89,7 +90,7 @@ extern struct timeout ipfr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.14 2001/07/15 22:06:15 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.20 2002/03/06 09:44:11 darrenr Exp $";
#endif
@@ -494,7 +495,6 @@ void ipfr_unload()
}
-#ifdef _KERNEL
void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
@@ -565,6 +565,7 @@ void ipfr_fragexpire()
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
+#ifdef _KERNEL
# if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
void ipfr_slowtimer()
@@ -574,6 +575,9 @@ void ipfr_slowtimer __P((void *ptr))
# else
int ipfr_slowtimer()
# endif
+#else
+void ipfr_slowtimer()
+#endif
{
#if defined(_KERNEL) && SOLARIS
extern int fr_running;
@@ -583,7 +587,7 @@ int ipfr_slowtimer()
#endif
READ_ENTER(&ipf_solaris);
-#ifdef __sgi
+#if defined(__sgi) && defined(_KERNEL)
ipfilter_sgi_intfsync();
#endif
@@ -591,6 +595,7 @@ int ipfr_slowtimer()
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
+#if defined(_KERNEL)
# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
RWLOCK_EXIT(&ipf_solaris);
@@ -601,8 +606,8 @@ 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);
+# if defined(__OpenBSD__)
+ timeout_add(&ipfr_slowtimer_ch, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
@@ -612,5 +617,5 @@ int ipfr_slowtimer()
# endif /* FreeBSD */
# endif /* NetBSD */
# endif /* SOLARIS */
-}
#endif /* defined(_KERNEL) */
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h
index 446510f0e9651..03f41f8d04cd2 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.h
+++ b/sys/contrib/ipfilter/netinet/ip_frag.h
@@ -4,7 +4,7 @@
* 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.5 2001/06/26 10:43:13 darrenr Exp $
+ * $Id: ip_frag.h,v 2.4.2.6 2002/01/01 15:09:38 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -56,14 +56,18 @@ extern void ipfr_forget __P((void *));
extern void ipfr_unload __P((void));
extern void ipfr_fragexpire __P((void));
-#if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
+#ifdef _KERNEL
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
+# if defined(SOLARIS2) && (SOLARIS2 < 7)
extern void ipfr_slowtimer __P((void));
-# else
+# else
extern void ipfr_slowtimer __P((void *));
-# endif
-#else
+# endif
+# else
extern int ipfr_slowtimer __P((void));
-#endif /* (BSD >= 199306) || SOLARIS */
+# endif /* (BSD >= 199306) || SOLARIS */
+#else
+extern void ipfr_slowtimer __P((void));
+#endif /* _KERNEL */
#endif /* __IP_FIL_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index 830a4f66c9ec9..0968b1055dc97 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.26 2001/07/15 13:50:54 darrenr Exp $
+ * $Id: ip_ftp_pxy.c,v 2.7.2.33 2002/02/15 14:48:38 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -49,10 +49,12 @@ int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_valid __P((char *, size_t));
+int ippr_ftp_valid __P((int, char *, size_t));
+int ippr_ftp_server_valid __P((char *, size_t));
+int ippr_ftp_client_valid __P((char *, size_t));
u_short ippr_ftp_atoi __P((char **));
-static frentry_t natfr;
+static frentry_t ftppxyfr;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0;
@@ -62,9 +64,9 @@ int ippr_ftp_insecure = 0;
*/
int ippr_ftp_init()
{
- bzero((char *)&natfr, sizeof(natfr));
- natfr.fr_ref = 1;
- natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
+ bzero((char *)&ftppxyfr, sizeof(ftppxyfr));
+ ftppxyfr.fr_ref = 1;
+ ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
return 0;
}
@@ -105,9 +107,9 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
char newbuf[IPF_FTPBUFSZ], *s;
- u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
struct in_addr swip;
+ u_short a5, a6, sp;
size_t nlen, olen;
fr_info_t fi;
int inc, off;
@@ -173,7 +175,7 @@ int dlen;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - f->ftps_rptr;
- /* DO NOT change this to sprintf! */
+ /* DO NOT change this to snprintf! */
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
@@ -241,46 +243,47 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = htons(a5 << 8 | a6);
+ sp = (a5 << 8 | a6);
/*
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
- if (ntohs(sp) < 1024)
+ if (sp < 1024)
return 0;
/*
* The server may not make the connection back from port 20, but
* it is the most likely so use it here to check for a conflicting
* mapping.
*/
- dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = sp;
+ fi.fin_data[1] = fin->fin_data[1] - 1;
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
+ tcp2->th_sport = htons(sp);
tcp2->th_off = 5;
tcp2->th_dport = 0; /* XXX - don't specify remote port */
- fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dlen = sizeof(*tcp2);
fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
+ fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@@ -340,7 +343,8 @@ int dlen;
!strncmp(cmd, "ADAT ", 5)) {
ftp->ftp_passok = FTPXY_ADAT_1;
ftp->ftp_incok = 1;
- } else if ((ftp->ftp_passok == FTPXY_PAOK_2) &&
+ } else if ((ftp->ftp_passok == FTPXY_PAOK_1 ||
+ ftp->ftp_passok == FTPXY_PAOK_2) &&
!strncmp(cmd, "ACCT ", 5)) {
ftp->ftp_passok = FTPXY_ACCT_1;
ftp->ftp_incok = 1;
@@ -368,8 +372,8 @@ int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
struct in_addr swip, swip2;
- u_short a5, a6, sp, dp;
u_int a1, a2, a3, a4;
+ u_short a5, a6, dp;
fr_info_t fi;
nat_t *ipn;
int inc;
@@ -501,26 +505,27 @@ int dlen;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = 0;
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = 0;
dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ fi.fin_data[1] = ntohs(dp);
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
tcp2->th_sport = 0; /* XXX - fake it for nat_new */
tcp2->th_off = 5;
- fi.fin_data[0] = a5 << 8 | a6;
+ fi.fin_data[1] = a5 << 8 | a6;
fi.fin_dlen = sizeof(*tcp2);
- tcp2->th_dport = htons(fi.fin_data[0]);
- fi.fin_data[1] = 0;
+ tcp2->th_dport = htons(fi.fin_data[1]);
+ fi.fin_data[0] = 0;
fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
+ fi.fin_fr = &ftppxyfr;
fi.fin_out = 1;
swip = ip->ip_src;
swip2 = ip->ip_dst;
@@ -528,11 +533,12 @@ int dlen;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_dst = ip->ip_src;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_SPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_SPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_SPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_SPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
@@ -601,7 +607,7 @@ int dlen;
* Look to see if the buffer starts with something which we recognise as
* being the correct syntax for the FTP protocol.
*/
-int ippr_ftp_valid(buf, len)
+int ippr_ftp_client_valid(buf, len)
char *buf;
size_t len;
{
@@ -614,36 +620,60 @@ size_t len;
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if (isdigit(c)) {
+ if (isalpha(c)) {
c = *s++;
i--;
- if ((c != '-') && (c != ' '))
+ if (isalpha(c)) {
+ c = *s++;
+ i--;
+ if ((c != ' ') && (c != '\r'))
+ return 1;
+ } else if ((c != ' ') && (c != '\r'))
return 1;
} else
return 1;
} else
return 1;
- } else if (isalpha(c)) {
+ } else
+ return 1;
+ for (; i; i--) {
+ c = *s++;
+ if (c == '\n')
+ return 0;
+ }
+ return 2;
+}
+
+
+int ippr_ftp_server_valid(buf, len)
+char *buf;
+size_t len;
+{
+ register char *s, c;
+ register size_t i = len;
+
+ if (i < 5)
+ return 2;
+ s = buf;
+ c = *s++;
+ i--;
+
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
+ if (isdigit(c)) {
c = *s++;
i--;
- if (isalpha(c)) {
- c = *s++;
- i--;
- if ((c != ' ') && (c != '\r'))
- return 1;
- } else if ((c != ' ') && (c != '\r'))
+ if ((c != '-') && (c != ' '))
return 1;
} else
return 1;
@@ -660,6 +690,21 @@ size_t len;
}
+int ippr_ftp_valid(side, buf, len)
+int side;
+char *buf;
+size_t len;
+{
+ int ret;
+
+ if (side == 0)
+ ret = ippr_ftp_client_valid(buf, len);
+ else
+ ret = ippr_ftp_server_valid(buf, len);
+ return ret;
+}
+
+
int ippr_ftp_process(fin, ip, nat, ftp, rv)
fr_info_t *fin;
ip_t *ip;
@@ -715,7 +760,7 @@ int rv;
if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq))
f->ftps_seq = ntohl(tcp->th_seq);
else if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
- return APR_ERR(-1);
+ return APR_ERR(1);
}
f->ftps_len = mlen;
@@ -732,11 +777,12 @@ int rv;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
if (f->ftps_junk == 0) {
+ f->ftps_cmds++;
len = wptr - rptr;
f->ftps_rptr = rptr;
if (rv)
@@ -746,9 +792,17 @@ int rv;
inc += ippr_ftp_client(fin, ip, nat,
ftp, len);
rptr = f->ftps_rptr;
+ wptr = f->ftps_wptr;
}
}
+ /*
+ * Off to a bad start so lets just forget about using the
+ * ftp proxy for this connection.
+ */
+ if ((f->ftps_cmds == 0) && (f->ftps_junk == 1))
+ return APR_ERR(2);
+
while ((f->ftps_junk == 1) && (rptr < wptr)) {
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 5968f46ad4b02..e56c60262460d 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_log.c,v 2.5.2.5 2001/06/26 10:43:14 darrenr Exp $
+ * $Id: ip_log.c,v 2.5.2.17 2002/03/13 03:57:05 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@@ -52,7 +52,6 @@
# if defined(_KERNEL)
# include <sys/systm.h>
# endif
-# include <sys/uio.h>
# if !SOLARIS
# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
# include <sys/dirent.h>
@@ -63,13 +62,14 @@
# else
# include <sys/filio.h>
# include <sys/cred.h>
-# include <sys/ddi.h>
-# include <sys/sunddi.h>
-# include <sys/ksynch.h>
# include <sys/kmem.h>
-# include <sys/mkdev.h>
-# include <sys/dditypes.h>
-# include <sys/cmn_err.h>
+# ifdef _KERNEL
+# include <sys/ddi.h>
+# include <sys/sunddi.h>
+# include <sys/ksynch.h>
+# include <sys/dditypes.h>
+# include <sys/cmn_err.h>
+# endif
# endif
# include <sys/protosw.h>
# include <sys/socket.h>
@@ -104,11 +104,6 @@
# include "netinet/ip_compat.h"
# include <netinet/tcpip.h>
# include "netinet/ip_fil.h"
-# include "netinet/ip_proxy.h"
-# include "netinet/ip_nat.h"
-# include "netinet/ip_frag.h"
-# include "netinet/ip_state.h"
-# include "netinet/ip_auth.h"
# if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# endif
@@ -116,6 +111,10 @@
# ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
# endif
+# ifdef IPFILTER_LOGSIZE
+# undef IPLLOGSIZE
+# define IPLLOGSIZE IPFILTER_LOGSIZE
+# endif
# if SOLARIS || defined(__sgi)
@@ -168,7 +167,7 @@ mb_t *m;
void *ptrs[2];
int types[2];
u_char p;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
ill_t *ifp = fin->fin_ifp;
# else
struct ifnet *ifp = fin->fin_ifp;
@@ -215,9 +214,11 @@ mb_t *m;
* Get the interface number and name to which this packet is
* currently associated.
*/
-# if SOLARIS
+ bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
+# if SOLARIS && defined(_KERNEL)
ipfl.fl_unit = (u_char)ifp->ill_ppa;
- bcopy(ifp->ill_name, ipfl.fl_ifname, MIN(ifp->ill_name_length, 4));
+ bcopy(ifp->ill_name, ipfl.fl_ifname,
+ MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
# else
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
@@ -225,10 +226,8 @@ mb_t *m;
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
# else
ipfl.fl_unit = (u_char)ifp->if_unit;
- 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]))
- ipfl.fl_ifname[3] = ifp->if_name[3];
+ strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
+ sizeof(ifp->if_name)));
# endif
mlen = (flags & FR_LOGBODY) ? MIN(fin->fin_plen - hlen, 128) : 0;
# endif
@@ -241,10 +240,11 @@ mb_t *m;
else
ipfl.fl_loglevel = 0xffff;
ipfl.fl_flags = flags;
+ ipfl.fl_dir = fin->fin_out;
ptrs[0] = (void *)&ipfl;
sizes[0] = sizeof(ipfl);
types[0] = 0;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
/*
* Are we copied from the mblk or an aligned array ?
*/
@@ -289,20 +289,20 @@ int *types, cnt;
MUTEX_ENTER(&ipl_mutex);
if (fin != NULL) {
if ((ipll[dev] != NULL) &&
- bcmp((char *)fin, (char *)&iplcrc[dev], FI_CSIZE) == 0) {
+ bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
ipll[dev]->ipl_count++;
MUTEX_EXIT(&ipl_mutex);
return 1;
}
- bcopy((char *)fin, (char *)&iplcrc[dev], FI_CSIZE);
+ bcopy((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE);
} else
- bzero((char *)&iplcrc[dev], FI_CSIZE);
+ bzero((char *)&iplcrc[dev], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
/*
* Get the total amount of data to be logged.
*/
- for (i = 0, len = sizeof(iplog_t); i < cnt; i++)
+ for (i = 0, len = IPLOG_SIZE; i < cnt; i++)
len += itemsz[i];
/*
@@ -330,23 +330,28 @@ int *types, cnt;
ipl->ipl_count = 1;
ipl->ipl_next = NULL;
ipl->ipl_dsize = len;
-# if SOLARIS || defined(sun)
+# ifdef _KERNEL
+# if SOLARIS || defined(sun)
uniqtime((struct timeval *)&ipl->ipl_sec);
-# else
-# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
+# else
+# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
microtime((struct timeval *)&ipl->ipl_sec);
+# endif
# endif
+# else
+ ipl->ipl_sec = 0;
+ ipl->ipl_usec = 0;
# endif
/*
* Loop through all the items to be logged, copying each one to the
* buffer. Use bcopy for normal data or the mb_t copyout routine.
*/
- for (i = 0, s = buf + sizeof(*ipl); i < cnt; i++) {
+ for (i = 0, s = buf + IPLOG_SIZE; i < cnt; i++) {
if (types[i] == 0)
bcopy(items[i], s, itemsz[i]);
else if (types[i] == 1) {
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
copyout_mblk(items[i], 0, itemsz[i], s);
# else
m_copydata(items[i], 0, itemsz[i], s);
@@ -358,12 +363,12 @@ int *types, cnt;
ipll[dev] = ipl;
*iplh[dev] = ipl;
iplh[dev] = &ipl->ipl_next;
-# if SOLARIS
+# if SOLARIS && defined(_KERNEL)
cv_signal(&iplwait);
mutex_exit(&ipl_mutex);
# else
MUTEX_EXIT(&ipl_mutex);
- wakeup(&iplh[dev]);
+ WAKEUP(&iplh[dev]);
# endif
return 1;
}
@@ -388,7 +393,7 @@ struct uio *uio;
return ENXIO;
if (!uio->uio_resid)
return 0;
- if (uio->uio_resid < sizeof(iplog_t))
+ if (uio->uio_resid < IPLOG_SIZE)
return EINVAL;
/*
@@ -430,15 +435,14 @@ struct uio *uio;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
+ MUTEX_ENTER(&ipl_mutex);
if (error) {
- MUTEX_ENTER(&ipl_mutex);
ipl->ipl_next = iplt[unit];
iplt[unit] = ipl;
iplused[unit] += dlen;
break;
}
KFREES((caddr_t)ipl, dlen);
- MUTEX_ENTER(&ipl_mutex);
}
if (!iplt[unit]) {
iplused[unit] = 0;
@@ -467,7 +471,7 @@ minor_t unit;
ipll[unit] = NULL;
used = iplused[unit];
iplused[unit] = 0;
- bzero((char *)&iplcrc[unit], FI_CSIZE);
+ bzero((char *)&iplcrc[unit], FI_LCSIZE);
MUTEX_EXIT(&ipl_mutex);
return used;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index eb6e133bfc0f9..5c10bc4ba3f33 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -9,6 +9,9 @@
#define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -30,7 +33,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -92,10 +94,10 @@ extern struct ifnet vpnif;
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
#endif
@@ -107,7 +109,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.44 2001/07/21 07:17:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.63 2002/03/06 09:44:11 darrenr Exp $";
#endif
nat_t **nat_table[2] = { NULL, NULL },
@@ -133,7 +135,6 @@ extern KRWLOCK_T ipf_nat;
#endif
static int nat_flushtable __P((void));
-static int nat_clearlist __P((void));
static void nat_addnat __P((struct ipnat *));
static void nat_addrdr __P((struct ipnat *));
static void nat_delete __P((struct nat *));
@@ -142,7 +143,7 @@ static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t));
-static void nat_tabmove __P((nat_t *, u_32_t));
+static void nat_tabmove __P((fr_info_t *, nat_t *));
static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr));
@@ -501,7 +502,7 @@ int mode;
if (!n->in_ifp)
n->in_ifp = (void *)-1;
if (n->in_plabel[0] != '\0') {
- n->in_apr = appr_match(n->in_p, n->in_plabel);
+ n->in_apr = appr_lookup(n->in_p, n->in_plabel);
if (!n->in_apr) {
error = ENOENT;
break;
@@ -900,7 +901,9 @@ caddr_t data;
nat->nat_aps = NULL;
in = nat->nat_ptr;
nat->nat_ptr = NULL;
+ nat->nat_hm = NULL;
nat->nat_data = NULL;
+ nat->nat_ifp = GETUNIT(nat->nat_ifname, 4);
/*
* Restore the rule associated with this nat session
@@ -922,7 +925,7 @@ caddr_t data;
in->in_pmnext = NULL;
in->in_ifp = GETUNIT(in->in_ifname, 4);
if (in->in_plabel[0] != '\0') {
- in->in_apr = appr_match(in->in_p, in->in_plabel);
+ in->in_apr = appr_lookup(in->in_p, in->in_plabel);
}
}
@@ -1015,6 +1018,8 @@ struct nat *natd;
if (natd->nat_hnext[1])
natd->nat_hnext[1]->nat_phnext[1] = natd->nat_phnext[1];
*natd->nat_phnext[1] = natd->nat_hnext[1];
+ if (natd->nat_me != NULL)
+ *natd->nat_me = NULL;
if (natd->nat_fr != NULL) {
ATOMIC_DEC32(natd->nat_fr->fr_ref);
@@ -1054,6 +1059,7 @@ struct nat *natd;
/*
* nat_flushtable - clear the NAT table of all mapping entries.
+ * (this is for the dynamic mappings)
*/
static int nat_flushtable()
{
@@ -1086,8 +1092,9 @@ static int nat_flushtable()
/*
* nat_clearlist - delete all rules in the active NAT mapping list.
+ * (this is for NAT/RDR rules)
*/
-static int nat_clearlist()
+int nat_clearlist()
{
register ipnat_t *n, **np = &nat_list;
int i = 0;
@@ -1118,22 +1125,25 @@ static int nat_clearlist()
/*
* Create a new NAT table entry.
- * NOTE: assumes write lock on ipf_nat has been obtained already.
+ * NOTE: Assumes write lock on ipf_nat has been obtained already.
+ * If you intend on changing this, beware: appr_new() may call nat_new()
+ * recursively!
*/
-nat_t *nat_new(np, ip, fin, flags, direction)
-ipnat_t *np;
-ip_t *ip;
+nat_t *nat_new(fin, ip, np, natsave, flags, direction)
fr_info_t *fin;
+ip_t *ip;
+ipnat_t *np;
+nat_t **natsave;
u_int flags;
int direction;
{
register u_32_t sum1, sum2, sumd, l;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in, inb;
+ u_short nflags, sp, dp;
tcphdr_t *tcp = NULL;
hostmap_t *hm = NULL;
nat_t *nat, *natl;
- u_short nflags;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
qif_t *qf = fin->fin_qif;
#endif
@@ -1141,8 +1151,8 @@ int direction;
nflags = flags & np->in_flags;
if (flags & IPN_TCPUDP) {
tcp = (tcphdr_t *)fin->fin_dp;
- sport = tcp->th_sport;
- dport = tcp->th_dport;
+ sport = htons(fin->fin_data[0]);
+ dport = htons(fin->fin_data[1]);
}
/* Give me a new nat */
@@ -1182,7 +1192,7 @@ int direction;
* Check to see if there is an existing NAT
* setup for this IP address pair.
*/
- hm = nat_hostmap(np, ip->ip_src, in);
+ hm = nat_hostmap(np, fin->fin_src, in);
if (hm != NULL)
in.s_addr = hm->hm_mapip.s_addr;
} else if ((l == 1) && (hm != NULL)) {
@@ -1206,7 +1216,7 @@ int direction;
/*
* map-block - Calculate destination address.
*/
- in.s_addr = ntohl(ip->ip_src.s_addr);
+ in.s_addr = ntohl(fin->fin_saddr);
in.s_addr &= ntohl(~np->in_inmsk);
inb.s_addr = in.s_addr;
in.s_addr /= np->in_ippip;
@@ -1239,7 +1249,7 @@ int direction;
*/
if (l > 0)
goto badnat;
- in.s_addr = ntohl(ip->ip_src.s_addr);
+ in.s_addr = ntohl(fin->fin_saddr);
} else if ((np->in_outmsk != 0xffffffff) &&
(np->in_pnext == 0) &&
((l > 0) || (hm == NULL)))
@@ -1261,7 +1271,7 @@ int direction;
port += (l % np->in_ppip);
port %= np->in_ppip;
port += np->in_ppip *
- (ntohl(ip->ip_src.s_addr) %
+ (ntohl(fin->fin_saddr) %
np->in_ippip);
port += MAPBLK_MINPORT;
port = htons(port);
@@ -1301,9 +1311,15 @@ int direction;
* this is appropriate.
*/
inb.s_addr = htonl(in.s_addr);
- natl = nat_inlookup(fin->fin_ifp, flags & ~FI_WILDP,
- (u_int)ip->ip_p, ip->ip_dst, inb,
- (port << 16) | dport, 1);
+ sp = fin->fin_data[0];
+ dp = fin->fin_data[1];
+ fin->fin_data[0] = fin->fin_data[1];
+ fin->fin_data[1] = htons(port);
+ natl = nat_inlookup(fin, flags & ~FI_WILDP,
+ (u_int)fin->fin_p, fin->fin_dst,
+ inb, 1);
+ fin->fin_data[0] = sp;
+ fin->fin_data[1] = dp;
/*
* Has the search wrapped around and come back to the
@@ -1320,14 +1336,14 @@ int direction;
np->in_space--;
/* Setup the NAT table */
- nat->nat_inip = ip->ip_src;
+ nat->nat_inip = fin->fin_src;
nat->nat_outip.s_addr = htonl(in.s_addr);
- nat->nat_oip = ip->ip_dst;
+ nat->nat_oip = fin->fin_dst;
if (nat->nat_hm == NULL)
- nat->nat_hm = nat_hostmap(np, ip->ip_src,
+ nat->nat_hm = nat_hostmap(np, fin->fin_src,
nat->nat_outip);
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr)) + ntohs(sport);
+ sum1 = LONG_SUM(ntohl(fin->fin_saddr)) + ntohs(sport);
sum2 = LONG_SUM(in.s_addr) + ntohs(port);
if (flags & IPN_TCPUDP) {
@@ -1367,27 +1383,26 @@ int direction;
* Whilst not optimized for the case where
* pmin == pmax, the gain is not significant.
*/
- nport = ntohs(dport) - ntohs(np->in_pmin) +
- ntohs(np->in_pnext);
- nport = htons(nport);
+ if (np->in_pmin != np->in_pmax) {
+ nport = ntohs(dport) - ntohs(np->in_pmin) +
+ ntohs(np->in_pnext);
+ nport = ntohs(nport);
+ } else
+ nport = np->in_pnext;
}
/*
* When the redirect-to address is set to 0.0.0.0, just
- * assume a blank `forwarding' of the packet. We don't
- * setup any translation for this either.
+ * assume a blank `forwarding' of the packet.
*/
- if (in.s_addr == 0) {
- if (nport == dport)
- goto badnat;
- in.s_addr = ntohl(ip->ip_dst.s_addr);
- }
+ if (in.s_addr == 0)
+ in.s_addr = ntohl(fin->fin_daddr);
nat->nat_inip.s_addr = htonl(in.s_addr);
- nat->nat_outip = ip->ip_dst;
- nat->nat_oip = ip->ip_src;
+ nat->nat_outip = fin->fin_dst;
+ nat->nat_oip = fin->fin_src;
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr)) + ntohs(dport);
+ sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport);
sum2 = LONG_SUM(in.s_addr) + ntohs(nport);
if (flags & IPN_TCPUDP) {
@@ -1405,8 +1420,8 @@ int direction;
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 = LONG_SUM(ntohl(fin->fin_saddr));
+ sum1 += LONG_SUM(ntohl(fin->fin_daddr));
sum1 += IPPROTO_TCP;
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
nat->nat_sumd[1] = NAT_HW_CKSUM|(sum1 & 0xffff);
@@ -1416,9 +1431,9 @@ int direction;
if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) {
if (direction == NAT_OUTBOUND)
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
+ sum1 = LONG_SUM(ntohl(fin->fin_saddr));
else
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr));
+ sum1 = LONG_SUM(ntohl(fin->fin_daddr));
sum2 = LONG_SUM(in.s_addr);
@@ -1429,15 +1444,13 @@ int direction;
in.s_addr = htonl(in.s_addr);
-#ifdef _KERNEL
strncpy(nat->nat_ifname, IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- nat_insert(nat);
+ nat->nat_me = natsave;
nat->nat_dir = direction;
nat->nat_ifp = fin->fin_ifp;
nat->nat_ptr = np;
- nat->nat_p = ip->ip_p;
+ nat->nat_p = fin->fin_p;
nat->nat_bytes = 0;
nat->nat_pkts = 0;
nat->nat_fr = fin->fin_fr;
@@ -1451,6 +1464,13 @@ int direction;
if (flags & IPN_TCPUDP)
tcp->th_dport = nport;
}
+
+ nat_insert(nat);
+
+ if ((np->in_apr != NULL) && (np->in_dport == 0 ||
+ (tcp != NULL && dport == np->in_dport)))
+ (void) appr_new(fin, ip, nat);
+
np->in_use++;
#ifdef IPFILTER_LOG
nat_log(nat, (u_int)np->in_redir);
@@ -1465,6 +1485,10 @@ badnat:
}
+/*
+ * Insert a NAT entry into the hash tables for searching and add it to the
+ * list of active NAT entries. Adjust global counters when complete.
+ */
void nat_insert(nat)
nat_t *nat;
{
@@ -1492,10 +1516,10 @@ nat_t *nat;
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);
+ hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, nat->nat_inip.s_addr,
+ ipf_nattable_sz);
+ hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, nat->nat_outip.s_addr,
+ ipf_nattable_sz);
}
natp = &nat_table[0][hv1];
@@ -1581,25 +1605,36 @@ int dir;
else if (oip->ip_p == IPPROTO_UDP)
flags = IPN_UDP;
if (flags & IPN_TCPUDP) {
+ u_short data[2];
+ nat_t *nat;
+
minlen += 8; /* + 64bits of data to get ports */
if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
return NULL;
+
+ data[0] = fin->fin_data[0];
+ data[1] = fin->fin_data[1];
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
- if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
- else
- return nat_outlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
+ fin->fin_data[0] = ntohs(tcp->th_dport);
+ fin->fin_data[1] = ntohs(tcp->th_sport);
+
+ if (dir == NAT_INBOUND) {
+ nat = nat_inlookup(fin, flags, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
+ } else {
+ nat = nat_outlookup(fin, flags, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
+ }
+ fin->fin_data[0] = data[0];
+ fin->fin_data[1] = data[1];
+ return nat;
}
if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
+ return nat_inlookup(fin, 0, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
else
- return nat_outlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
+ return nat_outlookup(fin, 0, (u_int)oip->ip_p,
+ oip->ip_dst, oip->ip_src, 0);
}
@@ -1619,7 +1654,7 @@ int dir;
udphdr_t *udp;
nat_t *nat;
ip_t *oip;
- int flags = 0;
+ int flags;
if ((fin->fin_fl & FI_SHORT) || (fin->fin_off != 0))
return NULL;
@@ -1628,6 +1663,8 @@ int dir;
*/
if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir)))
return NULL;
+
+ flags = 0;
*nflags = IPN_ICMPERR;
icmp = (icmphdr_t *)fin->fin_dp;
oip = (ip_t *)&icmp->icmp_ip;
@@ -1917,23 +1954,32 @@ int dir;
* we're looking for a table entry, based on the destination address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
-nat_t *nat_inlookup(ifp, flags, p, src, mapdst, ports, rw)
-void *ifp;
+nat_t *nat_inlookup(fin, flags, p, src, mapdst, rw)
+fr_info_t *fin;
register u_int flags, p;
struct in_addr src , mapdst;
-u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
register int nflags;
register u_32_t dst;
+ ipnat_t *ipn;
+ void *ifp;
u_int hv;
+ if (fin != NULL)
+ ifp = fin->fin_ifp;
+ else
+ ifp = NULL;
dst = mapdst.s_addr;
- dport = ports >> 16;
- sport = ports & 0xffff;
- flags &= IPN_TCPUDP;
+ if (flags & IPN_TCPUDP) {
+ sport = htons(fin->fin_data[0]);
+ dport = htons(fin->fin_data[1]);
+ } else {
+ sport = 0;
+ dport = 0;
+ }
hv = NAT_HASH_FN(dst, dport, 0xffffffff);
hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz);
@@ -1943,19 +1989,34 @@ int rw;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == dst &&
- (((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
- ((nat->nat_outport == dport) || (nflags & FI_W_SPORT)))))
+ ((p == 0) || (p == nat->nat_p))) {
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ if (nat->nat_oport != sport)
+ continue;
+ if (nat->nat_outport != dport)
+ continue;
+ break;
+ default :
+ break;
+ }
+
+ ipn = nat->nat_ptr;
+ if ((ipn != NULL) && (nat->nat_aps != NULL))
+ if (appr_match(fin, nat) != 0)
+ continue;
return nat;
+ }
}
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
+ if (!nat_stats.ns_wilds || !(flags & FI_WILDP))
return NULL;
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
hv = NAT_HASH_FN(dst, 0, 0xffffffff);
- hv = NAT_HASH_FN(src.s_addr, hv, ipf_nattable_sz);
+ hv = NAT_HASH_FN(src.s_addr, dst, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -1964,8 +2025,6 @@ int rw;
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
if (!(nflags & FI_WILDP))
continue;
if (nat->nat_oip.s_addr != src.s_addr ||
@@ -1973,7 +2032,7 @@ int rw;
continue;
if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
- nat_tabmove(nat, ports);
+ nat_tabmove(fin, nat);
break;
}
}
@@ -1989,21 +2048,18 @@ int rw;
* original was placed in the table without hashing on the ports and we now
* want to include hashing on port numbers.
*/
-static void nat_tabmove(nat, ports)
+static void nat_tabmove(fin, nat)
+fr_info_t *fin;
nat_t *nat;
-u_32_t ports;
{
register u_short sport, dport;
+ u_int hv, nflags;
nat_t **natp;
- u_int hv;
- dport = ports >> 16;
- sport = ports & 0xffff;
+ nflags = nat->nat_flags;
- if (nat->nat_oport == dport) {
- nat->nat_inport = sport;
- nat->nat_outport = sport;
- }
+ sport = ntohs(fin->fin_data[0]);
+ dport = ntohs(fin->fin_data[1]);
/*
* Remove the NAT entry from the old location
@@ -2045,23 +2101,29 @@ u_32_t ports;
* we're looking for a table entry, based on the source address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
-nat_t *nat_outlookup(ifp, flags, p, src, dst, ports, rw)
-void *ifp;
+nat_t *nat_outlookup(fin, flags, p, src, dst, rw)
+fr_info_t *fin;
register u_int flags, p;
struct in_addr src , dst;
-u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
register int nflags;
+ ipnat_t *ipn;
u_32_t srcip;
+ void *ifp;
u_int hv;
- sport = ports & 0xffff;
- dport = ports >> 16;
- flags &= IPN_TCPUDP;
+ ifp = fin->fin_ifp;
srcip = src.s_addr;
+ if (flags & IPN_TCPUDP) {
+ sport = ntohs(fin->fin_data[0]);
+ dport = ntohs(fin->fin_data[1]);
+ } else {
+ sport = 0;
+ dport = 0;
+ }
hv = NAT_HASH_FN(srcip, sport, 0xffffffff);
hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz);
@@ -2072,19 +2134,34 @@ int rw;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
- (((p == 0) && (flags == (nflags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- ((nat->nat_inport == sport || nflags & FI_W_SPORT) &&
- (nat->nat_oport == dport || nflags & FI_W_DPORT))))
+ ((p == 0) || (p == nat->nat_p))) {
+ switch (p)
+ {
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ if (nat->nat_oport != dport)
+ continue;
+ if (nat->nat_inport != sport)
+ continue;
+ break;
+ default :
+ break;
+ }
+
+ ipn = nat->nat_ptr;
+ if ((ipn != NULL) && (nat->nat_aps != NULL))
+ if (appr_match(fin, nat) != 0)
+ continue;
return nat;
+ }
}
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
+ if (!nat_stats.ns_wilds || !(flags & FI_WILDP))
return NULL;
if (!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);
+
+ hv = NAT_HASH_FN(dst.s_addr, srcip, ipf_nattable_sz);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
@@ -2093,8 +2170,6 @@ int rw;
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
if (!(nflags & FI_WILDP))
continue;
if ((nat->nat_inip.s_addr != srcip) ||
@@ -2102,7 +2177,7 @@ int rw;
continue;
if (((nat->nat_inport == sport) || (nflags & FI_W_SPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_DPORT))) {
- nat_tabmove(nat, ports);
+ nat_tabmove(fin, nat);
break;
}
}
@@ -2119,16 +2194,19 @@ int rw;
nat_t *nat_lookupredir(np)
register natlookup_t *np;
{
- u_32_t ports;
nat_t *nat;
+ fr_info_t fi;
+
+ bzero((char *)&fi, sizeof(fi));
+ fi.fin_data[0] = np->nl_inport;
+ fi.fin_data[1] = np->nl_outport;
- ports = (np->nl_outport << 16) | np->nl_inport;
/*
* If nl_inip is non null, this is a lookup based on the real
* ip address. Else, we use the fake.
*/
- if ((nat = nat_outlookup(NULL, np->nl_flags, 0, np->nl_inip,
- np->nl_outip, ports, 0))) {
+ if ((nat = nat_outlookup(&fi, np->nl_flags, 0, np->nl_inip,
+ np->nl_outip, 0))) {
np->nl_realip = nat->nat_outip;
np->nl_realport = nat->nat_outport;
}
@@ -2146,7 +2224,7 @@ ip_t *ip;
if (ip->ip_v != 4)
return 0;
- if (np->in_p && ip->ip_p != np->in_p)
+ if (np->in_p && fin->fin_p != np->in_p)
return 0;
if (fin->fin_out) {
if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
@@ -2196,6 +2274,7 @@ fr_info_t *fin;
u_int nflags = 0, hv, msk;
struct ifnet *ifp;
frentry_t *fr;
+ void *sifp;
u_32_t iph;
nat_t *nat;
@@ -2203,15 +2282,17 @@ fr_info_t *fin;
return 0;
if ((fr = fin->fin_fr) && !(fr->fr_flags & FR_DUP) &&
- fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1)
- ifp = fr->fr_tif.fd_ifp;
- else
- ifp = fin->fin_ifp;
+ fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1) {
+ sifp = fin->fin_ifp;
+ fin->fin_ifp = fr->fr_tif.fd_ifp;
+ } else
+ sifp = fin->fin_ifp;
+ ifp = fin->fin_ifp;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if (ip->ip_p == IPPROTO_TCP)
+ if (fin->fin_p == IPPROTO_TCP)
nflags = IPN_TCP;
- else if (ip->ip_p == IPPROTO_UDP)
+ else if (fin->fin_p == IPPROTO_UDP)
nflags = IPN_UDP;
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
@@ -2220,27 +2301,28 @@ fr_info_t *fin;
}
}
- ipa = ip->ip_src.s_addr;
+ ipa = fin->fin_saddr;
READ_ENTER(&ipf_nat);
- if ((ip->ip_p == IPPROTO_ICMP) &&
+ if ((fin->fin_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
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,
- ip->ip_src, ip->ip_dst,
- (dport << 16) | sport, 0))) {
+ else if ((nat = nat_outlookup(fin, nflags|FI_WILDP|FI_WILDA,
+ (u_int)fin->fin_p, fin->fin_src,
+ fin->fin_dst, 0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nflags & FI_W_SPORT) &&
(nat->nat_inport != sport))
nat->nat_inport = sport;
- else if ((nflags & FI_W_DPORT) &&
- (nat->nat_oport != dport))
+ if ((nflags & FI_W_DPORT) &&
+ (nat->nat_oport != dport))
nat->nat_oport = dport;
+
if (nat->nat_outport == 0)
nat->nat_outport = sport;
nat->nat_flags &= ~(FI_W_DPORT|FI_W_SPORT);
@@ -2249,13 +2331,15 @@ fr_info_t *fin;
}
} else {
RWLOCK_EXIT(&ipf_nat);
+
+ msk = 0xffffffff;
+ i = 32;
+
WRITE_ENTER(&ipf_nat);
/*
* If there is no current entry in the nat table for this IP#,
* create one for it (if there is a matching rule).
*/
- msk = 0xffffffff;
- i = 32;
maskloop:
iph = ipa & htonl(msk);
hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
@@ -2271,22 +2355,13 @@ maskloop:
continue;
} else if ((ipa & np->in_inmsk) != np->in_inip)
continue;
- if (np->in_redir & (NAT_MAP|NAT_MAPBLK)) {
- if (*np->in_plabel && !appr_ok(ip, tcp, np))
- continue;
- /*
- * If it's a redirection, then we don't want to
- * create new outgoing port stuff.
- * Redirections are only for incoming
- * connections.
- */
- if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
- continue;
- if ((nat = nat_new(np, ip, fin, (u_int)nflags,
- NAT_OUTBOUND))) {
- np->in_hits++;
- break;
- }
+ if (*np->in_plabel && !appr_ok(ip, tcp, np))
+ continue;
+ nat = nat_new(fin, ip, np, NULL,
+ (u_int)nflags, NAT_OUTBOUND);
+ if (nat != NULL) {
+ np->in_hits++;
+ break;
}
}
if ((np == NULL) && (i > 0)) {
@@ -2308,7 +2383,14 @@ maskloop:
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;
+ if (fin->fin_p != IPPROTO_TCP) {
+ if (np && np->in_age[1])
+ nat->nat_age = np->in_age[1];
+ else if (!icmpset && (fin->fin_p == IPPROTO_ICMP))
+ nat->nat_age = fr_defnaticmpage;
+ else
+ nat->nat_age = fr_defnatage;
+ }
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
MUTEX_EXIT(&nat->nat_lock);
@@ -2320,16 +2402,16 @@ maskloop:
if (nflags == IPN_ICMPERR) {
u_32_t s1, s2, sumd;
- s1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
+ s1 = LONG_SUM(ntohl(fin->fin_saddr));
s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
CALC_SUMD(s1, s2, sumd);
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(fin, &ip->ip_sum, sumd);
- else
fix_outcksum(fin, &ip->ip_sum, sumd);
+ else
+ fix_incksum(fin, &ip->ip_sum, sumd);
}
-#if SOLARIS || defined(__sgi)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
else {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
@@ -2337,16 +2419,19 @@ maskloop:
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
}
#endif
+ /*
+ * Only change the packet contents, not what is filtered upon.
+ */
ip->ip_src = nat->nat_outip;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
+ if ((nat->nat_outport != 0) && (tcp != NULL)) {
tcp->th_sport = nat->nat_outport;
fin->fin_data[0] = ntohs(tcp->th_sport);
}
- if (ip->ip_p == IPPROTO_TCP) {
+ if (fin->fin_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
MUTEX_ENTER(&nat->nat_lock);
fr_tcp_age(&nat->nat_age,
@@ -2366,25 +2451,24 @@ maskloop:
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
MUTEX_EXIT(&nat->nat_lock);
- } else if (ip->ip_p == IPPROTO_UDP) {
+ } else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
- } else if (ip->ip_p == IPPROTO_ICMP) {
- if (!icmpset)
- nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(fin, csump, nat->nat_sumd[1]);
+ fix_outcksum(fin, csump,
+ nat->nat_sumd[1]);
else
- fix_incksum(fin, csump, nat->nat_sumd[1]);
+ fix_incksum(fin, csump,
+ nat->nat_sumd[1]);
}
}
- if ((np->in_apr != NULL) && (np->in_dport == 0 ||
+ if (np && (np->in_apr != NULL) && (np->in_dport == 0 ||
(tcp != NULL && dport == np->in_dport))) {
i = appr_check(ip, fin, nat);
if (i == 0)
@@ -2393,9 +2477,11 @@ maskloop:
i = 1;
ATOMIC_INCL(nat_stats.ns_mapped[1]);
RWLOCK_EXIT(&ipf_nat); /* READ */
+ fin->fin_ifp = sifp;
return i;
}
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
+ fin->fin_ifp = sifp;
return 0;
}
@@ -2423,37 +2509,36 @@ fr_info_t *fin;
return 0;
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if (ip->ip_p == IPPROTO_TCP)
+ if (fin->fin_p == IPPROTO_TCP)
nflags = IPN_TCP;
- else if (ip->ip_p == IPPROTO_UDP)
+ else if (fin->fin_p == IPPROTO_UDP)
nflags = IPN_UDP;
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
- dport = tcp->th_dport;
sport = tcp->th_sport;
+ dport = tcp->th_dport;
}
}
- in = ip->ip_dst;
+ in = fin->fin_dst;
/* make sure the source address is to be redirected */
- src = ip->ip_src;
+ src = fin->fin_src;
READ_ENTER(&ipf_nat);
- if ((ip->ip_p == IPPROTO_ICMP) &&
+ if ((fin->fin_p == IPPROTO_ICMP) &&
(nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND)))
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,
- ip->ip_src, in, (dport << 16) | sport,
- 0))) {
+ else if ((nat = nat_inlookup(fin, nflags|FI_WILDP|FI_WILDA,
+ (u_int)fin->fin_p, fin->fin_src, in, 0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT))
nat->nat_oport = sport;
- else if ((nat->nat_outport != dport) &&
+ if ((nat->nat_outport != dport) &&
(nflags & FI_W_SPORT))
nat->nat_outport = dport;
nat->nat_flags &= ~(FI_W_SPORT|FI_W_DPORT);
@@ -2462,19 +2547,21 @@ fr_info_t *fin;
}
} else {
RWLOCK_EXIT(&ipf_nat);
+
+ msk = 0xffffffff;
+ i = 32;
+
WRITE_ENTER(&ipf_nat);
/*
* If there is no current entry in the nat table for this IP#,
* create one for it (if there is a matching rule).
*/
- msk = 0xffffffff;
- i = 32;
maskloop:
iph = in.s_addr & htonl(msk);
hv = NAT_HASH_FN(iph, 0, ipf_rdrrules_sz);
for (np = rdr_rules[hv]; np; np = np->in_rnext) {
if ((np->in_ifp && (np->in_ifp != ifp)) ||
- (np->in_p && (np->in_p != ip->ip_p)) ||
+ (np->in_p && (np->in_p != fin->fin_p)) ||
(np->in_flags && !(nflags & np->in_flags)))
continue;
if (np->in_flags & IPN_FILTER) {
@@ -2482,11 +2569,10 @@ maskloop:
continue;
} else if ((in.s_addr & np->in_outmsk) != np->in_outip)
continue;
- if ((np->in_redir & NAT_REDIRECT) &&
- (!np->in_pmin || (np->in_flags & IPN_FILTER) ||
+ if ((!np->in_pmin || (np->in_flags & IPN_FILTER) ||
((ntohs(np->in_pmax) >= ntohs(dport)) &&
(ntohs(dport) >= ntohs(np->in_pmin)))))
- if ((nat = nat_new(np, ip, fin, nflags,
+ if ((nat = nat_new(fin, ip, np, NULL, nflags,
NAT_INBOUND))) {
np->in_hits++;
break;
@@ -2512,8 +2598,8 @@ maskloop:
fin->fin_fr = nat->nat_fr;
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))) {
+ if (np && (np->in_apr != NULL) && (np->in_dport == 0 ||
+ (tcp != NULL && sport == np->in_dport))) {
i = appr_check(ip, fin, nat);
if (i == -1) {
RWLOCK_EXIT(&ipf_nat);
@@ -2522,9 +2608,14 @@ maskloop:
}
MUTEX_ENTER(&nat->nat_lock);
- if (nflags != IPN_ICMPERR)
- nat->nat_age = fr_defnatage;
-
+ if (fin->fin_p != IPPROTO_TCP) {
+ if (np && np->in_age[0])
+ nat->nat_age = np->in_age[0];
+ else if (!icmpset && (fin->fin_p == IPPROTO_ICMP))
+ nat->nat_age = fr_defnaticmpage;
+ else
+ nat->nat_age = fr_defnatage;
+ }
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
MUTEX_EXIT(&nat->nat_lock);
@@ -2535,7 +2626,7 @@ maskloop:
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
-#if SOLARIS || defined(__sgi)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
else
@@ -2543,12 +2634,12 @@ maskloop:
#endif
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
- if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) {
+ if ((nat->nat_inport != 0) && (tcp != NULL)) {
tcp->th_dport = nat->nat_inport;
fin->fin_data[1] = ntohs(tcp->th_dport);
}
- if (ip->ip_p == IPPROTO_TCP) {
+ if (fin->fin_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
MUTEX_ENTER(&nat->nat_lock);
fr_tcp_age(&nat->nat_age,
@@ -2568,21 +2659,20 @@ maskloop:
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
MUTEX_EXIT(&nat->nat_lock);
- } else if (ip->ip_p == IPPROTO_UDP) {
+ } else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
- } else if (ip->ip_p == IPPROTO_ICMP) {
- if (!icmpset)
- nat->nat_age = fr_defnaticmpage;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(fin, csump, nat->nat_sumd[0]);
+ fix_incksum(fin, csump,
+ nat->nat_sumd[0]);
else
- fix_outcksum(fin, csump, nat->nat_sumd[0]);
+ fix_outcksum(fin, csump,
+ nat->nat_sumd[0]);
}
}
ATOMIC_INCL(nat_stats.ns_mapped[0]);
@@ -2757,3 +2847,13 @@ u_int type;
(void) ipllog(IPL_LOGNAT, NULL, items, sizes, types, 1);
}
#endif
+
+
+#if defined(__OpenBSD__)
+void nat_ifdetach(ifp)
+void *ifp;
+{
+ frsync();
+ return;
+}
+#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index f712dfcd9c5e2..4b2acc4852834 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -4,7 +4,7 @@
* 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.20 2001/06/26 10:43:15 darrenr Exp $
+ * $Id: ip_nat.h,v 2.17.2.25 2002/01/01 15:10:49 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -88,6 +88,7 @@ typedef struct nat {
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_phnext[2];
+ struct nat **nat_me;
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
@@ -118,6 +119,7 @@ typedef struct ipnat {
struct in_addr in_out[2];
struct in_addr in_src[2];
struct frtuc in_tuc;
+ u_int in_age[2]; /* Aging for NAT entries. Not for TCP */
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
char in_ifname[IFNAMSIZ];
char in_plabel[APR_LABELLEN]; /* proxy label */
@@ -286,23 +288,27 @@ extern nat_t **nat_table[2];
extern nat_t *nat_instances;
extern ipnat_t **nat_rules;
extern ipnat_t **rdr_rules;
+extern ipnat_t *nat_list;
extern natstat_t nat_stats;
+#if defined(__OpenBSD__)
+extern void nat_ifdetach __P((void *));
+#endif
#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
extern int nat_ioctl __P((caddr_t, u_long, int));
#else
extern int nat_ioctl __P((caddr_t, int, int));
#endif
extern int nat_init __P((void));
-extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
-extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
- struct in_addr));
+extern nat_t *nat_new __P((fr_info_t *, ip_t *, ipnat_t *, nat_t **,
+ u_int, int));
+extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
+ struct in_addr, int));
+extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
+ struct in_addr, int));
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmplookup __P((ip_t *, fr_info_t *, int));
extern nat_t *nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
+extern int nat_clearlist __P((void));
extern void nat_insert __P((nat_t *));
extern int ip_natout __P((ip_t *, fr_info_t *));
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 325f36259ec26..a4ce80a5da97e 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-2001 by Darren Reed.
+ * Copyright (C) 1997-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -7,6 +7,9 @@
# define _KERNEL
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -16,7 +19,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
-#include <sys/uio.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
@@ -65,34 +67,38 @@
#include "netinet/ip_compat.h"
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
# 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 $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.21 2002/03/06 09:44:14 darrenr Exp $";
#endif
+#if defined(_KERNEL) && (SOLARIS || defined(__sgi))
+extern KRWLOCK_T ipf_nat, ipf_state;
+#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
-static ap_session_t *appr_new_session __P((aproxy_t *, ip_t *,
- fr_info_t *, nat_t *));
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
#define AP_SESS_SIZE 53
-#if defined(_KERNEL) && !defined(linux)
+#if defined(_KERNEL)
#include "netinet/ip_ftp_pxy.c"
#include "netinet/ip_rcmd_pxy.c"
#include "netinet/ip_raudio_pxy.c"
+#include "netinet/ip_netbios_pxy.c"
+#include "netinet/ip_h323_pxy.c"
#endif
+#include "netinet/ip_ipsec_pxy.c"
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
@@ -100,20 +106,39 @@ aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
- ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
+ ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL },
#endif
#ifdef IPF_RCMD_PROXY
{ NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
- ippr_rcmd_new, NULL, ippr_rcmd_out },
+ ippr_rcmd_new, NULL, NULL, ippr_rcmd_out, NULL },
#endif
#ifdef IPF_RAUDIO_PROXY
{ NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
- ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
+ ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL },
+#endif
+#ifdef IPF_IPSEC_PROXY
+ { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, ippr_ipsec_init, NULL,
+ ippr_ipsec_new, ippr_ipsec_del, NULL, ippr_ipsec_out,
+ ippr_ipsec_match },
#endif
- { NULL, "", '\0', 0, 0, NULL, NULL }
+#ifdef IPF_NETBIOS_PROXY
+ { NULL, "netbios", (char)IPPROTO_TCP, 0, 0, ippr_netbios_init, NULL,
+ NULL, NULL, NULL, ippr_netbios_out, NULL },
+#endif
+#ifdef IPF_H323_PROXY
+ { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, NULL,
+ ippr_h323_new, ippr_h323_del, ippr_h323_in, ippr_h323_out, NULL },
+ { NULL, "h245", (char)IPPROTO_TCP, 0, 0, ippr_h245_init, NULL,
+ ippr_h245_new, NULL, NULL, ippr_h245_out, NULL },
+#endif
+ { NULL, "", '\0', 0, 0, NULL, NULL, NULL }
};
+/*
+ * Dynamically add a new kernel proxy. Ensure that it is unique in the
+ * collection compiled in and dynamically added.
+ */
int appr_add(ap)
aproxy_t *ap;
{
@@ -125,7 +150,7 @@ aproxy_t *ap;
sizeof(ap->apr_label)))
return -1;
- for (a = ap_proxylist; a->apr_p; a = a->apr_next)
+ for (a = ap_proxylist; a && a->apr_p; a = a->apr_next)
if ((a->apr_p == ap->apr_p) &&
!strncmp(a->apr_label, ap->apr_label,
sizeof(ap->apr_label)))
@@ -136,6 +161,11 @@ aproxy_t *ap;
}
+/*
+ * Delete a proxy that has been added dynamically from those available.
+ * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1
+ * if it cannot be matched.
+ */
int appr_del(ap)
aproxy_t *ap;
{
@@ -143,15 +173,19 @@ aproxy_t *ap;
for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
if (a == ap) {
+ a->apr_flags |= APR_DELETE;
+ *app = a->apr_next;
if (ap->apr_ref != 0)
return 1;
- *app = a->apr_next;
return 0;
}
return -1;
}
+/*
+ * Return 1 if the packet is a good match against a proxy, else 0.
+ */
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@@ -160,34 +194,64 @@ ipnat_t *nat;
aproxy_t *apr = nat->in_apr;
u_short dport = nat->in_dport;
- if (!apr || (apr->apr_flags & APR_DELETE) ||
+ if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
(ip->ip_p != apr->apr_p))
return 0;
- if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
+ if (((tcp != NULL) && (tcp->th_dport != dport)) || (!tcp && dport))
return 0;
return 1;
}
/*
+ * If a proxy has a match function, call that to do extended packet
+ * matching.
+ */
+int appr_match(fin, nat)
+fr_info_t *fin;
+nat_t *nat;
+{
+ aproxy_t *apr;
+ ipnat_t *ipn;
+
+ ipn = nat->nat_ptr;
+ if (ipn == NULL)
+ return -1;
+ apr = ipn->in_apr;
+ if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
+ (nat->nat_aps == NULL))
+ return -1;
+ if (apr->apr_match != NULL)
+ if ((*apr->apr_match)(fin, nat->nat_aps, nat) != 0)
+ return -1;
+ return 0;
+}
+
+
+/*
* Allocate a new application proxy structure and fill it in with the
* relevant details. call the init function once complete, prior to
* returning.
*/
-static ap_session_t *appr_new_session(apr, ip, fin, nat)
-aproxy_t *apr;
-ip_t *ip;
+int appr_new(fin, ip, nat)
fr_info_t *fin;
+ip_t *ip;
nat_t *nat;
{
register ap_session_t *aps;
+ aproxy_t *apr;
+
+ if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL))
+ return -1;
+
+ apr = nat->nat_ptr->in_apr;
if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p))
- return NULL;
+ return -1;
KMALLOC(aps, ap_session_t *);
if (!aps)
- return NULL;
+ return -1;
bzero((char *)aps, sizeof(*aps));
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
@@ -195,13 +259,18 @@ nat_t *nat;
aps->aps_psiz = 0;
if (apr->apr_new != NULL)
if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
+ if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) {
+ KFREES(aps->aps_data, aps->aps_psiz);
+ }
KFREE(aps);
- return NULL;
+ return -1;
}
aps->aps_nat = nat;
aps->aps_next = ap_sess_list;
ap_sess_list = aps;
- return aps;
+ nat->nat_aps = aps;
+
+ return 0;
}
@@ -225,9 +294,6 @@ nat_t *nat;
short rv;
int err;
- if (nat->nat_aps == NULL)
- nat->nat_aps = appr_new_session(nat->nat_ptr->in_apr, ip,
- fin, nat);
aps = nat->nat_aps;
if ((aps != NULL) && (aps->aps_p == ip->ip_p)) {
if (ip->ip_p == IPPROTO_TCP) {
@@ -263,8 +329,13 @@ nat_t *nat;
}
rv = APR_EXIT(err);
- if (rv == -1)
- return rv;
+ if (rv == 1)
+ return -1;
+ if (rv == 2) {
+ appr_free(apr);
+ nat->nat_aps = NULL;
+ return -1;
+ }
if (tcp != NULL) {
err = appr_fixseqack(fin, ip, aps, APR_INC(err));
@@ -283,7 +354,10 @@ nat_t *nat;
}
-aproxy_t *appr_match(pr, name)
+/*
+ * Search for an proxy by the protocol it is being used with and its name.
+ */
+aproxy_t *appr_lookup(pr, name)
u_int pr;
char *name;
{
@@ -317,6 +391,7 @@ void aps_free(aps)
ap_session_t *aps;
{
ap_session_t *a, **ap;
+ aproxy_t *apr;
if (!aps)
return;
@@ -327,6 +402,10 @@ ap_session_t *aps;
break;
}
+ apr = aps->aps_apr;
+ if ((apr != NULL) && (apr->apr_del != NULL))
+ (*apr->apr_del)(aps);
+
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
@@ -432,6 +511,10 @@ int inc;
}
+/*
+ * Initialise hook for kernel application proxies.
+ * Call the initialise routine for all the compiled in kernel proxies.
+ */
int appr_init()
{
aproxy_t *ap;
@@ -446,6 +529,10 @@ int appr_init()
}
+/*
+ * Unload hook for kernel application proxies.
+ * Call the finialise routine for all the compiled in kernel proxies.
+ */
void appr_unload()
{
aproxy_t *ap;
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index b8c8eb086caec..0f1ab8469b2d9 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_proxy.h,v 2.8.2.7 2001/06/26 10:43:16 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.8.2.12 2002/01/01 13:41:43 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -74,10 +74,12 @@ typedef struct aproxy {
void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
+ void (* apr_del) __P((ap_session_t *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_outpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
+ int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *));
} aproxy_t;
#define APR_DELETE 1
@@ -96,6 +98,7 @@ typedef struct ftpside {
u_32_t ftps_seq;
u_32_t ftps_len;
int ftps_junk;
+ int ftps_cmds;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
@@ -108,7 +111,7 @@ typedef struct ftpinfo {
/*
* Real audio proxy structure and #defines
*/
-typedef struct {
+typedef struct raudio_s {
int rap_seenpna;
int rap_seenver;
int rap_version;
@@ -136,6 +139,19 @@ typedef struct {
#define RAP_M_TCP 4
#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
+/*
+ * IPSec proxy
+ */
+typedef u_32_t ipsec_cookie_t[2];
+
+typedef struct ipsec_pxy {
+ ipsec_cookie_t ipsc_icookie;
+ ipsec_cookie_t ipsc_rcookie;
+ int ipsc_rckset;
+ ipnat_t ipsc_rule;
+ nat_t *ipsc_nat;
+ ipstate_t *ipsc_state;
+} ipsec_pxy_t;
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
@@ -147,9 +163,11 @@ extern int appr_del __P((aproxy_t *));
extern int appr_init __P((void));
extern void appr_unload __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
+extern int appr_match __P((fr_info_t *, struct nat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
-extern aproxy_t *appr_match __P((u_int, char *));
+extern aproxy_t *appr_lookup __P((u_int, char *));
+extern int appr_new __P((fr_info_t *, ip_t *, struct nat *));
#endif /* __IP_PROXY_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
index 476e15949f354..ddd5ea3014b4f 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.6 2001/07/23 04:17:56 darrenr Exp $
+ * $Id: ip_raudio_pxy.c,v 1.7.2.8 2002/01/13 04:58:29 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -78,7 +78,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
bzero(membuf, sizeof(membuf));
#if SOLARIS
m = fin->fin_qfm;
@@ -194,7 +194,7 @@ nat_t *nat;
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
@@ -283,11 +283,13 @@ nat_t *nat;
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
fi.fin_out = 0;
- ipn = nat_new(nat->nat_ptr, ip, &fi,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL,
IPN_UDP | (sp ? 0 : FI_W_SPORT), NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_IGNOREPKT|FI_NORULE|
+ (sp ? 0 : FI_W_SPORT));
}
}
@@ -298,11 +300,12 @@ nat_t *nat;
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,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_UDP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT|FI_NORULE);
}
}
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index d017cf94c1d69..641d303c023ec 100644
--- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
@@ -1,5 +1,5 @@
/*
- * $Id: ip_rcmd_pxy.c,v 1.4.2.4 2000/11/01 14:34:20 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.4.2.5 2001/10/30 16:38:14 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -82,10 +82,10 @@ nat_t *nat;
{
char portbuf[8], *s;
struct in_addr swip;
- u_short sp, dp;
int off, dlen;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
fr_info_t fi;
+ u_short sp;
nat_t *ipn;
mb_t *m;
#if SOLARIS
@@ -103,7 +103,7 @@ nat_t *nat;
(tcp->th_seq != *(u_32_t *)aps->aps_data))
return 0;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
+ off = fin->fin_hlen + (tcp->th_off << 2);
#if SOLARIS
m = fin->fin_qfm;
@@ -128,33 +128,33 @@ nat_t *nat;
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
- sp = htons(sp);
- dp = htons(fin->fin_data[1]);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_data[0] = sp;
+ fi.fin_data[1] = fin->fin_data[1];
+ ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+ ip->ip_dst, 0);
if (ipn == NULL) {
int slen;
slen = ip->ip_len;
ip->ip_len = fin->fin_hlen + sizeof(*tcp);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
+ tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_off = 5;
- fi.fin_data[0] = ntohs(sp);
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_dlen = sizeof(*tcp2);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
+ ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
fi.fin_fr = &rcmdfr;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
+ (void) fr_addstate(ip, &fi, NULL,
+ FI_W_DPORT|FI_IGNOREPKT);
}
ip->ip_len = slen;
ip->ip_src = swip;
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 649ad939ddf8b..255bdad61f754 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 1995-2001 by Darren Reed.
+ * Copyright (C) 1995-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -35,7 +38,6 @@
# include <sys/ioctl.h>
#endif
#include <sys/time.h>
-#include <sys/uio.h>
#ifndef linux
# include <sys/protosw.h>
#endif
@@ -77,7 +79,6 @@
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_state.h"
#ifdef USE_INET6
#include <netinet/icmp6.h>
@@ -92,7 +93,7 @@
#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 $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.61 2002/03/06 14:07:36 darrenr Exp $";
#endif
#ifndef MIN
@@ -102,7 +103,6 @@ static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.38 2001/07/23 13:49:46
#define TCP_CLOSE (TH_FIN|TH_RST)
static ipstate_t **ips_table = NULL;
-static ipstate_t *ips_list = NULL;
static int ips_num = 0;
static int ips_wild = 0;
static ips_stat_t ips_stats;
@@ -145,8 +145,12 @@ int fr_statemax = IPSTATE_MAX,
fr_statesize = IPSTATE_SIZE;
int fr_state_doflush = 0,
fr_state_lock = 0;
+ipstate_t *ips_list = NULL;
static int icmpreplytype4[ICMP_MAXTYPE + 1];
+#ifdef USE_INET6
+static int icmpreplytype6[ICMP6_MAXTYPE + 1];
+#endif
int fr_stateinit()
{
@@ -165,6 +169,16 @@ int fr_stateinit()
icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY;
icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY;
icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY;
+#ifdef USE_INET6
+ /* fill icmp reply type table */
+ for (i = 0; i <= ICMP6_MAXTYPE; i++)
+ icmpreplytype6[i] = -1;
+ icmpreplytype6[ICMP6_ECHO_REQUEST] = ICMP6_ECHO_REPLY;
+ icmpreplytype6[ICMP6_MEMBERSHIP_QUERY] = ICMP6_MEMBERSHIP_REPORT;
+ icmpreplytype6[ICMP6_NI_QUERY] = ICMP6_NI_REPLY;
+ icmpreplytype6[ND_ROUTER_SOLICIT] = ND_ROUTER_ADVERT;
+ icmpreplytype6[ND_NEIGHBOR_SOLICIT] = ND_NEIGHBOR_ADVERT;
+#endif
return 0;
}
@@ -184,15 +198,18 @@ static ips_stat_t *fr_statetstats()
* which == 0 : flush all state table entries
* which == 1 : flush TCP connections which have started to close but are
* stuck for some reason.
+ * which == 2 : flush TCP connections which have been idle for a long time,
+ * starting at > 4 days idle and working back in successive half-
+ * days to at most 12 hours old.
*/
static int fr_state_flush(which)
int which;
{
- register ipstate_t *is, **isp;
+ ipstate_t *is, **isp;
#if defined(_KERNEL) && !SOLARIS
int s;
#endif
- int delete, removed = 0;
+ int delete, removed = 0, try;
SPL_NET(s);
for (isp = &ips_list; (is = *isp); ) {
@@ -204,6 +221,7 @@ int which;
delete = 1;
break;
case 1 :
+ case 2 :
if (is->is_p != IPPROTO_TCP)
break;
if ((is->is_state[0] != TCPS_ESTABLISHED) ||
@@ -225,6 +243,40 @@ int which;
} else
isp = &is->is_next;
}
+
+ /*
+ * Asked to remove inactive entries, try again if first attempt
+ * failed. In this case, 86400 is half a day because the counter is
+ * activated every half second.
+ */
+ if ((which == 2) && (removed == 0)) {
+ try = 86400; /* half a day */
+ for (; (try < FIVE_DAYS) && (removed == 0); try += 86400) {
+ for (isp = &ips_list; (is = *isp); ) {
+ delete = 0;
+ if ((is->is_p == IPPROTO_TCP) &&
+ ((is->is_state[0] == TCPS_ESTABLISHED) ||
+ (is->is_state[1] == TCPS_ESTABLISHED)) &&
+ (is->is_age < try)) {
+ ips_stats.iss_fin++;
+ delete = 1;
+ } else if ((is->is_p != IPPROTO_TCP) &&
+ (is->is_pkts > 1)) {
+ ips_stats.iss_expire++;
+ delete = 1;
+ }
+ if (delete) {
+#ifdef IPFILTER_LOG
+ ipstate_log(is, ISL_FLUSH);
+#endif
+ fr_delstate(is);
+ removed++;
+ } else
+ isp = &is->is_next;
+ }
+ }
+ }
+
SPL_X(s);
return removed;
}
@@ -337,19 +389,19 @@ int mode;
}
+/*
+ * Copy out state information from the kernel to a user space process.
+ */
int fr_stgetent(data)
caddr_t data;
{
register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
+ ipstate_save_t ips;
int error;
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
+ error = IRCOPYPTR(data, (caddr_t)&ips, sizeof(ips));
if (error)
- return EFAULT;
+ return error;
isn = ips.ips_next;
if (!isn) {
@@ -376,7 +428,7 @@ caddr_t data;
if (isn->is_rule)
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
+ error = IWCOPYPTR((caddr_t)&ips, data, sizeof(ips));
if (error)
error = EFAULT;
return error;
@@ -387,16 +439,14 @@ int fr_stputent(data)
caddr_t data;
{
register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
- int error, out;
+ ipstate_save_t ips;
+ int error, out, i;
frentry_t *fr;
+ char *name;
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
+ error = IRCOPYPTR(data, (caddr_t)&ips, sizeof(ips));
if (error)
- return EFAULT;
+ return error;
KMALLOC(isn, ipstate_t *);
if (isn == NULL)
@@ -415,24 +465,34 @@ caddr_t data;
out = fr->fr_flags & FR_OUTQUE ? 1 : 0;
isn->is_rule = fr;
ips.ips_is.is_rule = fr;
- if (*fr->fr_ifname) {
- fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_v);
- if (fr->fr_ifa == NULL)
- fr->fr_ifa = (void *)-1;
-#ifdef _KERNEL
- else {
- strncpy(isn->is_ifname[out],
- IFNAME(fr->fr_ifa), IFNAMSIZ);
- isn->is_ifp[out] = fr->fr_ifa;
+
+ /*
+ * Look up all the interface names in the rule.
+ */
+ for (i = 0; i < 4; i++) {
+ name = fr->fr_ifnames[i];
+ if ((name[1] == '\0') &&
+ ((name[0] == '-') || (name[0] == '*'))) {
+ fr->fr_ifas[i] = NULL;
+ } else if (*name != '\0') {
+ fr->fr_ifas[i] = GETUNIT(name,
+ fr->fr_v);
+ if (fr->fr_ifas[i] == NULL)
+ fr->fr_ifas[i] = (void *)-1;
+ else {
+ strncpy(isn->is_ifname[i],
+ IFNAME(fr->fr_ifas[i]),
+ IFNAMSIZ);
+ }
}
-#endif
- } else
- fr->fr_ifa = NULL;
+ isn->is_ifp[out] = fr->fr_ifas[i];
+ }
+
/*
* send a copy back to userland of what we ended up
* to allow for verification.
*/
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
+ error = IWCOPYPTR((caddr_t)&ips, data, sizeof(ips));
if (error) {
KFREE(isn);
KFREE(fr);
@@ -453,22 +513,34 @@ caddr_t data;
}
+/*
+ * Insert a state table entry manually.
+ */
void fr_stinsert(is)
register ipstate_t *is;
{
register u_int hv = is->is_hv;
+ char *name;
+ int i;
MUTEX_INIT(&is->is_lock, "ipf state entry", NULL);
- is->is_ifname[0][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[0][0] != '\0') {
- is->is_ifp[0] = GETUNIT(is->is_ifname[0], is->is_v);
- }
- is->is_ifname[1][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[1][0] != '\0') {
- is->is_ifp[1] = GETUNIT(is->is_ifname[1], is->is_v);
+ /*
+ * Look up all the interface names in the state entry.
+ */
+ for (i = 0; i < 4; i++) {
+ name = is->is_ifname[i];
+ if ((name[1] == '\0') &&
+ ((name[0] == '-') || (name[0] == '*'))) {
+ is->is_ifp[0] = NULL;
+ } else if (*name != '\0') {
+ is->is_ifp[i] = GETUNIT(name, is->is_v);
+ if (is->is_ifp[i] == NULL)
+ is->is_ifp[i] = (void *)-1;
+ }
}
+
/*
* add into list table.
*/
@@ -491,16 +563,19 @@ register ipstate_t *is;
/*
* Create a new ipstate structure and hang it off the hash table.
*/
-ipstate_t *fr_addstate(ip, fin, flags)
+ipstate_t *fr_addstate(ip, fin, stsave, flags)
ip_t *ip;
fr_info_t *fin;
+ipstate_t **stsave;
u_int flags;
{
register tcphdr_t *tcp = NULL;
register ipstate_t *is;
register u_int hv;
+ struct icmp *ic;
ipstate_t ips;
u_int pass;
+ void *ifp;
int out;
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
@@ -514,8 +589,6 @@ u_int flags;
is = &ips;
bzero((char *)is, sizeof(*is));
ips.is_age = 1;
- ips.is_state[0] = 0;
- ips.is_state[1] = 0;
/*
* Copy and calculate...
*/
@@ -526,14 +599,21 @@ u_int flags;
hv += is->is_daddr;
#ifdef USE_INET6
if (fin->fin_v == 6) {
- if (is->is_p == IPPROTO_ICMPV6) {
- if (IN6_IS_ADDR_MULTICAST(&is->is_dst.in6))
- flags |= FI_W_DADDR;
- if (out)
- hv -= is->is_daddr;
- else
- hv -= is->is_saddr;
+ if ((is->is_p == IPPROTO_ICMPV6) &&
+ IN6_IS_ADDR_MULTICAST(&is->is_dst.in6)) {
+ /*
+ * So you can do keep state with neighbour discovery.
+ */
+ flags |= FI_W_DADDR;
+ hv -= is->is_daddr;
+ } else {
+ hv += is->is_dst.i6[1];
+ hv += is->is_dst.i6[2];
+ hv += is->is_dst.i6[3];
}
+ hv += is->is_src.i6[1];
+ hv += is->is_src.i6[2];
+ hv += is->is_src.i6[3];
}
#endif
@@ -541,30 +621,35 @@ u_int flags;
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
-#endif
- case IPPROTO_ICMP :
- {
- struct icmp *ic = (struct icmp *)fin->fin_dp;
-
-#ifdef USE_INET6
- if ((is->is_p == IPPROTO_ICMPV6) &&
- ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0))
+ ic = (struct icmp *)fin->fin_dp;
+ if ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0)
return NULL;
-#endif
+
switch (ic->icmp_type)
{
-#ifdef USE_INET6
case ICMP6_ECHO_REQUEST :
- is->is_icmp.ics_type = ICMP6_ECHO_REPLY;
+ is->is_icmp.ics_type = ic->icmp_type;
hv += (is->is_icmp.ics_id = ic->icmp_id);
hv += (is->is_icmp.ics_seq = ic->icmp_seq);
break;
case ICMP6_MEMBERSHIP_QUERY :
case ND_ROUTER_SOLICIT :
case ND_NEIGHBOR_SOLICIT :
- is->is_icmp.ics_type = ic->icmp_type + 1;
+ case ICMP6_NI_QUERY :
+ is->is_icmp.ics_type = ic->icmp_type;
break;
+ default :
+ return NULL;
+ }
+ ATOMIC_INCL(ips_stats.iss_icmp);
+ is->is_age = fr_icmptimeout;
+ break;
#endif
+ case IPPROTO_ICMP :
+ ic = (struct icmp *)fin->fin_dp;
+
+ switch (ic->icmp_type)
+ {
case ICMP_ECHO :
case ICMP_TSTAMP :
case ICMP_IREQ :
@@ -579,9 +664,7 @@ u_int flags;
ATOMIC_INCL(ips_stats.iss_icmp);
is->is_age = fr_icmptimeout;
break;
- }
case IPPROTO_TCP :
- {
tcp = (tcphdr_t *)fin->fin_dp;
if (tcp->th_flags & TH_RST)
@@ -590,11 +673,11 @@ u_int flags;
* The endian of the ports doesn't matter, but the ack and
* sequence numbers do as we do mathematics on them later.
*/
- is->is_dport = tcp->th_dport;
- is->is_sport = tcp->th_sport;
+ is->is_sport = htons(fin->fin_data[0]);
+ is->is_dport = htons(fin->fin_data[1]);
if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
- hv += tcp->th_dport;
- hv += tcp->th_sport;
+ hv += is->is_sport;
+ hv += is->is_dport;
}
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
(tcp->th_off << 2) +
@@ -613,23 +696,22 @@ u_int flags;
*/
ATOMIC_INCL(ips_stats.iss_tcp);
break;
- }
+
case IPPROTO_UDP :
- {
tcp = (tcphdr_t *)fin->fin_dp;
- is->is_dport = tcp->th_dport;
- is->is_sport = tcp->th_sport;
+ is->is_sport = htons(fin->fin_data[0]);
+ is->is_dport = htons(fin->fin_data[1]);
if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
- hv += tcp->th_dport;
- hv += tcp->th_sport;
+ hv += is->is_sport;
+ hv += is->is_dport;
}
ATOMIC_INCL(ips_stats.iss_udp);
is->is_age = fr_udptimeout;
break;
- }
default :
- return NULL;
+ is->is_age = fr_udptimeout;
+ break;
}
KMALLOC(is, ipstate_t *);
@@ -644,19 +726,47 @@ u_int flags;
if (is->is_rule != NULL) {
ATOMIC_INC32(is->is_rule->fr_ref);
pass = is->is_rule->fr_flags;
+ is->is_frage[0] = is->is_rule->fr_age[0];
+ is->is_frage[1] = is->is_rule->fr_age[1];
+ if (is->is_frage[0] != 0)
+ is->is_age = is->is_frage[0];
+
+ is->is_ifp[(out << 1) + 1] = is->is_rule->fr_ifas[1];
+ is->is_ifp[(1 - out) << 1] = is->is_rule->fr_ifas[2];
+ is->is_ifp[((1 - out) << 1) + 1] = is->is_rule->fr_ifas[3];
+
+ if (((ifp = is->is_rule->fr_ifas[1]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[(out << 1) + 1],
+ IFNAME(ifp), IFNAMSIZ);
+ if (((ifp = is->is_rule->fr_ifas[2]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[(1 - out) << 1],
+ IFNAME(ifp), IFNAMSIZ);
+ if (((ifp = is->is_rule->fr_ifas[3]) != NULL) &&
+ (ifp != (void *)-1))
+ strncpy(is->is_ifname[((1 - out) << 1) + 1],
+ IFNAME(ifp), IFNAMSIZ);
} else
pass = fr_flags;
+
+ is->is_ifp[out << 1] = fin->fin_ifp;
+ strncpy(is->is_ifname[out << 1], IFNAME(fin->fin_ifp), IFNAMSIZ);
+
WRITE_ENTER(&ipf_state);
is->is_pass = pass;
- is->is_pkts = 1;
- is->is_bytes = fin->fin_dlen + fin->fin_hlen;
+ if ((flags & FI_IGNOREPKT) == 0) {
+ is->is_pkts = 1;
+ is->is_bytes = fin->fin_dlen + fin->fin_hlen;
+ }
/*
* We want to check everything that is a property of this packet,
* but we don't (automatically) care about it's fragment status as
* this may change.
*/
- is->is_v = fin->fin_fi.fi_v;
+ is->is_v = fin->fin_v;
+ is->is_rulen = fin->fin_rule;
is->is_opt = fin->fin_fi.fi_optmsk;
is->is_optmsk = 0xffffffff;
is->is_sec = fin->fin_fi.fi_secmsk;
@@ -668,20 +778,14 @@ u_int flags;
is->is_flags |= flags & (FI_WILDP|FI_WILDA);
if (flags & (FI_WILDP|FI_WILDA))
ips_wild++;
- is->is_ifp[1 - out] = NULL;
- is->is_ifp[out] = fin->fin_ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- is->is_ifname[1 - out][0] = '\0';
+
if (pass & FR_LOGFIRST)
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
fr_stinsert(is);
+ is->is_me = stsave;
if (is->is_p == IPPROTO_TCP) {
- MUTEX_ENTER(&is->is_lock);
fr_tcp_age(&is->is_age, is->is_state, fin,
0); /* 0 = packet from the source */
- MUTEX_EXIT(&is->is_lock);
}
#ifdef IPFILTER_LOG
ipstate_log(is, ISL_NEW);
@@ -801,19 +905,25 @@ tcphdr_t *tcp;
}
+/*
+ * Match a state table entry against an IP packet.
+ */
static int fr_matchsrcdst(is, src, dst, fin, tcp)
ipstate_t *is;
union i6addr src, dst;
fr_info_t *fin;
tcphdr_t *tcp;
{
- int ret = 0, rev, out, flags;
+ int ret = 0, rev, out, flags, idx;
u_short sp, dp;
void *ifp;
rev = IP6NEQ(is->is_dst, dst);
ifp = fin->fin_ifp;
out = fin->fin_out;
+ flags = is->is_flags & (FI_WILDA|FI_WILDP);
+ sp = 0;
+ dp = 0;
if (tcp != NULL) {
flags = is->is_flags;
@@ -825,44 +935,28 @@ tcphdr_t *tcp;
else if (!(flags & FI_W_DPORT) && (dp != is->is_dport))
rev = 1;
}
- } else {
- flags = is->is_flags & FI_WILDA;
- sp = 0;
- dp = 0;
}
- if (rev == 0) {
- if (!out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- } else {
- if (out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- }
+ idx = (out << 1) + rev;
+
+ if ((is->is_ifp[idx] == NULL &&
+ (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) ||
+ is->is_ifp[idx] == ifp)
+ ret = 1;
+
if (ret == 0)
return 0;
ret = 0;
if (rev == 0) {
- if (
- (IP6EQ(is->is_dst, dst) || (flags & FI_W_DADDR)) &&
+ if ((IP6EQ(is->is_dst, dst) || (flags & FI_W_DADDR)) &&
(IP6EQ(is->is_src, src) || (flags & FI_W_SADDR)) &&
(!tcp || ((sp == is->is_sport || flags & FI_W_SPORT) &&
(dp == is->is_dport || flags & FI_W_DPORT)))) {
ret = 1;
}
} else {
- if (
- (IP6EQ(is->is_dst, src) || (flags & FI_W_DADDR)) &&
+ if ((IP6EQ(is->is_dst, src) || (flags & FI_W_DADDR)) &&
(IP6EQ(is->is_src, dst) || (flags & FI_W_SADDR)) &&
(!tcp || ((sp == is->is_dport || flags & FI_W_DPORT) &&
(dp == is->is_sport || flags & FI_W_SPORT)))) {
@@ -885,6 +979,26 @@ tcphdr_t *tcp;
(fin->fin_fi.fi_auth != is->is_auth))
return 0;
+ flags = is->is_flags & (FI_WILDA|FI_WILDP);
+ if ((flags & (FI_W_SADDR|FI_W_DADDR))) {
+ if ((flags & FI_W_SADDR) != 0) {
+ if (rev == 0) {
+ is->is_src = fin->fin_fi.fi_src;
+ } else {
+ is->is_src = fin->fin_fi.fi_dst;
+ }
+ } else if ((flags & FI_W_DPORT) != 0) {
+ if (rev == 0) {
+ is->is_dst = fin->fin_fi.fi_dst;
+ } else {
+ is->is_dst = fin->fin_fi.fi_src;
+ }
+ }
+ is->is_flags &= ~(FI_W_SADDR|FI_W_DADDR);
+ if ((is->is_flags & (FI_WILDA|FI_WILDP)) == 0)
+ ips_wild--;
+ }
+
if ((flags & (FI_W_SPORT|FI_W_DPORT))) {
if ((flags & FI_W_SPORT) != 0) {
if (rev == 0) {
@@ -911,30 +1025,14 @@ tcphdr_t *tcp;
ret = -1;
- if (!rev) {
- if (out) {
- if (!is->is_ifpout)
- ret = 1;
- } else {
- if (!is->is_ifpin)
- ret = 0;
- }
- } else {
- if (out) {
- if (!is->is_ifpin)
- ret = 0;
- } else {
- if (!is->is_ifpout)
- ret = 1;
- }
- }
+ if (is->is_ifp[idx] == NULL &&
+ (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*'))
+ ret = idx;
if (ret >= 0) {
is->is_ifp[ret] = ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[ret], IFNAME(fin->fin_ifp),
+ strncpy(is->is_ifname[ret], IFNAME(ifp),
sizeof(is->is_ifname[ret]));
-#endif
}
fin->fin_rev = rev;
return 1;
@@ -951,20 +1049,24 @@ icmphdr_t *icmp;
* it will still be the same type.
*/
if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype4[is->is_type] == icmp->icmp_type)) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
+ (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
+ if (icmp->icmp_type != ICMP_ECHOREPLY)
+ return 1;
+ if ((icmp->icmp_id == is->is_icmp.ics_id) &&
+ (icmp->icmp_seq == is->is_icmp.ics_seq))
+ return 1;
+ }
}
#ifdef USE_INET6
else if (is->is_v == 6) {
- if ((is->is_type == ICMP6_ECHO_REPLY) &&
- (icmp->icmp_type == ICMP6_ECHO_REQUEST) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
+ if (((icmp->icmp_type == is->is_type) ||
+ (icmpreplytype6[is->is_type] == icmp->icmp_type))) {
+ if (icmp->icmp_type != ICMP6_ECHO_REPLY)
+ return 1;
+ if ((icmp->icmp_id == is->is_icmp.ics_id) &&
+ (icmp->icmp_seq == is->is_icmp.ics_seq))
+ return 1;
+ }
}
#endif
return 0;
@@ -996,6 +1098,7 @@ fr_info_t *fin;
if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
(fin->fin_plen < ICMPERR_MINPKTLEN))
return NULL;
+
ic = (struct icmp *)fin->fin_dp;
type = ic->icmp_type;
/*
@@ -1049,8 +1152,11 @@ fr_info_t *fin;
*/
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
+ fr = NULL;
- if (oip->ip_p == IPPROTO_ICMP) {
+ switch (oip->ip_p)
+ {
+ case IPPROTO_ICMP :
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
/*
@@ -1096,15 +1202,17 @@ fr_info_t *fin;
is->is_pkts++;
is->is_bytes += ip->ip_len;
fr = is->is_rule;
- RWLOCK_EXIT(&ipf_state);
- return fr;
+ break;
}
RWLOCK_EXIT(&ipf_state);
+ return fr;
+
+ case IPPROTO_TCP :
+ case IPPROTO_UDP :
+ break;
+ default :
return NULL;
- };
-
- if ((oip->ip_p != IPPROTO_TCP) && (oip->ip_p != IPPROTO_UDP))
- return NULL;
+ }
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
dport = tcp->th_dport;
@@ -1156,15 +1264,18 @@ fr_info_t *fin;
* for the accompanying state table entry.
* It remains to be seen if that is correct. XXX
*/
- RWLOCK_EXIT(&ipf_state);
- return fr;
+ break;
}
}
RWLOCK_EXIT(&ipf_state);
- return NULL;
+ return fr;
}
+/*
+ * Move a state hash table entry from its old location at is->is_hv to
+ * its new location, indexed by hv % fr_statesize.
+ */
static void fr_ipsmove(isp, is, hv)
ipstate_t **isp, *is;
u_int hv;
@@ -1211,6 +1322,7 @@ fr_info_t *fin;
struct icmp *ic;
frentry_t *fr;
tcphdr_t *tcp;
+ int rev;
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
return NULL;
@@ -1227,42 +1339,113 @@ fr_info_t *fin;
/*
* Search the hash table for matching packet header info.
+ * At the bottom of this switch statement, the following is expected:
+ * is == NULL, no lock on ipf_state is held.
+ * is != NULL, a lock on ipf_state is held.
*/
v = fin->fin_fi.fi_v;
- switch (fin->fin_fi.fi_p)
+#ifdef USE_INET6
+ if (v == 6) {
+ hv += fin->fin_fi.fi_src.i6[1];
+ hv += fin->fin_fi.fi_src.i6[2];
+ hv += fin->fin_fi.fi_src.i6[3];
+
+ if ((fin->fin_p == IPPROTO_ICMPV6) &&
+ IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_dst.in6)) {
+ hv -= dst.in4.s_addr;
+ } else {
+ hv += fin->fin_fi.fi_dst.i6[1];
+ hv += fin->fin_fi.fi_dst.i6[2];
+ hv += fin->fin_fi.fi_dst.i6[3];
+ }
+ }
+#endif
+
+ switch (fin->fin_p)
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
+ tcp = NULL;
+ tryagain = 0;
if (v == 6) {
- if (fin->fin_out)
- hv -= dst.in4.s_addr;
- else
- hv -= src.in4.s_addr;
if ((ic->icmp_type == ICMP6_ECHO_REQUEST) ||
(ic->icmp_type == ICMP6_ECHO_REPLY)) {
hv += ic->icmp_id;
hv += ic->icmp_seq;
}
}
+ READ_ENTER(&ipf_state);
+icmp6again:
+ hvm = hv % fr_statesize;
+ for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
+ if ((is->is_p == pr) && (is->is_v == v) &&
+ fr_matchsrcdst(is, src, dst, fin, NULL) &&
+ fr_matchicmpqueryreply(v, is, ic)) {
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
+ is->is_age = fr_icmpacktimeout;
+ else
+ is->is_age = fr_icmptimeout;
+ break;
+ }
+
+ if (is != NULL) {
+ if (tryagain && !(is->is_flags & FI_W_DADDR)) {
+ hv += fin->fin_fi.fi_src.i6[0];
+ hv += fin->fin_fi.fi_src.i6[1];
+ hv += fin->fin_fi.fi_src.i6[2];
+ hv += fin->fin_fi.fi_src.i6[3];
+ fr_ipsmove(isp, is, hv);
+ MUTEX_DOWNGRADE(&ipf_state);
+ }
+ break;
+ }
+ RWLOCK_EXIT(&ipf_state);
+
+ /*
+ * No matching icmp state entry. Perhaps this is a
+ * response to another state entry.
+ */
+ if ((ips_wild != 0) && (v == 6) && (tryagain == 0) &&
+ !IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_src.in6)) {
+ hv -= fin->fin_fi.fi_src.i6[0];
+ hv -= fin->fin_fi.fi_src.i6[1];
+ hv -= fin->fin_fi.fi_src.i6[2];
+ hv -= fin->fin_fi.fi_src.i6[3];
+ tryagain = 1;
+ WRITE_ENTER(&ipf_state);
+ goto icmp6again;
+ }
+
+ fr = fr_checkicmp6matchingstate((ip6_t *)ip, fin);
+ if (fr)
+ return fr;
+ break;
#endif
case IPPROTO_ICMP :
+ tcp = NULL;
if (v == 4) {
hv += ic->icmp_id;
hv += ic->icmp_seq;
}
- hv %= fr_statesize;
+ hvm = hv % fr_statesize;
READ_ENTER(&ipf_state);
- for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
+ for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, NULL) &&
fr_matchicmpqueryreply(v, is, ic)) {
- if (fin->fin_rev)
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
is->is_age = fr_icmpacktimeout;
else
is->is_age = fr_icmptimeout;
break;
}
- }
+
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
@@ -1270,28 +1453,21 @@ fr_info_t *fin;
* No matching icmp state entry. Perhaps this is a
* response to another state entry.
*/
-#ifdef USE_INET6
- if (v == 6)
- fr = fr_checkicmp6matchingstate((ip6_t *)ip, fin);
- else
-#endif
- fr = fr_checkicmpmatchingstate(ip, fin);
+ fr = fr_checkicmpmatchingstate(ip, fin);
if (fr)
return fr;
break;
case IPPROTO_TCP :
- {
- register u_short dport, sport;
- register int i;
-
- i = tcp->th_flags;
/*
* Just plain ignore RST flag set with either FIN or SYN.
*/
- if ((i & TH_RST) &&
- ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
+ if ((tcp->th_flags & TH_RST) &&
+ ((tcp->th_flags & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
break;
case IPPROTO_UDP :
+ {
+ register u_short dport, sport;
+
dport = tcp->th_dport;
sport = tcp->th_sport;
tryagain = 0;
@@ -1303,12 +1479,15 @@ retry_tcpudp:
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
+ rev = fin->fin_rev;
if ((pr == IPPROTO_TCP)) {
if (!fr_tcpstate(is, fin, ip, tcp)) {
continue;
}
} else if ((pr == IPPROTO_UDP)) {
- if (fin->fin_rev)
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else if (fin->fin_rev)
is->is_age = fr_udpacktimeout;
else
is->is_age = fr_udptimeout;
@@ -1336,47 +1515,74 @@ retry_tcpudp:
break;
}
default :
+ tcp = NULL;
+ hv %= fr_statesize;
+ READ_ENTER(&ipf_state);
+ for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
+ if ((is->is_p == pr) && (is->is_v == v) &&
+ fr_matchsrcdst(is, src, dst, fin, NULL)) {
+ rev = fin->fin_rev;
+ if (is->is_frage[rev] != 0)
+ is->is_age = is->is_frage[rev];
+ else
+ is->is_age = fr_udptimeout;
+ break;
+ }
+ }
+ if (is == NULL) {
+ RWLOCK_EXIT(&ipf_state);
+ }
break;
}
+
if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_miss);
return NULL;
}
+
MUTEX_ENTER(&is->is_lock);
is->is_bytes += fin->fin_plen;
ips_stats.iss_hits++;
is->is_pkts++;
MUTEX_EXIT(&is->is_lock);
fr = is->is_rule;
+ fin->fin_rule = is->is_rulen;
+ if (fr != NULL) {
+ fin->fin_group = fr->fr_group;
+ fin->fin_icode = fr->fr_icode;
+ }
fin->fin_fr = fr;
pass = is->is_pass;
-#ifndef _KERNEL
- if (tcp->th_flags & TCP_CLOSE)
- fr_delstate(is);
-#endif
RWLOCK_EXIT(&ipf_state);
if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
+#ifndef _KERNEL
+ if ((tcp != NULL) && (tcp->th_flags & TCP_CLOSE))
+ fr_delstate(is);
+#endif
return fr;
}
+/*
+ * Sync. state entries. If interfaces come or go or just change position,
+ * this is needed.
+ */
void ip_statesync(ifp)
void *ifp;
{
register ipstate_t *is;
+ int i;
WRITE_ENTER(&ipf_state);
for (is = ips_list; is; is = is->is_next) {
- if (is->is_ifpin == ifp) {
- is->is_ifpin = GETUNIT(is->is_ifname[0], is->is_v);
- if (!is->is_ifpin)
- is->is_ifpin = (void *)-1;
- }
- if (is->is_ifpout == ifp) {
- is->is_ifpout = GETUNIT(is->is_ifname[1], is->is_v);
- if (!is->is_ifpout)
- is->is_ifpout = (void *)-1;
+ for (i = 0; i < 4; i++) {
+ if (is->is_ifp[i] == ifp) {
+ is->is_ifpin = GETUNIT(is->is_ifname[i],
+ is->is_v);
+ if (!is->is_ifp[i])
+ is->is_ifp[i] = (void *)-1;
+ }
}
}
RWLOCK_EXIT(&ipf_state);
@@ -1401,6 +1607,8 @@ ipstate_t *is;
*is->is_phnext = is->is_hnext;
if (ips_table[is->is_hv] == NULL)
ips_stats.iss_inuse--;
+ if (is->is_me)
+ *is->is_me = NULL;
fr = is->is_rule;
if (fr != NULL) {
@@ -1462,7 +1670,7 @@ void fr_timeoutstate()
} else
isp = &is->is_next;
if (fr_state_doflush) {
- (void) fr_state_flush(1);
+ (void) fr_state_flush(2);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
@@ -1546,8 +1754,11 @@ int dir;
*/
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
- state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
+ if (state[1 - dir] == TCPS_CLOSED ||
+ state[1 - dir] == TCPS_ESTABLISHED) {
+ state[dir] = TCPS_ESTABLISHED;
+ *age = fr_tcpidletimeout;
+ }
}
/*
* TODO: besides regular ACK packets we can have other
@@ -1736,9 +1947,11 @@ u_int type;
ipsl.isl_state[0] = is->is_state[0];
ipsl.isl_state[1] = is->is_state[1];
}
- } else if (ipsl.isl_p == IPPROTO_ICMP)
+ } else if (ipsl.isl_p == IPPROTO_ICMP) {
+ ipsl.isl_itype = is->is_icmp.ics_type;
+ } else if (ipsl.isl_p == IPPROTO_ICMPV6) {
ipsl.isl_itype = is->is_icmp.ics_type;
- else {
+ } else {
ipsl.isl_ps.isl_filler[0] = 0;
ipsl.isl_ps.isl_filler[1] = 0;
}
@@ -1891,10 +2104,6 @@ fr_info_t *fin;
fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
fr = is->is_rule;
ips_stats.iss_hits++;
- /*
- * we must swap src and dst here because the icmp
- * comes the other way around
- */
is->is_pkts++;
is->is_bytes += fin->fin_plen;
/*
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index b940d774ade6c..fe6a505fe66dc 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.h
+++ b/sys/contrib/ipfilter/netinet/ip_state.h
@@ -4,7 +4,7 @@
* 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.4 2001/06/26 10:43:17 darrenr Exp $
+ * $Id: ip_state.h,v 2.13.2.10 2002/03/06 14:07:38 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -57,17 +57,20 @@ typedef struct ipstate {
struct ipstate **is_pnext;
struct ipstate *is_hnext;
struct ipstate **is_phnext;
+ struct ipstate **is_me;
u_long is_age;
+ u_int is_frage[2]; /* age from filter rule, forward & reverse */
u_int is_pass;
U_QUAD_T is_pkts;
U_QUAD_T is_bytes;
- void *is_ifp[2];
+ void *is_ifp[4];
frentry_t *is_rule;
union i6addr is_src;
union i6addr is_dst;
u_char is_p; /* Protocol */
u_char is_v;
u_int is_hv;
+ u_32_t is_rulen; /* rule number */
u_32_t is_flags;
u_32_t is_opt; /* packet options set */
u_32_t is_optmsk; /* " " mask */
@@ -80,7 +83,7 @@ typedef struct ipstate {
tcpstate_t is_ts;
udpstate_t is_us;
} is_ps;
- char is_ifname[2][IFNAMSIZ];
+ char is_ifname[4][IFNAMSIZ];
#if SOLARIS || defined(__sgi)
kmutex_t is_lock;
#endif
@@ -103,7 +106,7 @@ typedef struct ipstate {
#define is_dport is_tcp.ts_dport
#define is_state is_tcp.ts_state
#define is_ifpin is_ifp[0]
-#define is_ifpout is_ifp[1]
+#define is_ifpout is_ifp[2]
#define TH_OPENING (TH_SYN|TH_ACK)
/*
@@ -177,12 +180,15 @@ extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_tcphalfclosed;
extern u_long fr_udptimeout;
+extern u_long fr_udpacktimeout;
extern u_long fr_icmptimeout;
+extern u_long fr_icmpacktimeout;
+extern ipstate_t *ips_list;
extern int fr_state_lock;
extern int fr_stateinit __P((void));
extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
-extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int));
-extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
+extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, ipstate_t **, u_int));
+extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
extern void ip_statesync __P((void *));
extern void fr_timeoutstate __P((void));
extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 472bcce2f4f0e..75f9d67efaf29 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.15.2.23 2001/07/23 13:52:10 darrenr Exp $
+ * $Id: ipl.h,v 2.15.2.31 2002/03/13 03:57:42 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.20"
+#define IPL_VERSION "IP Filter: v3.4.25"
#endif
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 0dc4ff2027235..f33de37f30abd 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mlfk_ipl.c,v 2.1.2.6 2000/11/18 03:58:29 darrenr Exp $
+ * $Id: mlfk_ipl.c,v 2.1.2.7 2001/08/27 21:14:04 darrenr Exp $
*/
@@ -76,8 +76,12 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
+ &fr_udpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
&fr_icmptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
+ &fr_icmpacktimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
&fr_defnatage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,