summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/ip_frag.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-11-16 04:52:19 +0000
committerpeter <peter@FreeBSD.org>1997-11-16 04:52:19 +0000
commit594e73c3109178aa1c5317785aaa284a0c135ff4 (patch)
tree1abde20e1d717a2bf3509de2189cbe7fa3c9f91e /contrib/ipfilter/ip_frag.c
parentc4dc16ff2222e864e5ab4d236e0de3a2cb5b54da (diff)
downloadFreeBSD-src-594e73c3109178aa1c5317785aaa284a0c135ff4.zip
FreeBSD-src-594e73c3109178aa1c5317785aaa284a0c135ff4.tar.gz
Import ipfilter 3.2.1 (update from 3.1.8)
Diffstat (limited to 'contrib/ipfilter/ip_frag.c')
-rw-r--r--contrib/ipfilter/ip_frag.c105
1 files changed, 69 insertions, 36 deletions
diff --git a/contrib/ipfilter/ip_frag.c b/contrib/ipfilter/ip_frag.c
index 9b9bce3..923f685 100644
--- a/contrib/ipfilter/ip_frag.c
+++ b/contrib/ipfilter/ip_frag.c
@@ -1,13 +1,13 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:21 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@@ -26,13 +26,17 @@ static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp
#include <sys/ioctl.h>
#endif
#include <sys/uio.h>
+#ifndef linux
#include <sys/protosw.h>
+#endif
#include <sys/socket.h>
-#ifdef _KERNEL
+#if defined(_KERNEL) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
@@ -48,27 +52,30 @@ static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
ipfr_t *ipfr_heads[IPFT_SIZE];
ipfr_t *ipfr_nattab[IPFT_SIZE];
ipfrstat_t ipfr_stats;
-u_long ipfr_inuse = 0,
+int ipfr_inuse = 0,
fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
extern int ipfr_timer_id;
#endif
-#if SOLARIS && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_frag;
extern kmutex_t ipf_natfrag;
extern kmutex_t ipf_nat;
@@ -120,7 +127,6 @@ ipfr_t *table[];
if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src,
IPFR_CMPSZ)) {
ipfr_stats.ifs_exists++;
- MUTEX_EXIT(&ipf_frag);
return NULL;
}
@@ -131,7 +137,6 @@ ipfr_t *table[];
KMALLOC(fr, ipfr_t *, sizeof(*fr));
if (fr == NULL) {
ipfr_stats.ifs_nomem++;
- MUTEX_EXIT(&ipf_frag);
return NULL;
}
@@ -183,7 +188,7 @@ nat_t *nat;
MUTEX_ENTER(&ipf_natfrag);
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
ipf->ipfr_data = nat;
- nat->nat_frag = ipf;
+ nat->nat_data = ipf;
}
MUTEX_EXIT(&ipf_natfrag);
return ipf ? 0 : -1;
@@ -201,7 +206,6 @@ ipfr_t *table[];
{
ipfr_t *f, frag;
u_int idx;
- int ret;
/*
* For fragments, we record protocol, packet id, TOS and both IP#'s
@@ -242,16 +246,16 @@ ipfr_t *table[];
table[idx] = f;
}
off = ip->ip_off;
- atoff = (off & 0x1fff) - (fin->fin_dlen >> 3);
+ atoff = off + (fin->fin_dlen >> 3);
/*
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
- if (atoff == f->ipfr_off) {
+ if ((off & 0x1fff) == f->ipfr_off) {
if (!(off & IP_MF))
f->ipfr_ttl = 1;
else
- f->ipfr_off = off;
+ f->ipfr_off = atoff;
}
ipfr_stats.ifs_hits++;
return f;
@@ -261,7 +265,7 @@ ipfr_t *table[];
/*
- * functional interface for normal lookups of the fragment cache
+ * functional interface for NAT lookups of the NAT fragment cache
*/
nat_t *ipfr_nat_knownfrag(ip, fin)
ip_t *ip;
@@ -271,15 +275,25 @@ fr_info_t *fin;
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
- ipf = ipfr_lookup(ip, fin, ipfr_heads);
- nat = ipf ? ipf->ipfr_data : NULL;
+ ipf = ipfr_lookup(ip, fin, ipfr_nattab);
+ if (ipf) {
+ nat = ipf->ipfr_data;
+ /*
+ * This is the last fragment for this packet.
+ */
+ if (ipf->ipfr_ttl == 1) {
+ nat->nat_data = NULL;
+ ipf->ipfr_data = NULL;
+ }
+ } else
+ nat = NULL;
MUTEX_EXIT(&ipf_natfrag);
return nat;
}
/*
- * functional interface for NAT lookups of the NAT fragment cache
+ * functional interface for normal lookups of the fragment cache
*/
int ipfr_knownfrag(ip, fin)
ip_t *ip;
@@ -297,6 +311,25 @@ fr_info_t *fin;
/*
+ * forget any references to this external object.
+ */
+void ipfr_forget(nat)
+void *nat;
+{
+ ipfr_t *fr;
+ int idx;
+
+ MUTEX_ENTER(&ipf_natfrag);
+ for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
+ for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+ if (fr->ipfr_data == nat)
+ fr->ipfr_data = NULL;
+
+ MUTEX_EXIT(&ipf_natfrag);
+}
+
+
+/*
* Free memory in use by fragment state info. kept.
*/
void ipfr_unload()
@@ -304,11 +337,7 @@ void ipfr_unload()
ipfr_t **fp, *fr;
nat_t *nat;
int idx;
-#if !SOLARIS && defined(_KERNEL)
- int s;
-#endif
- SPLNET(s);
MUTEX_ENTER(&ipf_frag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
@@ -323,14 +352,13 @@ void ipfr_unload()
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
if ((nat = (nat_t *)fr->ipfr_data)) {
- if (nat->nat_frag == fr)
- nat->nat_frag = NULL;
+ if (nat->nat_data == fr)
+ nat->nat_data = NULL;
}
KFREE(fr);
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
- SPLX(s);
}
@@ -339,7 +367,7 @@ void ipfr_unload()
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
-# if (BSD >= 199306) || SOLARIS
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
void ipfr_slowtimer()
# else
int ipfr_slowtimer()
@@ -349,8 +377,12 @@ int ipfr_slowtimer()
nat_t *nat;
int s, idx;
+#ifdef __sgi
+ ipfilter_sgi_intfsync();
+#endif
+
+ SPL_NET(s);
MUTEX_ENTER(&ipf_frag);
- SPLNET(s);
/*
* Go through the entire table, looking for entries to expire,
@@ -399,8 +431,8 @@ int ipfr_slowtimer()
ipfr_stats.ifs_expire++;
ipfr_inuse--;
if ((nat = (nat_t *)fr->ipfr_data)) {
- if (nat->nat_frag == fr)
- nat->nat_frag = NULL;
+ if (nat->nat_data == fr)
+ nat->nat_data = NULL;
}
KFREE(fr);
} else
@@ -408,16 +440,17 @@ int ipfr_slowtimer()
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
- SPLX(s);
-# if SOLARIS
+ SPL_X(s);
fr_timeoutstate();
ip_natexpire();
+ fr_authexpire();
+# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
# else
- fr_timeoutstate();
- ip_natexpire();
+# ifndef linux
ip_slowtimo();
-# if BSD < 199306
+# endif
+# if (BSD < 199306) && !defined(__sgi)
return 0;
# endif
# endif
OpenPOWER on IntegriCloud