summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2000-05-24 04:21:35 +0000
committerdarrenr <darrenr@FreeBSD.org>2000-05-24 04:21:35 +0000
commit28218f546c7ba8b4fba010c0b0a1af5867aba192 (patch)
tree9a2fc1fac66823268c991d7585f8101708423fd3
parent08110f1e41975fed5b0ad5608d36a10683520a31 (diff)
downloadFreeBSD-src-28218f546c7ba8b4fba010c0b0a1af5867aba192.zip
FreeBSD-src-28218f546c7ba8b4fba010c0b0a1af5867aba192.tar.gz
fix conflicts
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c122
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.h5
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c104
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h30
-rw-r--r--sys/netinet/ip_frag.c122
-rw-r--r--sys/netinet/ip_frag.h5
-rw-r--r--sys/netinet/ip_proxy.c104
-rw-r--r--sys/netinet/ip_proxy.h30
8 files changed, 380 insertions, 142 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index 2b343e7..c99fe3e 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -25,7 +25,7 @@ static const char rcsid[] = "@(#)$FreeBSD$";
# include <string.h>
# include <stdlib.h>
#endif
-#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
+#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
@@ -86,13 +86,20 @@ static const char rcsid[] = "@(#)$FreeBSD$";
extern struct callout_handle ipfr_slowtimer_ch;
# endif
#endif
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
+# include <sys/callout.h>
+extern struct callout ipfr_slowtimer_ch;
+#endif
+
+
+static ipfr_t *ipfr_heads[IPFT_SIZE];
+static ipfr_t *ipfr_nattab[IPFT_SIZE];
+static ipfrstat_t ipfr_stats;
+static int ipfr_inuse = 0;
+int fr_ipfrttl = 120; /* 60 seconds */
+int fr_frag_lock = 0;
-ipfr_t *ipfr_heads[IPFT_SIZE];
-ipfr_t *ipfr_nattab[IPFT_SIZE];
-ipfrstat_t ipfr_stats;
-int ipfr_inuse = 0,
- fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
# if SOLARIS2 >= 7
extern timeout_id_t ipfr_timer_id;
@@ -156,7 +163,7 @@ ipfr_t *table[];
for (fp = &table[idx]; (fra = *fp); fp = &fra->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fra->ipfr_src,
IPFR_CMPSZ)) {
- ATOMIC_INC(ipfr_stats.ifs_exists);
+ ATOMIC_INCL(ipfr_stats.ifs_exists);
return NULL;
}
@@ -166,12 +173,12 @@ ipfr_t *table[];
*/
KMALLOC(fra, ipfr_t *);
if (fra == NULL) {
- ATOMIC_INC(ipfr_stats.ifs_nomem);
+ ATOMIC_INCL(ipfr_stats.ifs_nomem);
return NULL;
}
if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
- ATOMIC_INC(fin->fin_fr->fr_ref);
+ ATOMIC_INC32(fin->fin_fr->fr_ref);
}
@@ -191,8 +198,8 @@ ipfr_t *table[];
* Compute the offset of the expected start of the next packet.
*/
fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
- ATOMIC_INC(ipfr_stats.ifs_new);
- ATOMIC_INC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_new);
+ ATOMIC_INC32(ipfr_inuse);
return fra;
}
@@ -204,6 +211,8 @@ u_int pass;
{
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
@@ -219,6 +228,8 @@ nat_t *nat;
{
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@@ -292,7 +303,7 @@ ipfr_t *table[];
else
f->ipfr_off = atoff;
}
- ATOMIC_INC(ipfr_stats.ifs_hits);
+ ATOMIC_INCL(ipfr_stats.ifs_hits);
return f;
}
return NULL;
@@ -309,6 +320,8 @@ fr_info_t *fin;
nat_t *nat;
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
@@ -337,6 +350,8 @@ fr_info_t *fin;
frentry_t *fr = NULL;
ipfr_t *fra;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
READ_ENTER(&ipf_frag);
fra = ipfr_lookup(ip, fin, ipfr_heads);
if (fra != NULL)
@@ -372,7 +387,7 @@ ipfr_t *fra;
fr = fra->ipfr_rule;
if (fr != NULL) {
- ATOMIC_DEC(fr->fr_ref);
+ ATOMIC_DEC32(fr->fr_ref);
if (fr->fr_ref == 0)
KFREE(fr);
}
@@ -419,19 +434,7 @@ void ipfr_unload()
#ifdef _KERNEL
-/*
- * Slowly expire held state for fragments. Timeouts are set * in expectation
- * of this being called twice per second.
- */
-# if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
-void ipfr_slowtimer()
-# else
-void ipfr_slowtimer __P((void *ptr))
-# endif
-# else
-int ipfr_slowtimer()
-# endif
+void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
nat_t *nat;
@@ -439,18 +442,11 @@ int ipfr_slowtimer()
#if defined(_KERNEL)
# if !SOLARIS
int s;
-# else
- extern int fr_running;
-
- if (fr_running <= 0)
- return;
# endif
#endif
- READ_ENTER(&ipf_solaris);
-#ifdef __sgi
- ipfilter_sgi_intfsync();
-#endif
+ if (fr_frag_lock)
+ return;
SPL_NET(s);
WRITE_ENTER(&ipf_frag);
@@ -466,8 +462,8 @@ int ipfr_slowtimer()
if (fra->ipfr_ttl == 0) {
*fp = fra->ipfr_next;
ipfr_delete(fra);
- ATOMIC_INC(ipfr_stats.ifs_expire);
- ATOMIC_DEC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_expire);
+ ATOMIC_DEC32(ipfr_inuse);
} else
fp = &fra->ipfr_next;
}
@@ -486,8 +482,8 @@ int ipfr_slowtimer()
for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
--fra->ipfr_ttl;
if (fra->ipfr_ttl == 0) {
- ATOMIC_INC(ipfr_stats.ifs_expire);
- ATOMIC_DEC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_expire);
+ ATOMIC_DEC32(ipfr_inuse);
nat = fra->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fra)
@@ -501,23 +497,55 @@ int ipfr_slowtimer()
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
+}
+
+
+/*
+ * Slowly expire held state for fragments. Timeouts are set * in expectation
+ * of this being called twice per second.
+ */
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
+# if defined(SOLARIS2) && (SOLARIS2 < 7)
+void ipfr_slowtimer()
+# else
+void ipfr_slowtimer __P((void *ptr))
+# endif
+# else
+int ipfr_slowtimer()
+# endif
+{
+#if defined(_KERNEL) && SOLARIS
+ extern int fr_running;
+
+ if (fr_running <= 0)
+ return;
+#endif
+
+ READ_ENTER(&ipf_solaris);
+#ifdef __sgi
+ ipfilter_sgi_intfsync();
+#endif
+
+ ipfr_fragexpire();
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
-# if SOLARIS
+# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
+ RWLOCK_EXIT(&ipf_solaris);
# else
-# ifndef linux
+# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000)
+ callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
+# else
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
-# endif
-# if (BSD < 199306) && !defined(__sgi)
+# if (BSD < 199306) && !defined(__sgi)
return 0;
-# endif
-# endif
- RWLOCK_EXIT(&ipf_solaris);
+# endif /* FreeBSD */
+# endif /* NetBSD */
+# endif /* SOLARIS */
}
#endif /* defined(_KERNEL) */
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h
index 0494e9c..8b8fa8a 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.h
+++ b/sys/contrib/ipfilter/netinet/ip_frag.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -8,7 +8,6 @@
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.2 1999/08/06 06:26:38 darrenr Exp $
* $FreeBSD$
- */
#ifndef __IP_FRAG_H__
#define __IP_FRAG_H__
@@ -43,6 +42,7 @@ typedef struct ipfrstat {
#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
extern int fr_ipfrttl;
+extern int fr_frag_lock;
extern ipfrstat_t *ipfr_fragstats __P((void));
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
@@ -50,6 +50,7 @@ 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_unload __P((void));
+extern void ipfr_fragexpire __P((void));
#if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 3a03863..47d0e5e 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-1998 by Darren Reed.
+ * Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -99,23 +99,62 @@ static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
+aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
- { "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
- ippr_ftp_in, ippr_ftp_out },
+ { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
+ ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
#endif
#ifdef IPF_RCMD_PROXY
- { "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_new,
- NULL, ippr_rcmd_out },
+ { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
+ ippr_rcmd_new, NULL, ippr_rcmd_out },
#endif
#ifdef IPF_RAUDIO_PROXY
- { "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init,
+ { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
#endif
- { "", '\0', 0, 0, NULL, NULL }
+ { NULL, "", '\0', 0, 0, NULL, NULL }
};
+int appr_add(ap)
+aproxy_t *ap;
+{
+ aproxy_t *a;
+
+ for (a = ap_proxies; a->apr_p; a++)
+ if ((a->apr_p == ap->apr_p) &&
+ !strncmp(a->apr_label, ap->apr_label,
+ sizeof(ap->apr_label)))
+ return -1;
+
+ for (a = ap_proxylist; a->apr_p; a = a->apr_next)
+ if ((a->apr_p == ap->apr_p) &&
+ !strncmp(a->apr_label, ap->apr_label,
+ sizeof(ap->apr_label)))
+ return -1;
+ ap->apr_next = ap_proxylist;
+ ap_proxylist = ap;
+ return (*ap->apr_init)();
+}
+
+
+int appr_del(ap)
+aproxy_t *ap;
+{
+ aproxy_t *a, **app;
+
+ for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
+ if (a == ap) {
+ if (ap->apr_ref != 0)
+ return 1;
+ *app = a->apr_next;
+ return 0;
+ }
+ return -1;
+}
+
+
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@@ -153,16 +192,18 @@ nat_t *nat;
if (!aps)
return NULL;
bzero((char *)aps, sizeof(*aps));
- aps->aps_next = ap_sess_list;
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
aps->aps_apr = apr;
aps->aps_psiz = 0;
- ap_sess_list = aps;
- aps->aps_nat = nat;
- nat->nat_aps = aps;
if (apr->apr_new != NULL)
- (void) (*apr->apr_new)(fin, ip, aps, nat);
+ if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
+ KFREE(aps);
+ return NULL;
+ }
+ aps->aps_nat = nat;
+ aps->aps_next = ap_sess_list;
+ ap_sess_list = aps;
return aps;
}
@@ -180,6 +221,7 @@ nat_t *nat;
aproxy_t *apr;
tcphdr_t *tcp = NULL;
u_32_t sum;
+ short rv;
int err;
if (nat->nat_aps == NULL)
@@ -214,8 +256,12 @@ nat_t *nat;
err = (*apr->apr_inpkt)(fin, ip, aps, nat);
}
+ rv = APR_EXIT(err);
+ if (rv == -1)
+ return rv;
+
if (tcp != NULL) {
- err = appr_fixseqack(fin, ip, aps, err);
+ err = appr_fixseqack(fin, ip, aps, APR_INC(err));
#if SOLARIS && defined(_KERNEL)
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
@@ -224,9 +270,9 @@ nat_t *nat;
}
aps->aps_bytes += ip->ip_len;
aps->aps_pkts++;
- return 2;
+ return 1;
}
- return -1;
+ return 0;
}
@@ -242,6 +288,13 @@ char *name;
ap->apr_ref++;
return ap;
}
+
+ for (ap = ap_proxylist; ap; ap = ap->apr_next)
+ if ((ap->apr_p == pr) &&
+ !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
+ ap->apr_ref++;
+ return ap;
+ }
return NULL;
}
@@ -267,11 +320,9 @@ ap_session_t *aps;
break;
}
- if (a) {
- if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
- KFREES(aps->aps_data, aps->aps_psiz);
- KFREE(aps);
- }
+ if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
+ KFREES(aps->aps_data, aps->aps_psiz);
+ KFREE(aps);
}
@@ -386,3 +437,16 @@ int appr_init()
}
return err;
}
+
+
+void appr_unload()
+{
+ aproxy_t *ap;
+
+ for (ap = ap_proxies; ap->apr_p; ap++)
+ if (ap->apr_fini)
+ (*ap->apr_fini)();
+ for (ap = ap_proxylist; ap; ap = ap->apr_next)
+ if (ap->apr_fini)
+ (*ap->apr_fini)();
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index 9ccd46a..edee695 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-1998 by Darren Reed.
+ * Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -55,7 +55,7 @@ typedef struct ap_session {
int aps_psiz; /* size of private data */
struct ap_session *aps_hnext;
struct ap_session *aps_next;
-} ap_session_t ;
+} ap_session_t;
#define aps_sport aps_un.apu_tcp.apt_sport
#define aps_dport aps_un.apu_tcp.apt_dport
@@ -68,11 +68,13 @@ typedef struct ap_session {
typedef struct aproxy {
+ struct aproxy *apr_next;
char apr_label[APR_LABELLEN]; /* Proxy label # */
u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((void));
+ void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
@@ -83,6 +85,26 @@ typedef struct aproxy {
#define APR_DELETE 1
+#define APR_ERR(x) (((x) & 0xffff) << 16)
+#define APR_EXIT(x) (((x) >> 16) & 0xffff)
+#define APR_INC(x) ((x) & 0xffff)
+
+#define FTP_BUFSZ 160
+/*
+ * For the ftp proxy.
+ */
+typedef struct ftpside {
+ char *ftps_rptr;
+ char *ftps_wptr;
+ u_32_t ftps_seq;
+ int ftps_junk;
+ char ftps_buf[FTP_BUFSZ];
+} ftpside_t;
+
+typedef struct ftpinfo {
+ u_int ftp_passok;
+ ftpside_t ftp_side[2];
+} ftpinfo_t;
/*
* Real audio proxy structure and #defines
@@ -119,8 +141,12 @@ typedef struct {
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
extern aproxy_t ap_proxies[];
+extern int ippr_ftp_pasvonly;
+extern int appr_add __P((aproxy_t *));
+extern int appr_del __P((aproxy_t *));
extern int appr_init __P((void));
+extern void appr_unload __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
diff --git a/sys/netinet/ip_frag.c b/sys/netinet/ip_frag.c
index 2b343e7..c99fe3e 100644
--- a/sys/netinet/ip_frag.c
+++ b/sys/netinet/ip_frag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -25,7 +25,7 @@ static const char rcsid[] = "@(#)$FreeBSD$";
# include <string.h>
# include <stdlib.h>
#endif
-#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
+#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
@@ -86,13 +86,20 @@ static const char rcsid[] = "@(#)$FreeBSD$";
extern struct callout_handle ipfr_slowtimer_ch;
# endif
#endif
+#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
+# include <sys/callout.h>
+extern struct callout ipfr_slowtimer_ch;
+#endif
+
+
+static ipfr_t *ipfr_heads[IPFT_SIZE];
+static ipfr_t *ipfr_nattab[IPFT_SIZE];
+static ipfrstat_t ipfr_stats;
+static int ipfr_inuse = 0;
+int fr_ipfrttl = 120; /* 60 seconds */
+int fr_frag_lock = 0;
-ipfr_t *ipfr_heads[IPFT_SIZE];
-ipfr_t *ipfr_nattab[IPFT_SIZE];
-ipfrstat_t ipfr_stats;
-int ipfr_inuse = 0,
- fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
# if SOLARIS2 >= 7
extern timeout_id_t ipfr_timer_id;
@@ -156,7 +163,7 @@ ipfr_t *table[];
for (fp = &table[idx]; (fra = *fp); fp = &fra->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fra->ipfr_src,
IPFR_CMPSZ)) {
- ATOMIC_INC(ipfr_stats.ifs_exists);
+ ATOMIC_INCL(ipfr_stats.ifs_exists);
return NULL;
}
@@ -166,12 +173,12 @@ ipfr_t *table[];
*/
KMALLOC(fra, ipfr_t *);
if (fra == NULL) {
- ATOMIC_INC(ipfr_stats.ifs_nomem);
+ ATOMIC_INCL(ipfr_stats.ifs_nomem);
return NULL;
}
if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
- ATOMIC_INC(fin->fin_fr->fr_ref);
+ ATOMIC_INC32(fin->fin_fr->fr_ref);
}
@@ -191,8 +198,8 @@ ipfr_t *table[];
* Compute the offset of the expected start of the next packet.
*/
fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
- ATOMIC_INC(ipfr_stats.ifs_new);
- ATOMIC_INC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_new);
+ ATOMIC_INC32(ipfr_inuse);
return fra;
}
@@ -204,6 +211,8 @@ u_int pass;
{
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
@@ -219,6 +228,8 @@ nat_t *nat;
{
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@@ -292,7 +303,7 @@ ipfr_t *table[];
else
f->ipfr_off = atoff;
}
- ATOMIC_INC(ipfr_stats.ifs_hits);
+ ATOMIC_INCL(ipfr_stats.ifs_hits);
return f;
}
return NULL;
@@ -309,6 +320,8 @@ fr_info_t *fin;
nat_t *nat;
ipfr_t *ipf;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
@@ -337,6 +350,8 @@ fr_info_t *fin;
frentry_t *fr = NULL;
ipfr_t *fra;
+ if ((ip->ip_v != 4) || (fr_frag_lock))
+ return NULL;
READ_ENTER(&ipf_frag);
fra = ipfr_lookup(ip, fin, ipfr_heads);
if (fra != NULL)
@@ -372,7 +387,7 @@ ipfr_t *fra;
fr = fra->ipfr_rule;
if (fr != NULL) {
- ATOMIC_DEC(fr->fr_ref);
+ ATOMIC_DEC32(fr->fr_ref);
if (fr->fr_ref == 0)
KFREE(fr);
}
@@ -419,19 +434,7 @@ void ipfr_unload()
#ifdef _KERNEL
-/*
- * Slowly expire held state for fragments. Timeouts are set * in expectation
- * of this being called twice per second.
- */
-# if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
-void ipfr_slowtimer()
-# else
-void ipfr_slowtimer __P((void *ptr))
-# endif
-# else
-int ipfr_slowtimer()
-# endif
+void ipfr_fragexpire()
{
ipfr_t **fp, *fra;
nat_t *nat;
@@ -439,18 +442,11 @@ int ipfr_slowtimer()
#if defined(_KERNEL)
# if !SOLARIS
int s;
-# else
- extern int fr_running;
-
- if (fr_running <= 0)
- return;
# endif
#endif
- READ_ENTER(&ipf_solaris);
-#ifdef __sgi
- ipfilter_sgi_intfsync();
-#endif
+ if (fr_frag_lock)
+ return;
SPL_NET(s);
WRITE_ENTER(&ipf_frag);
@@ -466,8 +462,8 @@ int ipfr_slowtimer()
if (fra->ipfr_ttl == 0) {
*fp = fra->ipfr_next;
ipfr_delete(fra);
- ATOMIC_INC(ipfr_stats.ifs_expire);
- ATOMIC_DEC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_expire);
+ ATOMIC_DEC32(ipfr_inuse);
} else
fp = &fra->ipfr_next;
}
@@ -486,8 +482,8 @@ int ipfr_slowtimer()
for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
--fra->ipfr_ttl;
if (fra->ipfr_ttl == 0) {
- ATOMIC_INC(ipfr_stats.ifs_expire);
- ATOMIC_DEC(ipfr_inuse);
+ ATOMIC_INCL(ipfr_stats.ifs_expire);
+ ATOMIC_DEC32(ipfr_inuse);
nat = fra->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fra)
@@ -501,23 +497,55 @@ int ipfr_slowtimer()
RWLOCK_EXIT(&ipf_natfrag);
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
+}
+
+
+/*
+ * Slowly expire held state for fragments. Timeouts are set * in expectation
+ * of this being called twice per second.
+ */
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
+# if defined(SOLARIS2) && (SOLARIS2 < 7)
+void ipfr_slowtimer()
+# else
+void ipfr_slowtimer __P((void *ptr))
+# endif
+# else
+int ipfr_slowtimer()
+# endif
+{
+#if defined(_KERNEL) && SOLARIS
+ extern int fr_running;
+
+ if (fr_running <= 0)
+ return;
+#endif
+
+ READ_ENTER(&ipf_solaris);
+#ifdef __sgi
+ ipfilter_sgi_intfsync();
+#endif
+
+ ipfr_fragexpire();
fr_timeoutstate();
ip_natexpire();
fr_authexpire();
-# if SOLARIS
+# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
+ RWLOCK_EXIT(&ipf_solaris);
# else
-# ifndef linux
+# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000)
+ callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
+# else
# if (__FreeBSD_version >= 300000)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
# endif
-# endif
-# if (BSD < 199306) && !defined(__sgi)
+# if (BSD < 199306) && !defined(__sgi)
return 0;
-# endif
-# endif
- RWLOCK_EXIT(&ipf_solaris);
+# endif /* FreeBSD */
+# endif /* NetBSD */
+# endif /* SOLARIS */
}
#endif /* defined(_KERNEL) */
diff --git a/sys/netinet/ip_frag.h b/sys/netinet/ip_frag.h
index 0494e9c..8b8fa8a 100644
--- a/sys/netinet/ip_frag.h
+++ b/sys/netinet/ip_frag.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -8,7 +8,6 @@
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.2 1999/08/06 06:26:38 darrenr Exp $
* $FreeBSD$
- */
#ifndef __IP_FRAG_H__
#define __IP_FRAG_H__
@@ -43,6 +42,7 @@ typedef struct ipfrstat {
#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
extern int fr_ipfrttl;
+extern int fr_frag_lock;
extern ipfrstat_t *ipfr_fragstats __P((void));
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
@@ -50,6 +50,7 @@ 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_unload __P((void));
+extern void ipfr_fragexpire __P((void));
#if (BSD >= 199306) || SOLARIS || defined(__sgi)
# if defined(SOLARIS2) && (SOLARIS2 < 7)
diff --git a/sys/netinet/ip_proxy.c b/sys/netinet/ip_proxy.c
index 3a03863..47d0e5e 100644
--- a/sys/netinet/ip_proxy.c
+++ b/sys/netinet/ip_proxy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-1998 by Darren Reed.
+ * Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -99,23 +99,62 @@ static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
+aproxy_t *ap_proxylist = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
- { "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
- ippr_ftp_in, ippr_ftp_out },
+ { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
+ ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
#endif
#ifdef IPF_RCMD_PROXY
- { "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_new,
- NULL, ippr_rcmd_out },
+ { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
+ ippr_rcmd_new, NULL, ippr_rcmd_out },
#endif
#ifdef IPF_RAUDIO_PROXY
- { "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init,
+ { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
#endif
- { "", '\0', 0, 0, NULL, NULL }
+ { NULL, "", '\0', 0, 0, NULL, NULL }
};
+int appr_add(ap)
+aproxy_t *ap;
+{
+ aproxy_t *a;
+
+ for (a = ap_proxies; a->apr_p; a++)
+ if ((a->apr_p == ap->apr_p) &&
+ !strncmp(a->apr_label, ap->apr_label,
+ sizeof(ap->apr_label)))
+ return -1;
+
+ for (a = ap_proxylist; a->apr_p; a = a->apr_next)
+ if ((a->apr_p == ap->apr_p) &&
+ !strncmp(a->apr_label, ap->apr_label,
+ sizeof(ap->apr_label)))
+ return -1;
+ ap->apr_next = ap_proxylist;
+ ap_proxylist = ap;
+ return (*ap->apr_init)();
+}
+
+
+int appr_del(ap)
+aproxy_t *ap;
+{
+ aproxy_t *a, **app;
+
+ for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
+ if (a == ap) {
+ if (ap->apr_ref != 0)
+ return 1;
+ *app = a->apr_next;
+ return 0;
+ }
+ return -1;
+}
+
+
int appr_ok(ip, tcp, nat)
ip_t *ip;
tcphdr_t *tcp;
@@ -153,16 +192,18 @@ nat_t *nat;
if (!aps)
return NULL;
bzero((char *)aps, sizeof(*aps));
- aps->aps_next = ap_sess_list;
aps->aps_p = ip->ip_p;
aps->aps_data = NULL;
aps->aps_apr = apr;
aps->aps_psiz = 0;
- ap_sess_list = aps;
- aps->aps_nat = nat;
- nat->nat_aps = aps;
if (apr->apr_new != NULL)
- (void) (*apr->apr_new)(fin, ip, aps, nat);
+ if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
+ KFREE(aps);
+ return NULL;
+ }
+ aps->aps_nat = nat;
+ aps->aps_next = ap_sess_list;
+ ap_sess_list = aps;
return aps;
}
@@ -180,6 +221,7 @@ nat_t *nat;
aproxy_t *apr;
tcphdr_t *tcp = NULL;
u_32_t sum;
+ short rv;
int err;
if (nat->nat_aps == NULL)
@@ -214,8 +256,12 @@ nat_t *nat;
err = (*apr->apr_inpkt)(fin, ip, aps, nat);
}
+ rv = APR_EXIT(err);
+ if (rv == -1)
+ return rv;
+
if (tcp != NULL) {
- err = appr_fixseqack(fin, ip, aps, err);
+ err = appr_fixseqack(fin, ip, aps, APR_INC(err));
#if SOLARIS && defined(_KERNEL)
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
#else
@@ -224,9 +270,9 @@ nat_t *nat;
}
aps->aps_bytes += ip->ip_len;
aps->aps_pkts++;
- return 2;
+ return 1;
}
- return -1;
+ return 0;
}
@@ -242,6 +288,13 @@ char *name;
ap->apr_ref++;
return ap;
}
+
+ for (ap = ap_proxylist; ap; ap = ap->apr_next)
+ if ((ap->apr_p == pr) &&
+ !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
+ ap->apr_ref++;
+ return ap;
+ }
return NULL;
}
@@ -267,11 +320,9 @@ ap_session_t *aps;
break;
}
- if (a) {
- if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
- KFREES(aps->aps_data, aps->aps_psiz);
- KFREE(aps);
- }
+ if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
+ KFREES(aps->aps_data, aps->aps_psiz);
+ KFREE(aps);
}
@@ -386,3 +437,16 @@ int appr_init()
}
return err;
}
+
+
+void appr_unload()
+{
+ aproxy_t *ap;
+
+ for (ap = ap_proxies; ap->apr_p; ap++)
+ if (ap->apr_fini)
+ (*ap->apr_fini)();
+ for (ap = ap_proxylist; ap; ap = ap->apr_next)
+ if (ap->apr_fini)
+ (*ap->apr_fini)();
+}
diff --git a/sys/netinet/ip_proxy.h b/sys/netinet/ip_proxy.h
index 9ccd46a..edee695 100644
--- a/sys/netinet/ip_proxy.h
+++ b/sys/netinet/ip_proxy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1997-1998 by Darren Reed.
+ * Copyright (C) 1997-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -55,7 +55,7 @@ typedef struct ap_session {
int aps_psiz; /* size of private data */
struct ap_session *aps_hnext;
struct ap_session *aps_next;
-} ap_session_t ;
+} ap_session_t;
#define aps_sport aps_un.apu_tcp.apt_sport
#define aps_dport aps_un.apu_tcp.apt_dport
@@ -68,11 +68,13 @@ typedef struct ap_session {
typedef struct aproxy {
+ struct aproxy *apr_next;
char apr_label[APR_LABELLEN]; /* Proxy label # */
u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((void));
+ void (* apr_fini) __P((void));
int (* apr_new) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
@@ -83,6 +85,26 @@ typedef struct aproxy {
#define APR_DELETE 1
+#define APR_ERR(x) (((x) & 0xffff) << 16)
+#define APR_EXIT(x) (((x) >> 16) & 0xffff)
+#define APR_INC(x) ((x) & 0xffff)
+
+#define FTP_BUFSZ 160
+/*
+ * For the ftp proxy.
+ */
+typedef struct ftpside {
+ char *ftps_rptr;
+ char *ftps_wptr;
+ u_32_t ftps_seq;
+ int ftps_junk;
+ char ftps_buf[FTP_BUFSZ];
+} ftpside_t;
+
+typedef struct ftpinfo {
+ u_int ftp_passok;
+ ftpside_t ftp_side[2];
+} ftpinfo_t;
/*
* Real audio proxy structure and #defines
@@ -119,8 +141,12 @@ typedef struct {
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
extern aproxy_t ap_proxies[];
+extern int ippr_ftp_pasvonly;
+extern int appr_add __P((aproxy_t *));
+extern int appr_del __P((aproxy_t *));
extern int appr_init __P((void));
+extern void appr_unload __P((void));
extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern void appr_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
OpenPOWER on IntegriCloud