aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rooij <guido@FreeBSD.org>2005-12-30 11:22:11 +0000
committerGuido van Rooij <guido@FreeBSD.org>2005-12-30 11:22:11 +0000
commitfc79eaf127b2927f108bf1971bfb850f7dabea63 (patch)
treeb7932fb536591098a7a0c82617edb30ea41453b7
parent8158c4468d2bf40eabe8e413f647e1dd581bb6e7 (diff)
downloadsrc-fc79eaf127b2927f108bf1971bfb850f7dabea63.tar.gz
src-fc79eaf127b2927f108bf1971bfb850f7dabea63.zip
Import IP Filter version 4.1.10
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=153872
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c798
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c26
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h153
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c47
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c26
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.h8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c7
-rw-r--r--sys/contrib/ipfilter/netinet/ip_htable.c15
-rw-r--r--sys/contrib/ipfilter/netinet/ip_htable.h2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_irc_pxy.c6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c16
-rw-r--r--sys/contrib/ipfilter/netinet/ip_lookup.c19
-rw-r--r--sys/contrib/ipfilter/netinet/ip_lookup.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c105
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h9
-rw-r--r--sys/contrib/ipfilter/netinet/ip_netbios_pxy.c16
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pool.c12
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pool.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pptp_pxy.c8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c14
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h21
-rw-r--r--sys/contrib/ipfilter/netinet/ip_raudio_pxy.c4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_scan.c10
-rw-r--r--sys/contrib/ipfilter/netinet/ip_scan.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c256
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h10
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.c29
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h8
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c3
35 files changed, 1053 insertions, 651 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index e62b0edf7bba..c8c1b55074f4 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2003 by Darren Reed.
*
@@ -34,7 +32,9 @@
#else
# include <sys/ioctl.h>
#endif
-#include <sys/fcntl.h>
+#if !defined(_AIX51)
+# include <sys/fcntl.h>
+#endif
#if defined(_KERNEL)
# include <sys/systm.h>
# include <sys/file.h>
@@ -74,6 +74,9 @@ struct file;
# include <net/af.h>
#endif
#if !defined(_KERNEL) && defined(__FreeBSD__)
+# if (__FreeBSD_version >= 504000)
+# undef _RADIX_H_
+# endif
# include "radix_ipf.h"
#endif
#include <net/route.h>
@@ -88,7 +91,7 @@ struct file;
# include <netinet/in_var.h>
#endif
#include <netinet/tcp.h>
-#if !defined(__sgi) || defined(_KERNEL)
+#if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL)
# include <netinet/udp.h>
# include <netinet/ip_icmp.h>
#endif
@@ -134,7 +137,7 @@ struct file;
#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.243.2.57 2005/03/28 10:47:50 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $";
#endif
#ifndef _KERNEL
@@ -173,6 +176,7 @@ int fr_update_ipid = 0;
u_short fr_ip_id = 0;
int fr_chksrc = 0; /* causes a system crash if enabled */
int fr_minttl = 4;
+int fr_icmpminfragmtu = 68;
u_long fr_frouteok[2] = {0, 0};
u_long fr_userifqs = 0;
u_long fr_badcoalesces[2] = {0, 0};
@@ -218,6 +222,7 @@ static int frflushlist __P((int, minor_t, int *, frentry_t **));
static ipfunc_t fr_findfunc __P((ipfunc_t));
static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *));
static int fr_funcinit __P((frentry_t *fr));
+static INLINE void frpr_ah __P((fr_info_t *));
static INLINE void frpr_esp __P((fr_info_t *));
static INLINE void frpr_gre __P((fr_info_t *));
static INLINE void frpr_udp __P((fr_info_t *));
@@ -226,15 +231,15 @@ static INLINE void frpr_icmp __P((fr_info_t *));
static INLINE void frpr_ipv4hdr __P((fr_info_t *));
static INLINE int frpr_pullup __P((fr_info_t *, int));
static INLINE void frpr_short __P((fr_info_t *, int));
-static INLINE void frpr_tcpcommon __P((fr_info_t *));
-static INLINE void frpr_udpcommon __P((fr_info_t *));
-static INLINE int fr_updateipid __P((fr_info_t *));
+static INLINE int frpr_tcpcommon __P((fr_info_t *));
+static INLINE int frpr_udpcommon __P((fr_info_t *));
+static int fr_updateipid __P((fr_info_t *));
#ifdef IPFILTER_LOOKUP
static int fr_grpmapinit __P((frentry_t *fr));
static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *));
#endif
static void frsynclist __P((frentry_t *, void *));
-static ipftuneable_t *fr_findtunebyname __P((char *));
+static ipftuneable_t *fr_findtunebyname __P((const char *));
static ipftuneable_t *fr_findtunebycookie __P((void *, void **));
@@ -277,6 +282,7 @@ struct optlist ip6exthdr[] = {
{ IPPROTO_AH, 0x000020 },
{ IPPROTO_NONE, 0x000040 },
{ IPPROTO_DSTOPTS, 0x000080 },
+ { IPPROTO_MOBILITY, 0x000100 },
{ 0, 0 }
};
#endif
@@ -328,15 +334,20 @@ static ipfunc_resolve_t fr_availfuncs[] = {
* adding more code to a growing switch statement.
*/
#ifdef USE_INET6
+static INLINE int frpr_ah6 __P((fr_info_t *));
+static INLINE void frpr_esp6 __P((fr_info_t *));
+static INLINE void frpr_gre6 __P((fr_info_t *));
static INLINE void frpr_udp6 __P((fr_info_t *));
static INLINE void frpr_tcp6 __P((fr_info_t *));
static INLINE void frpr_icmp6 __P((fr_info_t *));
-static INLINE void frpr_ipv6hdr __P((fr_info_t *));
+static INLINE int frpr_ipv6hdr __P((fr_info_t *));
static INLINE void frpr_short6 __P((fr_info_t *, int));
static INLINE int frpr_hopopts6 __P((fr_info_t *));
+static INLINE int frpr_mobility6 __P((fr_info_t *));
static INLINE int frpr_routing6 __P((fr_info_t *));
static INLINE int frpr_dstopts6 __P((fr_info_t *));
-static INLINE int frpr_fragment6 __P((fr_info_t *));
+static INLINE void frpr_fragment6 __P((fr_info_t *));
+static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int));
/* ------------------------------------------------------------------------ */
@@ -349,37 +360,32 @@ static INLINE int frpr_fragment6 __P((fr_info_t *));
/* for IPv6 and marks the packet with FI_SHORT if so. See function comment */
/* for frpr_short() for more details. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_short6(fin, min)
+static INLINE void frpr_short6(fin, xmin)
fr_info_t *fin;
-int min;
+int xmin;
{
- fr_ip_t *fi = &fin->fin_fi;
- int off;
- off = fin->fin_off;
- if (off == 0) {
- if (fin->fin_plen < fin->fin_hlen + min)
- fi->fi_flx |= FI_SHORT;
- } else if (off < min) {
- fi->fi_flx |= FI_SHORT;
- }
+ if (fin->fin_dlen < xmin)
+ fin->fin_flx |= FI_SHORT;
}
/* ------------------------------------------------------------------------ */
/* Function: frpr_ipv6hdr */
-/* Returns: void */
+/* Returns: int - 0 = IPv6 packet intact, -1 = packet lost */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* IPv6 Only */
/* Copy values from the IPv6 header into the fr_info_t struct and call the */
-/* per-protocol analyzer if it exists. */
+/* per-protocol analyzer if it exists. In validating the packet, a protocol*/
+/* analyzer may pullup or free the packet itself so we need to be vigiliant */
+/* of that possibility arising. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_ipv6hdr(fin)
+static INLINE int frpr_ipv6hdr(fin)
fr_info_t *fin;
{
- int p, go = 1, i, hdrcount, coalesced;
ip6_t *ip6 = (ip6_t *)fin->fin_ip;
+ int p, go = 1, i, hdrcount;
fr_ip_t *fi = &fin->fin_fi;
fin->fin_off = 0;
@@ -389,7 +395,6 @@ fr_info_t *fin;
fi->fi_secmsk = 0;
fi->fi_auth = 0;
- coalesced = (fin->fin_flx & FI_COALESCE) ? 1 : 0;
p = ip6->ip6_nxt;
fi->fi_ttl = ip6->ip6_hlim;
fi->fi_src.in6 = ip6->ip6_src;
@@ -416,48 +421,35 @@ fr_info_t *fin;
break;
case IPPROTO_GRE :
- frpr_gre(fin);
+ frpr_gre6(fin);
go = 0;
break;
case IPPROTO_HOPOPTS :
- /*
- * Actually, hop by hop header is only allowed right
- * after IPv6 header!
- */
- if (hdrcount != 0)
- fin->fin_flx |= FI_BAD;
-
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return;
- }
p = frpr_hopopts6(fin);
break;
+ case IPPROTO_MOBILITY :
+ p = frpr_mobility6(fin);
+ break;
+
case IPPROTO_DSTOPTS :
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return;
- }
p = frpr_dstopts6(fin);
break;
case IPPROTO_ROUTING :
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return;
- }
p = frpr_routing6(fin);
break;
- case IPPROTO_ESP :
- frpr_esp(fin);
- /*FALLTHROUGH*/
case IPPROTO_AH :
+ p = frpr_ah6(fin);
+ break;
+
+ case IPPROTO_ESP :
+ frpr_esp6(fin);
+ go = 0;
+ break;
+
case IPPROTO_IPV6 :
for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
if (ip6exthdr[i].ol_val == p) {
@@ -472,12 +464,8 @@ fr_info_t *fin;
break;
case IPPROTO_FRAGMENT :
- if (coalesced == 0) {
- coalesced = fr_coalesce(fin);
- if (coalesced != 1)
- return;
- }
- p = frpr_fragment6(fin);
+ frpr_fragment6(fin);
+ go = 0;
break;
default :
@@ -491,9 +479,9 @@ fr_info_t *fin;
* extension headers (go != 0), the entire header may not have
* been pulled up when the code gets to this point. This is
* only done for "go != 0" because the other header handlers
- * will all pullup their complete header and the other
- * indicator of an incomplete header is that this eas just an
- * extension header.
+ * will all pullup their complete header. The other indicator
+ * of an incomplete packet is that this was just an extension
+ * header.
*/
if ((go != 0) && (p != IPPROTO_NONE) &&
(frpr_pullup(fin, 0) == -1)) {
@@ -502,19 +490,32 @@ fr_info_t *fin;
}
}
fi->fi_p = p;
+
+ /*
+ * Some of the above functions, like frpr_esp6(), can call fr_pullup
+ * and destroy whatever packet was here. The caller of this function
+ * expects us to return -1 if there is a problem with fr_pullup.
+ */
+ if (fin->fin_m == NULL)
+ return -1;
+
+ return 0;
}
/* ------------------------------------------------------------------------ */
-/* Function: frpr_hopopts6 */
+/* Function: frpr_ipv6exthdr */
/* Returns: int - value of the next header or IPPROTO_NONE if error */
-/* Parameters: fin(I) - pointer to packet information */
+/* Parameters: fin(I) - pointer to packet information */
+/* multiple(I) - flag indicating yes/no if multiple occurances */
+/* of this extension header are allowed. */
+/* proto(I) - protocol number for this extension header */
/* */
/* IPv6 Only */
-/* This is function checks pending hop by hop options extension header */
/* ------------------------------------------------------------------------ */
-static INLINE int frpr_hopopts6(fin)
+static INLINE int frpr_ipv6exthdr(fin, multiple, proto)
fr_info_t *fin;
+int multiple, proto;
{
struct ip6_ext *hdr;
u_short shift;
@@ -539,8 +540,15 @@ fr_info_t *fin;
}
for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_HOPOPTS) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ if (ip6exthdr[i].ol_val == proto) {
+ /*
+ * Most IPv6 extension headers are only allowed once.
+ */
+ if ((multiple == 0) &&
+ ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0))
+ fin->fin_flx |= FI_BAD;
+ else
+ fin->fin_optmsk |= ip6exthdr[i].ol_bit;
break;
}
@@ -552,6 +560,36 @@ fr_info_t *fin;
/* ------------------------------------------------------------------------ */
+/* Function: frpr_hopopts6 */
+/* Returns: int - value of the next header or IPPROTO_NONE if error */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* This is function checks pending hop by hop options extension header */
+/* ------------------------------------------------------------------------ */
+static INLINE int frpr_hopopts6(fin)
+fr_info_t *fin;
+{
+ return frpr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_mobility6 */
+/* Returns: int - value of the next header or IPPROTO_NONE if error */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* This is function checks the IPv6 mobility extension header */
+/* ------------------------------------------------------------------------ */
+static INLINE int frpr_mobility6(fin)
+fr_info_t *fin;
+{
+ return frpr_ipv6exthdr(fin, 0, IPPROTO_MOBILITY);
+}
+
+
+/* ------------------------------------------------------------------------ */
/* Function: frpr_routing6 */
/* Returns: int - value of the next header or IPPROTO_NONE if error */
/* Parameters: fin(I) - pointer to packet information */
@@ -563,100 +601,67 @@ static INLINE int frpr_routing6(fin)
fr_info_t *fin;
{
struct ip6_ext *hdr;
- u_short shift;
- int i;
+ int shift;
- fin->fin_flx |= FI_V6EXTHDR;
-
- /* 8 is default length of extension hdr */
- if ((fin->fin_dlen - 8) < 0) {
- fin->fin_flx |= FI_SHORT;
+ if (frpr_ipv6exthdr(fin, 0, IPPROTO_ROUTING) == IPPROTO_NONE)
return IPPROTO_NONE;
- }
- if (frpr_pullup(fin, 8) == -1)
- return IPPROTO_NONE;
hdr = fin->fin_dp;
-
shift = 8 + (hdr->ip6e_len << 3);
/*
* Nasty extension header length?
*/
- if ((shift > fin->fin_dlen) || (shift < sizeof(struct ip6_hdr)) ||
+ if ((shift < sizeof(struct ip6_hdr)) ||
((shift - sizeof(struct ip6_hdr)) & 15)) {
fin->fin_flx |= FI_BAD;
+ /*
+ * Compensate for the changes made in frpr_ipv6exthdr()
+ */
+ fin->fin_dlen += shift;
+ fin->fin_dp = (char *)fin->fin_dp - shift;
return IPPROTO_NONE;
}
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) {
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- break;
- }
-
- fin->fin_dp = (char *)fin->fin_dp + shift;
- fin->fin_dlen -= shift;
-
return hdr->ip6e_nxt;
}
/* ------------------------------------------------------------------------ */
/* Function: frpr_fragment6 */
-/* Returns: int - value of the next header or IPPROTO_NONE if error */
+/* Returns: void */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* IPv6 Only */
/* Examine the IPv6 fragment header and extract fragment offset information.*/
+/* */
+/* We don't know where the transport layer header (or whatever is next is), */
+/* as it could be behind destination options (amongst others). Because */
+/* there is no fragment cache, there is no knowledge about whether or not an*/
+/* upper layer header has been seen (or where it ends) and thus we are not */
+/* able to continue processing beyond this header with any confidence. */
/* ------------------------------------------------------------------------ */
-static INLINE int frpr_fragment6(fin)
+static INLINE void frpr_fragment6(fin)
fr_info_t *fin;
{
struct ip6_frag *frag;
- struct ip6_ext *hdr;
- int i;
- fin->fin_flx |= (FI_FRAG|FI_V6EXTHDR);
-
- /* 8 is default length of extension hdr */
- if ((fin->fin_dlen - 8) < 0) {
- fin->fin_flx |= FI_SHORT;
- return IPPROTO_NONE;
- }
+ fin->fin_flx |= FI_FRAG;
- /*
- * Only one frgament header is allowed per IPv6 packet but it need
- * not be the first nor last (not possible in some cases.)
- */
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_FRAGMENT)
- break;
-
- if (fin->fin_optmsk & ip6exthdr[i].ol_bit) {
- fin->fin_flx |= FI_BAD;
- return IPPROTO_NONE;
- }
-
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE)
+ return;
if (frpr_pullup(fin, sizeof(*frag)) == -1)
- return IPPROTO_NONE;
- hdr = fin->fin_dp;
+ return;
+ frag = fin->fin_dp;
/*
- * Length must be zero, i.e. it has no length.
+ * Fragment but no fragmentation info set? Bad packet...
*/
- if (hdr->ip6e_len != 0) {
+ if (frag->ip6f_offlg == 0) {
fin->fin_flx |= FI_BAD;
- return IPPROTO_NONE;
- }
-
- if ((int)(fin->fin_dlen - sizeof(*frag)) < 0) {
- fin->fin_flx |= FI_SHORT;
- return IPPROTO_NONE;
+ return;
}
- frag = fin->fin_dp;
fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
fin->fin_off <<= 3;
if (fin->fin_off != 0)
@@ -664,8 +669,6 @@ fr_info_t *fin;
fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
fin->fin_dlen -= sizeof(*frag);
-
- return frag->ip6f_nxt;
}
@@ -681,34 +684,7 @@ fr_info_t *fin;
static INLINE int frpr_dstopts6(fin)
fr_info_t *fin;
{
- struct ip6_ext *hdr;
- u_short shift;
- int i;
-
- /* 8 is default length of extension hdr */
- if ((fin->fin_dlen - 8) < 0) {
- fin->fin_flx |= FI_SHORT;
- return IPPROTO_NONE;
- }
-
- if (frpr_pullup(fin, 8) == -1)
- return IPPROTO_NONE;
- hdr = fin->fin_dp;
-
- shift = 8 + (hdr->ip6e_len << 3);
- if (shift > fin->fin_dlen) { /* Nasty extension header length? */
- fin->fin_flx |= FI_BAD;
- return IPPROTO_NONE;
- }
-
- for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
- if (ip6exthdr[i].ol_val == IPPROTO_DSTOPTS)
- break;
- fin->fin_optmsk |= ip6exthdr[i].ol_bit;
- fin->fin_dp = (char *)fin->fin_dp + shift;
- fin->fin_dlen -= shift;
-
- return hdr->ip6e_nxt;
+ return frpr_ipv6exthdr(fin, 1, IPPROTO_DSTOPTS);
}
@@ -758,7 +734,7 @@ fr_info_t *fin;
}
}
- frpr_short(fin, minicmpsz);
+ frpr_short6(fin, minicmpsz);
}
@@ -769,16 +745,16 @@ fr_info_t *fin;
/* */
/* IPv6 Only */
/* Analyse the packet for IPv6/UDP properties. */
+/* Is not expected to be called for fragmented packets. */
/* ------------------------------------------------------------------------ */
static INLINE void frpr_udp6(fin)
fr_info_t *fin;
{
- fr_checkv6sum(fin);
+ frpr_short6(fin, sizeof(struct udphdr));
- frpr_short(fin, sizeof(struct udphdr));
-
- frpr_udpcommon(fin);
+ if (frpr_udpcommon(fin) == 0)
+ fr_checkv6sum(fin);
}
@@ -789,16 +765,86 @@ fr_info_t *fin;
/* */
/* IPv6 Only */
/* Analyse the packet for IPv6/TCP properties. */
+/* Is not expected to be called for fragmented packets. */
/* ------------------------------------------------------------------------ */
static INLINE void frpr_tcp6(fin)
fr_info_t *fin;
{
- fr_checkv6sum(fin);
+ frpr_short6(fin, sizeof(struct tcphdr));
+
+ if (frpr_tcpcommon(fin) == 0)
+ fr_checkv6sum(fin);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_esp6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* Analyse the packet for ESP properties. */
+/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */
+/* even though the newer ESP packets must also have a sequence number that */
+/* is 32bits as well, it is not possible(?) to determine the version from a */
+/* simple packet header. */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_esp6(fin)
+fr_info_t *fin;
+{
+
+ frpr_short6(fin, sizeof(grehdr_t));
+
+ (void) frpr_pullup(fin, 8);
+}
- frpr_short(fin, sizeof(struct tcphdr));
- frpr_tcpcommon(fin);
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_ah6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* IPv6 Only */
+/* Analyse the packet for AH properties. */
+/* The minimum length is taken to be the combination of all fields in the */
+/* header being present and no authentication data (null algorithm used.) */
+/* ------------------------------------------------------------------------ */
+static INLINE int frpr_ah6(fin)
+fr_info_t *fin;
+{
+ authhdr_t *ah;
+
+ frpr_short6(fin, 12);
+
+ if (frpr_pullup(fin, sizeof(*ah)) == -1)
+ return IPPROTO_NONE;
+
+ ah = (authhdr_t *)fin->fin_dp;
+ return ah->ah_next;
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_gre6 */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* Analyse the packet for GRE properties. */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_gre6(fin)
+fr_info_t *fin;
+{
+ grehdr_t *gre;
+
+ frpr_short6(fin, sizeof(grehdr_t));
+
+ if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
+ return;
+
+ gre = fin->fin_dp;
+ if (GRE_REV(gre->gr_flags) == 1)
+ fin->fin_data[0] = gre->gr_call;
}
#endif /* USE_INET6 */
@@ -836,28 +882,25 @@ int plen;
/* ------------------------------------------------------------------------ */
/* Function: frpr_short */
/* Returns: void */
-/* Parameters: fin(I) - pointer to packet information */
-/* min(I) - minimum header size */
+/* Parameters: fin(I) - pointer to packet information */
+/* xmin(I) - minimum header size */
/* */
-/* Check if a packet is "short" as defined by min. The rule we are */
+/* Check if a packet is "short" as defined by xmin. The rule we are */
/* applying here is that the packet must not be fragmented within the layer */
/* 4 header. That is, it must not be a fragment that has its offset set to */
/* start within the layer 4 header (hdrmin) or if it is at offset 0, the */
/* entire layer 4 header must be present (min). */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_short(fin, min)
+static INLINE void frpr_short(fin, xmin)
fr_info_t *fin;
-int min;
+int xmin;
{
- fr_ip_t *fi = &fin->fin_fi;
- int off;
- off = fin->fin_off;
- if (off == 0) {
- if (fin->fin_plen < fin->fin_hlen + min)
- fi->fi_flx |= FI_SHORT;
- } else if (off < min) {
- fi->fi_flx |= FI_SHORT;
+ if (fin->fin_off == 0) {
+ if (fin->fin_dlen < xmin)
+ fin->fin_flx |= FI_SHORT;
+ } else if (fin->fin_off < xmin) {
+ fin->fin_flx |= FI_SHORT;
}
}
@@ -870,7 +913,7 @@ int min;
/* IPv4 Only */
/* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */
/* except extrememly bad packets, both type and code will be present. */
-/* The expected minimum size of an ICMP packet is very much dependant on */
+/* The expected minimum size of an ICMP packet is very much dependent on */
/* the type of it. */
/* */
/* XXX - other ICMP sanity checks? */
@@ -880,13 +923,17 @@ fr_info_t *fin;
{
int minicmpsz = sizeof(struct icmp);
icmphdr_t *icmp;
+ ip_t *oip;
- if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1)
+ if (fin->fin_off != 0) {
+ frpr_short(fin, ICMPERR_ICMPHLEN);
return;
+ }
- fr_checkv4sum(fin);
+ if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1)
+ return;
- if (!fin->fin_off && (fin->fin_dlen > 1)) {
+ if (fin->fin_dlen > 1) {
icmp = fin->fin_dp;
fin->fin_data[0] = *(u_short *)icmp;
@@ -920,13 +967,27 @@ fr_info_t *fin;
* type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+)
*/
case ICMP_UNREACH :
+#ifdef icmp_nextmtu
+ if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) {
+ if (icmp->icmp_nextmtu < fr_icmpminfragmtu)
+ fin->fin_flx |= FI_BAD;
+ }
+#endif
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
+ fin->fin_flx |= FI_ICMPERR;
if (fr_coalesce(fin) != 1)
return;
- fin->fin_flx |= FI_ICMPERR;
+ /*
+ * ICMP error packets should not be generated for IP
+ * packets that are a fragment that isn't the first
+ * fragment.
+ */
+ oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN);
+ if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0)
+ fin->fin_flx |= FI_BAD;
break;
default :
break;
@@ -937,12 +998,14 @@ fr_info_t *fin;
}
frpr_short(fin, minicmpsz);
+
+ fr_checkv4sum(fin);
}
/* ------------------------------------------------------------------------ */
/* Function: frpr_tcpcommon */
-/* Returns: void */
+/* Returns: int - 0 = header ok, 1 = bad packet, -1 = buffer error */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* TCP header sanity checking. Look for bad combinations of TCP flags, */
@@ -950,20 +1013,18 @@ fr_info_t *fin;
/* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */
/* valid and mark the packet as bad if not. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_tcpcommon(fin)
+static INLINE int frpr_tcpcommon(fin)
fr_info_t *fin;
{
int flags, tlen;
tcphdr_t *tcp;
- fr_ip_t *fi;
- fi = &fin->fin_fi;
- fi->fi_flx |= FI_TCPUDP;
+ fin->fin_flx |= FI_TCPUDP;
if (fin->fin_off != 0)
- return;
+ return 0;
if (frpr_pullup(fin, sizeof(*tcp)) == -1)
- return;
+ return -1;
tcp = fin->fin_dp;
if (fin->fin_dlen > 3) {
@@ -971,8 +1032,8 @@ fr_info_t *fin;
fin->fin_dport = ntohs(tcp->th_dport);
}
- if ((fi->fi_flx & FI_SHORT) != 0)
- return;
+ if ((fin->fin_flx & FI_SHORT) != 0)
+ return 1;
/*
* Use of the TCP data offset *must* result in a value that is at
@@ -981,7 +1042,7 @@ fr_info_t *fin;
tlen = TCP_OFF(tcp) << 2;
if (tlen < sizeof(tcphdr_t)) {
fin->fin_flx |= FI_BAD;
- return;
+ return 1;
}
flags = tcp->th_flags;
@@ -1035,10 +1096,10 @@ fr_info_t *fin;
* then that might add some weight to adding this...
*/
if (tlen == sizeof(tcphdr_t))
- return;
+ return 0;
if (frpr_pullup(fin, tlen) == -1)
- return;
+ return -1;
#if 0
ip = fin->fin_ip;
@@ -1077,31 +1138,31 @@ fr_info_t *fin;
s += ol;
}
#endif /* 0 */
+
+ return 0;
}
/* ------------------------------------------------------------------------ */
/* Function: frpr_udpcommon */
-/* Returns: void */
+/* Returns: int - 0 = header ok, 1 = bad packet */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* Extract the UDP source and destination ports, if present. If compiled */
/* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_udpcommon(fin)
+static INLINE int frpr_udpcommon(fin)
fr_info_t *fin;
{
udphdr_t *udp;
- fr_ip_t *fi;
- fi = &fin->fin_fi;
- fi->fi_flx |= FI_TCPUDP;
+ fin->fin_flx |= FI_TCPUDP;
if (!fin->fin_off && (fin->fin_dlen > 3)) {
if (frpr_pullup(fin, sizeof(*udp)) == -1) {
- fi->fi_flx |= FI_SHORT;
- return;
+ fin->fin_flx |= FI_SHORT;
+ return 1;
}
udp = fin->fin_dp;
@@ -1109,6 +1170,8 @@ fr_info_t *fin;
fin->fin_sport = ntohs(udp->uh_sport);
fin->fin_dport = ntohs(udp->uh_dport);
}
+
+ return 0;
}
@@ -1124,11 +1187,10 @@ static INLINE void frpr_tcp(fin)
fr_info_t *fin;
{
- fr_checkv4sum(fin);
-
frpr_short(fin, sizeof(tcphdr_t));
- frpr_tcpcommon(fin);
+ if (frpr_tcpcommon(fin) == 0)
+ fr_checkv4sum(fin);
}
@@ -1144,11 +1206,10 @@ static INLINE void frpr_udp(fin)
fr_info_t *fin;
{
- fr_checkv4sum(fin);
-
frpr_short(fin, sizeof(udphdr_t));
- frpr_udpcommon(fin);
+ if (frpr_udpcommon(fin) == 0)
+ fr_checkv4sum(fin);
}
@@ -1166,15 +1227,42 @@ fr_info_t *fin;
static INLINE void frpr_esp(fin)
fr_info_t *fin;
{
- if (frpr_pullup(fin, 8) == -1)
- return;
- if (fin->fin_v == 4)
+ if (fin->fin_off == 0) {
frpr_short(fin, 8);
-#ifdef USE_INET6
- else if (fin->fin_v == 6)
- frpr_short6(fin, sizeof(grehdr_t));
-#endif
+ (void) frpr_pullup(fin, 8);
+ }
+
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: frpr_ah */
+/* Returns: void */
+/* Parameters: fin(I) - pointer to packet information */
+/* */
+/* Analyse the packet for AH properties. */
+/* The minimum length is taken to be the combination of all fields in the */
+/* header being present and no authentication data (null algorithm used.) */
+/* ------------------------------------------------------------------------ */
+static INLINE void frpr_ah(fin)
+fr_info_t *fin;
+{
+ authhdr_t *ah;
+ int len;
+
+ frpr_short(fin, sizeof(*ah));
+
+ if (((fin->fin_flx & FI_SHORT) != 0) || (fin->fin_off != 0))
+ return;
+
+ if (frpr_pullup(fin, sizeof(*ah)) == -1)
+ return;
+
+ ah = (authhdr_t *)fin->fin_dp;
+
+ len = (ah->ah_plen + 2) << 2;
+ frpr_short(fin, len);
}
@@ -1190,18 +1278,19 @@ fr_info_t *fin;
{
grehdr_t *gre;
- if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
+ frpr_short(fin, sizeof(*gre));
+
+ if (fin->fin_off != 0)
return;
- if (fin->fin_v == 4)
- frpr_short(fin, sizeof(grehdr_t));
-#ifdef USE_INET6
- else if (fin->fin_v == 6)
- frpr_short6(fin, sizeof(grehdr_t));
-#endif
- gre = fin->fin_dp;
- if (GRE_REV(gre->gr_flags) == 1)
- fin->fin_data[0] = gre->gr_call;
+ if (frpr_pullup(fin, sizeof(*gre)) == -1)
+ return;
+
+ if (fin->fin_off == 0) {
+ gre = fin->fin_dp;
+ if (GRE_REV(gre->gr_flags) == 1)
+ fin->fin_data[0] = gre->gr_call;
+ }
}
@@ -1257,12 +1346,6 @@ fr_info_t *fin;
* set packet attribute flags based on the offset and
* calculate the byte offset that it represents.
*/
- if ((off & IP_MF) != 0) {
- fi->fi_flx |= FI_FRAG;
- if (fin->fin_dlen == 0)
- fi->fi_flx |= FI_BAD;
- }
-
off &= IP_MF|IP_OFFMASK;
if (off != 0) {
fi->fi_flx |= FI_FRAG;
@@ -1270,7 +1353,17 @@ fr_info_t *fin;
if (off != 0) {
fin->fin_flx |= FI_FRAGBODY;
off <<= 3;
- if (off + fin->fin_dlen > 0xffff) {
+ if ((off + fin->fin_dlen > 65535) ||
+ (fin->fin_dlen == 0) || (fin->fin_dlen & 7)) {
+ /*
+ * The length of the packet, starting at its
+ * offset cannot exceed 65535 (0xffff) as the
+ * length of an IP packet is only 16 bits.
+ *
+ * Any fragment that isn't the last fragment
+ * must have a length greater than 0 and it
+ * must be an even multiple of 8.
+ */
fi->fi_flx |= FI_BAD;
}
}
@@ -1291,6 +1384,9 @@ fr_info_t *fin;
case IPPROTO_ICMP :
frpr_icmp(fin);
break;
+ case IPPROTO_AH :
+ frpr_ah(fin);
+ break;
case IPPROTO_ESP :
frpr_esp(fin);
break;
@@ -1419,8 +1515,10 @@ fr_info_t *fin;
if (v == 4)
frpr_ipv4hdr(fin);
#ifdef USE_INET6
- else if (v == 6)
- frpr_ipv6hdr(fin);
+ else if (v == 6) {
+ if (frpr_ipv6hdr(fin) == -1)
+ return -1;
+ }
#endif
if (fin->fin_ip == NULL)
return -1;
@@ -1548,6 +1646,7 @@ frtuc_t *ft;
}
+
/* ------------------------------------------------------------------------ */
/* Function: fr_ipfcheck */
/* Returns: int - 0 == match, 1 == no match */
@@ -1753,7 +1852,7 @@ u_32_t pass;
{
int rulen, portcmp, off, logged, skip;
struct frentry *fr, *fnext;
- u_32_t passt;
+ u_32_t passt, passo;
/*
* Do not allow nesting deeper than 16 levels.
@@ -1821,15 +1920,13 @@ u_32_t pass;
case FR_T_BPFOPC|FR_T_BUILTIN :
{
u_char *mc;
- int wlen;
if (*fin->fin_mp == NULL)
continue;
if (fin->fin_v != fr->fr_v)
continue;
mc = (u_char *)fin->fin_m;
- wlen = fin->fin_dlen + fin->fin_hlen;
- if (!bpf_filter(fr->fr_data, mc, wlen, 0))
+ if (!bpf_filter(fr->fr_data, mc, fin->fin_plen, 0))
continue;
break;
}
@@ -1911,6 +2008,7 @@ u_32_t pass;
}
#endif /* IPFILTER_LOG */
fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
+ passo = pass;
if (FR_ISSKIP(passt))
skip = fr->fr_arg;
else if ((passt & FR_LOGMASK) != FR_LOG)
@@ -1933,8 +2031,29 @@ u_32_t pass;
if (fin->fin_flx & FI_DONTCACHE)
logged = 1;
}
- if (pass & FR_QUICK)
+
+ if (pass & FR_QUICK) {
+ /*
+ * Finally, if we've asked to track state for this
+ * packet, set it up. Add state for "quick" rules
+ * here so that if the action fails we can consider
+ * the rule to "not match" and keep on processing
+ * filter rules.
+ */
+ if ((pass & FR_KEEPSTATE) &&
+ !(fin->fin_flx & FI_STATE)) {
+ int out = fin->fin_out;
+
+ if (fr_addstate(fin, NULL, 0) != NULL) {
+ ATOMIC_INCL(frstats[out].fr_ads);
+ } else {
+ ATOMIC_INCL(frstats[out].fr_bads);
+ pass = passo;
+ continue;
+ }
+ }
break;
+ }
}
if (logged)
fin->fin_flx |= FI_DONTCACHE;
@@ -2019,18 +2138,22 @@ u_32_t *passp;
* the result as if it were from the ACL's.
*/
fc = &frcache[out][CACHE_HASH(fin)];
+ READ_ENTER(&ipf_frcache);
if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
/*
- * copy cached data so we can unlock the mutex
- * earlier.
+ * copy cached data so we can unlock the mutexes earlier.
*/
bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
+ RWLOCK_EXIT(&ipf_frcache);
ATOMIC_INCL(frstats[out].fr_chit);
+
if ((fr = fin->fin_fr) != NULL) {
ATOMIC_INC64(fr->fr_hits);
pass = fr->fr_flags;
}
} else {
+ RWLOCK_EXIT(&ipf_frcache);
+
#ifdef USE_INET6
if (fin->fin_v == 6)
fin->fin_fr = ipfilter6[out][fr_active];
@@ -2039,9 +2162,13 @@ u_32_t *passp;
fin->fin_fr = ipfilter[out][fr_active];
if (fin->fin_fr != NULL)
pass = fr_scanlist(fin, fr_pass);
+
if (((pass & FR_KEEPSTATE) == 0) &&
- ((fin->fin_flx & FI_DONTCACHE) == 0))
+ ((fin->fin_flx & FI_DONTCACHE) == 0)) {
+ WRITE_ENTER(&ipf_frcache);
bcopy((char *)fin, (char *)fc, FI_COPYSIZE);
+ RWLOCK_EXIT(&ipf_frcache);
+ }
if ((pass & FR_NOMATCH)) {
ATOMIC_INCL(frstats[out].fr_nom);
}
@@ -2136,7 +2263,7 @@ u_32_t *passp;
/* User space: */
/* -1 == packet blocked */
/* 1 == packet not matched */
-/* -2 == requires authantication */
+/* -2 == requires authentication */
/* Kernel: */
/* > 0 == filter error # for packet */
/* Parameters: ip(I) - pointer to start of IPv4/6 packet */
@@ -2186,6 +2313,7 @@ int out;
#ifdef USE_INET6
ip6_t *ip6;
#endif
+ SPL_INT(s);
/*
* The first part of fr_check() deals with making sure that what goes
@@ -2225,6 +2353,10 @@ int out;
if ((m->m_flags & M_MCAST) != 0)
fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
# endif
+# if defined(M_MLOOP)
+ if ((m->m_flags & M_MLOOP) != 0)
+ fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
+# endif
# if defined(M_BCAST)
if ((m->m_flags & M_BCAST) != 0)
fin->fin_flx |= FI_MBCAST|FI_BROADCAST;
@@ -2261,11 +2393,13 @@ int out;
fin->fin_out = out;
fin->fin_ifp = ifp;
fin->fin_error = ENETUNREACH;
- fin->fin_hlen = (u_short )hlen;
+ fin->fin_hlen = (u_short)hlen;
fin->fin_dp = (char *)ip + hlen;
fin->fin_ipoff = (char *)ip - MTOD(m, char *);
+ SPL_NET(s);
+
#ifdef USE_INET6
if (v == 6) {
ATOMIC_INCL(frstats[out].fr_ipv6);
@@ -2278,7 +2412,7 @@ int out;
fin->fin_plen = ntohs(ip6->ip6_plen);
if (fin->fin_plen == 0) {
pass = FR_BLOCK|FR_NOMATCH;
- goto filtered;
+ goto finished;
}
fin->fin_plen += sizeof(ip6_t);
} else
@@ -2291,8 +2425,10 @@ int out;
fin->fin_plen = ip->ip_len;
}
- if (fr_makefrip(hlen, ip, fin) == -1)
+ if (fr_makefrip(hlen, ip, fin) == -1) {
+ pass = FR_BLOCK|FR_NOMATCH;
goto finished;
+ }
/*
* For at least IPv6 packets, if a m_pullup() fails then this pointer
@@ -2386,22 +2522,31 @@ int out;
}
#endif
- if (fin->fin_state != NULL)
+ if (fin->fin_state != NULL) {
fr_statederef(fin, (ipstate_t **)&fin->fin_state);
+ fin->fin_state = NULL;
+ }
- if (fin->fin_nat != NULL)
+ if (fin->fin_nat != NULL) {
fr_natderef((nat_t **)&fin->fin_nat);
+ fin->fin_nat = NULL;
+ }
/*
- * Only allow FR_DUP to work if a rule matched - it makes no sense to
- * set FR_DUP as a "default" as there are no instructions about where
- * to send the packet. Use fin_m here because it may have changed
- * (without an update of 'm') in prior processing.
+ * Up the reference on fr_lock and exit ipf_mutex. fr_fastroute
+ * only frees up the lock on ipf_global and the generation of a
+ * packet below could cause a recursive call into IPFilter.
+ * Hang onto the filter rule just in case someone decides to remove
+ * or flush it in the meantime.
*/
- if ((fr != NULL) && (pass & FR_DUP)) {
- mc = M_DUPLICATE(fin->fin_m);
+ if (fr != NULL) {
+ MUTEX_ENTER(&fr->fr_lock);
+ fr->fr_ref++;
+ MUTEX_EXIT(&fr->fr_lock);
}
+ RWLOCK_EXIT(&ipf_mutex);
+
if (pass & (FR_RETRST|FR_RETICMP)) {
/*
* Should we return an ICMP packet to indicate error
@@ -2423,7 +2568,8 @@ int out;
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
!(fin->fin_flx & FI_SHORT)) {
- if (fr_send_reset(fin) == 0) {
+ if (((fin->fin_flx & FI_OOW) != 0) ||
+ (fr_send_reset(fin) == 0)) {
ATOMIC_INCL(frstats[1].fr_ret);
}
}
@@ -2439,13 +2585,7 @@ int out;
* instructions about what to do with a packet.
* Once we're finished return to our caller, freeing the packet if
* we are dropping it (* BSD ONLY *).
- * Reassign m from fin_m as we may have a new buffer, now.
*/
-#if defined(USE_INET6) || (defined(__sgi) && defined(_KERNEL))
-filtered:
-#endif
- m = fin->fin_m;
-
if (fr != NULL) {
frdest_t *fdp;
@@ -2456,26 +2596,26 @@ filtered:
* For fastroute rule, no destioation interface defined
* so pass NULL as the frdest_t parameter
*/
- (void) fr_fastroute(m, mp, fin, NULL);
+ (void) fr_fastroute(fin->fin_m, mp, fin, NULL);
m = *mp = NULL;
} else if ((fdp->fd_ifp != NULL) &&
(fdp->fd_ifp != (struct ifnet *)-1)) {
/* this is for to rules: */
- (void) fr_fastroute(m, mp, fin, fdp);
+ (void) fr_fastroute(fin->fin_m, mp, fin, fdp);
m = *mp = NULL;
}
/*
* Generate a duplicated packet.
*/
- if (mc != NULL)
- (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif);
- }
+ if ((pass & FR_DUP) != 0) {
+ mc = M_DUPLICATE(fin->fin_m);
+ if (mc != NULL)
+ (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif);
+ }
- /*
- * This late because the likes of fr_fastroute() use fin_fr.
- */
- RWLOCK_EXIT(&ipf_mutex);
+ (void) fr_derefrule(&fr);
+ }
finished:
if (!FR_ISPASS(pass)) {
@@ -2489,14 +2629,16 @@ finished:
#if defined(_KERNEL) && defined(__sgi)
if ((fin->fin_hbuf != NULL) &&
(mtod(fin->fin_m, struct ip *) != fin->fin_ip)) {
- COPYBACK(m, 0, fin->fin_plen, fin->fin_hbuf);
+ COPYBACK(fin->fin_m, 0, fin->fin_plen, fin->fin_hbuf);
}
#endif
}
+ SPL_X(s);
RWLOCK_EXIT(&ipf_global);
+
#ifdef _KERNEL
-# if OpenBSD >= 200311
+# if OpenBSD >= 200311
if (FR_ISPASS(pass) && (v == 4)) {
ip = fin->fin_ip;
ip->ip_len = ntohs(ip->ip_len);
@@ -2887,7 +3029,7 @@ nodata:
#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \
- defined(__sgi) ) && !defined(linux)
+ defined(__sgi) ) && !defined(linux) && !defined(_AIX51)
/*
* Copyright (c) 1982, 1986, 1988, 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -2917,7 +3059,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp
+ * $Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -2986,7 +3128,7 @@ m_copyback(m0, off, len, cp)
m = m->m_next;
}
while (len > 0) {
- mlen = min (m->m_len - off, len);
+ mlen = min(m->m_len - off, len);
bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
cp += mlen;
len -= mlen;
@@ -3035,7 +3177,7 @@ frgroup_t ***fgpp;
frgroup_t *fg, **fgp;
/*
- * Which list of groups to search in is dependant on which list of
+ * Which list of groups to search in is dependent on which list of
* rules are being operated on.
*/
fgp = &ipfgroups[unit][set];
@@ -3328,7 +3470,8 @@ int proto, flags;
/* slen bytes. */
/* ------------------------------------------------------------------------ */
char *memstr(src, dst, slen, dlen)
-char *src, *dst;
+const char *src;
+char *dst;
int slen, dlen;
{
char *s = NULL;
@@ -3995,10 +4138,15 @@ caddr_t data;
fprev = &fg->fg_start;
}
- for (f = *fprev; (f = *fprev) != NULL; fprev = &f->fr_next)
- if (fp->fr_collect <= f->fr_collect)
- break;
ftail = fprev;
+ for (f = *ftail; (f = *ftail) != NULL; ftail = &f->fr_next) {
+ if (fp->fr_collect <= f->fr_collect) {
+ ftail = fprev;
+ f = NULL;
+ break;
+ }
+ fprev = ftail;
+ }
/*
* Copy in extra data for the rule.
@@ -4097,7 +4245,6 @@ caddr_t data;
break;
#endif
default :
-
break;
}
break;
@@ -4137,14 +4284,17 @@ caddr_t data;
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache));
- for (; (f = *ftail) != NULL; ftail = &f->fr_next)
- if ((fp->fr_cksum == f->fr_cksum) &&
- (f->fr_dsize == fp->fr_dsize) &&
- !bcmp((char *)&f->fr_func,
- (char *)&fp->fr_func, FR_CMPSIZ) &&
- (!ptr || !f->fr_data ||
+ for (; (f = *ftail) != NULL; ftail = &f->fr_next) {
+ if ((fp->fr_cksum != f->fr_cksum) ||
+ (f->fr_dsize != fp->fr_dsize))
+ continue;
+ if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func, FR_CMPSIZ))
+ continue;
+ if ((!ptr && !f->fr_data) ||
+ (ptr && f->fr_data &&
!bcmp((char *)ptr, (char *)f->fr_data, f->fr_dsize)))
break;
+ }
/*
* If zero'ing statistics, copy current to caller and zero.
@@ -4190,12 +4340,40 @@ caddr_t data;
}
if (!f) {
- if (req == (ioctlcmd_t)SIOCINAFR ||
- req == (ioctlcmd_t)SIOCINIFR) {
+ /*
+ * At the end of this, ftail must point to the place where the
+ * new rule is to be saved/inserted/added.
+ * For SIOCAD*FR, this should be the last rule in the group of
+ * rules that have equal fr_collect fields.
+ * For SIOCIN*FR, ...
+ */
+ if (req == (ioctlcmd_t)SIOCADAFR ||
+ req == (ioctlcmd_t)SIOCADIFR) {
+
+ for (ftail = fprev; (f = *ftail) != NULL; ) {
+ if (f->fr_collect > fp->fr_collect)
+ break;
+ ftail = &f->fr_next;
+ }
+ f = NULL;
+ ptr = NULL;
+ error = 0;
+ } else if (req == (ioctlcmd_t)SIOCINAFR ||
+ req == (ioctlcmd_t)SIOCINIFR) {
+ while ((f = *fprev) != NULL) {
+ if (f->fr_collect >= fp->fr_collect)
+ break;
+ fprev = &f->fr_next;
+ }
ftail = fprev;
if (fp->fr_hits != 0) {
- while (--fp->fr_hits && (f = *ftail))
+ while (fp->fr_hits && (f = *ftail)) {
+ if (f->fr_collect != fp->fr_collect)
+ break;
+ fprev = ftail;
ftail = &f->fr_next;
+ fp->fr_hits--;
+ }
}
f = NULL;
ptr = NULL;
@@ -4240,7 +4418,7 @@ caddr_t data;
}
if (*f->fr_grhead != '\0')
fr_delgroup(f->fr_grhead, unit, set);
- fr_fixskip(fprev, f, -1);
+ fr_fixskip(ftail, f, -1);
*ftail = f->fr_next;
f->fr_next = NULL;
(void)fr_derefrule(&f);
@@ -4261,7 +4439,7 @@ caddr_t data;
} else
f = fp;
if (f != NULL) {
- if (fg != NULL && fg->fg_head!= NULL )
+ if (fg != NULL && fg->fg_head != NULL)
fg->fg_head->fr_ref++;
if (fp != f)
bcopy((char *)fp, (char *)f,
@@ -4280,7 +4458,7 @@ caddr_t data;
*ftail = f;
if (req == (ioctlcmd_t)SIOCINIFR ||
req == (ioctlcmd_t)SIOCINAFR)
- fr_fixskip(fprev, f, 1);
+ fr_fixskip(ftail, f, 1);
f->fr_grp = NULL;
group = f->fr_grhead;
if (*group != '\0') {
@@ -4928,7 +5106,7 @@ ipftq_t *oifq, *nifq;
/* the fragment cache for non-leading fragments. If a non-leading fragment */
/* has no match in the cache, return an error. */
/* ------------------------------------------------------------------------ */
-static INLINE int fr_updateipid(fin)
+static int fr_updateipid(fin)
fr_info_t *fin;
{
u_short id, ido, sums;
@@ -4980,7 +5158,7 @@ char *buffer;
{
static char namebuf[LIFNAMSIZ];
# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
- defined(__sgi) || defined(linux) || \
+ defined(__sgi) || defined(linux) || defined(_AIX51) || \
(defined(sun) && !defined(__SVR4) && !defined(__svr4__))
int unit, space;
char temp[20];
@@ -4992,7 +5170,7 @@ char *buffer;
(void) strncpy(buffer, ifp->if_name, LIFNAMSIZ);
buffer[LIFNAMSIZ - 1] = '\0';
# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
- defined(__sgi) || \
+ defined(__sgi) || defined(_AIX51) || \
(defined(sun) && !defined(__SVR4) && !defined(__svr4__))
for (s = buffer; *s; s++)
;
@@ -5605,6 +5783,10 @@ ipftuneable_t ipf_tuneables[] = {
sizeof(fr_update_ipid), 0 },
{ { &fr_chksrc }, "fr_chksrc", 0, 1,
sizeof(fr_chksrc), 0 },
+ { { &fr_minttl }, "fr_minttl", 0, 1,
+ sizeof(fr_minttl), 0 },
+ { { &fr_icmpminfragmtu }, "fr_icmpminfragmtu", 0, 1,
+ sizeof(fr_icmpminfragmtu), 0 },
{ { &fr_pass }, "fr_pass", 0, 0xffffffff,
sizeof(fr_pass), 0 },
/* state */
@@ -5750,7 +5932,7 @@ void *cookie, **next;
/* to the matching structure. */
/* ------------------------------------------------------------------------ */
static ipftuneable_t *fr_findtunebyname(name)
-char *name;
+const char *name;
{
ipftuneable_t *ta;
@@ -5930,6 +6112,7 @@ void *data;
tu.ipft_vshort = *ta->ipft_pshort;
else if (ta->ipft_sz == sizeof(u_char))
tu.ipft_vchar = *ta->ipft_pchar;
+ tu.ipft_cookie = ta;
tu.ipft_sz = ta->ipft_sz;
tu.ipft_min = ta->ipft_min;
tu.ipft_max = ta->ipft_max;
@@ -6141,31 +6324,6 @@ int v;
/* ------------------------------------------------------------------------ */
-/* Function: fr_icmp4errortype */
-/* Returns: int - 1 == success, 0 == failure */
-/* Parameters: icmptype(I) - ICMP type number */
-/* */
-/* Tests to see if the ICMP type number passed is an error type or not. */
-/* ------------------------------------------------------------------------ */
-int fr_icmp4errortype(icmptype)
-int icmptype;
-{
-
- switch (icmptype)
- {
- case ICMP_SOURCEQUENCH :
- case ICMP_PARAMPROB :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_UNREACH :
- return 1;
- default:
- return 0;
- }
-}
-
-
-/* ------------------------------------------------------------------------ */
/* Function: fr_resolvenic */
/* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */
/* pointer to interface structure for NIC */
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index a1e029af7e55..b6f0844354bf 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij.
*
@@ -119,7 +117,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.5 2005/06/12 07:18:14 darrenr Exp $";
#endif
@@ -368,9 +366,7 @@ int mode;
#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
(!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
struct ifqueue *ifq;
-# ifdef USE_SPL
- int s;
-# endif /* USE_SPL */
+ SPL_INT(s);
#endif
frauth_t auth, *au = &auth, *fra;
int i, error = 0, len;
@@ -507,10 +503,10 @@ fr_authioctlloop:
# ifdef MENTAT
error = !putq(fra->fra_q, m);
# else /* MENTAT */
-# ifdef linux
+# if defined(linux) || defined(AIX)
# else
# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \
- (defined(__sgi) && (IRIX >= 60500) || \
+ (defined(__sgi) && (IRIX >= 60500) || defined(AIX) || \
(defined(__FreeBSD__) && (__FreeBSD_version >= 470102)))
error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
NULL);
@@ -527,12 +523,12 @@ fr_authioctlloop:
# ifdef MENTAT
error = !putq(fra->fra_q, m);
# else /* MENTAT */
-# ifdef linux
+# if defined(linux) || defined(AIX)
# else
-# if __FreeBSD_version >= 501000
+# if (__FreeBSD_version >= 501000)
netisr_dispatch(NETISR_IP, m);
# else
-# if IRIX >= 60516
+# if (IRIX >= 60516)
ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd;
# else
ifq = &ipintrq;
@@ -663,9 +659,7 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
-# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
if (fr_auth_lock)
return;
@@ -714,9 +708,7 @@ frentry_t *fr, **frptr;
{
frauthent_t *fae, **faep;
int error = 0;
-# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR))
return EIO;
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h
index 8e96f39bd5f1..389277827009 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.h
+++ b/sys/contrib/ipfilter/netinet/ip_auth.h
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1997-2001 by Darren Reed & Guido Van Rooij.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp
+ * $Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index dbadfea58136..f48a98dbfda3 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
- * Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp
+ * $Id: ip_compat.h,v 2.142.2.33 2005/12/04 23:40:17 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -768,7 +766,7 @@ typedef u_int32_t u_32_t;
/* F R E E B S D */
/* ----------------------------------------------------------------------- */
#ifdef __FreeBSD__
-# if defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(KLD_MODULE)
+# if defined(_KERNEL)
# if (__FreeBSD_version >= 500000)
# include "opt_bpf.h"
# else
@@ -1122,6 +1120,7 @@ extern mb_t *m_pullup __P((mb_t *, int));
# define mbuf sk_buff
# define mtod(m, t) ((t)(m)->data)
+# define m_data data
# define m_len len
# define m_next next
# define M_DUPLICATE(m) skb_clone((m), in_interrupt() ? GFP_ATOMIC : \
@@ -1206,6 +1205,115 @@ typedef u_int32_t u_32_t;
#endif
+/* ----------------------------------------------------------------------- */
+/* A I X */
+/* ----------------------------------------------------------------------- */
+#if defined(_AIX51)
+# undef MENTAT
+
+# include <sys/lock.h>
+# include <sys/sysmacros.h>
+
+# ifdef _KERNEL
+# define rw_read_locked(x) 0
+# include <net/net_globals.h>
+# include <net/net_malloc.h>
+# define KMUTEX_T simple_lock_t
+# define KRWLOCK_T complex_lock_t
+# define USE_MUTEXES 1
+# define USE_SPL 1
+# define READ_ENTER(x) lock_read((x)->ipf_lk)
+# define WRITE_ENTER(x) lock_write((x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) lock_write_to_read((x)->ipf_lk)
+# define RWLOCK_INIT(x, y) lock_alloc(&(x)->ipf_lk, \
+ LOCK_ALLOC_PIN, \
+ (u_short)y, 0); \
+ lock_init((x)->ipf_lk, TRUE)
+# define RWLOCK_EXIT(x) lock_done((x)->ipf_lk)
+# define RW_DESTROY(x) lock_free(&(x)->ipf_lk)
+# define MUTEX_ENTER(x) simple_lock((x)->ipf_lk)
+# define MUTEX_INIT(x, y) lock_alloc(&(x)->ipf_lk, \
+ LOCK_ALLOC_PIN, \
+ (u_short)y, 0); \
+ simple_lock_init((x)->ipf_lk)
+# define MUTEX_DESTROY(x) lock_free(&(x)->ipf_lk)
+# define MUTEX_EXIT(x) simple_unlock((x)->ipf_lk)
+# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk))
+# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \
+ MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \
+ MUTEX_EXIT(&ipf_rw); }
+# define SPL_NET(x) x = splnet()
+# define SPL_IMP(x) x = splimp()
+# undef SPL_X
+# define SPL_X(x) splx(x)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
+extern void* getifp __P((char *, int));
+# define GETIFP(n, v) getifp(n, v)
+# define GET_MINOR minor
+# define SLEEP(id, n) sleepx((id), PZERO+1, 0)
+# define WAKEUP(id,x) wakeup(id)
+# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
+# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c))
+# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, \
+ ((c) > 4096) ? M_WAITOK : M_NOWAIT)
+# define KFREE(x) FREE((x), M_TEMP)
+# define KFREES(x,s) FREE((x), M_TEMP)
+# define MSGDSIZE(x) mbufchainlen(x)
+# define M_LEN(x) (x)->m_len
+# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define GETKTIME(x)
+# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
+ ((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
+# define IPF_PANIC(x,y)
+typedef struct mbuf mb_t;
+# endif /* _KERNEL */
+
+/*
+ * These are from's Solaris' #defines for little endian.
+ */
+#if !defined(IP6F_MORE_FRAG)
+# define IP6F_MORE_FRAG 0x0100
+#endif
+#if !defined(IP6F_RESERVED_MASK)
+# define IP6F_RESERVED_MASK 0x0600
+#endif
+#if !defined(IP6F_OFF_MASK)
+# define IP6F_OFF_MASK 0xf8ff
+#endif
+
+struct ip6_ext {
+ u_char ip6e_nxt;
+ u_char ip6e_len;
+};
+
+typedef int ioctlcmd_t;
+typedef int minor_t;
+/*
+ * Really, any arch where sizeof(long) != sizeof(int).
+ */
+typedef unsigned int u_32_t;
+# define U_32_T 1
+
+# define OS_RECOGNISED 1
+#endif /* _AIX51 */
+
+
#ifndef OS_RECOGNISED
#error ip_compat.h does not recognise this platform/OS.
#endif
@@ -1221,8 +1329,11 @@ typedef u_int32_t u_32_t;
* For BSD kernels, if bpf is in the kernel, enable ipfilter to use bpf in
* filter rules.
*/
-#if !defined(IPFILTER_BPF) && ((NBPF > 0) || (NBPFILTER > 0))
-# define IPFILTER_BPF
+#if !defined(IPFILTER_BPF)
+# if (defined(NBPF) && (NBPF > 0)) || (defined(DEV_BPF) && (DEV_BPF > 0)) || \
+ (defined(NBPFILTER) && (NBPFILTER > 0))
+# define IPFILTER_BPF
+# endif
#endif
/*
@@ -1290,10 +1401,10 @@ typedef union {
#endif
#if defined(linux) && defined(_KERNEL)
-extern INLINE void ipf_read_enter __P((ipfrwlock_t *));
-extern INLINE void ipf_write_enter __P((ipfrwlock_t *));
-extern INLINE void ipf_rw_exit __P((ipfrwlock_t *));
-extern INLINE void ipf_rw_downgrade __P((ipfrwlock_t *));
+extern void ipf_read_enter __P((ipfrwlock_t *));
+extern void ipf_write_enter __P((ipfrwlock_t *));
+extern void ipf_rw_exit __P((ipfrwlock_t *));
+extern void ipf_rw_downgrade __P((ipfrwlock_t *));
#endif
/*
@@ -1313,6 +1424,7 @@ typedef struct mb_s {
# define M_LEN(x) (x)->mb_len
# define M_DUPLICATE(x) (x)
# define GETKTIME(x) gettimeofday((struct timeval *)(x), NULL)
+# undef MTOD
# define MTOD(m, t) ((t)(m)->mb_buf)
# define FREE_MB_T(x)
# define SLEEP(x,y) 1;
@@ -1327,8 +1439,8 @@ typedef struct mb_s {
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
# define GETIFP(x, v) get_unit(x,v)
-# define COPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
-# define COPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
+# define COPYIN(a,b,c) bcopywrap((a), (b), (c))
+# define COPYOUT(a,b,c) bcopywrap((a), (b), (c))
# define BCOPYIN(a,b,c) (bcopy((a), (b), (c)), 0)
# define BCOPYOUT(a,b,c) (bcopy((a), (b), (c)), 0)
# define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \
@@ -1563,6 +1675,12 @@ extern char *fr_getifname __P((struct ifnet *, char *));
# define ATOMIC_DEC(x) (x)--
#endif
+#if defined(USE_SPL) && defined(_KERNEL)
+# define SPL_INT(x) int x
+#else
+# define SPL_INT(x)
+#endif
+
/*
* If there are no atomic operations for bit sizes defined, define them to all
* use a generic one that works for all sizes.
@@ -2037,9 +2155,10 @@ typedef struct tcpiphdr tcpiphdr_t;
#ifndef IPPROTO_DSTOPTS
# define IPPROTO_DSTOPTS 60
#endif
-#ifndef IPPROTO_FRAGMENT
-# define IPPROTO_FRAGMENT 44
+#ifndef IPPROTO_MOBILITY
+# define IPPROTO_MOBILITY 135
#endif
+
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
@@ -2273,7 +2392,7 @@ typedef struct tcpiphdr tcpiphdr_t;
/*
* ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
* another IP header and then 64 bits of data, totalling 56. Of course,
- * the last 64 bits is dependant on that being available.
+ * the last 64 bits is dependent on that being available.
*/
#define ICMPERR_ICMPHLEN 8
#define ICMPERR_IPICMPHLEN (20 + 8)
@@ -2292,4 +2411,8 @@ typedef struct tcpiphdr tcpiphdr_t;
# define DPRINT(x)
#endif
+#ifdef RESCUE
+# undef IPFILTER_BPF
+#endif
+
#endif /* __IP_COMPAT_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index 626dddeb2f37..45d5bb4734c8 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1,17 +1,17 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * Id: ip_fil.h,v 2.170.2.18 2005/03/28 10:47:52 darrenr Exp
+ * $Id: ip_fil.h,v 2.170.2.23 2005/12/04 23:39:28 darrenr Exp $
*/
#ifndef __IP_FIL_H__
#define __IP_FIL_H__
+#include "netinet/ip_compat.h"
+
#ifndef SOLARIS
# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
@@ -24,7 +24,7 @@
# endif
#endif
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCADAFR _IOW('r', 60, struct ipfobj)
# define SIOCRMAFR _IOW('r', 61, struct ipfobj)
# define SIOCSETFF _IOW('r', 62, u_int)
@@ -904,6 +904,7 @@ typedef struct tcpdata {
#define TCP_WSCALE_SEEN 0x00000001
#define TCP_WSCALE_FIRST 0x00000002
+#define TCP_SACK_PERMIT 0x00000004
typedef struct tcpinfo {
@@ -913,6 +914,9 @@ typedef struct tcpinfo {
} tcpinfo_t;
+/*
+ * Structures to define a GRE header as seen in a packet.
+ */
struct grebits {
u_32_t grb_C:1;
u_32_t grb_R:1;
@@ -947,7 +951,9 @@ typedef struct grehdr {
#define gr_A gr_bits.grb_A
#define gr_ver gr_bits.grb_ver
-
+/*
+ * GRE information tracked by "keep state"
+ */
typedef struct greinfo {
u_short gs_call[2];
u_short gs_flags;
@@ -958,6 +964,20 @@ typedef struct greinfo {
/*
+ * Format of an Authentication header
+ */
+typedef struct authhdr {
+ u_char ah_next;
+ u_char ah_plen;
+ u_short ah_reserved;
+ u_32_t ah_spi;
+ u_32_t ah_seq;
+ /* Following the sequence number field is 0 or more bytes of */
+ /* authentication data, as specified by ah_plen - RFC 2402. */
+} authhdr_t;
+
+
+/*
* Timeout tail queue list member
*/
typedef struct ipftqent {
@@ -1237,8 +1257,9 @@ extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
extern ipfmutex_t ipf_timeoutlock, ipf_stinsert, ipf_natio, ipf_nat_new;
extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag;
extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
+extern ipfrwlock_t ipf_frcache;
-extern char *memstr __P((char *, char *, int, int));
+extern char *memstr __P((const char *, char *, int, int));
extern int count4bits __P((u_32_t));
extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int));
extern char *getifname __P((struct ifnet *));
@@ -1311,7 +1332,6 @@ extern void fr_fixskip __P((frentry_t **, frentry_t *, int));
extern void fr_forgetifp __P((void *));
extern frentry_t *fr_getrulen __P((int, char *, u_32_t));
extern void fr_getstat __P((struct friostat *));
-extern int fr_icmp4errortype __P((int));
extern int fr_ifpaddr __P((int, int, void *,
struct in_addr *, struct in_addr *));
extern int fr_initialise __P((void));
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 4ee0d3b23052..760122e393b3 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2003 by Darren Reed.
*
@@ -7,7 +5,7 @@
*/
#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_freebsd.c,v 2.53.2.25 2005/02/01 03:15:56 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.27 2005/08/20 13:48:19 darrenr Exp $";
#endif
#if defined(KERNEL) || defined(_KERNEL)
@@ -125,7 +123,7 @@ static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **));
# ifdef USE_MUTEXES
ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert;
ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock;
-ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag;
+ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ipf_frcache;
ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
# endif
int ipf_locks_done = 0;
@@ -147,6 +145,19 @@ int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
#endif /* __FreeBSD_version >= 500011 */
+#if (__FreeBSD_version >= 502103)
+static eventhandler_tag ipf_arrivetag, ipf_departtag, ipf_clonetag;
+
+static void ipf_ifevent(void *arg);
+
+static void ipf_ifevent(arg)
+void *arg;
+{
+ frsync(NULL);
+}
+#endif
+
+
#if (__FreeBSD_version >= 501108) && defined(_KERNEL)
static int
@@ -203,6 +214,7 @@ int iplattach()
RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex");
RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
+ RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock");
ipf_locks_done = 1;
@@ -271,6 +283,18 @@ pfil_error:
}
# endif
# endif
+
+#if (__FreeBSD_version >= 502103)
+ ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
+ NULL, EVENTHANDLER_PRI_ANY);
+#endif
+
if (fr_checkp != fr_check) {
fr_savep = fr_checkp;
fr_checkp = fr_check;
@@ -315,6 +339,18 @@ int ipldetach()
if (fr_control_forwarding & 2)
ipforwarding = 0;
+#if (__FreeBSD_version >= 502103)
+ if (ipf_arrivetag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag);
+ }
+ if (ipf_departtag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipf_departtag);
+ }
+ if (ipf_clonetag != NULL) {
+ EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag);
+ }
+#endif
+
SPL_NET(s);
#if (__FreeBSD_version >= 300000)
@@ -380,6 +416,7 @@ int ipldetach()
MUTEX_DESTROY(&ipf_timeoutlock);
MUTEX_DESTROY(&ipf_rw);
RW_DESTROY(&ipf_mutex);
+ RW_DESTROY(&ipf_frcache);
RW_DESTROY(&ipf_ipidfrag);
RW_DESTROY(&ipf_global);
ipf_locks_done = 0;
@@ -421,7 +458,7 @@ int mode;
friostat_t fio;
#if (BSD >= 199306) && defined(_KERNEL)
- if ((securelevel >= 2) && (mode & FWRITE))
+ if ((securelevel >= 3) && (mode & FWRITE))
return EPERM;
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index 6baa57013879..db1a0afbd8db 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2003 by Darren Reed.
*
@@ -47,7 +45,7 @@ struct file;
# endif
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# if defined(_KERNEL) && !defined(__sgi)
+# if defined(_KERNEL) && !defined(__sgi) && !defined(AIX)
# include <sys/kernel.h>
# endif
#else
@@ -102,7 +100,7 @@ extern struct timeout fr_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.77 2004/01/27 00:24:54 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.4 2005/08/20 13:48:21 darrenr Exp $";
#endif
@@ -237,7 +235,7 @@ ipfr_t *table[];
ip = fin->fin_ip;
if (pass & FR_FRSTRICT)
- if ((ip->ip_off & IP_OFFMASK) != 0)
+ if (fin->fin_off != 0)
return NULL;
frag.ipfr_p = ip->ip_p;
@@ -277,8 +275,16 @@ ipfr_t *table[];
return NULL;
}
- if ((fra->ipfr_rule = fin->fin_fr) != NULL)
- fin->fin_fr->fr_ref++;
+ fra->ipfr_rule = fin->fin_fr;
+ if (fra->ipfr_rule != NULL) {
+
+ frentry_t *fr;
+
+ fr = fin->fin_fr;
+ MUTEX_ENTER(&fr->fr_lock);
+ fr->fr_ref++;
+ MUTEX_EXIT(&fr->fr_lock);
+ }
/*
* Insert the fragment into the fragment table, copy the struct used
@@ -746,9 +752,7 @@ void fr_fragexpire()
{
ipfr_t **fp, *fra;
nat_t *nat;
-#if defined(USE_SPL) && defined(_KERNEL)
- int s;
-#endif
+ SPL_INT(s);
if (fr_frag_lock)
return;
@@ -814,7 +818,7 @@ void fr_fragexpire()
/* expectation of this being called twice per second. */
/* ------------------------------------------------------------------------ */
#if !defined(_KERNEL) || (!SOLARIS && !defined(__hpux) && !defined(__sgi) && \
- !defined(__osf__))
+ !defined(__osf__) && !defined(linux))
# if defined(_KERNEL) && ((BSD >= 199103) || defined(__sgi))
void fr_slowtimer __P((void *ptr))
# else
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h
index 7861507d36a3..07b841c19742 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.h
+++ b/sys/contrib/ipfilter/netinet/ip_frag.h
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_frag.h 1.5 3/24/96
- * Id: ip_frag.h,v 2.23.2.1 2004/03/29 16:21:56 darrenr Exp
+ * $Id: ip_frag.h,v 2.23.2.2 2005/06/10 18:02:37 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -80,7 +78,11 @@ extern void fr_slowtimer __P((void));
extern void fr_slowtimer __P((void *));
# endif
#else
+# if defined(linux) && defined(_KERNEL)
+extern void fr_slowtimer __P((long));
+# else
extern int fr_slowtimer __P((void));
+# endif
#endif
#endif /* __IP_FRAG_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index ab866ac2d539..860d75ecb80d 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1997-2003 by Darren Reed
*
@@ -8,7 +6,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp
+ * $Id: ip_ftp_pxy.c,v 2.88.2.16 2005/12/04 23:39:27 darrenr Exp $
*/
#define IPF_FTP_PROXY
@@ -473,9 +471,10 @@ int dlen;
{
u_int a1, a2, a3, a4, data_ip;
char newbuf[IPF_FTPBUFSZ];
- char *s, *brackets[2];
+ const char *brackets[2];
u_short a5, a6;
ftpside_t *f;
+ char *s;
if (ippr_ftp_forcepasv != 0 &&
ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) {
diff --git a/sys/contrib/ipfilter/netinet/ip_htable.c b/sys/contrib/ipfilter/netinet/ip_htable.c
index 22acbec764ca..92ed8d56edc5 100644
--- a/sys/contrib/ipfilter/netinet/ip_htable.c
+++ b/sys/contrib/ipfilter/netinet/ip_htable.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
@@ -53,7 +51,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.2 2004/10/17 15:49:15 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.4 2005/11/13 15:38:37 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -104,8 +102,10 @@ iplookupop_t *op;
int err, i, unit;
KMALLOC(iph, iphtable_t *);
- if (iph == NULL)
+ if (iph == NULL) {
+ ipht_nomem[op->iplo_unit]++;
return ENOMEM;
+ }
err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
if (err != 0) {
@@ -139,12 +139,9 @@ iplookupop_t *op;
sizeof(oiph->iph_name)) == 0)
break;
} while (oiph != NULL);
+
(void)strncpy(iph->iph_name, name, sizeof(iph->iph_name));
- err = COPYOUT(iph, op->iplo_struct, sizeof(*iph));
- if (err != 0) {
- KFREE(iph);
- return EFAULT;
- }
+ (void)strncpy(op->iplo_name, name, sizeof(op->iplo_name));
iph->iph_type |= IPHASH_ANON;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_htable.h b/sys/contrib/ipfilter/netinet/ip_htable.h
index 1bc40876dcb5..ebee58d7525f 100644
--- a/sys/contrib/ipfilter/netinet/ip_htable.h
+++ b/sys/contrib/ipfilter/netinet/ip_htable.h
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
#ifndef __IP_HTABLE_H__
#define __IP_HTABLE_H__
diff --git a/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c b/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c
index b54961113012..93cf070c8b72 100644
--- a/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2001-2003 by Darren Reed
*
@@ -8,7 +6,7 @@
* Simple ISAKMP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * Id: ip_ipsec_pxy.c,v 2.20.2.6 2005/03/28 10:47:53 darrenr Exp
+ * $Id: ip_ipsec_pxy.c,v 2.20.2.7 2005/08/20 13:48:22 darrenr Exp $
*
*/
#define IPF_IPSEC_PROXY
@@ -96,8 +94,8 @@ nat_t *nat;
mb_t *m;
ip_t *ip;
+ off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff;
bzero(ipsec_buffer, sizeof(ipsec_buffer));
- off = fin->fin_hlen + sizeof(udphdr_t);
ip = fin->fin_ip;
m = fin->fin_m;
@@ -287,8 +285,8 @@ nat_t *nat;
if ((fin->fin_dlen < sizeof(cookies)) || (fin->fin_flx & FI_FRAG))
return -1;
+ off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff;
ipsec = aps->aps_data;
- off = fin->fin_hlen + sizeof(udphdr_t);
m = fin->fin_m;
COPYDATA(m, off, sizeof(cookies), (char *)cookies);
diff --git a/sys/contrib/ipfilter/netinet/ip_irc_pxy.c b/sys/contrib/ipfilter/netinet/ip_irc_pxy.c
index 0f61d767ba71..0aa571024c22 100644
--- a/sys/contrib/ipfilter/netinet/ip_irc_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_irc_pxy.c
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2000-2003 Darren Reed
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp
+ * $Id: ip_irc_pxy.c,v 2.39.2.5 2005/12/04 23:39:27 darrenr Exp $
*/
#define IPF_IRC_PROXY
@@ -50,7 +48,7 @@ void ippr_irc_fini()
}
-char *ippr_irc_dcctypes[] = {
+const char *ippr_irc_dcctypes[] = {
"CHAT ", /* CHAT chat ipnumber portnumber */
"SEND ", /* SEND filename ipnumber portnumber */
"MOVE ",
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 804f7c7c23fb..6618c6d6d841 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1997-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_log.c,v 2.75.2.6 2004/10/16 07:59:27 darrenr Exp
+ * $Id: ip_log.c,v 2.75.2.7 2005/06/11 07:47:44 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL)
@@ -416,9 +414,7 @@ int *types, cnt;
iplog_t *ipl;
size_t len;
int i;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
/*
* Check to see if this log record has a CRC which matches the last
@@ -538,9 +534,7 @@ struct uio *uio;
size_t dlen, copied;
int error = 0;
iplog_t *ipl;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
/*
* Sanity checks. Make sure the minor # is valid and we're copying
@@ -652,9 +646,7 @@ minor_t unit;
{
iplog_t *ipl;
int used;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.c b/sys/contrib/ipfilter/netinet/ip_lookup.c
index 2f404eededeb..3c7eb5f75c52 100644
--- a/sys/contrib/ipfilter/netinet/ip_lookup.c
+++ b/sys/contrib/ipfilter/netinet/ip_lookup.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2002-2003 by Darren Reed.
*
@@ -35,7 +33,7 @@ struct file;
# undef _KERNEL
#endif
#include <sys/socket.h>
-#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
+#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
# ifdef __osf__
# include <net/radix.h>
# endif
@@ -63,7 +61,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.5 2004/07/06 11:16:25 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.8 2005/11/13 15:35:45 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -137,9 +135,7 @@ ioctlcmd_t cmd;
int mode;
{
int err;
-# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-# endif
+ SPL_INT(s);
mode = mode; /* LINT */
@@ -370,6 +366,15 @@ caddr_t data;
err = EINVAL;
break;
}
+
+ /*
+ * For anonymous pools, copy back the operation struct because in the
+ * case of success it will contain the new table's name.
+ */
+ if ((err == 0) && ((op.iplo_arg & IPOOL_ANON) != 0)) {
+ BCOPYOUT(&op, data, sizeof(op));
+ }
+
return err;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.h b/sys/contrib/ipfilter/netinet/ip_lookup.h
index 7d9acad6a079..953dde1149f1 100644
--- a/sys/contrib/ipfilter/netinet/ip_lookup.h
+++ b/sys/contrib/ipfilter/netinet/ip_lookup.h
@@ -1,10 +1,8 @@
-/* $FreeBSD$ */
-
#ifndef __IP_LOOKUP_H__
#define __IP_LOOKUP_H__
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop)
# define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop)
# define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop)
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index f3618c78039e..30bba0787643 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-2003 by Darren Reed.
*
@@ -37,7 +35,9 @@ struct file;
#else
# include <sys/ioctl.h>
#endif
-#include <sys/fcntl.h>
+#if !defined(AIX)
+# include <sys/fcntl.h>
+#endif
#if !defined(linux)
# include <sys/protosw.h>
#endif
@@ -107,7 +107,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.38 2005/03/28 11:09:54 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.47 2005/11/14 17:13:35 darrenr Exp $";
#endif
@@ -186,15 +186,15 @@ static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr, struct in_addr, u_32_t));
static void nat_hostmapdel __P((struct hostmap *));
-static INLINE int nat_icmpquerytype4 __P((int));
+static int nat_icmpquerytype4 __P((int));
static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int));
static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int));
-static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
+static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *,
tcphdr_t *, nat_t **, int));
static void nat_resolverule __P((ipnat_t *));
static nat_t *fr_natclone __P((fr_info_t *, nat_t *));
static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
-static INLINE int nat_wildok __P((nat_t *, int, int, int, int));
+static int nat_wildok __P((nat_t *, int, int, int, int));
/* ------------------------------------------------------------------------ */
@@ -799,10 +799,14 @@ int mode;
error = appr_ioctl(data, cmd, mode);
break;
case SIOCSTLCK :
- fr_lock(data, &fr_nat_lock);
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ } else {
+ fr_lock(data, &fr_nat_lock);
+ }
break;
case SIOCSTPUT :
- if (fr_nat_lock) {
+ if ((mode & FWRITE) != 0) {
error = fr_natputent(data, getlock);
} else {
error = EACCES;
@@ -1346,8 +1350,15 @@ int getlock;
fin.fin_data[0] = ntohs(nat->nat_oport);
fin.fin_data[1] = ntohs(nat->nat_outport);
fin.fin_ifp = nat->nat_ifps[1];
- if (nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip,
- nat->nat_inip) != NULL) {
+ if (getlock) {
+ READ_ENTER(&ipf_nat);
+ }
+ n = nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip,
+ nat->nat_inip);
+ if (getlock) {
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ if (n != NULL) {
error = EEXIST;
goto junkput;
}
@@ -1355,8 +1366,15 @@ int getlock;
fin.fin_data[0] = ntohs(nat->nat_outport);
fin.fin_data[1] = ntohs(nat->nat_oport);
fin.fin_ifp = nat->nat_ifps[0];
- if (nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip,
- nat->nat_oip) != NULL) {
+ if (getlock) {
+ READ_ENTER(&ipf_nat);
+ }
+ n = nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip,
+ nat->nat_oip);
+ if (getlock) {
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ if (n != NULL) {
error = EEXIST;
goto junkput;
}
@@ -1420,7 +1438,9 @@ int getlock;
MUTEX_NUKE(&fr->fr_lock);
MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
} else {
- READ_ENTER(&ipf_nat);
+ if (getlock) {
+ READ_ENTER(&ipf_nat);
+ }
for (n = nat_instances; n; n = n->nat_next)
if (n->nat_fr == fr)
break;
@@ -1430,7 +1450,9 @@ int getlock;
fr->fr_ref++;
MUTEX_EXIT(&fr->fr_lock);
}
- RWLOCK_EXIT(&ipf_nat);
+ if (getlock) {
+ RWLOCK_EXIT(&ipf_nat);
+ }
if (!n) {
error = ESRCH;
@@ -1981,8 +2003,8 @@ natinfo_t *ni;
* packet might match a different one to the previous connection but
* we want the same destination to be used.
*/
- if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) ==
- (IPN_ROUNDR|IPN_STICKY)) {
+ if (((np->in_flags & (IPN_ROUNDR|IPN_SPLIT)) != 0) &&
+ ((np->in_flags & IPN_STICKY) != 0)) {
hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in,
(u_32_t)dport);
if (hm != NULL) {
@@ -2003,7 +2025,7 @@ natinfo_t *ni;
in.s_addr = np->in_nip;
if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) {
- hm = nat_hostmap(np, fin->fin_src, fin->fin_dst,
+ hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst,
in, (u_32_t)dport);
if (hm != NULL) {
in.s_addr = hm->hm_mapip.s_addr;
@@ -2076,6 +2098,9 @@ natinfo_t *ni;
nat->nat_inip.s_addr = htonl(in.s_addr);
nat->nat_outip = fin->fin_dst;
nat->nat_oip = fin->fin_src;
+ if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0))
+ nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, in,
+ (u_32_t)dport);
ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport);
ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport);
@@ -2337,7 +2362,7 @@ done:
/* for both IPv4 and IPv6. */
/* ------------------------------------------------------------------------ */
/*ARGSUSED*/
-static INLINE int nat_finalise(fin, nat, ni, tcp, natsave, direction)
+static int nat_finalise(fin, nat, ni, tcp, natsave, direction)
fr_info_t *fin;
nat_t *nat;
natinfo_t *ni;
@@ -2362,8 +2387,6 @@ int direction;
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
- fr = fin->fin_fr;
- nat->nat_fr = fr;
if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0))
if (appr_new(fin, nat) == -1)
@@ -2373,6 +2396,8 @@ int direction;
if (nat_logging)
nat_log(nat, (u_int)np->in_redir);
np->in_use++;
+ fr = fin->fin_fr;
+ nat->nat_fr = fr;
if (fr != NULL) {
MUTEX_ENTER(&fr->fr_lock);
fr->fr_ref++;
@@ -2514,8 +2539,7 @@ int dir;
* Only a basic IP header (no options) should be with an ICMP error
* header. Also, if it's not an error type, then return.
*/
- if ((fin->fin_hlen != sizeof(ip_t)) ||
- !fr_icmp4errortype(type))
+ if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR))
return NULL;
/*
@@ -3805,8 +3829,15 @@ u_32_t nflags;
CALC_SUMD(s1, s2, sumd);
fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd);
}
-#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || defined(linux)
+#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \
+ defined(linux) || defined(BRIDGE_IPF)
else {
+ /*
+ * Strictly speaking, this isn't necessary on BSD
+ * kernels because they do checksum calculation after
+ * this code has run BUT if ipfilter is being used
+ * to do NAT as a bridge, that code doesn't exist.
+ */
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(fin, &fin->fin_ip->ip_sum,
nat->nat_ipsumd);
@@ -4315,9 +4346,7 @@ void fr_natexpire()
{
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
int i;
SPL_NET(s);
@@ -4372,9 +4401,7 @@ void *ifp;
ipnat_t *n;
nat_t *nat;
void *ifp2;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
if (fr_running <= 0)
return;
@@ -4456,7 +4483,7 @@ void *ifp;
/* Tests to see if the ICMP type number passed is a query/response type or */
/* not. */
/* ------------------------------------------------------------------------ */
-static INLINE int nat_icmpquerytype4(icmptype)
+static int nat_icmpquerytype4(icmptype)
int icmptype;
{
@@ -4609,9 +4636,20 @@ nat_t *nat;
MUTEX_NUKE(&clone->nat_lock);
+ clone->nat_aps = NULL;
+ /*
+ * Initialize all these so that nat_delete() doesn't cause a crash.
+ */
+ clone->nat_tqe.tqe_pnext = NULL;
+ clone->nat_tqe.tqe_next = NULL;
+ clone->nat_tqe.tqe_ifq = NULL;
+ clone->nat_tqe.tqe_parent = clone;
+
clone->nat_flags &= ~SI_CLONE;
clone->nat_flags |= SI_CLONED;
+ if (clone->nat_hm)
+ clone->nat_hm->hm_ref++;
if (nat_insert(clone, fin->fin_rev) == -1) {
KFREE(clone);
@@ -4630,14 +4668,13 @@ nat_t *nat;
MUTEX_EXIT(&fr->fr_lock);
}
-
/*
* Because the clone is created outside the normal loop of things and
* TCP has special needs in terms of state, initialise the timeout
* state of the new NAT from here.
*/
if (clone->nat_p == IPPROTO_TCP) {
- (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, \
+ (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb,
clone->nat_flags);
}
#ifdef IPFILTER_SYNC
@@ -4662,7 +4699,7 @@ nat_t *nat;
/* Use NAT entry and packet direction to determine which combination of */
/* wildcard flags should be used. */
/* ------------------------------------------------------------------------ */
-static INLINE int nat_wildok(nat, sport, dport, flags, dir)
+static int nat_wildok(nat, sport, dport, flags, dir)
nat_t *nat;
int sport;
int dport;
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 9a74fe6b6767..68396cd148de 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * Id: ip_nat.h,v 2.90.2.9 2005/03/28 11:09:55 darrenr Exp
+ * $Id: ip_nat.h,v 2.90.2.11 2005/06/18 02:41:32 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -16,18 +14,16 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
#define SIOCADNAT _IOW('r', 60, struct ipfobj)
#define SIOCRMNAT _IOW('r', 61, struct ipfobj)
#define SIOCGNATS _IOWR('r', 62, struct ipfobj)
#define SIOCGNATL _IOWR('r', 63, struct ipfobj)
-#define SIOCPROXY _IOWR('r', 64, struct ap_control)
#else
#define SIOCADNAT _IOW(r, 60, struct ipfobj)
#define SIOCRMNAT _IOW(r, 61, struct ipfobj)
#define SIOCGNATS _IOWR(r, 62, struct ipfobj)
#define SIOCGNATL _IOWR(r, 63, struct ipfobj)
-#define SIOCPROXY _IOWR(r, 64, struct ap_control)
#endif
#undef LARGE_NAT /* define this if you're setting up a system to NAT
@@ -297,6 +293,7 @@ typedef struct natget {
} natget_t;
+#undef tr_flags
typedef struct nattrpnt {
struct in_addr tr_dstip; /* real destination IP# */
struct in_addr tr_srcip; /* real source IP# */
diff --git a/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c b/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c
index a55cc33c23c3..1a0b2a2e49ed 100644
--- a/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c
@@ -1,9 +1,7 @@
-/* $FreeBSD$ */
-
/*
* Simple netbios-dgm transparent proxy for in-kernel use.
* For use with the NAT code.
- * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp
+ * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp $
*/
/*-
@@ -31,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp
+ * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp $
*/
#define IPF_NETBIOS_PROXY
@@ -82,19 +80,17 @@ nat_t *nat;
aps = aps; /* LINT */
nat = nat; /* LINT */
- ip = fin->fin_ip;
- m = *(mb_t **)fin->fin_mp;
- off = fin->fin_hlen + sizeof(udphdr_t);
- dlen = M_LEN(m);
- dlen -= off;
-
+ m = fin->fin_m;
+ dlen = fin->fin_dlen - sizeof(*udp);
/*
* no net bios datagram could possibly be shorter than this
*/
if (dlen < 11)
return 0;
+ ip = fin->fin_ip;
udp = (udphdr_t *)fin->fin_dp;
+ off = (char *)udp - (char *)ip + sizeof(*udp) + fin->fin_ipoff;
/*
* move past the
diff --git a/sys/contrib/ipfilter/netinet/ip_pool.c b/sys/contrib/ipfilter/netinet/ip_pool.c
index 9880c9d3d308..3d19afbf06ba 100644
--- a/sys/contrib/ipfilter/netinet/ip_pool.c
+++ b/sys/contrib/ipfilter/netinet/ip_pool.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
@@ -55,7 +53,8 @@ struct file;
# include <sys/malloc.h>
#endif
-#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
+#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \
+ defined(__hpux) || defined(__sgi))
# ifdef __osf__
# include <net/radix.h>
# endif
@@ -79,7 +78,7 @@ static int rn_freenode __P((struct radix_node *, void *));
#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_pool.c,v 2.55.2.12 2005/02/01 04:04:46 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.15 2005/11/13 15:38:37 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -356,11 +355,9 @@ ip_pool_t *ipo;
addrfamily_t *addr, *mask;
{
struct radix_node *n;
-#ifdef USE_SPL
- int s;
+ SPL_INT(s);
SPL_NET(s);
-#endif
RADIX_NODE_HEAD_LOCK(ipo->ipo_head);
n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head);
RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head);
@@ -550,6 +547,7 @@ iplookupop_t *op;
}
(void)strncpy(h->ipo_name, name, sizeof(h->ipo_name));
+ (void)strncpy(op->iplo_name, name, sizeof(op->iplo_name));
} else {
(void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name));
}
diff --git a/sys/contrib/ipfilter/netinet/ip_pool.h b/sys/contrib/ipfilter/netinet/ip_pool.h
index 5ddc74ee19a5..3731fe964bcb 100644
--- a/sys/contrib/ipfilter/netinet/ip_pool.h
+++ b/sys/contrib/ipfilter/netinet/ip_pool.h
@@ -1,18 +1,16 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_pool.h,v 2.26.2.2 2004/03/23 12:44:34 darrenr Exp
+ * $Id: ip_pool.h,v 2.26.2.3 2005/06/12 07:18:27 darrenr Exp $
*/
#ifndef __IP_POOL_H__
#define __IP_POOL_H__
#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \
- !defined(linux) && !defined(sun)
+ !defined(linux) && !defined(sun) && !defined(AIX)
# include <net/radix.h>
extern void rn_freehead __P((struct radix_node_head *));
# define FreeS(p, z) KFREES(p, z)
diff --git a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
index b7ec697d63fe..0047e1032acf 100644
--- a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2002-2003 by Darren Reed
*
* Simple PPTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * Id: ip_pptp_pxy.c,v 2.10.2.9 2005/03/16 18:17:34 darrenr Exp
+ * $Id: ip_pptp_pxy.c,v 2.10.2.11 2005/12/04 23:39:27 darrenr Exp $
*
*/
#define IPF_PPTP_PROXY
@@ -89,10 +87,8 @@ nat_t *nat;
pptp_pxy_t *pptp;
ipnat_t *ipn;
ip_t *ip;
- int off;
ip = fin->fin_ip;
- off = fin->fin_hlen + sizeof(udphdr_t);
if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
ip->ip_dst) != NULL) {
@@ -238,7 +234,7 @@ nat_t *nat;
pptp_pxy_t *pptp;
int rev;
{
- static char *funcname = "ippr_pptp_nextmessage";
+ static const char *funcname = "ippr_pptp_nextmessage";
pptp_side_t *pptps;
u_32_t start, end;
pptp_hdr_t *hdr;
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 062d8b4433a8..60b6ac04af21 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1997-2003 by Darren Reed.
*
@@ -16,7 +14,9 @@
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
-#include <sys/fcntl.h>
+#if !defined(AIX)
+# include <sys/fcntl.h>
+#endif
#if !defined(_KERNEL) && !defined(__KERNEL__)
# include <stdio.h>
# include <string.h>
@@ -35,7 +35,8 @@ struct file;
#include <sys/socket.h>
#if defined(_KERNEL)
# if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \
- !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi)
+ !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) && \
+ !defined(AIX)
# include <sys/ctype.h>
# endif
# include <sys/systm.h>
@@ -94,9 +95,6 @@ struct file;
# include "netinet/ip_irc_pxy.c"
# include "netinet/ip_raudio_pxy.c"
# include "netinet/ip_h323_pxy.c"
-# ifdef IPFILTER_PRO
-# include "netinet/ip_msnrpc_pxy.c"
-# endif
# include "netinet/ip_netbios_pxy.c"
#endif
#include "netinet/ip_ipsec_pxy.c"
@@ -105,7 +103,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.62.2.12 2005/03/03 14:28:24 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.14 2005/06/18 02:41:33 darrenr Exp $";
#endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index 5f92797bccd0..1e0bedef6499 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1997-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_proxy.h,v 2.31.2.2 2005/03/12 19:33:48 darrenr Exp
+ * $Id: ip_proxy.h,v 2.31.2.3 2005/06/18 02:41:33 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -15,6 +13,12 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
+#define SIOCPROXY _IOWR('r', 64, struct ap_control)
+#else
+#define SIOCPROXY _IOWR(r, 64, struct ap_control)
+#endif
+
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
#endif
@@ -22,15 +26,16 @@
struct nat;
struct ipnat;
+struct ipstate;
typedef struct ap_tcp {
u_short apt_sport; /* source port */
u_short apt_dport; /* destination port */
short apt_sel[2]; /* {seq,ack}{off,min} set selector */
short apt_seqoff[2]; /* sequence # difference */
- tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
+ u_32_t apt_seqmin[2]; /* don't change seq-off until after this */
short apt_ackoff[2]; /* sequence # difference */
- tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
+ u_32_t apt_ackmin[2]; /* don't change seq-off until after this */
u_char apt_state[2]; /* connection state */
} ap_tcp_t;
@@ -197,7 +202,7 @@ typedef struct raudio_s {
u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have
* been filled
*/
- tcp_seq rap_sseq;
+ u_32_t rap_sseq;
} raudio_t;
#define RA_ID_END 0
@@ -233,7 +238,7 @@ typedef struct ipsec_pxy {
int ipsc_rckset;
ipnat_t ipsc_rule;
nat_t *ipsc_nat;
- ipstate_t *ipsc_state;
+ struct ipstate *ipsc_state;
} ipsec_pxy_t;
/*
@@ -253,7 +258,7 @@ typedef struct pptp_side {
typedef struct pptp_pxy {
ipnat_t pptp_rule;
nat_t *pptp_nat;
- ipstate_t *pptp_state;
+ struct ipstate *pptp_state;
u_short pptp_call[2];
pptp_side_t pptp_side[2];
} pptp_pxy_t;
diff --git a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
index a049349b4dad..a81e12dd52b0 100644
--- a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1998-2003 by Darren Reed
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_raudio_pxy.c,v 1.40.2.3 2005/02/04 10:22:55 darrenr Exp
+ * $Id: ip_raudio_pxy.c,v 1.40.2.3 2005/02/04 10:22:55 darrenr Exp $
*/
#define IPF_RAUDIO_PROXY
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 3a3e0d920f08..1782064ed0a2 100644
--- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
@@ -1,11 +1,9 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1998-2003 by Darren Reed
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * Id: ip_rcmd_pxy.c,v 1.41.2.4 2005/02/04 10:22:55 darrenr Exp
+ * $Id: ip_rcmd_pxy.c,v 1.41.2.5 2005/10/02 04:20:07 darrenr Exp $
*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
* code.
@@ -153,6 +151,8 @@ nat_t *nat;
* other way.
*/
bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
fi.fin_flx |= FI_IGNORE;
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
diff --git a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
index 4c012230130c..112e4da8e5ca 100644
--- a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2002-2003 by Ryan Beasley <ryanb@goddamnbastard.org>
*
@@ -39,7 +37,7 @@
* o The enclosed hack of STREAMS support is pretty sick and most likely
* broken.
*
- * Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp
+ * $Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp $
*/
#define IPF_RPCB_PROXY
diff --git a/sys/contrib/ipfilter/netinet/ip_scan.c b/sys/contrib/ipfilter/netinet/ip_scan.c
index b36fccf3dc4a..73977c7d224e 100644
--- a/sys/contrib/ipfilter/netinet/ip_scan.c
+++ b/sys/contrib/ipfilter/netinet/ip_scan.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-2001 by Darren Reed.
*
@@ -34,7 +32,7 @@ struct file;
# endif
#endif
#include <sys/socket.h>
-#if !defined(__hpux) && !defined(__osf__) && !defined(linux)
+#if !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(AIX)
# include <sys/ioccom.h>
#endif
#ifdef __FreeBSD__
@@ -60,7 +58,7 @@ struct file;
#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_scan.c,v 2.40.2.2 2005/01/18 10:13:16 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.4 2005/08/20 13:48:24 darrenr Exp $";
#endif
#ifdef IPFILTER_SCAN /* endif at bottom of file */
@@ -539,8 +537,8 @@ ipstate_t *is;
j = 0xffff >> (16 - dlen);
i = (0xffff & j) << off;
#ifdef _KERNEL
- COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_hlen + thoff, dlen,
- (caddr_t)is->is_sbuf[rv] + off);
+ COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_plen - fin->fin_dlen + thoff,
+ dlen, (caddr_t)is->is_sbuf[rv] + off);
#endif
is->is_smsk[rv] |= i;
for (j = 0, i = is->is_smsk[rv]; i & 1; i >>= 1)
diff --git a/sys/contrib/ipfilter/netinet/ip_scan.h b/sys/contrib/ipfilter/netinet/ip_scan.h
index 8891367b9d2d..d85745378b81 100644
--- a/sys/contrib/ipfilter/netinet/ip_scan.h
+++ b/sys/contrib/ipfilter/netinet/ip_scan.h
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * Id: ip_scan.h,v 2.9 2003/07/25 22:05:01 darrenr Exp
+ * $Id: ip_scan.h,v 2.9.2.1 2005/06/12 07:18:29 darrenr Exp $
*/
#ifndef __IP_SCAN_H__
@@ -27,7 +25,7 @@ struct ip;
struct ipstate;
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCADSCA _IOWR('r', 60, struct ipscan *)
# define SIOCRMSCA _IOWR('r', 61, struct ipscan *)
# define SIOCGSCST _IOWR('r', 62, struct ipscan *)
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 7c1b3119d075..b0bf74245f2a 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-2003 by Darren Reed.
*
@@ -109,7 +107,7 @@ struct file;
#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.186.2.29 2005/03/28 10:47:54 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.36 2005/12/04 22:25:36 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@@ -507,13 +505,17 @@ int mode;
* means no packets match).
*/
case SIOCSTLCK :
- fr_lock(data, &fr_state_lock);
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ } else {
+ fr_lock(data, &fr_state_lock);
+ }
break;
/*
* Add an entry to the current state table.
*/
case SIOCSTPUT :
- if (!fr_state_lock) {
+ if (!fr_state_lock || !(mode &FWRITE)) {
error = EACCES;
break;
}
@@ -635,6 +637,7 @@ caddr_t data;
if (fr == NULL) {
READ_ENTER(&ipf_state);
fr_stinsert(isn, 0);
+ MUTEX_EXIT(&isn->is_lock);
RWLOCK_EXIT(&ipf_state);
return 0;
}
@@ -682,6 +685,7 @@ caddr_t data;
}
READ_ENTER(&ipf_state);
fr_stinsert(isn, 0);
+ MUTEX_EXIT(&isn->is_lock);
RWLOCK_EXIT(&ipf_state);
} else {
@@ -689,6 +693,7 @@ caddr_t data;
for (is = ips_list; is; is = is->is_next)
if (is->is_rule == fr) {
fr_stinsert(isn, 0);
+ MUTEX_EXIT(&isn->is_lock);
break;
}
@@ -716,6 +721,7 @@ caddr_t data;
/* to pointers and adjusts running stats for the hash table as appropriate. */
/* */
/* Locking: it is assumed that some kind of lock on ipf_state is held. */
+/* Exits with is_lock initialised and held. */
/* ------------------------------------------------------------------------ */
void fr_stinsert(is, rev)
ipstate_t *is;
@@ -780,7 +786,6 @@ int rev;
MUTEX_EXIT(&ipf_stinsert);
fr_setstatequeue(is, rev);
- MUTEX_EXIT(&is->is_lock);
}
@@ -830,6 +835,7 @@ u_int flags;
* to it, then schedule an automatic flush in case we can clear out
* some "dead old wood".
*/
+ MUTEX_ENTER(&fr->fr_lock);
if ((fr != NULL) && (fr->fr_statemax != 0) &&
(fr->fr_statecnt >= fr->fr_statemax)) {
MUTEX_EXIT(&fr->fr_lock);
@@ -837,6 +843,8 @@ u_int flags;
fr_state_doflush = 1;
return NULL;
}
+ fr->fr_statecnt++;
+ MUTEX_EXIT(&fr->fr_lock);
pass = (fr == NULL) ? 0 : fr->fr_flags;
@@ -979,9 +987,9 @@ u_int flags;
TH_SYN &&
(TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) {
if (fr_tcpoptions(fin, tcp,
- &is->is_tcp.ts_data[0]))
- is->is_swinflags = TCP_WSCALE_SEEN|
- TCP_WSCALE_FIRST;
+ &is->is_tcp.ts_data[0]) == -1) {
+ fin->fin_flx |= FI_BAD;
+ }
}
if ((fin->fin_out != 0) && (pass & FR_NEWISN) != 0) {
@@ -1038,16 +1046,16 @@ u_int flags;
break;
}
if (is != NULL)
- return NULL;
+ goto cantaddstate;
if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) {
ATOMIC_INCL(ips_stats.iss_bucketfull);
- return NULL;
+ goto cantaddstate;
}
KMALLOC(is, ipstate_t *);
if (is == NULL) {
ATOMIC_INCL(ips_stats.iss_nomem);
- return NULL;
+ goto cantaddstate;
}
bcopy((char *)&ips, (char *)is, sizeof(*is));
/*
@@ -1124,8 +1132,14 @@ u_int flags;
* this may change.
*/
is->is_v = fin->fin_v;
- is->is_opt = fin->fin_optmsk;
- is->is_optmsk = 0xffffffff;
+ is->is_opt[0] = fin->fin_optmsk;
+ is->is_optmsk[0] = 0xffffffff;
+ is->is_optmsk[1] = 0xffffffff;
+ if (is->is_v == 6) {
+ is->is_opt[0] &= ~0x8;
+ is->is_optmsk[0] &= ~0x8;
+ is->is_optmsk[1] &= ~0x8;
+ }
is->is_sec = fin->fin_secmsk;
is->is_secmsk = 0xffff;
is->is_auth = fin->fin_auth;
@@ -1150,13 +1164,14 @@ u_int flags;
* timer on it as we'll never see an error if it fails to
* connect.
*/
- MUTEX_ENTER(&is->is_lock);
(void) fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags);
MUTEX_EXIT(&is->is_lock);
#ifdef IPFILTER_SCAN
if ((is->is_flags & SI_CLONE) == 0)
(void) ipsc_attachis(is);
#endif
+ } else {
+ MUTEX_EXIT(&is->is_lock);
}
#ifdef IPFILTER_SYNC
if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0))
@@ -1173,12 +1188,21 @@ u_int flags;
(void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
return is;
+
+cantaddstate:
+ if (fr != NULL) {
+ MUTEX_ENTER(&fr->fr_lock);
+ fr->fr_statecnt--;
+ MUTEX_EXIT(&fr->fr_lock);
+ }
+ return NULL;
}
/* ------------------------------------------------------------------------ */
/* Function: fr_tcpoptions */
-/* Returns: int - 1 == packet matches state entry, 0 == it does not */
+/* Returns: int - 1 == packet matches state entry, 0 == it does not, */
+/* -1 == packet has bad TCP options data */
/* Parameters: fin(I) - pointer to packet information */
/* tcp(I) - pointer to TCP packet header */
/* td(I) - pointer to TCP data held as part of the state */
@@ -1195,13 +1219,14 @@ tcpdata_t *td;
char buf[64], *s, opt;
mb_t *m = NULL;
- off = fin->fin_hlen + sizeof(*tcp);
- len = (TCP_OFF(tcp) << 2) - sizeof(*tcp);
- if (fin->fin_plen < off + len)
+ len = (TCP_OFF(tcp) << 2);
+ if (fin->fin_dlen < len)
return 0;
+ len -= sizeof(*tcp);
+
+ off = fin->fin_plen - fin->fin_dlen + sizeof(*tcp) + fin->fin_ipoff;
m = fin->fin_m;
- off += fin->fin_ipoff;
mlen = MSGDSIZE(m) - off;
if (len > mlen) {
len = mlen;
@@ -1239,7 +1264,10 @@ tcpdata_t *td;
else if (i < 0)
i = 0;
td->td_winscale = i;
- }
+ td->td_winflags |= TCP_WSCALE_SEEN|
+ TCP_WSCALE_FIRST;
+ } else
+ retval = -1;
break;
case TCPOPT_MAXSEG :
/*
@@ -1251,7 +1279,14 @@ tcpdata_t *td;
i <<= 8;
i += (int)*(s + 3);
td->td_maxseg = i;
- }
+ } else
+ retval = -1;
+ break;
+ case TCPOPT_SACK_PERMITTED :
+ if (ol == TCPOLEN_SACK_PERMITTED)
+ td->td_winflags |= TCP_SACK_PERMIT;
+ else
+ retval = -1;
break;
}
}
@@ -1322,24 +1357,22 @@ ipstate_t *is;
is->is_s0[source] = ntohl(tcp->th_ack);
is->is_s0[!source] = ntohl(tcp->th_seq) + 1;
if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)) &&
- tdata->td_winscale) {
- if (fr_tcpoptions(fin, tcp, fdata)) {
- fdata->td_winflags = TCP_WSCALE_SEEN|
- TCP_WSCALE_FIRST;
- } else {
- if (!fdata->td_winscale)
- tdata->td_winscale = 0;
+ (tdata->td_winflags & TCP_WSCALE_SEEN)) {
+ if (fr_tcpoptions(fin, tcp, fdata) == -1)
+ fin->fin_flx |= FI_BAD;
+ if (!(fdata->td_winflags & TCP_WSCALE_SEEN)) {
+ fdata->td_winscale = 0;
+ tdata->td_winscale = 0;
}
}
if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
fr_checknewisn(fin, is);
} else if (flags == TH_SYN) {
is->is_s0[source] = ntohl(tcp->th_seq) + 1;
- if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)))
- if (fr_tcpoptions(fin, tcp, tdata)) {
- tdata->td_winflags = TCP_WSCALE_SEEN|
- TCP_WSCALE_FIRST;
- }
+ if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) {
+ if (fr_tcpoptions(fin, tcp, tdata) == -1)
+ fin->fin_flx |= FI_BAD;
+ }
if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
fr_checknewisn(fin, is);
@@ -1410,6 +1443,7 @@ int flags;
tcp_seq seq, ack, end;
int ackskew, tcpflags;
u_32_t win, maxwin;
+ int dsize, inseq;
/*
* Find difference between last checked packet and this packet.
@@ -1421,9 +1455,28 @@ int flags;
win = ntohs(tcp->th_win);
else
win = ntohs(tcp->th_win) << fdata->td_winscale;
+#if 0
+ /*
+ * XXX - This is a kludge is here because IPFilter doesn't track SACK
+ * options in TCP packets. This is not a trivial to do if one is to
+ * consider the performance impact of it. So instead, if the
+ * receiver has said SACK is ok, double the allowed window size.
+ * This is disabled for testing of another workaround for a problem
+ * with Microsoft Windows - see below.
+ */
+ if ((tdata->td_winflags & TCP_SACK_PERMIT) != 0)
+ win *= 2;
+#endif
+
+ /*
+ * A window of 0 produces undesirable behaviour from this function.
+ */
if (win == 0)
win = 1;
+ dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
+ ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0);
+
/*
* if window scaling is present, the scaling is only allowed
* for windows not in the first SYN packet. In that packet the
@@ -1441,14 +1494,15 @@ int flags;
fdata->td_maxwin = win;
} else {
fdata->td_winscale = 0;
- fdata->td_winflags = 0;
+ fdata->td_winflags &= ~(TCP_WSCALE_FIRST|
+ TCP_WSCALE_SEEN);
tdata->td_winscale = 0;
- tdata->td_winflags = 0;
+ tdata->td_winflags &= ~(TCP_WSCALE_FIRST|
+ TCP_WSCALE_SEEN);
}
}
- end = seq + fin->fin_dlen - (TCP_OFF(tcp) << 2) +
- ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0);
+ end = seq + dsize;
if ((fdata->td_end == 0) &&
(!(flags & IS_TCPFSM) ||
@@ -1456,7 +1510,7 @@ int flags;
/*
* Must be a (outgoing) SYN-ACK in reply to a SYN.
*/
- fdata->td_end = end;
+ fdata->td_end = end - 1;
fdata->td_maxwin = 1;
fdata->td_maxend = end + win;
}
@@ -1469,9 +1523,6 @@ int flags;
ack = tdata->td_end;
}
- if (seq == end)
- seq = end = fdata->td_end;
-
maxwin = tdata->td_maxwin;
ackskew = tdata->td_end - ack;
@@ -1486,16 +1537,25 @@ int flags;
#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
- if (
-#if defined(_KERNEL)
- (SEQ_GE(fdata->td_maxend, end)) &&
+ inseq = 0;
+ if ((SEQ_GE(fdata->td_maxend, end)) &&
(SEQ_GE(seq, fdata->td_end - maxwin)) &&
-#endif
/* XXX what about big packets */
#define MAXACKWINDOW 66000
(-ackskew <= (MAXACKWINDOW << fdata->td_winscale)) &&
( ackskew <= (MAXACKWINDOW << fdata->td_winscale))) {
+ inseq = 1;
+ /*
+ * Microsoft Windows will send the next packet to the right of the
+ * window if SACK is in use.
+ */
+ } else if ((seq == fdata->td_maxend) && (ackskew == 0) &&
+ (fdata->td_winflags & TCP_SACK_PERMIT) &&
+ (tdata->td_winflags & TCP_SACK_PERMIT)) {
+ inseq = 1;
+ }
+ if (inseq) {
/* 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.
@@ -1584,8 +1644,7 @@ ipstate_t *is;
clone->is_flags &= ~SI_CLONE;
clone->is_flags |= SI_CLONED;
fr_stinsert(clone, fin->fin_rev);
- MUTEX_ENTER(&clone->is_lock);
- clone->is_ref = 1;
+ clone->is_ref = 2;
if (clone->is_p == IPPROTO_TCP) {
(void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb,
clone->is_flags);
@@ -1770,7 +1829,7 @@ u_32_t cmask;
* Match up any flags set from IP options.
*/
if ((cflx && (flx != (cflx & cmask))) ||
- ((fin->fin_optmsk & is->is_optmsk) != is->is_opt) ||
+ ((fin->fin_optmsk & is->is_optmsk[rev]) != is->is_opt[rev]) ||
((fin->fin_secmsk & is->is_secmsk) != is->is_sec) ||
((fin->fin_auth & is->is_authmsk) != is->is_auth))
return NULL;
@@ -1787,9 +1846,12 @@ u_32_t cmask;
if ((flags & (SI_W_SPORT|SI_W_DPORT))) {
if ((flags & SI_CLONE) != 0) {
- is = fr_stclone(fin, tcp, is);
- if (is == NULL)
+ ipstate_t *clone;
+
+ clone = fr_stclone(fin, tcp, is);
+ if (clone == NULL)
return NULL;
+ is = clone;
} else {
ATOMIC_DECL(ips_stats.iss_wild);
}
@@ -1820,8 +1882,14 @@ u_32_t cmask;
ret = -1;
- if (is->is_flx[out][rev] == 0)
+ if (is->is_flx[out][rev] == 0) {
is->is_flx[out][rev] = flx;
+ is->is_opt[rev] = fin->fin_optmsk;
+ if (is->is_v == 6) {
+ is->is_opt[rev] &= ~0x8;
+ is->is_optmsk[rev] &= ~0x8;
+ }
+ }
/*
* Check if the interface name for this "direction" is set and if not,
@@ -1867,21 +1935,16 @@ fr_info_t *fin;
/*
* Does it at least have the return (basic) IP header ?
+ * Is it an actual recognised ICMP error type?
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
if ((fin->fin_v != 4) || (fin->fin_hlen != sizeof(ip_t)) ||
- (fin->fin_plen < ICMPERR_MINPKTLEN))
+ (fin->fin_plen < ICMPERR_MINPKTLEN) ||
+ !(fin->fin_flx & FI_ICMPERR))
return NULL;
ic = fin->fin_dp;
type = ic->icmp_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&
- (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) &&
- (type != ICMP_PARAMPROB))
- return NULL;
oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
/*
@@ -1944,7 +2007,7 @@ fr_info_t *fin;
*/
savelen = oip->ip_len;
oip->ip_len = len;
- oip->ip_off = htons(oip->ip_off);
+ oip->ip_off = ntohs(oip->ip_off);
ofin.fin_flx = FI_NOCKSUM;
ofin.fin_v = 4;
@@ -1972,8 +2035,6 @@ fr_info_t *fin;
switch (oip->ip_p)
{
case IPPROTO_ICMP :
- icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2));
-
/*
* an ICMP error can only be generated as a result of an
* ICMP query, not as the response on an ICMP error
@@ -1981,15 +2042,13 @@ fr_info_t *fin;
* XXX theoretically ICMP_ECHOREP and the other reply's are
* ICMP query's as well, but adding them here seems strange XXX
*/
- if ((icmp->icmp_type != ICMP_ECHO) &&
- (icmp->icmp_type != ICMP_TSTAMP) &&
- (icmp->icmp_type != ICMP_IREQ) &&
- (icmp->icmp_type != ICMP_MASKREQ))
+ if ((ofin.fin_flx & FI_ICMPERR) != 0)
return NULL;
/*
* perform a lookup of the ICMP packet in the state table
*/
+ icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2));
hv = (pr = oip->ip_p);
src.in4 = oip->ip_src;
hv += src.in4.s_addr;
@@ -2008,10 +2067,6 @@ fr_info_t *fin;
is = fr_matchsrcdst(&ofin, is, &src, &dst,
NULL, FI_ICMPCMP);
if (is != NULL) {
- if ((is->is_pass & FR_NOICMPERR) != 0) {
- RWLOCK_EXIT(&ipf_state);
- return NULL;
- }
/*
* i : the index of this packet (the icmp
* unreachable)
@@ -2774,6 +2829,11 @@ int why;
if (ipstate_logging != 0 && why != 0)
ipstate_log(is, why);
+ if (is->is_p == IPPROTO_TCP)
+ ips_stats.iss_fin++;
+ else
+ ips_stats.iss_expire++;
+
if (is->is_rule != NULL) {
is->is_rule->fr_statecnt--;
(void)fr_derefrule(&is->is_rule);
@@ -2800,9 +2860,7 @@ void fr_timeoutstate()
ipftq_t *ifq, *ifqnext;
ipftqent_t *tqe, *tqn;
ipstate_t *is;
-#if defined(USE_SPL) && defined(_KERNEL)
- int s;
-#endif
+ SPL_INT(s);
SPL_NET(s);
WRITE_ENTER(&ipf_state);
@@ -2872,9 +2930,7 @@ int which, proto;
int delete, removed;
long try, maxtick;
u_long interval;
-#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL)
- int s;
-#endif
+ SPL_INT(s);
removed = 0;
@@ -2903,10 +2959,6 @@ int which, proto;
}
if (delete) {
- if (is->is_p == IPPROTO_TCP)
- ips_stats.iss_fin++;
- else
- ips_stats.iss_expire++;
fr_delstate(is, ISL_FLUSH);
removed++;
} else
@@ -3042,7 +3094,7 @@ int flags;
rval = 0;
dir = fin->fin_rev;
tcpflags = tcp->th_flags;
- dlen = fin->fin_plen - fin->fin_hlen - (TCP_OFF(tcp) << 2);
+ dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
if (tcpflags & TH_RST) {
if (!(tcpflags & TH_PUSH) && !dlen)
@@ -3180,13 +3232,34 @@ int flags;
break;
case IPF_TCPS_HALF_ESTAB: /* 4 */
- if (ostate >= IPF_TCPS_HALF_ESTAB) {
- if ((tcpflags & TH_ACKMASK) == TH_ACK) {
+ if (tcpflags & TH_FIN) {
+ nstate = IPF_TCPS_FIN_WAIT_1;
+ rval = 1;
+ } else if ((tcpflags & TH_ACKMASK) == TH_ACK) {
+ /*
+ * If we've picked up a connection in mid
+ * flight, we could be looking at a follow on
+ * packet from the same direction as the one
+ * that created this state. Recognise it but
+ * do not advance the entire connection's
+ * state.
+ */
+ switch (ostate)
+ {
+ case IPF_TCPS_CLOSED :
+ case IPF_TCPS_SYN_SENT :
+ case IPF_TCPS_SYN_RECEIVED :
+ rval = 1;
+ break;
+ case IPF_TCPS_HALF_ESTAB :
+ case IPF_TCPS_ESTABLISHED :
nstate = IPF_TCPS_ESTABLISHED;
rval = 1;
+ break;
+ default :
+ break;
}
}
-
break;
case IPF_TCPS_ESTABLISHED: /* 5 */
@@ -3316,9 +3389,6 @@ int flags;
(u_long)tcp, tcpflags, (u_long)tqe,
nstate, ostate);
# endif
-# ifdef DIAGNOSTIC
- panic("invalid TCP state");
-# endif
#else
abort();
#endif
@@ -3442,20 +3512,16 @@ fr_info_t *fin;
/*
* Does it at least have the return (basic) IP header ?
+ * Is it an actual recognised ICMP error type?
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
- if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN))
+ if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN) ||
+ !(fin->fin_flx & FI_ICMPERR))
return NULL;
ic6 = fin->fin_dp;
type = ic6->icmp6_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP6_DST_UNREACH) && (type != ICMP6_PACKET_TOO_BIG) &&
- (type != ICMP6_TIME_EXCEEDED) && (type != ICMP6_PARAM_PROB))
- return NULL;
oip6 = (ip6_t *)((char *)ic6 + ICMPERR_ICMPHLEN);
if (fin->fin_plen < sizeof(*oip6))
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index 44bb860fa1b2..7167f15fe543 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.h
+++ b/sys/contrib/ipfilter/netinet/ip_state.h
@@ -1,17 +1,15 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-2001 by Darren Reed.
*
* 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.68.2.3 2005/03/03 14:24:11 darrenr Exp
+ * $Id: ip_state.h,v 2.68.2.5 2005/08/20 13:48:25 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
-#if defined(__STDC__) || defined(__GNUC__)
+#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define SIOCDELST _IOW('r', 61, struct ipfobj)
#else
# define SIOCDELST _IOW(r, 61, struct ipfobj)
@@ -60,8 +58,8 @@ typedef struct ipstate {
u_char is_v;
u_32_t is_hv;
u_32_t is_tag;
- u_32_t is_opt; /* packet options set */
- u_32_t is_optmsk; /* " " mask */
+ u_32_t is_opt[2]; /* packet options set */
+ u_32_t is_optmsk[2]; /* " " mask */
u_short is_sec; /* security options set */
u_short is_secmsk; /* " " mask */
u_short is_auth; /* authentication options set */
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.c b/sys/contrib/ipfilter/netinet/ip_sync.c
index 40a027e12a5a..768d1c538e60 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.c
+++ b/sys/contrib/ipfilter/netinet/ip_sync.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1995-1998 by Darren Reed.
*
@@ -98,7 +96,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.3 2005/02/18 13:06:29 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.5 2005/09/04 12:51:12 darrenr Exp $";
#endif
#define SYNC_STATETABSZ 256
@@ -231,8 +229,10 @@ ipstate_t *ips;
ips->is_die = htonl(ips->is_die);
ips->is_pass = htonl(ips->is_pass);
ips->is_flags = htonl(ips->is_flags);
- ips->is_opt = htonl(ips->is_opt);
- ips->is_optmsk = htonl(ips->is_optmsk);
+ ips->is_opt[0] = htonl(ips->is_opt[0]);
+ ips->is_opt[1] = htonl(ips->is_opt[1]);
+ ips->is_optmsk[0] = htonl(ips->is_optmsk[0]);
+ ips->is_optmsk[1] = htonl(ips->is_optmsk[1]);
ips->is_sec = htons(ips->is_sec);
ips->is_secmsk = htons(ips->is_secmsk);
ips->is_auth = htons(ips->is_auth);
@@ -246,8 +246,10 @@ ipstate_t *ips;
ips->is_die = ntohl(ips->is_die);
ips->is_pass = ntohl(ips->is_pass);
ips->is_flags = ntohl(ips->is_flags);
- ips->is_opt = ntohl(ips->is_opt);
- ips->is_optmsk = ntohl(ips->is_optmsk);
+ ips->is_opt[0] = ntohl(ips->is_opt[0]);
+ ips->is_opt[1] = ntohl(ips->is_opt[1]);
+ ips->is_optmsk[0] = ntohl(ips->is_optmsk[0]);
+ ips->is_optmsk[1] = ntohl(ips->is_optmsk[1]);
ips->is_sec = ntohs(ips->is_sec);
ips->is_secmsk = ntohs(ips->is_secmsk);
ips->is_auth = ntohs(ips->is_auth);
@@ -442,21 +444,26 @@ struct uio *uio;
l = get_sleep_lock(&sl_tail);
err = sleep(&sl_tail, PZERO+1);
+ if (err) {
+ MUTEX_EXIT(&ipsl_mutex);
+ return EINTR;
+ }
spinunlock(l);
}
# else /* __hpux */
# ifdef __osf__
err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0,
&ipsl_mutex, MS_LOCK_SIMPLE);
+ if (err)
+ return EINTR;
# else
MUTEX_EXIT(&ipsl_mutex);
err = SLEEP(&sl_tail, "ipl sleep");
+ if (err)
+ return EINTR;
+ MUTEX_ENTER(&ipsl_mutex);
# endif /* __osf__ */
# endif /* __hpux */
- if (err) {
- MUTEX_EXIT(&ipsl_mutex);
- return err;
- }
# endif /* SOLARIS */
}
MUTEX_EXIT(&ipsl_mutex);
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.h b/sys/contrib/ipfilter/netinet/ip_sync.h
index 25ad708207e5..8a62192dbfb0 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.h
+++ b/sys/contrib/ipfilter/netinet/ip_sync.h
@@ -1,12 +1,10 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp
+ * $Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp $
*/
#ifndef __IP_SYNC_H__
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 05e884e7ab57..ee9a9550b884 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -1,19 +1,17 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * Id: ipl.h,v 2.52.2.9 2005/03/30 14:14:05 darrenr Exp
+ * $Id: ipl.h,v 2.52.2.11 2005/12/04 22:37:24 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v4.1.8"
+#define IPL_VERSION "IP Filter: v4.1.10"
-#define IPFILTER_VERSION 4010800
+#define IPFILTER_VERSION 4011000
#endif
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 570db0f8a56c..26a51aa69feb 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (C) 2000 by Darren Reed.
*
@@ -102,6 +100,7 @@ static struct cdevsw ipl_cdevsw = {
.d_open = iplopen,
.d_close = iplclose,
.d_read = iplread,
+ .d_write = iplwrite,
.d_ioctl = iplioctl,
.d_name = "ipl",
# if __FreeBSD_version < 600000