diff options
author | guido <guido@FreeBSD.org> | 2005-12-30 11:22:11 +0000 |
---|---|---|
committer | guido <guido@FreeBSD.org> | 2005-12-30 11:22:11 +0000 |
commit | 74f74123f3fdf4235d201dc8b4227d9d11d7dce5 (patch) | |
tree | 658db597994c3e9227c2101b920c16b0f10bfdfc | |
parent | 28f64fe3cea04b47311e7db06814b6b9be539040 (diff) | |
download | FreeBSD-src-74f74123f3fdf4235d201dc8b4227d9d11d7dce5.zip FreeBSD-src-74f74123f3fdf4235d201dc8b4227d9d11d7dce5.tar.gz |
Import IP Filter version 4.1.10
35 files changed, 1053 insertions, 651 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index e62b0ed..c8c1b55 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 a1e029a..b6f0844 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 8e96f39..3892778 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 dbadfea..f48a98d 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 626ddde..45d5bb4 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 4ee0d3b..760122e 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 6baa570..db1a0af 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 7861507d..07b841c 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 ab866ac..860d75e 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 22acbec..92ed8d5 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 1bc4087..ebee58d 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 b549611..93cf070 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 0f61d76..0aa5710 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 804f7c7..6618c6d 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 2f404ee..3c7eb5f 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 7d9acad..953dde1 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 f3618c7..30bba07 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 9a74fe6..68396cd 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 a55cc33..1a0b2a2 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 9880c9d..3d19afb 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 5ddc74e..3731fe9 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 b7ec697..0047e10 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 062d8b4..60b6ac0 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 5f92797..1e0bede 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 a049349..a81e12d 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 3a3e0d9..1782064 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 4c01223..112e4da 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 b36fccf..73977c7 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 8891367..d857453 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 7c1b311..b0bf742 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 44bb860..7167f15 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 40a027e..768d1c5 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 25ad708..8a62192 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 05e884e..ee9a955 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 570db0f..26a51aa 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 |