summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2004-06-21 22:26:10 +0000
committerdarrenr <darrenr@FreeBSD.org>2004-06-21 22:26:10 +0000
commit88e219ce9d353ae6b1fa86f63f33960bbc7dfbc5 (patch)
tree28fc4757b2fb4196fee8b3625fd94ea57becb060
parent6c914c7379a092da784f7d28d9a2f92e5cc0fc87 (diff)
downloadFreeBSD-src-88e219ce9d353ae6b1fa86f63f33960bbc7dfbc5.zip
FreeBSD-src-88e219ce9d353ae6b1fa86f63f33960bbc7dfbc5.tar.gz
Import ipfilter 3.4.35 (destinated for RELENG_4) to vendor branch
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c297
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c16
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h20
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.c109
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c27
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.h3
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c38
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c13
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c386
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h43
-rw-r--r--sys/contrib/ipfilter/netinet/ip_raudio_pxy.c8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c5
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c172
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h3
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h4
16 files changed, 736 insertions, 414 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index a981fcb..1a1da36 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -42,6 +42,7 @@
# include <sys/mbuf.h>
# endif
#else
+# include <sys/cmn_err.h>
# include <sys/byteorder.h>
# if SOLARIS2 < 5
# include <sys/dditypes.h>
@@ -97,7 +98,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.67 2002/12/06 13:28:05 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $";
#endif
#ifndef _KERNEL
@@ -144,6 +145,9 @@ fr_info_t frcache[2];
static int frflushlist __P((int, minor_t, int *, frentry_t **));
#ifdef _KERNEL
static void frsynclist __P((frentry_t *));
+# ifndef __sgi
+static void *ipf_pullup __P((mb_t *, fr_info_t *, int, void *));
+# endif
#endif
@@ -192,19 +196,27 @@ struct optlist secopt[8] = {
* compact the IP header into a structure which contains just the info.
* which is useful for comparing IP headers with.
*/
-void fr_makefrip(hlen, ip, fin)
+int fr_makefrip(hlen, ip, fin)
int hlen;
ip_t *ip;
fr_info_t *fin;
{
u_short optmsk = 0, secmsk = 0, auth = 0;
int i, mv, ol, off, p, plen, v;
+#if defined(_KERNEL)
+# if SOLARIS
+ mb_t *m = fin->fin_qfm;
+# else
+ mb_t *m = fin->fin_mp ? *fin->fin_mp : NULL;
+# endif
+#endif
fr_ip_t *fi = &fin->fin_fi;
struct optlist *op;
u_char *s, opt;
tcphdr_t *tcp;
fin->fin_rev = 0;
+ fin->fin_dp = NULL;
fin->fin_fr = NULL;
fin->fin_tcpf = 0;
fin->fin_data[0] = 0;
@@ -218,8 +230,10 @@ fr_info_t *fin;
if (v == 4) {
fin->fin_id = ip->ip_id;
fi->fi_tos = ip->ip_tos;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+ ip->ip_off = ntohs(ip->ip_off);
+#endif
off = (ip->ip_off & IP_OFFMASK);
- tcp = (tcphdr_t *)((char *)ip + hlen);
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
fi->fi_src.i6[1] = 0;
fi->fi_src.i6[2] = 0;
@@ -233,6 +247,9 @@ fr_info_t *fin;
fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
if (ip->ip_off & (IP_MF|IP_OFFMASK))
fi->fi_fl |= FI_FRAG;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+ ip->ip_len = ntohs(ip->ip_len);
+#endif
plen = ip->ip_len;
fin->fin_dlen = plen - hlen;
}
@@ -244,7 +261,6 @@ fr_info_t *fin;
p = ip6->ip6_nxt;
fi->fi_p = p;
fi->fi_ttl = ip6->ip6_hlim;
- tcp = (tcphdr_t *)(ip6 + 1);
fi->fi_src.in6 = ip6->ip6_src;
fi->fi_dst.in6 = ip6->ip6_dst;
fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
@@ -256,14 +272,23 @@ fr_info_t *fin;
}
#endif
else
- return;
+ return -1;
fin->fin_off = off;
fin->fin_plen = plen;
- fin->fin_dp = (char *)tcp;
+ tcp = (tcphdr_t *)((char *)ip + hlen);
fin->fin_misc = 0;
off <<= 3;
+ /*
+ * For both ICMPV6 & ICMP, we attempt to pullup the entire packet into
+ * a single buffer for recognised error return packets. Why? Because
+ * the entire data section of the ICMP payload is considered to be of
+ * significance and maybe required in NAT/state processing, so rather
+ * than be careful later, attempt to get it all in one buffeer first.
+ * For TCP we just make sure the _entire_ TCP header is in the first
+ * buffer for convienience.
+ */
switch (p)
{
#ifdef USE_INET6
@@ -272,7 +297,7 @@ fr_info_t *fin;
int minicmpsz = sizeof(struct icmp6_hdr);
struct icmp6_hdr *icmp6;
- if (fin->fin_dlen > 1) {
+ if (!(fin->fin_fl & FI_SHORT) && (fin->fin_dlen > 1)) {
fin->fin_data[0] = *(u_short *)tcp;
icmp6 = (struct icmp6_hdr *)tcp;
@@ -287,6 +312,14 @@ fr_info_t *fin;
case ICMP6_PACKET_TOO_BIG :
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
+# if defined(KERNEL) && !defined(__sgi)
+ if ((m != NULL) && (M_BLEN(m) < plen)) {
+ ip = ipf_pullup(m, fin, plen, ip);
+ if (ip == NULL)
+ return -1;
+ tcp = (tcphdr_t *)((char *)ip + hlen);
+ }
+# endif /* KERNEL && !__sgi */
minicmpsz = ICMP6ERR_IPICMPHLEN;
break;
default :
@@ -294,22 +327,27 @@ fr_info_t *fin;
}
}
- if (!(plen >= minicmpsz))
+ if (!(fin->fin_dlen >= minicmpsz))
fi->fi_fl |= FI_SHORT;
break;
}
-#endif
+#endif /* USE_INET6 */
+
case IPPROTO_ICMP :
{
int minicmpsz = sizeof(struct icmp);
icmphdr_t *icmp;
- if (!off && (fin->fin_dlen > 1)) {
+ if (!off && (fin->fin_dlen > 1) && !(fin->fin_fl & FI_SHORT)) {
fin->fin_data[0] = *(u_short *)tcp;
icmp = (icmphdr_t *)tcp;
+ /*
+ * Minimum ICMP packet is type(1) code(1) cksum(2)
+ * plus 4 bytes following, totalling 8 bytes.
+ */
switch (icmp->icmp_type)
{
case ICMP_ECHOREPLY :
@@ -325,7 +363,7 @@ fr_info_t *fin;
*/
case ICMP_TSTAMP :
case ICMP_TSTAMPREPLY :
- minicmpsz = 20;
+ minicmpsz = ICMP_MINLEN + 12;
break;
/*
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
@@ -333,9 +371,28 @@ fr_info_t *fin;
*/
case ICMP_MASKREQ :
case ICMP_MASKREPLY :
- minicmpsz = 12;
+ minicmpsz = ICMP_MINLEN + 4;
+ break;
+ /*
+ * type(1) + code(1) + cksum(2) + arg(4) ip(20+)
+ */
+ case ICMP_UNREACH :
+ case ICMP_SOURCEQUENCH :
+ case ICMP_REDIRECT :
+ case ICMP_TIMXCEED :
+ case ICMP_PARAMPROB :
+#if defined(KERNEL) && !defined(__sgi)
+ if ((m != NULL) && (M_BLEN(m) < plen)) {
+ ip = ipf_pullup(m, fin, plen, ip);
+ if (ip == NULL)
+ return -1;
+ tcp = (tcphdr_t *)((char *)ip + hlen);
+ }
+#endif /* KERNEL && !__sgi */
+ minicmpsz = ICMPERR_MINPKTLEN - sizeof(ip_t);
break;
default :
+ minicmpsz = ICMP_MINLEN;
break;
}
}
@@ -343,9 +400,9 @@ fr_info_t *fin;
if ((!(plen >= hlen + minicmpsz) && !off) ||
(off && off < sizeof(struct icmp)))
fi->fi_fl |= FI_SHORT;
-
break;
}
+
case IPPROTO_TCP :
fi->fi_fl |= FI_TCPUDP;
#ifdef USE_INET6
@@ -359,6 +416,20 @@ fr_info_t *fin;
(off && off < sizeof(struct tcphdr)))
fi->fi_fl |= FI_SHORT;
}
+
+#if defined(KERNEL) && !defined(__sgi)
+ if (!off && !(fi->fi_fl & FI_SHORT)) {
+ int tlen = hlen + (tcp->th_off << 2);
+
+ if ((m != NULL) && (M_BLEN(m) < tlen)) {
+ ip = ipf_pullup(m, fin, tlen, ip);
+ if (ip == NULL)
+ return -1;
+ tcp = (tcphdr_t *)((char *)ip + hlen);
+ }
+ }
+#endif /* _KERNEL && !_sgi */
+
if (!(fi->fi_fl & FI_SHORT) && !off)
fin->fin_tcpf = tcp->th_flags;
goto getports;
@@ -398,12 +469,14 @@ getports:
break;
}
+ fin->fin_dp = (char *)tcp;
+
#ifdef USE_INET6
if (v == 6) {
fi->fi_optmsk = 0;
fi->fi_secmsk = 0;
fi->fi_auth = 0;
- return;
+ return 0;
}
#endif
@@ -460,6 +533,7 @@ getports:
fi->fi_optmsk = optmsk;
fi->fi_secmsk = secmsk;
fi->fi_auth = auth;
+ return 0;
}
@@ -747,7 +821,7 @@ void *m;
#endif /* IPFILTER_LOG */
ATOMIC_INCL(fr->fr_hits);
if (passt & FR_ACCOUNT)
- fr->fr_bytes += (U_QUAD_T)ip->ip_len;
+ fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
else
fin->fin_icode = fr->fr_icode;
fin->fin_rule = rulen;
@@ -810,12 +884,17 @@ int out;
int p, len, drop = 0, logit = 0;
mb_t *mc = NULL;
# if !defined(__SVR4) && !defined(__svr4__)
+ /*
+ * We don't do this section for Solaris because fr_precheck() does a
+ * pullupmsg() instead, effectively achieving the same result as here
+ * so no need to duplicate it.
+ */
# ifdef __sgi
char hbuf[128];
# endif
int up;
-# if !SOLARIS && !defined(NETBSD_PF) && \
+# if !defined(NETBSD_PF) && \
((defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
defined(__OpenBSD__) || defined(_BSDI_VERSION))
if (fr_checkp != fr_check && fr_running > 0) {
@@ -853,7 +932,7 @@ int out;
}
# endif /* CSUM_DELAY_DATA */
-# ifdef USE_INET6
+# ifdef USE_INET6
if (v == 6) {
len = ntohs(((ip6_t*)ip)->ip6_plen);
if (!len)
@@ -861,17 +940,20 @@ int out;
len += sizeof(ip6_t);
p = ((ip6_t *)ip)->ip6_nxt;
} else
-# endif
+# endif
{
p = ip->ip_p;
len = ip->ip_len;
}
+ fin->fin_mp = mp;
+ fin->fin_out = out;
+
if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
(v == 4 && p == IPPROTO_ICMP)
-# ifdef USE_INET6
+# ifdef USE_INET6
|| (v == 6 && p == IPPROTO_ICMPV6)
-# endif
+# endif
)) {
int plen = 0;
@@ -891,7 +973,7 @@ int out;
case IPPROTO_ESP:
plen = 8;
break;
-# ifdef USE_INET6
+# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
* XXX does not take intermediate header
@@ -899,8 +981,10 @@ int out;
*/
plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
break;
-# endif
+# endif
}
+ if ((plen > 0) && (len < hlen + plen))
+ fin->fin_fl |= FI_SHORT;
up = MIN(hlen + plen, len);
if (up > m->m_len) {
@@ -915,14 +999,34 @@ int out;
ip = (ip_t *)hbuf;
# else /* __ sgi */
# ifndef linux
- if ((*mp = m_pullup(m, up)) == 0) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
+ /*
+ * Having determined that we need to pullup some data,
+ * try to bring as much of the packet up into a single
+ * buffer with the first pullup. This hopefully means
+ * less need for doing futher pullups. Not needed for
+ * Solaris because fr_precheck() does it anyway.
+ *
+ * The main potential for trouble here is if MLEN/MHLEN
+ * become quite small, lets say < 64 bytes...but if
+ * that did happen, BSD networking as a whole would be
+ * slow/inefficient.
+ */
+# ifdef MHLEN
+ /*
+ * Assume that M_PKTHDR is set and just work with what
+ * is left rather than check.. Should not make any
+ * real difference, anyway.
+ */
+ if ((MHLEN > up) && (len > up))
+ up = MIN(len, MHLEN);
+# else
+ if ((MLEN > up) && (len > up))
+ up = MIN(len, MLEN);
+# endif
+ ip = ipf_pullup(m, fin, up, ip);
+ if (ip == NULL)
return -1;
- } else {
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- m = *mp;
- ip = mtod(m, ip_t *);
- }
+ m = *mp;
# endif /* !linux */
# endif /* __sgi */
} else
@@ -935,17 +1039,21 @@ int out;
if ((u_int)ip & 0x3)
return 2;
+ fin->fin_mp = mp;
+ fin->fin_out = out;
fin->fin_qfm = m;
fin->fin_qif = qif;
# endif
+#else
+ fin->fin_mp = mp;
+ fin->fin_out = out;
#endif /* _KERNEL */
changed = 0;
- fin->fin_ifp = ifp;
fin->fin_v = v;
- fin->fin_out = out;
- fin->fin_mp = mp;
- fr_makefrip(hlen, ip, fin);
+ fin->fin_ifp = ifp;
+ if (fr_makefrip(hlen, ip, fin) == -1)
+ return -1;
#ifdef _KERNEL
# ifdef USE_INET6
@@ -1109,6 +1217,10 @@ int out;
if (pass & FR_KEEPSTATE) {
if (fr_addstate(ip, fin, NULL, 0) == NULL) {
ATOMIC_INCL(frstats[out].fr_bads);
+ if (pass & FR_PASS) {
+ pass &= ~FR_PASS;
+ pass |= FR_BLOCK;
+ }
} else {
ATOMIC_INCL(frstats[out].fr_ads);
}
@@ -1290,6 +1402,12 @@ logit:
(void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
}
# endif /* !SOLARIS */
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+ if (pass & FR_PASS) {
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+ }
+#endif
return (pass & FR_PASS) ? 0 : error;
#else /* _KERNEL */
if (pass & FR_NOMATCH)
@@ -1387,10 +1505,10 @@ tcphdr_t *tcp;
/*
* Both sum and sum2 are partial sums, so combine them together.
*/
- sum = (sum & 0xffff) + (sum >> 16);
- sum = ~sum & 0xffff;
- sum2 += sum;
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ sum += ~sum2 & 0xffff;
+ while (sum > 0xffff)
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum2 = ~sum & 0xffff;
# else /* defined(BSD) || defined(sun) */
{
union {
@@ -1531,7 +1649,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1963,12 +2081,40 @@ struct in_addr *inp;
static void frsynclist(fr)
register frentry_t *fr;
{
+ frdest_t *fdp;
+ int i;
+
for (; fr; fr = fr->fr_next) {
- if (fr->fr_ifa != NULL) {
- fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_ip.fi_v);
- if (fr->fr_ifa == NULL)
- fr->fr_ifa = (void *)-1;
+ for (i = 0; i < 4; i++) {
+ if ((fr->fr_ifnames[i][1] == '\0') &&
+ ((fr->fr_ifnames[i][0] == '-') ||
+ (fr->fr_ifnames[i][0] == '*'))) {
+ fr->fr_ifas[i] = NULL;
+ } else if (*fr->fr_ifnames[i]) {
+ fr->fr_ifas[i] = GETUNIT(fr->fr_ifnames[i],
+ fr->fr_v);
+ if (!fr->fr_ifas[i])
+ fr->fr_ifas[i] = (void *)-1;
+ }
+ }
+
+ fdp = &fr->fr_dif;
+ fr->fr_flags &= ~FR_DUP;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ else
+ fr->fr_flags |= FR_DUP;
}
+
+ fdp = &fr->fr_tif;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ }
+
if (fr->fr_grp)
frsynclist(fr->fr_grp);
}
@@ -1984,6 +2130,9 @@ void frsync()
(defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
# if (NetBSD >= 199905) || defined(__OpenBSD__)
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
+# elif defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
+ IFNET_RLOCK();
+ TAILQ_FOREACH(ifp, &ifnet, if_link);
# else
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
# endif
@@ -1995,6 +2144,9 @@ void frsync()
ip_statesync(ifp);
}
ip_natsync((struct ifnet *)-1);
+# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
+ IFNET_RUNLOCK();
+# endif
# endif /* !SOLARIS */
WRITE_ENTER(&ipf_mutex);
@@ -2223,3 +2375,64 @@ mb_t *buf;
return ip->ip_len;
}
#endif
+
+
+#if defined(_KERNEL) && !defined(__sgi)
+void *ipf_pullup(m, fin, len, ipin)
+mb_t *m;
+fr_info_t *fin;
+int len;
+void *ipin;
+{
+# if SOLARIS
+ qif_t *qf = fin->fin_qif;
+# endif
+ int out = fin->fin_out, dpoff, ipoff;
+ char *ip;
+
+ if (m == NULL)
+ return NULL;
+
+ ipoff = (char *)ipin - MTOD(m, char *);
+ if (fin->fin_dp != NULL)
+ dpoff = (char *)fin->fin_dp - (char *)ipin;
+ else
+ dpoff = 0;
+
+ if (M_BLEN(m) < len) {
+# if SOLARIS
+ qif_t *qf = fin->fin_qif;
+ int inc = 0;
+
+ if (ipoff > 0) {
+ if ((ipoff & 3) != 0) {
+ inc = 4 - (ipoff & 3);
+ if (m->b_rptr - inc >= m->b_datap->db_base)
+ m->b_rptr -= inc;
+ else
+ inc = 0;
+ }
+ }
+ if (!pullupmsg(m, len + ipoff + inc)) {
+ ATOMIC_INCL(frstats[out].fr_pull[1]);
+ return NULL;
+ }
+ m->b_rptr += inc;
+ ATOMIC_INCL(frstats[out].fr_pull[0]);
+ qf->qf_data = MTOD(m, char *) + ipoff;
+# else
+ m = m_pullup(m, len);
+ *fin->fin_mp = m;
+ if (m == NULL) {
+ ATOMIC_INCL(frstats[out].fr_pull[1]);
+ return NULL;
+ }
+ ATOMIC_INCL(frstats[out].fr_pull[0]);
+# endif /* SOLARIS */
+ }
+ ip = MTOD(m, char *) + ipoff;
+ if (fin->fin_dp != NULL)
+ fin->fin_dp = (char *)ip + dpoff;
+ return ip;
+}
+#endif /* _KERNEL */
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index 604d754..566f203 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -104,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.24 2002/12/06 11:40:21 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.26 2003/09/22 12:37:04 darrenr Exp $";
#endif
@@ -314,7 +314,8 @@ int cmd;
#endif
{
mb_t *m;
-#if defined(_KERNEL) && !SOLARIS
+#if defined(_KERNEL) && !SOLARIS && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq;
int s;
#endif
@@ -418,7 +419,8 @@ fr_authioctlloop:
bzero((char *)&ro, sizeof(ro));
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
- defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605))
+ defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
+ (__FreeBSD_version >= 470102)
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
# else
@@ -436,6 +438,9 @@ fr_authioctlloop:
# if SOLARIS
error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
# else /* SOLARIS */
+# if __FreeBSD_version >= 501104
+ netisr_dispatch(NETISR_IP, m);
+# else
ifq = &ipintrq;
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
@@ -443,10 +448,11 @@ fr_authioctlloop:
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
-# if IRIX < 605
+# if IRIX < 605
schednetisr(NETISR_IP);
-# endif
+# endif
}
+# endif
# endif /* SOLARIS */
if (error)
fr_authstats.fas_quefail++;
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 3eacc73..7674424 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.47 2002/10/26 06:24:42 darrenr Exp $
+ * $Id: ip_compat.h,v 2.26.2.52 2004/06/09 00:01:14 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -65,7 +65,7 @@
#if defined(__sgi) || defined(bsdi)
struct ether_addr {
- u_char ether_addr_octet[6];
+ u_char ether_addr_octet[6];
};
#endif
@@ -163,6 +163,7 @@ struct file;
# define V4_PART_OF_V6(v6) v6.s6_addr32[3]
# endif
# endif
+# define M_BLEN(m) ((m)->b_wptr - (m)->b_rptr)
typedef struct qif {
struct qif *qf_next;
@@ -172,6 +173,7 @@ typedef struct qif {
void *qf_optr;
queue_t *qf_in;
queue_t *qf_out;
+ void *qf_data; /* layer 3 header pointer */
struct qinit *qf_wqinfo;
struct qinit *qf_rqinfo;
struct qinit qf_wqinit;
@@ -260,7 +262,8 @@ typedef u_int32_t u_32_t;
# endif
# endif
# if !defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(USE_INET6)
-# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 400000)) || \
+# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
+ !defined(NOINET6)) || \
(defined(OpenBSD) && (OpenBSD >= 200111)) || \
(defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000))
# define USE_INET6
@@ -523,6 +526,7 @@ extern ill_t *get_unit __P((char *, int));
# ifndef linux
# define FREE_MB_T(m) m_freem(m)
# define MTOD(m,t) mtod(m,t)
+# define M_BLEN(m) (m)->m_len
# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
# define IRCOPYPTR ircopyptr
@@ -541,7 +545,7 @@ extern ill_t *get_unit __P((char *, int));
# ifndef linux
# define GETUNIT(n, v) ifunit(n)
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+ (defined(OpenBSD) && (OpenBSD >= 199603))
# define IFNAME(x) ((struct ifnet *)x)->if_xname
# else
# define USE_GETIFNAME 1
@@ -960,7 +964,7 @@ typedef struct {
__u32 th_seq;
__u32 th_ack;
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
- defined(vax)
+ defined(__vax__)
__u8 th_res:4;
__u8 th_off:4;
#else
@@ -982,7 +986,7 @@ typedef struct {
typedef struct {
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
- defined(vax)
+ defined(__vax__)
__u8 ip_hl:4;
__u8 ip_v:4;
# else
@@ -1206,8 +1210,8 @@ struct ether_addr {
#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)
+#define ICMP6ERR_IPICMPHLEN (40 + 8)
+#define ICMP6ERR_MINPKTLEN (40 + 8 + 40)
#ifndef ICMP6_DST_UNREACH
# define ICMP6_DST_UNREACH 1
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c
index 8fcd05d..00e8565 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil.c
@@ -124,7 +124,7 @@ extern int ip6_getpmtu(struct route_in6 *, struct route_in6 *,
#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.64 2002/12/06 11:45:45 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.76 2004/05/12 23:21:03 darrenr Exp $";
#endif
@@ -504,9 +504,9 @@ int ipldetach()
((__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011))
int error = 0;
# if __NetBSD_Version__ >= 105150000
- struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+ 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);
+ struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
# endif
# endif
#endif
@@ -651,7 +651,7 @@ int mode;
int error = 0, unit = 0, tmp;
#if (BSD >= 199306) && defined(_KERNEL)
- if ((securelevel >= 2) && (mode & FWRITE))
+ if ((securelevel >= 3) && (mode & FWRITE))
return EPERM;
#endif
#ifdef _KERNEL
@@ -1020,8 +1020,8 @@ caddr_t data;
while ((f = *ftail))
ftail = &f->fr_next;
else {
+ ftail = fprev;
if (fp->fr_hits) {
- ftail = fprev;
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
}
@@ -1275,7 +1275,7 @@ struct mbuf **mp;
frn.fin_ifp = fin->fin_ifp;
frn.fin_v = fin->fin_v;
frn.fin_out = fin->fin_out;
- frn.fin_mp = fin->fin_mp;
+ frn.fin_mp = mp;
ip = mtod(m, ip_t *);
hlen = sizeof(*ip);
@@ -1319,9 +1319,10 @@ struct mbuf **mp;
m->m_pkthdr.rcvif = NULL;
# endif
- fr_makefrip(hlen, ip, &frn);
-
- error = ipfr_fastroute(m, mp, &frn, NULL);
+ if (fr_makefrip(hlen, ip, &frn) == 0)
+ error = ipfr_fastroute(m, mp, &frn, NULL);
+ else
+ error = EINVAL;
return error;
}
@@ -1454,7 +1455,13 @@ int dst;
#endif
if (avail) {
+ slen = oip->ip_len;
+ oip->ip_len = htons(oip->ip_len);
+ soff = oip->ip_off;
+ oip->ip_off = htons(oip->ip_off);
bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
+ oip->ip_len = slen;
+ oip->ip_off = soff;
avail -= MIN(ohlen, avail);
}
@@ -1475,10 +1482,6 @@ int dst;
} else
#endif
{
- slen = oip->ip_len;
- oip->ip_len = htons(oip->ip_len);
- soff = oip->ip_off;
- oip->ip_off = htons(ip->ip_off);
ip->ip_src.s_addr = dst4.s_addr;
ip->ip_dst.s_addr = oip->ip_src.s_addr;
@@ -1498,13 +1501,7 @@ int dst;
fin->fin_hlen = hlen;
err = send_ip(oip, fin, &m);
fin->fin_hlen = shlen;
-#ifdef USE_INET6
- if (fin->fin_v == 4)
-#endif
- {
- oip->ip_len = slen;
- oip->ip_off = soff;
- }
+
return err;
}
@@ -1562,7 +1559,7 @@ frdest_t *fdp;
register struct ip *ip, *mhip;
register struct mbuf *m = m0;
register struct route *ro;
- int len, off, error = 0, hlen, code;
+ int len, off, error = 0, hlen, code, sout;
struct ifnet *ifp, *sifp;
struct sockaddr_in *dst;
struct route iproute;
@@ -1628,7 +1625,7 @@ frdest_t *fdp;
/*
* Route packet.
*/
-#if defined(__sgi) && (IRIX >= 605)
+#if (defined(IRIX) && (IRIX >= 605))
ROUTE_RDLOCK();
#endif
bzero((caddr_t)ro, sizeof (*ro));
@@ -1647,8 +1644,12 @@ frdest_t *fdp;
* check that we're going in the correct direction.
*/
if ((fr != NULL) && (fin->fin_rev != 0)) {
- if ((ifp != NULL) && (fdp == &fr->fr_tif))
+ if ((ifp != NULL) && (fdp == &fr->fr_tif)) {
+# if (defined(IRIX) && (IRIX >= 605))
+ ROUTE_UNLOCK();
+# endif
return 0;
+ }
} else if (fdp != NULL) {
if (fdp->fd_ip.s_addr != 0)
dst->sin_addr = fdp->fd_ip;
@@ -1668,13 +1669,12 @@ frdest_t *fdp;
rtalloc(ro);
# endif
-#if defined(__sgi) && (IRIX > 602)
- ROUTE_UNLOCK();
-#endif
-
if (!ifp) {
if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
error = -2;
+# if (defined(IRIX) && (IRIX >= 605))
+ ROUTE_UNLOCK();
+# endif
goto bad;
}
}
@@ -1687,11 +1687,14 @@ frdest_t *fdp;
error = EHOSTUNREACH;
else
error = ENETUNREACH;
+# if (defined(IRIX) && (IRIX >= 605))
+ ROUTE_UNLOCK();
+# endif
goto bad;
}
if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
-#if BSD >= 199306
+#if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
#else
dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
@@ -1699,6 +1702,10 @@ frdest_t *fdp;
}
ro->ro_rt->rt_use++;
+#if (defined(IRIX) && (IRIX > 602))
+ ROUTE_UNLOCK();
+#endif
+
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
@@ -1706,6 +1713,7 @@ frdest_t *fdp;
*/
if (fin->fin_out == 0) {
sifp = fin->fin_ifp;
+ sout = fin->fin_out;
fin->fin_ifp = ifp;
fin->fin_out = 1;
if ((fin->fin_fr = ipacct[1][fr_active]) &&
@@ -1715,10 +1723,25 @@ frdest_t *fdp;
fin->fin_fr = NULL;
if (!fr || !(fr->fr_flags & FR_RETMASK))
(void) fr_checkstate(ip, fin);
- (void) ip_natout(ip, fin);
+
+ switch (ip_natout(ip, fin))
+ {
+ case 0 :
+ break;
+ case 1 :
+ ip->ip_sum = 0;
+ break;
+ case -1 :
+ error = EINVAL;
+ goto done;
+ break;
+ }
+
fin->fin_ifp = sifp;
+ fin->fin_out = sout;
} else
ip->ip_sum = 0;
+
/*
* If small enough for interface, can just send directly.
*/
@@ -1748,8 +1771,14 @@ frdest_t *fdp;
ip->ip_sum = in_cksum(m, hlen);
# endif /* __NetBSD__ && M_CSUM_IPv4 */
# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
+# ifdef IRIX
+ IFNET_UPPERLOCK(ifp);
+# endif
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
ro->ro_rt);
+# ifdef IRIX
+ IFNET_UPPERUNLOCK(ifp);
+# endif
# else
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
# endif
@@ -1895,7 +1924,7 @@ void *ifp;
dst->sin_family = AF_INET;
dst->sin_addr = ipa;
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
- !defined(__OpenBSD__)
+ !defined(__OpenBSD__)
# ifdef RTF_CLONING
rtalloc_ign(&iproute, RTF_CLONING);
# else
@@ -1947,17 +1976,18 @@ frdest_t *fdp;
u_long mtu;
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;
+ dst6->sin6_addr = fin->fin_fi.fi_dst.in6;
if (fdp != NULL)
ifp = fdp->fd_ifp;
+ else
+ ifp = fin->fin_ifp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
@@ -1966,9 +1996,14 @@ frdest_t *fdp;
if (IP6_NOTZERO(&fdp->fd_ip6))
dst6->sin6_addr = fdp->fd_ip6.in6;
}
- if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
+ if (ifp == NULL)
return -2;
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ /* KAME */
+ if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr))
+ dst6->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+#endif
rtalloc((struct route *)ro);
if ((ifp == NULL) && (ro->ro_rt != NULL))
@@ -1989,7 +2024,15 @@ frdest_t *fdp;
error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu);
if (error == 0) {
#else
+# ifdef IN6_LINKMTU
+ mtu = IN6_LINKMTU(ifp);
+# else
+# ifdef ND_IFINFO
+ mtu = ND_IFINFO(ifp)->linkmtu;
+# else
mtu = nd_ifinfo[ifp->if_index].linkmtu;
+# endif
+# endif
#endif
if (m0->m_pkthdr.len <= mtu)
error = nd6_output(ifp, fin->fin_ifp, m0,
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index b97c796..73099ec 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ip_fil.h,v 2.29.2.34 2002/10/01 15:23:37 darrenr Exp $
+ * $Id: ip_fil.h,v 2.29.2.35 2003/06/07 11:56:02 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -151,7 +151,7 @@ typedef struct fr_info {
u_short fin_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
u_int fin_misc;
- void *fin_mp; /* pointer to pointer to mbuf */
+ mb_t **fin_mp; /* pointer to pointer to mbuf */
#if SOLARIS
void *fin_qfm; /* pointer to mblk where pkt starts */
void *fin_qif;
@@ -628,7 +628,7 @@ extern void fr_forgetifp __P((void *));
extern void fr_getstat __P((struct friostat *));
extern int fr_ifpaddr __P((int, void *, struct in_addr *));
extern int fr_lock __P((caddr_t, int *));
-extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
+extern int fr_makefrip __P((int, ip_t *, fr_info_t *));
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
extern int fr_tcpudpchk __P((frtuc_t *, fr_info_t *));
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index 0f3b818..73f98c4 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -90,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.25 2002/12/06 11:40:21 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.28 2003/06/11 22:28:15 darrenr Exp $";
#endif
@@ -195,7 +195,7 @@ ipfr_t *table[];
/*
- * Instert the fragment into the fragment table, copy the struct used
+ * Insert the fragment into the fragment table, copy the struct used
* in the search using bcopy rather than reassign each field.
* Set the ttl to the default.
*/
@@ -423,7 +423,26 @@ fr_info_t *fin;
/*
* forget any references to this external object.
*/
-void ipfr_forget(nat)
+void ipfr_forget(ptr)
+void *ptr;
+{
+ ipfr_t *fr;
+ int idx;
+
+ WRITE_ENTER(&ipf_frag);
+ for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
+ for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+ if (fr->ipfr_data == ptr)
+ fr->ipfr_data = NULL;
+
+ RWLOCK_EXIT(&ipf_frag);
+}
+
+
+/*
+ * forget any references to this external object.
+ */
+void ipfr_forgetnat(nat)
void *nat;
{
ipfr_t *fr;
@@ -431,7 +450,7 @@ void *nat;
WRITE_ENTER(&ipf_natfrag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+ for (fr = ipfr_nattab[idx]; fr; fr = fr->ipfr_next)
if (fr->ipfr_data == nat)
fr->ipfr_data = NULL;
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h
index 4bd6b52..925f285 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.7 2002/07/06 14:17:51 darrenr Exp $
+ * $Id: ip_frag.h,v 2.4.2.8 2003/06/11 22:28:16 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -53,6 +53,7 @@ extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, struct nat *));
extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
extern void ipfr_forget __P((void *));
+extern void ipfr_forgetnat __P((void *));
extern void ipfr_unload __P((void));
extern void ipfr_fragexpire __P((void));
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index 0108410..ae158de 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.42 2002/11/25 21:42:35 darrenr Exp $
+ * $Id: ip_ftp_pxy.c,v 2.7.2.47 2004/06/21 11:48:07 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -121,7 +121,7 @@ int dlen;
int inc, off;
nat_t *ipn;
mb_t *m;
-#if SOLARIS
+#if SOLARIS && defined(_KERNEL)
mb_t *m1;
#endif
@@ -207,8 +207,13 @@ int dlen;
a1 >>= 24;
olen = s - f->ftps_rptr;
/* DO NOT change this to snprintf! */
+#if defined(OpenBSD) && (200311 >= 200311)
+ (void) snprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
+ "PORT", a1, a2, a3, a4, a5, a6);
+#else
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
+#endif
nlen = strlen(newbuf);
inc = nlen - olen;
@@ -221,7 +226,7 @@ int dlen;
}
#if !defined(_KERNEL)
- m = *((mb_t **)fin->fin_mp);
+ m = *fin->fin_mp;
bcopy(newbuf, (char *)m + off, nlen);
#else
# if SOLARIS
@@ -251,7 +256,7 @@ int dlen;
}
copyin_mblk(m, off, nlen, newbuf);
# else
- m = *((mb_t **)fin->fin_mp);
+ m = *fin->fin_mp;
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -263,7 +268,7 @@ int dlen;
# endif
#endif
if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
@@ -542,7 +547,7 @@ int dlen;
return 0;
#if !defined(_KERNEL)
- m = *((mb_t **)fin->fin_mp);
+ m = *fin->fin_mp;
m_copyback(m, off, nlen, newbuf);
#else
# if SOLARIS
@@ -569,7 +574,7 @@ int dlen;
}
/*copyin_mblk(m, off, nlen, newbuf);*/
# else /* SOLARIS */
- m = *((mb_t **)fin->fin_mp);
+ m = *fin->fin_mp;
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -577,7 +582,7 @@ int dlen;
# endif /* SOLARIS */
#endif /* _KERNEL */
if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
@@ -714,7 +719,8 @@ size_t len;
if (i < 5) {
#if !defined(_KERNEL) && !defined(KERNEL)
- fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
+ fprintf(stdout, "ippr_ftp_client_valid:i(%lu) < 5\n",
+ (u_long)i);
#endif
return 2;
}
@@ -750,8 +756,8 @@ size_t len;
bad_client_command:
#if !defined(_KERNEL) && !defined(KERNEL)
fprintf(stdout,
- "ippr_ftp_client_valid:bad cmd:len %d i %d c 0x%x\n",
- i, len, c);
+ "ippr_ftp_client_valid:bad cmd:len %lu i %lu c 0x%x\n",
+ (u_long)i, (u_long)len, c);
#endif
return 1;
}
@@ -812,8 +818,8 @@ size_t len;
bad_server_command:
#if !defined(_KERNEL) && !defined(KERNEL)
fprintf(stdout,
- "ippr_ftp_server_valid:bad cmd:len %d i %d c 0x%x\n",
- i, len, c);
+ "ippr_ftp_server_valid:bad cmd:len %lu i %lu c 0x%x\n",
+ (u_long)i, (u_long)len, c);
#endif
return 1;
}
@@ -875,7 +881,7 @@ int rv;
#if SOLARIS && defined(_KERNEL)
m = fin->fin_qfm;
#else
- m = *((mb_t **)fin->fin_mp);
+ m = *fin->fin_mp;
#endif
#ifndef _KERNEL
@@ -1025,9 +1031,9 @@ int rv;
printf("inc %d sel %d rv %d\n", inc, sel, rv);
printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
f->ftps_seq[1]);
- printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
+ printf("ackmin %x ackoff %d\n", (u_int)aps->aps_ackmin[sel],
aps->aps_ackoff[sel]);
- printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
+ printf("seqmin %x seqoff %d\n", (u_int)aps->aps_seqmin[sel],
aps->aps_seqoff[sel]);
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index e57bd69..3628a58 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.21 2002/10/26 06:21:30 darrenr Exp $
+ * $Id: ip_log.c,v 2.5.2.26 2004/06/20 01:59:01 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) && !defined(_KERNEL)
@@ -241,16 +241,17 @@ mb_t *m;
*/
bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
# if SOLARIS && defined(_KERNEL)
- ipfl.fl_unit = (u_char)ifp->ill_ppa;
+ ipfl.fl_unit = (u_int)ifp->ill_ppa;
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)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
+ (defined(OpenBSD) && (OpenBSD >= 199603)) || \
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
# else
- ipfl.fl_unit = (u_char)ifp->if_unit;
+ ipfl.fl_unit = (u_int)ifp->if_unit;
strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
sizeof(ifp->if_name)));
# endif
@@ -312,7 +313,7 @@ int *types, cnt;
* rather than create a new one.
*/
MUTEX_ENTER(&ipl_mutex);
- if (fin != NULL) {
+ if ((fin != NULL) && (fin->fin_off == 0)) {
if ((ipll[dev] != NULL) &&
bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
ipll[dev]->ipl_count++;
@@ -428,7 +429,7 @@ struct uio *uio;
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
- while (!iplused[unit] || !iplt[unit]) {
+ while (iplt[unit] == NULL) {
# if SOLARIS && defined(_KERNEL)
if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
MUTEX_EXIT(&ipl_mutex);
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index d8c8622..4193933 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -109,12 +109,13 @@ 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.74 2002/12/06 11:40:21 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.82 2004/05/30 17:56:52 darrenr Exp $";
#endif
nat_t **nat_table[2] = { NULL, NULL },
*nat_instances = NULL;
ipnat_t *nat_list = NULL;
+u_int ipf_nattable_max = NAT_TABLE_MAX;
u_int ipf_nattable_sz = NAT_TABLE_SZ;
u_int ipf_natrules_sz = NAT_SIZE;
u_int ipf_rdrrules_sz = RDR_SIZE;
@@ -778,6 +779,8 @@ caddr_t data;
if ((aps != NULL) && (aps->aps_data != 0)) {
ng.ng_sz += sizeof(ap_session_t);
ng.ng_sz += aps->aps_psiz;
+ if (aps->aps_psiz > 4) /* XXX - sizeof(ipn_data) */
+ ng.ng_sz -= 4;
}
error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
@@ -793,6 +796,7 @@ caddr_t data;
nat_save_t ipn, *ipnp, *ipnn = NULL;
register nat_t *n, *nat;
ap_session_t *aps;
+ size_t dsz;
int error;
error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
@@ -824,7 +828,6 @@ caddr_t data;
}
ipn.ipn_next = nat->nat_next;
- ipn.ipn_dsize = 0;
bcopy((char *)nat, (char *)&ipn.ipn_nat, sizeof(ipn.ipn_nat));
ipn.ipn_nat.nat_data = NULL;
@@ -838,10 +841,13 @@ caddr_t data;
sizeof(ipn.ipn_rule));
if ((aps = nat->nat_aps)) {
- ipn.ipn_dsize = sizeof(*aps);
+ dsz = sizeof(*aps);
if (aps->aps_data)
- ipn.ipn_dsize += aps->aps_psiz;
- KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
+ dsz += aps->aps_psiz;
+ ipn.ipn_dsize = dsz;
+ if (dsz > sizeof(ipn.ipn_data))
+ dsz -= sizeof(ipn.ipn_data);
+ KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + dsz);
if (ipnn == NULL)
return ENOMEM;
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
@@ -850,14 +856,14 @@ caddr_t data;
if (aps->aps_data) {
bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
aps->aps_psiz);
- ipnn->ipn_dsize += aps->aps_psiz;
}
error = IWCOPY((caddr_t)ipnn, ipnp,
- sizeof(ipn) + ipn.ipn_dsize);
+ sizeof(ipn) + dsz);
if (error)
error = EFAULT;
- KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
+ KFREES(ipnn, sizeof(*ipnn) + dsz);
} else {
+ ipn.ipn_dsize = 0;
error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
if (error)
error = EFAULT;
@@ -885,12 +891,12 @@ caddr_t data;
return EFAULT;
nat = NULL;
if (ipn.ipn_dsize) {
- KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
+ KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
if (ipnn == NULL)
return ENOMEM;
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
- error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
- ipn.ipn_dsize);
+ error = IRCOPY((caddr_t)ipnp + offsetof(nat_save_t, ipn_data),
+ (caddr_t)ipnn->ipn_data, ipn.ipn_dsize);
if (error) {
error = EFAULT;
goto junkput;
@@ -1065,7 +1071,7 @@ struct nat *natd;
* If there's a fragment table entry too for this nat entry, then
* dereference that as well.
*/
- ipfr_forget((void *)natd);
+ ipfr_forgetnat((void *)natd);
aps_free(natd->nat_aps);
nat_stats.ns_inuse--;
KFREE(natd);
@@ -1163,6 +1169,11 @@ int direction;
qif_t *qf = fin->fin_qif;
#endif
+ if (nat_stats.ns_inuse >= ipf_nattable_max) {
+ nat_stats.ns_memfail++;
+ return NULL;
+ }
+
nflags = flags & np->in_flags;
if (flags & IPN_TCPUDP) {
tcp = (tcphdr_t *)fin->fin_dp;
@@ -1174,6 +1185,17 @@ int direction;
KMALLOC(nat, nat_t *);
if (nat == NULL) {
nat_stats.ns_memfail++;
+ /*
+ * Try to automatically tune the max # of entries in the
+ * table allowed to be less than what will cause kmem_alloc()
+ * to fail and try to eliminate panics due to out of memory
+ * conditions arising.
+ */
+ if (ipf_nattable_max > ipf_nattable_sz) {
+ ipf_nattable_max = nat_stats.ns_inuse - 100;
+ printf("ipf_nattable_max reduced to %d\n",
+ ipf_nattable_max);
+ }
return NULL;
}
@@ -1430,7 +1452,7 @@ int direction;
CALC_SUMD(sum1, sum2, sumd);
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
- if ((flags & IPN_TCPUDP) && dohwcksum &&
+ if ((flags & IPN_TCP) && dohwcksum &&
(qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
if (direction == NAT_OUTBOUND)
sum1 = LONG_SUM(ntohl(in.s_addr));
@@ -1682,6 +1704,7 @@ int dir;
return NULL;
flags = 0;
+ sumd2 = 0;
*nflags = IPN_ICMPERR;
icmp = (icmphdr_t *)fin->fin_dp;
oip = (ip_t *)&icmp->icmp_ip;
@@ -1735,137 +1758,75 @@ int dir;
CALC_SUMD(sum1, sum2, sumd);
- if (nat->nat_dir == NAT_OUTBOUND) {
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
+ /*
+ * Fix IP checksum of the offending IP packet to adjust for
+ * the change in the IP address.
+ *
+ * Normally, you would expect that the ICMP checksum of the
+ * ICMP error message needs to be adjusted as well for the
+ * IP address change in oip.
+ * However, this is a NOP, because the ICMP checksum is
+ * calculated over the complete ICMP packet, which includes the
+ * changed oip IP addresses and oip->ip_sum. However, these
+ * two changes cancel each other out (if the delta for
+ * the IP address is x, then the delta for ip_sum is minus x),
+ * so no change in the icmp_cksum is necessary.
+ *
+ * Be careful that nat_dir refers to the direction of the
+ * offending IP packet (oip), not to its ICMP response (icmp)
+ */
+ fix_datacksum(&oip->ip_sum, sumd);
+ /* Fix icmp cksum : IP Addr + Cksum */
+ /*
+ * Fix UDP pseudo header checksum to compensate for the
+ * IP address change.
+ */
+ if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && udp->uh_sum) {
/*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
+ * The UDP checksum is optional, only adjust it
+ * if it has been set.
*/
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set.
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
+ sum1 = ntohs(udp->uh_sum);
+ fix_datacksum(&udp->uh_sum, sumd);
+ sum2 = ntohs(udp->uh_sum);
/*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
+ * Fix ICMP checksum to compensate the UDP
+ * checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
-
- /*
- * Fix ICMP checksum to compensate the TCP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
- } else {
+ sumd2 = sumd << 1;
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ }
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
+ /*
+ * Fix TCP pseudo header checksum to compensate for the
+ * IP address change. Before we can do the change, we
+ * must make sure that oip is sufficient large to hold
+ * the TCP checksum (normally it does not!).
+ */
+ else if ((oip->ip_p == IPPROTO_TCP) && (dlen >= 18)) {
+ sum1 = ntohs(tcp->th_sum);
+ fix_datacksum(&tcp->th_sum, sumd);
+ sum2 = ntohs(tcp->th_sum);
-/* XXX FV : without having looked at Solaris source code, it seems unlikely
- * that SOLARIS would compensate this in the kernel (a body of an IP packet
- * in the data section of an ICMP packet). I have the feeling that this should
- * be unconditional, but I'm not in a position to check.
- */
-#if !SOLARIS && !defined(__sgi)
/*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
+ * Fix ICMP checksum to compensate the TCP
+ * checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
-
- /*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
- */
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
-
- /*
- * Fix ICMP checksum to compensate the TCP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
-#endif
+ sumd2 = sumd << 1;
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ } else {
+ sumd2 = (sumd >> 16);
+ if (nat->nat_dir == NAT_OUTBOUND)
+ sumd2 = ~sumd2;
+ else
+ sumd2 = ~sumd2 + 1;
}
- if ((flags & IPN_TCPUDP) != 0) {
+ if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) {
/*
* Step 2 :
* For offending TCP/UDP IP packets, translate the ports as
@@ -1885,17 +1846,14 @@ int dir;
* include the TCP checksum. So we have to check if the
* ip->ip_len actually holds the TCP checksum of the oip!
*/
-
if (nat->nat_oport == tcp->th_dport) {
if (tcp->th_sport != nat->nat_inport) {
/*
* Fix ICMP checksum to compensate port
* adjustment.
*/
- sum1 = ntohs(tcp->th_sport);
- sum2 = ntohs(nat->nat_inport);
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
+ sum1 = ntohs(nat->nat_inport);
+ sum2 = ntohs(tcp->th_sport);
tcp->th_sport = nat->nat_inport;
/*
@@ -1907,16 +1865,18 @@ int dir;
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
+ if ((oip->ip_p == IPPROTO_UDP) &&
+ (dlen >= 8) && udp->uh_sum) {
+ sumd = sum1 - sum2;
+ sumd2 += sumd;
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
- * Fix ICMP checksum to
- * compensate UDP checksum
- * adjustment.
+ * Fix ICMP checksum to compensate
+ * UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
@@ -1928,63 +1888,73 @@ int dir;
* packet flows the other direction compared to
* the ICMP message.
*/
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
- sum1 = ntohs(tcp->th_sum);
- fix_datacksum(&tcp->th_sum, sumd);
- sum2 = ntohs(tcp->th_sum);
-
- /*
- * Fix ICMP checksum to
- * compensate TCP checksum
- * adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
+ if (oip->ip_p == IPPROTO_TCP) {
+ if (dlen >= 18) {
+ sumd = sum1 - sum2;
+ sumd2 += sumd;
+
+ sum1 = ntohs(tcp->th_sum);
+ fix_datacksum(&tcp->th_sum,
+ sumd);
+ sum2 = ntohs(tcp->th_sum);
+
+ /*
+ * Fix ICMP checksum to
+ * compensate TCP checksum
+ * adjustment.
+ */
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd2 += sumd;
+ } else {
+ sumd = sum2 - sum1 + 1;
+ sumd2 += sumd;
+ }
}
}
- } else {
- if (tcp->th_dport != nat->nat_outport) {
- /*
- * Fix ICMP checksum to compensate port
- * adjustment.
- */
- sum1 = ntohs(tcp->th_dport);
- sum2 = ntohs(nat->nat_outport);
- CALC_SUMD(sum1, sum2, sumd);
+ } else if (tcp->th_dport != nat->nat_outport) {
+ /*
+ * Fix ICMP checksum to compensate port
+ * adjustment.
+ */
+ sum1 = ntohs(nat->nat_outport);
+ sum2 = ntohs(tcp->th_dport);
+ tcp->th_dport = nat->nat_outport;
+
+ /*
+ * Fix udp checksum to compensate port
+ * adjustment. NOTE : the offending IP
+ * packet flows the other direction compared
+ * to the ICMP message.
+ *
+ * The UDP checksum is optional, only adjust
+ * it if it has been set.
+ */
+ if ((oip->ip_p == IPPROTO_UDP) &&
+ (dlen >= 8) && udp->uh_sum) {
+ sumd = sum1 - sum2;
sumd2 += sumd;
- tcp->th_dport = nat->nat_outport;
+
+ sum1 = ntohs(udp->uh_sum);
+ fix_datacksum(&udp->uh_sum, sumd);
+ sum2 = ntohs(udp->uh_sum);
/*
- * Fix udp checksum to compensate port
- * adjustment. NOTE : the offending IP
- * packet flows the other direction compared
- * to the ICMP message.
- *
- * The UDP checksum is optional, only adjust
- * it if it has been set.
+ * Fix ICMP checksum to compensate
+ * UDP checksum adjustment.
*/
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
+ CALC_SUMD(sum1, sum2, sumd);
+ }
- /*
- * Fix ICMP checksum to compensate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
+ /*
+ * Fix tcp checksum (if present) to compensate
+ * port adjustment. NOTE : the offending IP
+ * packet flows the other direction compared to
+ * the ICMP message.
+ */
+ if (oip->ip_p == IPPROTO_TCP) {
+ if (dlen >= 18) {
+ sumd = sum1 - sum2;
sumd2 += sumd;
- }
-
- /*
- * Fix tcp checksum (if present) to compensate
- * port adjustment. NOTE : the offending IP
- * packet flows the other direction compared to
- * the ICMP message.
- */
- if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
sum1 = ntohs(tcp->th_sum);
fix_datacksum(&tcp->th_sum, sumd);
@@ -1995,18 +1965,18 @@ int dir;
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
+ } else {
+ sumd = sum2 - sum1;
+ if (nat->nat_dir == NAT_OUTBOUND)
+ sumd++;
}
}
+ sumd2 += sumd;
}
if (sumd2) {
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- if (nat->nat_dir == NAT_OUTBOUND) {
- fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
- } else {
- fix_incksum(fin, &icmp->icmp_cksum, sumd2);
- }
+ fix_incksum(fin, &icmp->icmp_cksum, sumd2);
}
}
if (oip->ip_p == IPPROTO_ICMP)
@@ -2476,13 +2446,9 @@ maskloop:
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_outcksum(fin, &ip->ip_sum, sumd);
- else
- fix_incksum(fin, &ip->ip_sum, sumd);
+ fix_outcksum(fin, &ip->ip_sum, sumd);
}
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) || !defined(_KERNEL)
else {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
@@ -2510,7 +2476,8 @@ maskloop:
if (nat->nat_age < fr_defnaticmpage)
nat->nat_age = fr_defnaticmpage;
#ifdef LARGE_NAT
- else if (nat->nat_age > fr_defnatage)
+ else if ((!np || !np->in_age[1]) &&
+ (nat->nat_age > fr_defnatage))
nat->nat_age = fr_defnatage;
#endif
/*
@@ -2703,19 +2670,19 @@ maskloop:
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
MUTEX_EXIT(&nat->nat_lock);
- ip->ip_dst = nat->nat_inip;
- fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
/*
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
else
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
-#endif
+
+ ip->ip_dst = nat->nat_inip;
+ fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
+
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
if ((nat->nat_inport != 0) && (tcp != NULL)) {
@@ -2731,7 +2698,8 @@ maskloop:
if (nat->nat_age < fr_defnaticmpage)
nat->nat_age = fr_defnaticmpage;
#ifdef LARGE_NAT
- else if (nat->nat_age > fr_defnatage)
+ else if ((!np || !np->in_age[0]) &&
+ (nat->nat_age > fr_defnatage))
nat->nat_age = fr_defnatage;
#endif
/*
@@ -2983,7 +2951,7 @@ u_short *csump;
if (&cp[1] >= ep)
break;
advance = cp[1];
- if (&cp[advance] >= ep)
+ if (&cp[advance] > ep)
break;
switch (opt) {
case TCPOPT_MAXSEG:
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index e052449..14e9d25 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.28 2002/11/03 13:06:21 darrenr Exp $
+ * $Id: ip_nat.h,v 2.17.2.32 2004/02/11 15:16:37 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -34,26 +34,39 @@
* a setup with 1000-2000 networks to NAT.
*/
#ifndef NAT_SIZE
-# define NAT_SIZE 127
+# ifdef LARGE_NAT
+# define NAT_SIZE 2047
+# else
+# define NAT_SIZE 127
+# endif
#endif
#ifndef RDR_SIZE
-# define RDR_SIZE 127
+# ifdef LARGE_NAT
+# define RDR_SIZE 2047
+# else
+# define RDR_SIZE 127
+# endif
#endif
#ifndef HOSTMAP_SIZE
-# define HOSTMAP_SIZE 127
+# ifdef LARGE_NAT
+# define HOSTMAP_SIZE 8191
+# else
+# define HOSTMAP_SIZE 2047
+# endif
#endif
-#ifndef NAT_TABLE_SZ
-# define NAT_TABLE_SZ 127
+#ifndef NAT_TABLE_MAX
+# ifdef LARGE_NAT
+# define NAT_TABLE_MAX 180000
+# else
+# define NAT_TABLE_MAX 30000
+# endif
#endif
-#ifdef LARGE_NAT
-#undef NAT_SIZE
-#undef RDR_SIZE
-#undef NAT_TABLE_SZ
-#undef HOSTMAP_SIZE 127
-#define NAT_SIZE 2047
-#define RDR_SIZE 2047
-#define NAT_TABLE_SZ 16383
-#define HOSTMAP_SIZE 8191
+#ifndef NAT_TABLE_SZ
+# ifdef LARGE_NAT
+# define NAT_TABLE_SZ 16383
+# else
+# define NAT_TABLE_SZ 2047
+# endif
#endif
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
diff --git a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
index ddd5ea3..12d3981 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.8 2002/01/13 04:58:29 darrenr Exp $
+ * $Id: ip_raudio_pxy.c,v 1.7.2.9 2003/04/26 05:59:39 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@@ -66,9 +66,6 @@ nat_t *nat;
tcphdr_t *tcp;
int len = 0;
mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
/*
* If we've already processed the start messages, then nothing left
@@ -181,9 +178,6 @@ nat_t *nat;
nat_t *ipn;
u_char swp;
mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
/*
* Wait until we've seen the end of the start messages and even then
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 3fecf49..93cd32b 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.6 2002/10/01 15:24:59 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.4.2.7 2003/04/26 05:59:39 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -88,9 +88,6 @@ nat_t *nat;
u_short sp;
nat_t *ipn;
mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
tcp = (tcphdr_t *)fin->fin_dp;
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 5ab78cc..4934279 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -93,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.77 2002/12/06 11:40:24 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.88 2004/01/05 12:46:05 darrenr Exp $";
#endif
#ifndef MIN
@@ -921,7 +921,8 @@ tcphdr_t *tcp;
fdata->td_wscale = wscale;
else if (wscale == -2)
fdata->td_wscale = tdata->td_wscale = 0;
- win <<= fdata->td_wscale;
+ if (!(tcp->th_flags & TH_SYN))
+ win <<= fdata->td_wscale;
if ((fdata->td_end == 0) &&
(!is->is_fsm || ((tcp->th_flags & TH_OPENING) == TH_OPENING))) {
@@ -955,14 +956,15 @@ tcphdr_t *tcp;
(SEQ_GE(seq, fdata->td_end - maxwin)) &&
/* XXX what about big packets */
#define MAXACKWINDOW 66000
- (ackskew >= -MAXACKWINDOW) &&
- (ackskew <= MAXACKWINDOW)) {
- /* if ackskew < 0 then this should be due to fragented
+ (-ackskew <= (MAXACKWINDOW << tdata->td_wscale)) &&
+ ( ackskew <= (MAXACKWINDOW << tdata->td_wscale))) {
+
+ /* if ackskew < 0 then this should be due to fragmented
* packets. There is no way to know the length of the
* total packet in advance.
* We do know the total length from the fragment cache though.
* Note however that there might be more sessions with
- * exactly the same source and destination paramters in the
+ * exactly the same source and destination parameters in the
* state cache (and source and destination is the only stuff
* that is saved in the fragment cache). Note further that
* some TCP connections in the state cache are hashed with
@@ -1208,6 +1210,10 @@ fr_info_t *fin;
oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
ohlen = oip->ip_hl << 2;
+ /*
+ * Check if the at least the old IP header (with options) and
+ * 8 bytes of payload is present.
+ */
if (fin->fin_plen < ICMPERR_MAXPKTLEN + ohlen - sizeof(*oip))
return NULL;
@@ -1224,7 +1230,7 @@ fr_info_t *fin;
* may be too big to be in this buffer but not so big that it's
* outside the ICMP packet, leading to TCP deref's causing problems.
* This is possible because we don't know how big oip_hl is when we
- * do the pullup early in fr_check() and thus can't gaurantee it is
+ * do the pullup early in fr_check() and thus can't guarantee it is
* all here now.
*/
#ifdef _KERNEL
@@ -1251,9 +1257,43 @@ fr_info_t *fin;
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
bzero((char *)&ofin, sizeof(ofin));
+ /*
+ * We make an fin entry to be able to feed it to
+ * matchsrcdst. Note that not all fields are encessary
+ * but this is the cleanest way. Note further that we
+ * fill in fin_mp such that if someone uses it we'll get
+ * a kernel panic. fr_matchsrcdst does not use this.
+ */
ofin.fin_ifp = fin->fin_ifp;
ofin.fin_out = !fin->fin_out;
+ ofin.fin_mp = NULL;
ofin.fin_v = 4;
+ /*
+ * watch out here, as ip is in host order and oip in network
+ * order. Any change we make must be undone afterwards, like
+ * oip->ip_off - it is still in network byte order so fix it.
+ */
+ savelen = oip->ip_len;
+ oip->ip_len = len;
+ oip->ip_off = ntohs(oip->ip_off);
+ (void) fr_makefrip(ohlen, oip, &ofin);
+ /*
+ * Reset the short flag here because in fr_matchsrcdst() the flags
+ * for the current packet (fin_fl) are compared against * those for
+ * the existing session.
+ */
+ ofin.fin_fl &= ~FI_SHORT;
+
+ /*
+ * Put old values of ip_len and ip_off back as we don't know
+ * if we have to forward the packet (or process it again.
+ */
+ oip->ip_len = savelen;
+ oip->ip_off = htons(oip->ip_off);
+
+#if SOLARIS
+ ofin.fin_qfm = NULL;
+#endif
fr = NULL;
switch (oip->ip_p)
@@ -1262,7 +1302,7 @@ fr_info_t *fin;
icmp = (icmphdr_t *)((char *)oip + ohlen);
/*
- * a ICMP error can only be generated as a result of an
+ * an ICMP error can only be generated as a result of an
* ICMP query, not as the response on an ICMP error
*
* XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -1286,18 +1326,15 @@ fr_info_t *fin;
hv += icmp->icmp_seq;
hv %= fr_statesize;
- savelen = oip->ip_len;
- oip->ip_len = len;
- fr_makefrip(ohlen, oip, &ofin);
- oip->ip_len = savelen;
-
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == 4) &&
+ (is->is_icmppkts < is->is_pkts) &&
fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
- fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
+ fr_matchicmpqueryreply(is->is_v, is, icmp,
+ fin->fin_rev)) {
ips_stats.iss_hits++;
- is->is_pkts++;
+ is->is_icmppkts++;
is->is_bytes += ip->ip_len;
fr = is->is_rule;
break;
@@ -1326,20 +1363,7 @@ fr_info_t *fin;
hv += dport;
hv += sport;
hv %= fr_statesize;
- /*
- * we make an fin entry to be able to feed it to
- * matchsrcdst note that not all fields are encessary
- * but this is the cleanest way. Note further we fill
- * in fin_mp such that if someone uses it we'll get
- * a kernel panic. fr_matchsrcdst does not use this.
- *
- * watch out here, as ip is in host order and oip in network
- * order. Any change we make must be undone afterwards.
- */
- savelen = oip->ip_len;
- oip->ip_len = len;
- fr_makefrip(ohlen, oip, &ofin);
- oip->ip_len = savelen;
+
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
/*
@@ -1347,13 +1371,16 @@ fr_info_t *fin;
* encapsulated packet was allowed through the
* other way around. Note that the minimal amount
* of info present does not allow for checking against
- * tcp internals such as seq and ack numbers.
+ * tcp internals such as seq and ack numbers. Only the
+ * ports are known to be present and can be even if the
+ * short flag is set.
*/
if ((is->is_p == pr) && (is->is_v == 4) &&
+ (is->is_icmppkts < is->is_pkts) &&
fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
fr = is->is_rule;
ips_stats.iss_hits++;
- is->is_pkts++;
+ is->is_icmppkts++;
is->is_bytes += fin->fin_plen;
/*
* we deliberately do not touch the timeouts
@@ -1675,8 +1702,8 @@ void *ifp;
for (is = ips_list; is; is = is->is_next) {
for (i = 0; i < 4; i++) {
if (is->is_ifp[i] == ifp) {
- is->is_ifpin = GETUNIT(is->is_ifname[i],
- is->is_v);
+ is->is_ifp[i] = GETUNIT(is->is_ifname[i],
+ is->is_v);
if (!is->is_ifp[i])
is->is_ifp[i] = (void *)-1;
}
@@ -1843,17 +1870,41 @@ int dir, fsm;
state[dir] = TCPS_SYN_SENT;
newage = fr_tcptimeout;
}
+
+ /*
+ * It is apparently possible that a hosts sends two syncs
+ * before the remote party is able to respond with a SA. In
+ * such a case the remote server sometimes ACK's the second
+ * sync, and then responds with a SA. The following code
+ * is used to prevent this ack from being blocked.
+ *
+ * We do not reset the timeout here to fr_tcptimeout because
+ * a connection connect timeout does not renew after every
+ * packet that is sent. We need to set newage to something
+ * to indicate the packet has passed the check for its flags
+ * being valid in the TCP FSM.
+ */
+ else if ((ostate == TCPS_SYN_SENT) &&
+ ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK)) {
+ newage = *age;
+ }
+
/*
* The next piece of code makes it possible to get
* already established connections into the state table
* after a restart or reload of the filter rules; this
* does not work when a strict 'flags S keep state' is
- * used for tcp connections of course
+ * used for tcp connections of course, however, use a
+ * lower time-out so the state disappears quickly if
+ * the other side does not pick it up.
*/
- if (!fsm && (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
+ else if (!fsm &&
+ (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
- if (state[1 - dir] == TCPS_CLOSED ||
- state[1 - dir] == TCPS_ESTABLISHED) {
+ if (ostate == TCPS_CLOSED) {
+ state[dir] = TCPS_ESTABLISHED;
+ newage = fr_tcptimeout;
+ } else if (ostate == TCPS_ESTABLISHED) {
state[dir] = TCPS_ESTABLISHED;
newage = fr_tcpidletimeout;
}
@@ -2056,7 +2107,7 @@ u_int type;
int types[1];
ipsl.isl_type = type;
- ipsl.isl_pkts = is->is_pkts;
+ ipsl.isl_pkts = is->is_pkts + is->is_icmppkts;
ipsl.isl_bytes = is->is_bytes;
ipsl.isl_src = is->is_src;
ipsl.isl_dst = is->is_dst;
@@ -2084,7 +2135,11 @@ u_int type;
sizes[0] = sizeof(ipsl);
types[0] = 0;
- (void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
+ if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) {
+ ATOMIC_INCL(ips_stats.iss_logged);
+ } else {
+ ATOMIC_INCL(ips_stats.iss_logfail);
+ }
}
#endif
@@ -2134,12 +2189,30 @@ fr_info_t *fin;
bzero((char *)&ofin, sizeof(ofin));
ofin.fin_out = !fin->fin_out;
ofin.fin_ifp = fin->fin_ifp;
+ ofin.fin_mp = NULL;
ofin.fin_v = 6;
+#if SOLARIS
+ ofin.fin_qfm = NULL;
+#endif
+ /*
+ * We make a fin entry to be able to feed it to
+ * matchsrcdst. Note that not all fields are necessary
+ * but this is the cleanest way. Note further we fill
+ * in fin_mp such that if someone uses it we'll get
+ * a kernel panic. fr_matchsrcdst does not use this.
+ *
+ * watch out here, as ip is in host order and oip in network
+ * order. Any change we make must be undone afterwards.
+ */
+ savelen = oip->ip6_plen;
+ oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
+ fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
+ oip->ip6_plen = savelen;
if (oip->ip6_nxt == IPPROTO_ICMPV6) {
oic = (struct icmp6_hdr *)(oip + 1);
/*
- * a ICMP error can only be generated as a result of an
+ * an ICMP error can only be generated as a result of an
* ICMP query, not as the response on an ICMP error
*
* XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -2160,10 +2233,6 @@ fr_info_t *fin;
hv += oic->icmp6_seq;
hv %= fr_statesize;
- oip->ip6_plen = ntohs(oip->ip6_plen);
- fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
- oip->ip6_plen = htons(oip->ip6_plen);
-
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) &&
@@ -2207,20 +2276,7 @@ fr_info_t *fin;
hv += dport;
hv += sport;
hv %= fr_statesize;
- /*
- * we make an fin entry to be able to feed it to
- * matchsrcdst note that not all fields are encessary
- * but this is the cleanest way. Note further we fill
- * in fin_mp such that if someone uses it we'll get
- * a kernel panic. fr_matchsrcdst does not use this.
- *
- * watch out here, as ip is in host order and oip in network
- * order. Any change we make must be undone afterwards.
- */
- savelen = oip->ip6_plen;
- oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
- fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
- oip->ip6_plen = savelen;
+
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
/*
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index 35368c4..d155302 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.13 2002/06/27 14:40:29 darrenr Exp $
+ * $Id: ip_state.h,v 2.13.2.14 2003/11/15 11:47:46 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -62,6 +62,7 @@ typedef struct ipstate {
frentry_t *is_rule;
U_QUAD_T is_pkts;
U_QUAD_T is_bytes;
+ U_QUAD_T is_icmppkts;
union i6addr is_src;
union i6addr is_dst;
void *is_ifp[4];
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 2a23a44..b975ee9 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -4,12 +4,12 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.15.2.38 2002/12/07 02:40:05 darrenr Exp $
+ * $Id: ipl.h,v 2.15.2.44 2004/06/03 17:28:20 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.31"
+#define IPL_VERSION "IP Filter: v3.4.35"
#endif
OpenPOWER on IntegriCloud