summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2003-03-01 03:55:55 +0000
committerDarren Reed <darrenr@FreeBSD.org>2003-03-01 03:55:55 +0000
commit0d1d567f8c31d8736649c9472a40235d42470dbf (patch)
treea48c93964cf6a83bfe11ade470b278a7682bbf0c /sys
parent83cab3dcd16b8ec2bd3c8eb8ae232687452a9e38 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c64
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c120
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.c111
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h16
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c276
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c27
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c86
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c22
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h1
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c3
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c84
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h2
16 files changed, 625 insertions, 199 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index e852b17928d2..99916ee9e54a 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -99,7 +99,6 @@
#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.63 2002/08/28 12:40:08 darrenr Exp $"; */
static const char rcsid[] = "@(#)$FreeBSD$";
#endif
@@ -702,7 +701,8 @@ void *m;
if (!fr_tcpudpchk(&fr->fr_tuc, fin))
continue;
} else if (fr->fr_icmpm || fr->fr_icmp) {
- if ((fi->fi_p != IPPROTO_ICMP) || off ||
+ if (((fi->fi_p != IPPROTO_ICMP) &&
+ (fi->fi_p != IPPROTO_ICMPV6)) || off ||
(fin->fin_dlen < 2))
continue;
if ((fin->fin_data[0] & fr->fr_icmpm) != fr->fr_icmp) {
@@ -817,6 +817,26 @@ int out;
# endif
int up;
+# if !SOLARIS && !defined(NETBSD_PF) && \
+ ((defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
+ defined(__OpenBSD__) || defined(_BSDI_VERSION))
+ if (fr_checkp != fr_check && fr_running > 0) {
+ static int counter = 0;
+
+ if (counter == 0) {
+ printf("WARNING: fr_checkp corrupt: value %lx\n",
+ (u_long)fr_checkp);
+ printf("WARNING: fr_checkp should be %lx\n",
+ (u_long)fr_check);
+ printf("WARNING: fixing fr_checkp\n");
+ }
+ fr_checkp = fr_check;
+ counter++;
+ if (counter == 10000)
+ counter = 0;
+ }
+# endif
+
# ifdef M_CANFASTFWD
/*
* XXX For now, IP Filter and fast-forwarding of cached flows
@@ -1513,7 +1533,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.63 2002/08/28 12:40:08 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1719,9 +1739,9 @@ frentry_t **listp;
}
-int frflush(unit, flags)
+int frflush(unit, proto, flags)
minor_t unit;
-int flags;
+int proto, flags;
{
int flushed = 0, set;
@@ -1736,19 +1756,35 @@ int flags;
if (flags & FR_OUTQUE) {
#ifdef USE_INET6
- (void) frflushlist(set, unit, &flushed, &ipfilter6[1][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct6[1][set]);
+ if (proto == 0 || proto == 6) {
+ (void) frflushlist(set, unit,
+ &flushed, &ipfilter6[1][set]);
+ (void) frflushlist(set, unit,
+ &flushed, &ipacct6[1][set]);
+ }
#endif
- (void) frflushlist(set, unit, &flushed, &ipfilter[1][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct[1][set]);
+ if (proto == 0 || proto == 4) {
+ (void) frflushlist(set, unit,
+ &flushed, &ipfilter[1][set]);
+ (void) frflushlist(set, unit,
+ &flushed, &ipacct[1][set]);
+ }
}
if (flags & FR_INQUE) {
#ifdef USE_INET6
- (void) frflushlist(set, unit, &flushed, &ipfilter6[0][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct6[0][set]);
+ if (proto == 0 || proto == 6) {
+ (void) frflushlist(set, unit,
+ &flushed, &ipfilter6[0][set]);
+ (void) frflushlist(set, unit,
+ &flushed, &ipacct6[0][set]);
+ }
#endif
- (void) frflushlist(set, unit, &flushed, &ipfilter[0][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct[0][set]);
+ if (proto == 0 || proto == 4) {
+ (void) frflushlist(set, unit,
+ &flushed, &ipfilter[0][set]);
+ (void) frflushlist(set, unit,
+ &flushed, &ipacct[0][set]);
+ }
}
RWLOCK_EXIT(&ipf_mutex);
return flushed;
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index 4e3af57e4bc8..ff0d0770cd54 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -293,9 +293,9 @@ ip_t *ip;
cv_signal(&ipfauthwait);
#else
# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
- if (!fin->fin_out) {
- HTONS(ip->ip_len);
- HTONS(ip->ip_off);
+ if (fin->fin_out == 0) {
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
}
# endif
fr_authpkts[i] = m;
@@ -305,7 +305,7 @@ ip_t *ip;
}
-int fr_auth_ioctl(data, mode, cmd, fr, frptr)
+int fr_auth_ioctl(data, mode, cmd)
caddr_t data;
int mode;
#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
@@ -313,7 +313,6 @@ u_long cmd;
#else
int cmd;
#endif
-frentry_t *fr, **frptr;
{
mb_t *m;
#if defined(_KERNEL) && !SOLARIS
@@ -321,12 +320,15 @@ frentry_t *fr, **frptr;
int s;
#endif
frauth_t auth, *au = &auth, *fra;
- frauthent_t *fae, **faep;
int i, error = 0;
switch (cmd)
{
case SIOCSTLCK :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
error = fr_lock(data, &fr_auth_lock);
break;
case SIOCINIFR :
@@ -339,45 +341,8 @@ frentry_t *fr, **frptr;
break;
case SIOCRMAFR :
case SIOCADAFR :
- for (faep = &fae_list; (fae = *faep); )
- if (&fae->fae_fr == fr)
- break;
- else
- faep = &fae->fae_next;
- if (cmd == SIOCRMAFR) {
- if (!fr || !frptr)
- error = EINVAL;
- else if (!fae)
- error = ESRCH;
- else {
- WRITE_ENTER(&ipf_auth);
- SPL_NET(s);
- *faep = fae->fae_next;
- *frptr = fr->fr_next;
- SPL_X(s);
- RWLOCK_EXIT(&ipf_auth);
- KFREE(fae);
- }
- } else if (fr && frptr) {
- KMALLOC(fae, frauthent_t *);
- if (fae != NULL) {
- bcopy((char *)fr, (char *)&fae->fae_fr,
- sizeof(*fr));
- WRITE_ENTER(&ipf_auth);
- SPL_NET(s);
- fae->fae_age = fr_defaultauthage;
- fae->fae_fr.fr_hits = 0;
- fae->fae_fr.fr_next = *frptr;
- *frptr = &fae->fae_fr;
- fae->fae_next = *faep;
- *faep = fae;
- ipauth = &fae_list->fae_fr;
- SPL_X(s);
- RWLOCK_EXIT(&ipf_auth);
- } else
- error = ENOMEM;
- } else
- error = EINVAL;
+ /* These commands go via request to fr_preauthcmd */
+ error = EINVAL;
break;
case SIOCATHST:
fr_authstats.fas_faelist = fae_list;
@@ -632,3 +597,66 @@ void fr_authexpire()
RWLOCK_EXIT(&ipf_auth);
SPL_X(s);
}
+
+int fr_preauthcmd(cmd, fr, frptr)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || \
+ (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
+u_long cmd;
+#else
+int cmd;
+#endif
+frentry_t *fr, **frptr;
+{
+ frauthent_t *fae, **faep;
+ int error = 0;
+#if defined(KERNEL) && !SOLARIS
+ int s;
+#endif
+
+ if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) {
+ /* Should not happen */
+ printf("fr_preauthcmd called with bad cmd 0x%lx", (u_long)cmd);
+ return EIO;
+ }
+
+ for (faep = &fae_list; (fae = *faep); )
+ if (&fae->fae_fr == fr)
+ break;
+ else
+ faep = &fae->fae_next;
+ if (cmd == SIOCRMAFR) {
+ if (!fr || !frptr)
+ error = EINVAL;
+ else if (!fae)
+ error = ESRCH;
+ else {
+ WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
+ *faep = fae->fae_next;
+ *frptr = fr->fr_next;
+ SPL_X(s);
+ RWLOCK_EXIT(&ipf_auth);
+ KFREE(fae);
+ }
+ } else if (fr && frptr) {
+ KMALLOC(fae, frauthent_t *);
+ if (fae != NULL) {
+ bcopy((char *)fr, (char *)&fae->fae_fr,
+ sizeof(*fr));
+ WRITE_ENTER(&ipf_auth);
+ SPL_NET(s);
+ fae->fae_age = fr_defaultauthage;
+ fae->fae_fr.fr_hits = 0;
+ fae->fae_fr.fr_next = *frptr;
+ *frptr = &fae->fae_fr;
+ fae->fae_next = *faep;
+ *faep = fae;
+ ipauth = &fae_list->fae_fr;
+ SPL_X(s);
+ RWLOCK_EXIT(&ipf_auth);
+ } else
+ error = ENOMEM;
+ } else
+ error = EINVAL;
+ return error;
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 24263345a509..4136e96ac3ee 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -55,8 +55,10 @@ extern mb_t *fr_authpkts[];
extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
#if defined(__NetBSD__) || defined(__OpenBSD__) || \
(__FreeBSD_version >= 300003)
-extern int fr_auth_ioctl __P((caddr_t, int, u_long, frentry_t *, frentry_t **));
+extern int fr_preauthcmd __P((u_long, frentry_t *, frentry_t **));
+extern int fr_auth_ioctl __P((caddr_t, int, u_long));
#else
-extern int fr_auth_ioctl __P((caddr_t, int, int, frentry_t *, frentry_t **));
+extern int fr_preauthcmd __P((int, frentry_t *, frentry_t **));
+extern int fr_auth_ioctl __P((caddr_t, int, int));
#endif
#endif /* __IP_AUTH_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 167da07cb58d..8a78a04892f5 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -533,6 +533,7 @@ extern ill_t *get_unit __P((char *, int));
# ifdef sun
# if !SOLARIS
+# include <sys/time.h>
# include <sys/kmem_alloc.h>
# define GETUNIT(n, v) ifunit(n, IFNAMSIZ)
# define IFNAME(x) ((struct ifnet *)x)->if_name
@@ -655,6 +656,7 @@ extern vm_map_t kmem_map;
# define IWCOPYPTR iwcopyptr
# define IFNAME(x) get_ifname((struct ifnet *)x)
# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
+# include <sys/time.h>
extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
#endif /* KERNEL */
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c
index 4a10df6ce30d..129fcbba8da9 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil.c
@@ -24,7 +24,7 @@
# include <osreldate.h>
# endif
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# define _KMEMUSER
# include <sys/ptimers.h>
#endif
@@ -117,6 +117,10 @@
# include <sys/kernel.h>
extern int ip_optcopy __P((struct ip *, struct ip *));
#endif
+#if defined(OpenBSD) && (OpenBSD >= 200211) && defined(_KERNEL)
+extern int ip6_getpmtu(struct route_in6 *, struct route_in6 *,
+ struct ifnet *, struct in6_addr *, u_long *);
+#endif
#include <machine/in_cksum.h>
@@ -195,6 +199,15 @@ struct timeout ipfr_slowtimer_ch;
toid_t ipfr_slowtimer_ch;
#endif
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) && \
+ defined(_KERNEL)
+# include <sys/conf.h>
+const struct cdevsw ipl_cdevsw = {
+ iplopen, iplclose, iplread, nowrite, iplioctl,
+ nostop, notty, nopoll, nommap,
+};
+#endif
+
#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
# include <sys/device.h>
# include <sys/conf.h>
@@ -322,7 +335,7 @@ int count;
# endif
-# if defined(__NetBSD__)
+# if defined(__NetBSD__) || defined(__OpenBSD__)
int ipl_enable()
# else
int iplattach()
@@ -366,10 +379,13 @@ int iplattach()
# ifdef NETBSD_PF
# if (__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011)
# if __NetBSD_Version__ >= 105110000
- if (
- !(ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET))
+ ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+# ifdef USE_INET6
+ ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+# endif
+ if (ph_inet == NULL
# ifdef USE_INET6
- && !(ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6))
+ && ph_inet6 == NULL
# endif
)
return ENODEV;
@@ -487,7 +503,8 @@ int ipldetach()
# endif
{
int s, i;
-#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
+#if defined(NETBSD_PF) && \
+ ((__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);
@@ -527,8 +544,8 @@ int ipldetach()
printf("%s unloaded\n", ipfilter_version);
fr_checkp = fr_savep;
- i = frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
- i += frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE);
+ i = frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE);
+ i += frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE);
fr_running = 0;
# ifdef NETBSD_PF
@@ -673,7 +690,16 @@ int mode;
if (!fr_running)
error = EIO;
else
- error = fr_auth_ioctl(data, mode, cmd, NULL, NULL);
+ if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) {
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ } else {
+ error = frrequest(unit, cmd, data,
+ fr_active);
+ }
+ } else {
+ error = fr_auth_ioctl(data, mode, cmd);
+ }
SPL_X(s);
return error;
}
@@ -697,7 +723,7 @@ int mode;
if (error)
break;
if (enable)
-# if defined(__NetBSD__)
+# if defined(__NetBSD__) || defined(__OpenBSD__)
error = ipl_enable();
# else
error = iplattach();
@@ -770,12 +796,26 @@ int mode;
else {
error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
if (!error) {
- tmp = frflush(unit, tmp);
+ tmp = frflush(unit, 4, tmp);
error = IWCOPY((caddr_t)&tmp, data,
sizeof(tmp));
}
}
break;
+#ifdef USE_INET6
+ case SIOCIPFL6 :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
+ if (!error) {
+ tmp = frflush(unit, 6, tmp);
+ error = IWCOPY((caddr_t)&tmp, data,
+ sizeof(tmp));
+ }
+ }
+ break;
+#endif
case SIOCSTLCK :
error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
if (!error) {
@@ -800,12 +840,6 @@ int mode;
if (error)
error = EFAULT;
break;
- case SIOCAUTHW :
- case SIOCAUTHR :
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
case SIOCFRSYN :
if (!(mode & FWRITE))
error = EPERM;
@@ -1011,6 +1045,9 @@ caddr_t data;
return EBUSY;
if (fg && fg->fg_head)
fg->fg_head->fr_ref--;
+ if (unit == IPL_LOGAUTH) {
+ return fr_preauthcmd(req, f, ftail);
+ }
if (f->fr_grhead)
fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
unit, set);
@@ -1025,6 +1062,9 @@ caddr_t data;
if (f)
error = EEXIST;
else {
+ if (unit == IPL_LOGAUTH) {
+ return fr_preauthcmd(req, fp, ftail);
+ }
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
@@ -1250,7 +1290,8 @@ struct mbuf **mp;
ip->ip_tos = oip->ip_tos;
ip->ip_id = oip->ip_id;
-# if defined(__NetBSD__) || defined(__OpenBSD__)
+# if defined(__NetBSD__) || \
+ (defined(__OpenBSD__) && (OpenBSD >= 200012))
if (ip_mtudisc != 0)
ip->ip_off = IP_DF;
# else
@@ -1485,7 +1526,7 @@ void
iplinit()
{
-# if defined(__NetBSD__)
+# if defined(__NetBSD__) || defined(__OpenBSD__)
if (ipl_enable() != 0)
# else
if (iplattach() != 0)
@@ -1590,7 +1631,7 @@ frdest_t *fdp;
/*
* Route packet.
*/
-#ifdef __sgi
+#if defined(__sgi) && (IRIX >= 605)
ROUTE_RDLOCK();
#endif
bzero((caddr_t)ro, sizeof (*ro));
@@ -1630,7 +1671,7 @@ frdest_t *fdp;
rtalloc(ro);
# endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
ROUTE_UNLOCK();
#endif
@@ -1901,6 +1942,12 @@ frdest_t *fdp;
struct route_in6 *ro;
struct ifnet *ifp;
frentry_t *fr;
+#if defined(OpenBSD) && (OpenBSD >= 200211)
+ struct route_in6 *ro_pmtu = NULL;
+ struct in6_addr finaldst;
+ ip6_t *ip6;
+#endif
+ u_long mtu;
int error;
ifp = NULL;
@@ -1938,11 +1985,23 @@ frdest_t *fdp;
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 defined(OpenBSD) && (OpenBSD >= 200211)
+ ip6 = mtod(m0, ip6_t *);
+ ro_pmtu = ro;
+ finaldst = ip6->ip6_dst;
+ error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu);
+ if (error == 0) {
+#else
+ mtu = nd_ifinfo[ifp->if_index].linkmtu;
+#endif
+ if (m0->m_pkthdr.len <= mtu)
+ error = nd6_output(ifp, fin->fin_ifp, m0,
+ dst6, ro->ro_rt);
+ else
+ error = EMSGSIZE;
+#if defined(OpenBSD) && (OpenBSD >= 200211)
+ }
+#endif
}
if (ro->ro_rt != NULL) {
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index e3ca7f3a3d55..f987789c210c 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -64,6 +64,7 @@
# define SIOCSTGET _IOWR('r', 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR('r', 82, struct natget)
# define SIOCGFRST _IOWR('r', 83, struct ipfrstat *)
+# define SIOCIPFL6 _IOWR('r', 84, int)
#else
# define SIOCADAFR _IOW(r, 60, struct frentry *)
# define SIOCRMAFR _IOW(r, 61, struct frentry *)
@@ -89,6 +90,7 @@
# define SIOCSTGET _IOWR(r, 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR(r, 82, struct natget)
# define SIOCGFRST _IOWR(r, 83, struct ipfrstat *)
+# define SIOCIPFL6 _IOWR(r, 84, int)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
@@ -413,14 +415,16 @@ typedef struct frgroup {
* structure which is then followed by any packet data.
*/
typedef struct iplog {
- u_32_t ipl_magic;
- u_int ipl_count;
- u_long ipl_sec;
- u_long ipl_usec;
- size_t ipl_dsize;
+ u_32_t ipl_magic;
+ u_int ipl_count;
+ struct timeval ipl_tv;
+ size_t ipl_dsize;
struct iplog *ipl_next;
} iplog_t;
+#define ipl_sec ipl_tv.tv_sec
+#define ipl_usec ipl_tv.tv_usec
+
#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
#define IPLOG_SIZE sizeof(iplog_t)
@@ -614,7 +618,7 @@ 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 int frflush __P((minor_t, int, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
extern void fr_delgroup __P((u_32_t, u_32_t, minor_t, int));
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index a4fa134b8218..c303f6668835 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -7,7 +7,7 @@
# define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index 457e717d1d91..7a74a2cfc18b 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -38,24 +38,30 @@ extern kmutex_t ipf_rw;
#define FTPXY_PASS_2 14
#define FTPXY_PAOK_2 15
+/*
+ * Values for FTP commands. Numerics cover 0-999
+ */
+#define FTPXY_C_PASV 1000
+
int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_complete __P((char *, size_t));
int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_init __P((void));
int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
+int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_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((int, char *, size_t));
-int ippr_ftp_server_valid __P((char *, size_t));
-int ippr_ftp_client_valid __P((char *, size_t));
+int ippr_ftp_valid __P((ftpinfo_t *, int, char *, size_t));
+int ippr_ftp_server_valid __P((ftpside_t *, char *, size_t));
+int ippr_ftp_client_valid __P((ftpside_t *, char *, size_t));
u_short ippr_ftp_atoi __P((char **));
static frentry_t ftppxyfr;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0;
+int ippr_ftp_forcepasv = 0;
/*
@@ -122,8 +128,13 @@ int dlen;
/*
* Check for client sending out PORT message.
*/
- if (dlen < IPF_MINPORTLEN)
+ if (dlen < IPF_MINPORTLEN) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", dlen);
+#endif
return 0;
+ }
off = fin->fin_hlen + (tcp->th_off << 2);
/*
* Skip the PORT command + space
@@ -133,23 +144,39 @@ int dlen;
* Pick out the address components, two at a time.
*/
a1 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(1) failed\n");
+#endif
return 0;
+ }
a2 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(2) failed\n");
+#endif
return 0;
+ }
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
- if (a1 != ntohl(nat->nat_inip.s_addr))
+ if (a1 != ntohl(nat->nat_inip.s_addr)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:a1 != nat->nat_inip\n");
+#endif
return 0;
+ }
a5 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(3) failed\n");
+#endif
return 0;
+ }
if (*s == ')')
s++;
@@ -161,8 +188,12 @@ int dlen;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
- } else
+ } else {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:missing cr-lf\n");
+#endif
return 0;
+ }
a5 >>= 8;
a5 &= 0xff;
/*
@@ -180,8 +211,13 @@ int dlen;
nlen = strlen(newbuf);
inc = nlen - olen;
- if ((inc + ip->ip_len) > 65535)
+ if ((inc + ip->ip_len) > 65535) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", inc);
+#endif
return 0;
+ }
#if !defined(_KERNEL)
m = *((mb_t **)fin->fin_mp);
@@ -252,8 +288,13 @@ int dlen;
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
- if (sp < 1024)
+ if (sp < 1024) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:sp(%d) < 1024\n", sp);
+#endif
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
@@ -368,11 +409,11 @@ int dlen;
}
-int ippr_ftp_pasv(fin, ip, nat, f, dlen)
+int ippr_ftp_pasv(fin, ip, nat, ftp, dlen)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
-ftpside_t *f;
+ftpinfo_t *ftp;
int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
@@ -380,23 +421,45 @@ int dlen;
u_int a1, a2, a3, a4;
u_short a5, a6, dp;
fr_info_t fi;
+ ftpside_t *f;
nat_t *ipn;
int inc;
char *s;
+ if (ippr_ftp_forcepasv != 0 &&
+ ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
+ ftp->ftp_side[0].ftps_cmds);
+#endif
+ return 0;
+ }
+
+ f = &ftp->ftp_side[1];
+
#define PASV_REPLEN 24
/*
* Check for PASV reply message.
*/
- if (dlen < IPF_MIN227LEN)
+ if (dlen < IPF_MIN227LEN) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", dlen);
+#endif
return 0;
- else if (strncmp(f->ftps_rptr, "227 Entering Passive Mod", PASV_REPLEN))
+ } else if (strncmp(f->ftps_rptr,
+ "227 Entering Passive Mod", PASV_REPLEN)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:227 reply wrong\n");
+#endif
return 0;
+ }
tcp = (tcphdr_t *)fin->fin_dp;
/*
- * Skip the PORT command + space
+ * Skip the PASV reply + space
*/
s = f->ftps_rptr + PASV_REPLEN;
while (*s && !isdigit(*s))
@@ -405,11 +468,19 @@ int dlen;
* Pick out the address components, two at a time.
*/
a1 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(1) failed\n");
+#endif
return 0;
+ }
a2 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(2) failed\n");
+#endif
return 0;
+ }
/*
* check that IP address in the PORT/PASV reply is the same as the
@@ -417,12 +488,20 @@ int dlen;
*/
a1 <<= 16;
a1 |= a2;
- if (a1 != ntohl(nat->nat_oip.s_addr))
+ if (a1 != ntohl(nat->nat_oip.s_addr)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:a1 != nat->nat_oip\n");
+#endif
return 0;
+ }
a5 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(3) failed\n");
+#endif
return 0;
+ }
if (*s == ')')
s++;
@@ -436,8 +515,12 @@ int dlen;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
- } else
+ } else {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:missing cr-lf\n");
+#endif
return 0;
+ }
a5 >>= 8;
/*
* Calculate new address parts for 227 reply
@@ -579,9 +662,9 @@ int dlen;
return 0;
if (ftp->ftp_passok == FTPXY_GO) {
if (!strncmp(rptr, "227 ", 4))
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen);
} else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) {
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen);
} else if (*rptr == '5' || *rptr == '4')
ftp->ftp_passok = FTPXY_INIT;
else if (ftp->ftp_incok) {
@@ -607,6 +690,7 @@ int dlen;
}
}
ftp->ftp_incok = 0;
+
while ((*rptr++ != '\n') && (rptr < wptr))
;
f->ftps_rptr = rptr;
@@ -618,100 +702,150 @@ 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_client_valid(buf, len)
+int ippr_ftp_client_valid(ftps, buf, len)
+ftpside_t *ftps;
char *buf;
size_t len;
{
register char *s, c;
register size_t i = len;
+ char cmd[5];
- if (i < 5)
+ if (i < 5) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
+#endif
return 2;
+ }
s = buf;
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[0] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[1] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[2] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[3] = toupper(c);
c = *s++;
i--;
if ((c != ' ') && (c != '\r'))
- return 1;
+ goto bad_client_command;
} else if ((c != ' ') && (c != '\r'))
- return 1;
+ goto bad_client_command;
} else
- return 1;
+ goto bad_client_command;
} else
- return 1;
- } else
+ goto bad_client_command;
+ } else {
+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);
+#endif
return 1;
+ }
+
for (; i; i--) {
c = *s++;
- if (c == '\n')
+ if (c == '\n') {
+ cmd[4] = '\0';
+ if (!strcmp(cmd, "PASV"))
+ ftps->ftps_cmds = FTPXY_C_PASV;
+ else
+ ftps->ftps_cmds = 0;
return 0;
+ }
}
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_client_valid:junk after cmd[%s]\n", buf);
+#endif
return 2;
}
-int ippr_ftp_server_valid(buf, len)
+int ippr_ftp_server_valid(ftps, buf, len)
+ftpside_t *ftps;
char *buf;
size_t len;
{
register char *s, c;
register size_t i = len;
+ int cmd;
if (i < 5)
return 2;
s = buf;
c = *s++;
+ cmd = 0;
i--;
if (isdigit(c)) {
+ cmd = (c - '0') * 100;
c = *s++;
i--;
if (isdigit(c)) {
+ cmd += (c - '0') * 10;
c = *s++;
i--;
if (isdigit(c)) {
+ cmd += (c - '0');
c = *s++;
i--;
if ((c != '-') && (c != ' '))
- return 1;
+ goto bad_server_command;
} else
- return 1;
+ goto bad_server_command;
} else
- return 1;
- } else
+ goto bad_server_command;
+ } else {
+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);
+#endif
return 1;
+ }
+
for (; i; i--) {
c = *s++;
- if (c == '\n')
+ if (c == '\n') {
+ ftps->ftps_cmds = cmd;
return 0;
+ }
}
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_server_valid:junk after cmd[%s]\n", buf);
+#endif
return 2;
}
-int ippr_ftp_valid(side, buf, len)
+int ippr_ftp_valid(ftp, side, buf, len)
+ftpinfo_t *ftp;
int side;
char *buf;
size_t len;
{
+ ftpside_t *ftps;
int ret;
+ ftps = &ftp->ftp_side[side];
+
if (side == 0)
- ret = ippr_ftp_client_valid(buf, len);
+ ret = ippr_ftp_client_valid(ftps, buf, len);
else
- ret = ippr_ftp_server_valid(buf, len);
+ ret = ippr_ftp_server_valid(ftps, buf, len);
return ret;
}
@@ -813,9 +947,10 @@ int rv;
#endif
ok = 0;
- if (t->ftps_seq[0] == 0)
- t->ftps_seq[0] = thack, ok = 1;
- else {
+ if (t->ftps_seq[0] == 0) {
+ t->ftps_seq[0] = thack;
+ ok = 1;
+ } else {
if (ackoff == 0) {
if (t->ftps_seq[0] == thack)
ok = 1;
@@ -844,20 +979,24 @@ int rv;
#endif
if (!mlen) {
- if (t->ftps_seq[0] + ackoff != thack)
+ if (t->ftps_seq[0] + ackoff != thack) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_process:seq[0](%x) + ackoff(%x) != thack(%x)\n",
+ t->ftps_seq[0], ackoff, thack);
+#endif
return APR_ERR(1);
+ }
#if PROXY_DEBUG
printf("f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]);
#endif
if (tcp->th_flags & TH_FIN) {
- if (thseq + seqoff == f->ftps_seq[0] + 1 ||
- f->ftps_seq[0] + seqoff + 1 == thseq ||
- thseq + seqoff == f->ftps_seq[0] ||
- thseq == f->ftps_seq[0] + seqoff)
- ;
- else {
-#if PROXY_DEBUG
+ if (thseq == f->ftps_seq[1]) {
+ f->ftps_seq[0] = f->ftps_seq[1] - seqoff;
+ f->ftps_seq[1] = thseq + 1 - seqoff;
+ } else {
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
thseq, seqoff, f->ftps_seq[0]);
#endif
@@ -869,17 +1008,19 @@ int rv;
}
ok = 0;
- if (thseq == f->ftps_seq[0] || thseq == f->ftps_seq[1])
+ if ((thseq == f->ftps_seq[0]) || (thseq == f->ftps_seq[1])) {
ok = 1;
/*
* Retransmitted data packet.
*/
- else if (thseq + mlen == f->ftps_seq[0] ||
- thseq + mlen == f->ftps_seq[1])
+ } else if ((thseq + mlen == f->ftps_seq[0]) ||
+ (thseq + mlen == f->ftps_seq[1])) {
ok = 1;
+ }
+
if (ok == 0) {
inc = thseq - f->ftps_seq[0];
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
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]);
@@ -916,10 +1057,12 @@ int rv;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
- f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
+ wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
+ wptr - rptr);
if (f->ftps_junk == 0) {
f->ftps_cmds++;
len = wptr - rptr;
@@ -941,6 +1084,10 @@ int rv;
*/
if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) {
/* f->ftps_seq[1] += inc; */
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_process:cmds == 0 junk == 1\n");
+#endif
return APR_ERR(2);
}
@@ -984,18 +1131,17 @@ int rv;
/* f->ftps_seq[1] += inc; */
if (tcp->th_flags & TH_FIN)
f->ftps_seq[1]++;
-#ifndef _KERNEL
+#if PROXY_DEBUG
+# ifndef _KERNEL
mlen = mbuflen(m);
-#else
-# if SOLARIS
- mlen = msgdsize(m);
# else
+# if SOLARIS
+ mlen = msgdsize(m);
+# else
mlen = mbufchainlen(m);
+# endif
# endif
-#endif
- off = fin->fin_hlen + (tcp->th_off << 2);
mlen -= off;
-#if PROXY_DEBUG
printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen);
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 4e8488bbc575..7edba023627a 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -105,6 +105,9 @@
# include <netinet/tcp.h>
# include <netinet/udp.h>
# include <netinet/ip_icmp.h>
+# ifdef USE_INET6
+# include <netinet/icmp6.h>
+# endif
# include <netinet/ip_var.h>
# ifndef _KERNEL
# include <syslog.h>
@@ -217,6 +220,26 @@ mb_t *m;
break;
}
}
+#ifdef USE_INET6
+ else if (p == IPPROTO_ICMPV6) {
+ struct icmp6_hdr *icmp;
+
+ icmp = (struct icmp6_hdr *)fin->fin_dp;
+
+ /*
+ * For ICMPV6, if the packet is an error packet, also
+ * include the information about the packet which
+ * caused the error.
+ */
+ if (icmp->icmp6_type < 128) {
+ hlen += MIN(sizeof(struct icmp6_hdr) + 8,
+ fin->fin_dlen);
+ } else {
+ hlen += MIN(sizeof(struct icmp6_hdr),
+ fin->fin_dlen);
+ }
+ }
+#endif
}
/*
* Get the interface number and name to which this packet is
@@ -340,10 +363,10 @@ int *types, cnt;
ipl->ipl_dsize = len;
# ifdef _KERNEL
# if SOLARIS || defined(sun)
- uniqtime((struct timeval *)&ipl->ipl_sec);
+ uniqtime(&ipl->ipl_tv);
# else
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
- microtime((struct timeval *)&ipl->ipl_sec);
+ microtime(&ipl->ipl_tv);
# endif
# endif
# else
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 6b26d68bfb3d..135361d65b7b 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -9,7 +9,7 @@
#define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -149,6 +149,7 @@ 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));
static void nat_hostmapdel __P((struct hostmap *));
+static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
int nat_init()
@@ -457,8 +458,9 @@ int mode;
/*
* For add/delete, look to see if the NAT entry is already present
*/
- if (getlock == 1)
+ if (getlock == 1) {
WRITE_ENTER(&ipf_nat);
+ }
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
nat = &natd;
nat->in_flags &= IPN_USERFLAGS;
@@ -727,8 +729,9 @@ int mode;
error = EINVAL;
break;
}
- if (getlock == 1)
+ if (getlock == 1) {
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
+ }
done:
if (nt)
KFREE(nt);
@@ -1466,6 +1469,7 @@ int direction;
nat->nat_p = fin->fin_p;
nat->nat_bytes = 0;
nat->nat_pkts = 0;
+ nat->nat_mssclamp = np->in_mssclamp;
nat->nat_fr = fin->fin_fr;
if (nat->nat_fr != NULL) {
ATOMIC_INC32(nat->nat_fr->fr_ref);
@@ -2518,6 +2522,16 @@ maskloop:
*/
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
+
+ /*
+ * Do a MSS CLAMPING on a SYN packet,
+ * only deal IPv4 for now.
+ */
+ if (nat->nat_mssclamp &&
+ (tcp->th_flags & TH_SYN) != 0)
+ nat_mssclamp(tcp, nat->nat_mssclamp,
+ fin, csump);
+
MUTEX_EXIT(&nat->nat_lock);
} else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
@@ -2729,6 +2743,15 @@ maskloop:
*/
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
+ /*
+ * Do a MSS CLAMPING on a SYN packet,
+ * only deal IPv4 for now.
+ */
+ if (nat->nat_mssclamp &&
+ (tcp->th_flags & TH_SYN) != 0)
+ nat_mssclamp(tcp, nat->nat_mssclamp,
+ fin, csump);
+
MUTEX_EXIT(&nat->nat_lock);
} else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
@@ -2928,3 +2951,60 @@ void *ifp;
return;
}
#endif
+
+
+/*
+ * Check for MSS option and clamp it if necessary.
+ */
+static void nat_mssclamp(tcp, maxmss, fin, csump)
+tcphdr_t *tcp;
+u_32_t maxmss;
+fr_info_t *fin;
+u_short *csump;
+{
+ u_char *cp, *ep, opt;
+ int hlen, advance;
+ u_32_t mss, sumd;
+ u_short v;
+
+ hlen = tcp->th_off << 2;
+ if (hlen > sizeof(*tcp)) {
+ cp = (u_char *)tcp + sizeof(*tcp);
+ ep = (u_char *)tcp + hlen;
+
+ while (cp < ep) {
+ opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ else if (opt == TCPOPT_NOP) {
+ cp++;
+ continue;
+ }
+
+ if (&cp[1] >= ep)
+ break;
+ advance = cp[1];
+ if (&cp[advance] >= ep)
+ break;
+ switch (opt) {
+ case TCPOPT_MAXSEG:
+ if (advance != 4)
+ break;
+ bcopy(&cp[2], &v, sizeof(v));
+ mss = ntohs(v);
+ if (mss > maxmss) {
+ v = htons(maxmss);
+ bcopy(&v, &cp[2], sizeof(v));
+ CALC_SUMD(mss, maxmss, sumd);
+ fix_outcksum(fin, csump, sumd);
+ }
+ break;
+ default:
+ /* ignore unknown options */
+ break;
+ }
+
+ cp += advance;
+ }
+ }
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 5dc7fd998679..0c3f1bd95409 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -85,6 +85,7 @@ typedef struct nat {
u_short nat_use;
u_char nat_tcpstate[2];
u_char nat_p; /* protocol for NAT */
+ u_32_t nat_mssclamp; /* if != zero clamp MSS to this */
struct ipnat *nat_ptr; /* pointer back to the rule */
struct hostmap *nat_hm;
struct nat *nat_next;
@@ -114,6 +115,7 @@ typedef struct ipnat {
u_short in_pnext;
u_short in_ippip; /* IP #'s per IP# */
u_32_t in_flags; /* From here to in_dport must be reflected */
+ u_32_t in_mssclamp; /* if != zero clamp MSS to this */
u_short in_spare;
u_short in_ppip; /* ports per IP */
u_short in_port[2]; /* correctly in IPN_CMPSIZ */
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 4bf1a39b4aa0..c335ad01d675 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -7,7 +7,7 @@
# define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -316,7 +316,7 @@ nat_t *nat;
sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
if (sum != tcp->th_sum) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy tcp checksum failure\n");
#endif
frstats[fin->fin_out].fr_tcpbad++;
@@ -324,8 +324,8 @@ nat_t *nat;
}
/*
- * Don't both the proxy with these...or in fact, should
- * we free up proxy stuff when seen?
+ * Don't bother the proxy with these...or in fact,
+ * should we free up proxy stuff when seen?
*/
if ((tcp->th_flags & TH_RST) != 0)
return 0;
@@ -343,13 +343,13 @@ nat_t *nat;
rv = APR_EXIT(err);
if (rv == 1) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy says bad packet received\n");
#endif
return -1;
}
if (rv == 2) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy says free app proxy data\n");
#endif
appr_free(apr);
@@ -425,7 +425,7 @@ ap_session_t *aps;
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);
@@ -469,7 +469,7 @@ int inc;
sel, !sel, seq1, aps->aps_seqmin[!sel]);
#endif
sel = aps->aps_sel[out] = !sel;
-}
+ }
if (aps->aps_seqoff[sel]) {
seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
@@ -504,7 +504,7 @@ int inc;
sel, !sel, seq1, aps->aps_ackmin[!sel]);
#endif
sel = aps->aps_sel[1 - out] = !sel;
-}
+ }
if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
seq2 = aps->aps_ackoff[sel];
@@ -523,7 +523,7 @@ int inc;
sel, !sel, seq1, aps->aps_ackmin[!sel]);
#endif
sel = aps->aps_sel[out] = !sel;
-}
+ }
if (aps->aps_ackoff[sel]) {
seq2 = aps->aps_ackmin[sel] - aps->aps_ackoff[sel];
@@ -558,7 +558,7 @@ int inc;
sel, !sel, seq1, aps->aps_seqmin[!sel]);
#endif
sel = aps->aps_sel[1 - out] = !sel;
-}
+ }
if (aps->aps_seqoff[sel] != 0) {
#if PROXY_DEBUG
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index 2e90270f6422..2dec0a22dd35 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -100,6 +100,7 @@ typedef struct ftpside {
u_32_t ftps_len;
int ftps_junk;
int ftps_cmds;
+ int ftps_cmd;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 1d6bc71893d6..6715b07e6d53 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.5 2001/10/30 16:38:14 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.4.2.6 2002/10/01 15:24:59 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -144,6 +144,7 @@ nat_t *nat;
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_off = 5;
+ tcp2->th_flags = TH_SYN;
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_dlen = sizeof(*tcp2);
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index afd275ce92ec..510aeea4eab8 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -3,7 +3,8 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#ifdef __sgi
+
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -118,8 +119,8 @@ static frentry_t *fr_checkicmp6matchingstate __P((ip6_t *, fr_info_t *));
static int fr_matchsrcdst __P((ipstate_t *, union i6addr, union i6addr,
fr_info_t *, tcphdr_t *));
static frentry_t *fr_checkicmpmatchingstate __P((ip_t *, fr_info_t *));
-static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *));
-static int fr_state_flush __P((int));
+static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *, int));
+static int fr_state_flush __P((int, int));
static ips_stat_t *fr_statetstats __P((void));
static void fr_delstate __P((ipstate_t *));
static int fr_state_remove __P((caddr_t));
@@ -204,8 +205,8 @@ static ips_stat_t *fr_statetstats()
* 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;
+static int fr_state_flush(which, proto)
+int which, proto;
{
ipstate_t *is, **isp;
#if defined(_KERNEL) && !SOLARIS
@@ -217,6 +218,9 @@ int which;
for (isp = &ips_list; (is = *isp); ) {
delete = 0;
+ if ((proto != 0) && (is->is_v != proto))
+ continue;
+
switch (which)
{
case 0 :
@@ -338,12 +342,26 @@ int mode;
break;
if (arg == 0 || arg == 1) {
WRITE_ENTER(&ipf_state);
- ret = fr_state_flush(arg);
+ ret = fr_state_flush(arg, 4);
+ RWLOCK_EXIT(&ipf_state);
+ error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
+ } else
+ error = EINVAL;
+ break;
+#ifdef USE_INET6
+ case SIOCIPFL6 :
+ error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
+ if (error)
+ break;
+ if (arg == 0 || arg == 1) {
+ WRITE_ENTER(&ipf_state);
+ ret = fr_state_flush(arg, 6);
RWLOCK_EXIT(&ipf_state);
error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
} else
error = EINVAL;
break;
+#endif
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
@@ -1119,7 +1137,7 @@ tcphdr_t *tcp;
return 1;
}
-static int fr_matchicmpqueryreply(v, is, icmp)
+static int fr_matchicmpqueryreply(v, is, icmp, rev)
int v;
ipstate_t *is;
icmphdr_t *icmp;
@@ -1129,8 +1147,8 @@ icmphdr_t *icmp;
* If we matched its type on the way in, then when going out
* it will still be the same type.
*/
- if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
+ if ((!rev && (icmp->icmp_type == is->is_type)) ||
+ (rev && (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
if (icmp->icmp_type != ICMP_ECHOREPLY)
return 1;
if ((icmp->icmp_id == is->is_icmp.ics_id) &&
@@ -1140,8 +1158,8 @@ icmphdr_t *icmp;
}
#ifdef USE_INET6
else if (is->is_v == 6) {
- if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype6[is->is_type] == icmp->icmp_type))) {
+ if ((!rev && (icmp->icmp_type == is->is_type)) ||
+ (rev && (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) &&
@@ -1279,7 +1297,7 @@ fr_info_t *fin;
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == 4) &&
fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
- fr_matchicmpqueryreply(is->is_v, is, icmp)) {
+ fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
ips_stats.iss_hits++;
is->is_pkts++;
is->is_bytes += ip->ip_len;
@@ -1461,7 +1479,7 @@ icmp6again:
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)) {
+ fr_matchicmpqueryreply(v, is, ic, fin->fin_rev)) {
rev = fin->fin_rev;
if (is->is_frage[rev] != 0)
is->is_age = is->is_frage[rev];
@@ -1516,7 +1534,7 @@ icmp6again:
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)) {
+ fr_matchicmpqueryreply(v, is, ic, fin->fin_rev)) {
rev = fin->fin_rev;
if (is->is_frage[rev] != 0)
is->is_age = is->is_frage[rev];
@@ -1659,8 +1677,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;
}
@@ -1751,7 +1769,7 @@ void fr_timeoutstate()
} else
isp = &is->is_next;
if (fr_state_doflush) {
- (void) fr_state_flush(2);
+ (void) fr_state_flush(2, 0);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
@@ -1827,17 +1845,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;
}
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 3995b204ae49..04367add9255 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -11,6 +11,6 @@
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.29"
+#define IPL_VERSION "IP Filter: v3.4.31"
#endif