From 1fa4f6782a7e92a232e56892d8bce7920d49292e Mon Sep 17 00:00:00 2001 From: guido Date: Wed, 9 Feb 2000 20:46:45 +0000 Subject: Import of ipfilter 3.3.8 Approved by: jkh --- contrib/ipfilter/BNF | 3 +- contrib/ipfilter/HISTORY | 39 +++++++++++++++++++++++++- contrib/ipfilter/fil.c | 16 +++++++++-- contrib/ipfilter/fils.c | 8 ++++-- contrib/ipfilter/ip_auth.c | 4 +-- contrib/ipfilter/ip_fil.c | 34 +++++++++++++---------- contrib/ipfilter/ip_fil.h | 5 ++-- contrib/ipfilter/ip_lfil.c | 12 ++++---- contrib/ipfilter/ip_nat.c | 15 ++++++++-- contrib/ipfilter/ip_nat.h | 3 +- contrib/ipfilter/ip_sfil.c | 8 ++++-- contrib/ipfilter/ip_state.c | 55 +++++++++++++++++++++++++------------ contrib/ipfilter/ip_state.h | 3 +- contrib/ipfilter/ipl.h | 2 +- contrib/ipfilter/ipmon.c | 11 +++++--- contrib/ipfilter/ipt.c | 4 ++- contrib/ipfilter/man/ipf.5 | 3 +- contrib/ipfilter/mlf_ipl.c | 4 +-- contrib/ipfilter/parse.c | 67 +++++++++++++++++++++++++++++---------------- contrib/ipfilter/solaris.c | 14 ++++++++-- 20 files changed, 218 insertions(+), 92 deletions(-) diff --git a/contrib/ipfilter/BNF b/contrib/ipfilter/BNF index a30c743..cfa5423 100644 --- a/contrib/ipfilter/BNF +++ b/contrib/ipfilter/BNF @@ -53,7 +53,8 @@ icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" | "routersol" | decnumber . icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" | "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | - "net-prohib" | "host-prohib" | "net-tos" | "host-tos" . + "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | + "filter-prohib" | "host-preced" | "cutoff-preced" . optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" . diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY index 41f3f82..49f7ace 100644 --- a/contrib/ipfilter/HISTORY +++ b/contrib/ipfilter/HISTORY @@ -8,7 +8,7 @@ # # Thanks to Tel.Net Media for allowing me to maintain and further develop # IP Filter as part of my job and supplying Sun equipment for testing the -# move to 64bits. +# move to 64bits and Gigabit Ethernet. # # Thanks to BSDI for providing object files for BSD/OS 3.1 and the means # to further support development of IP Filter under BSDI. @@ -20,6 +20,43 @@ # and especially those who have found the time to port IP Filter to new # platforms. # +3.3.8 01/02/2000 - Released + +fix state handling of SYN packets. + +add parsing recognition of extra icmp types/codes and fix handling of +icmp time stamps and mask requests - Frank volf + +3.3.7 25/01/2000 - Released + +sync on state information as well as NAT information when required + +record nat protocol in all nat log records + +don't reuse the IP# from an active NAT session if the IP# in the rule +has changed dynamically. + +lookup the protocol for NAT log information in ipmon and pass that to +portname. + +fix the bug with changing the outbound interface of a packet where it +would lead to a panic. + +use fr_running instead of ipl_inited. (sysctl name change on freebsd) + +return EIO if someone attempts an ioctl on state/nat if ipfilter is not +enabled. + +fix rule insertion bug + +make state flushing clean anything that's not fully established (4/4) + +call fr_state_flush() after we've released ipf_state so we don't generate +a recursive mutex acquisition panic + +fix parsing of icmp code after return-icmp/return-icmp-as-dest and add +some patches to enhance parsing strength + 3.3.6 28/12/1999 - Released add in missing rwlock release in fr_checkicmpmatchingstate() and fix check diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c index 7e0a007..f527bdb 100644 --- a/contrib/ipfilter/fil.c +++ b/contrib/ipfilter/fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.14 1999/12/07 12:53:40 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.16 2000/01/27 08:49:37 darrenr Exp $"; #endif #include @@ -245,6 +245,12 @@ fr_info_t *fin; if (!off && (icmp->icmp_type == ICMP_ECHOREPLY || icmp->icmp_type == ICMP_ECHO)) minicmpsz = ICMP_MINLEN; + if (!off && (icmp->icmp_type == ICMP_TSTAMP || + icmp->icmp_type == ICMP_TSTAMPREPLY)) + minicmpsz = 20; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + 3*timestamp(3*4) */ + if (!off && (icmp->icmp_type == ICMP_MASKREQ || + icmp->icmp_type == ICMP_MASKREPLY)) + minicmpsz = 12; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + mask(4) */ if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || (off && off < sizeof(struct icmp))) fi->fi_fl |= FI_SHORT; @@ -688,6 +694,9 @@ int out; READ_ENTER(&ipf_mutex); + if (fin->fin_fi.fi_fl & FI_SHORT) + ATOMIC_INC(frstats[out].fr_short); + /* * Check auth now. This, combined with the check below to see if apass * is 0 is to ensure that we don't count the packet twice, which can @@ -1178,7 +1187,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.3.2.14 1999/12/07 12:53:40 darrenr Exp $ + * $Id: fil.c,v 2.3.2.16 2000/01/27 08:49:37 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -1579,7 +1588,10 @@ void frsync() # else for (ifp = ifnet; ifp; ifp = ifp->if_next) # endif + { ip_natsync(ifp); + ip_statesync(ifp); + } # endif WRITE_ENTER(&ipf_mutex); diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c index eab0b4a..713691d 100644 --- a/contrib/ipfilter/fils.c +++ b/contrib/ipfilter/fils.c @@ -51,7 +51,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fils.c,v 2.2.2.4 1999/12/04 02:06:24 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fils.c,v 2.2.2.5 2000/01/27 08:49:40 darrenr Exp $"; #endif extern char *optarg; @@ -238,11 +238,13 @@ struct friostat *fp; PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[0].fr_block, fp->f_st[0].fr_pass, fp->f_st[0].fr_nom); - PRINTF(" counted %lu\n", fp->f_st[0].fr_acct); + PRINTF(" counted %lu short %lu\n", + fp->f_st[0].fr_acct, fp->f_st[0].fr_short); PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[1].fr_block, fp->f_st[1].fr_pass, fp->f_st[1].fr_nom); - PRINTF(" counted %lu\n", fp->f_st[0].fr_acct); + PRINTF(" counted %lu short %lu\n", + fp->f_st[1].fr_acct, fp->f_st[1].fr_short); PRINTF(" input packets logged:\tblocked %lu passed %lu\n", fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); PRINTF("output packets logged:\tblocked %lu passed %lu\n", diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c index 443eefe..f4fcf1e 100644 --- a/contrib/ipfilter/ip_auth.c +++ b/contrib/ipfilter/ip_auth.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.1 1999/09/28 11:44:04 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.2 2000/01/16 10:12:14 darrenr Exp $"; #endif #include @@ -396,7 +396,7 @@ fr_authioctlloop: # if SOLARIS error = fr_qout(fr_auth[i].fra_q, m); # else /* SOLARIS */ -# if _BSDI_VERSION >= 199802 +# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); # else diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c index 20b8ff3..7943cdc 100644 --- a/contrib/ipfilter/ip_fil.c +++ b/contrib/ipfilter/ip_fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.14 1999/12/11 05:31:08 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.16 2000/01/16 10:12:42 darrenr Exp $"; #endif #ifndef SOLARIS @@ -126,7 +126,6 @@ extern int tcp_ttl; # endif #endif -int ipl_inited = 0; int ipl_unreach = ICMP_UNREACH_FILTER; u_long ipl_frouteok[2] = {0, 0}; @@ -230,7 +229,7 @@ int iplattach() # endif SPL_NET(s); - if (ipl_inited || (fr_checkp == fr_check)) { + if (fr_running || (fr_checkp == fr_check)) { printf("IP Filter: already initialized\n"); SPL_X(s); return EBUSY; @@ -258,7 +257,6 @@ int iplattach() } # endif - ipl_inited = 1; bzero((char *)frcache, sizeof(frcache)); fr_savep = fr_checkp; fr_checkp = fr_check; @@ -286,6 +284,7 @@ int iplattach() timeout(ipfr_slowtimer, NULL, hz/2); # endif #endif + fr_running = 1; return 0; } @@ -310,7 +309,7 @@ int ipldetach() # endif #endif SPL_NET(s); - if (!ipl_inited) + if (!fr_running) { printf("IP Filter: not initialized\n"); SPL_X(s); @@ -319,7 +318,7 @@ int ipldetach() fr_checkp = fr_savep; i = frflush(IPL_LOGIPF, i); - ipl_inited = 0; + fr_running = 0; # ifdef NETBSD_PF pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); @@ -412,11 +411,15 @@ int mode; SPL_NET(s); if (unit == IPL_LOGNAT) { + if (!fr_running) + return EIO; error = nat_ioctl(data, cmd, mode); SPL_X(s); return error; } if (unit == IPL_LOGSTATE) { + if (!fr_running) + return EIO; error = fr_state_ioctl(data, cmd, mode); SPL_X(s); return error; @@ -437,15 +440,10 @@ int mode; error = EPERM; else { IRCOPY(data, (caddr_t)&enable, sizeof(enable)); - if (enable) { + if (enable) error = iplattach(); - if (error == 0) - fr_running = 1; - } else { + else error = ipldetach(); - if (error == 0) - fr_running = 0; - } } break; } @@ -702,13 +700,15 @@ caddr_t data; } if (!f) { - if (req != SIOCINAFR || req != SIOCINIFR) + if (req != SIOCINAFR && req != SIOCINIFR) while ((f = *ftail)) ftail = &f->fr_next; else { - if (fp->fr_hits) + if (fp->fr_hits) { + ftail = fprev; while (--fp->fr_hits && (f = *ftail)) ftail = &f->fr_next; + } f = NULL; } } @@ -944,7 +944,11 @@ ip_t *ip; # if _BSDI_VERSION >= 199802 return ip_output(m, (struct mbuf *)0, &ro, 0, 0, NULL); # else +# if defined(__OpenBSD__) + return ip_output(m, (struct mbuf *)0, 0, 0, 0, NULL); +# else return ip_output(m, (struct mbuf *)0, 0, 0, 0); +# endif # endif # endif } diff --git a/contrib/ipfilter/ip_fil.h b/contrib/ipfilter/ip_fil.h index 66f2128..aa42f2f 100644 --- a/contrib/ipfilter/ip_fil.h +++ b/contrib/ipfilter/ip_fil.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ip_fil.h,v 2.3.2.6 1999/12/17 12:58:16 darrenr Exp $ + * $Id: ip_fil.h,v 2.3.2.7 2000/01/27 08:49:41 darrenr Exp $ */ #ifndef __IP_FIL_H__ @@ -271,6 +271,7 @@ typedef struct filterstats { u_long fr_pass; /* packets allowed */ u_long fr_block; /* packets denied */ u_long fr_nom; /* packets which don't match any rule */ + u_long fr_short; /* packets which are short */ u_long fr_ppkl; /* packets allowed and logged */ u_long fr_bpkl; /* packets denied and logged */ u_long fr_npkl; /* packets unmatched and logged */ @@ -552,7 +553,7 @@ extern void fr_makefrip __P((int, ip_t *, fr_info_t *)); extern int fr_ifpaddr __P((void *, struct in_addr *)); extern char *memstr __P((char *, char *, int, int)); extern int ipl_unreach; -extern int ipl_inited; +extern int fr_running; extern u_long ipl_frouteok[2]; extern int fr_pass; extern int fr_flags; diff --git a/contrib/ipfilter/ip_lfil.c b/contrib/ipfilter/ip_lfil.c index fe073ff..8e7ea33 100644 --- a/contrib/ipfilter/ip_lfil.c +++ b/contrib/ipfilter/ip_lfil.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.1 1999/08/04 17:29:57 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.1.2.1 2000/01/16 10:13:02 darrenr Exp $"; #endif #if defined(KERNEL) && !defined(_KERNEL) @@ -63,7 +63,7 @@ static struct ifnet **ifneta = NULL; static int nifs = 0; #endif -int ipl_inited = 0; +int fr_running = 0; int ipl_unreach = ICMP_UNREACH_FILTER; u_long ipl_frouteok[2] = {0, 0}; @@ -98,12 +98,12 @@ int iplattach() char *defpass; int s; - if (ipl_inited || (fr_checkp == fr_precheck)) { + if (fr_running || (fr_checkp == fr_precheck)) { printk("IP Filter: already initialized\n"); return EBUSY; } - ipl_inited = 1; + fr_running = 1; bzero((char *)frcache, sizeof(frcache)); bzero((char *)nat_table, sizeof(nat_table)); fr_savep = fr_checkp; @@ -138,7 +138,7 @@ int ipldetach() { int s, i = FR_INQUE|FR_OUTQUE; - if (!ipl_inited) + if (!fr_running) { printk("IP Filter: not initialized\n"); return 0; @@ -146,7 +146,7 @@ int ipldetach() fr_checkp = fr_savep; i = frflush(IPL_LOGIPF, i); - ipl_inited = 0; + fr_running = 0; ipfr_unload(); ip_natunload(); diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c index 9333259..bf11843 100644 --- a/contrib/ipfilter/ip_nat.c +++ b/contrib/ipfilter/ip_nat.c @@ -9,7 +9,7 @@ */ #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.2.2.11 1999/12/17 13:05:40 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.2.2.12 2000/01/24 12:43:40 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) @@ -726,12 +726,22 @@ int direction; port = 0; in.s_addr = np->in_nip; if (l == 0) { + /* + * Check to see if there is an existing NAT + * setup for this IP address pair. + */ natl = nat_maplookup(fin->fin_ifp, flags, ip->ip_src, ip->ip_dst); if (natl != NULL) { in = natl->nat_outip; + if ((in.s_addr & np->in_outmsk) != + np->in_outip) + in.s_addr = 0; + else #ifndef sparc - in.s_addr = ntohl(in.s_addr); + in.s_addr = ntohl(in.s_addr); +#else + ; #endif } } @@ -1766,6 +1776,7 @@ u_int type; natl.nl_origport = nat->nat_oport; natl.nl_inport = nat->nat_inport; natl.nl_outport = nat->nat_outport; + natl.nl_p = nat->nat_p; natl.nl_type = type; natl.nl_rule = -1; #ifndef LARGE_NAT diff --git a/contrib/ipfilter/ip_nat.h b/contrib/ipfilter/ip_nat.h index bca52e5..c57b4e7 100644 --- a/contrib/ipfilter/ip_nat.h +++ b/contrib/ipfilter/ip_nat.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_nat.h 1.5 2/4/96 - * $Id: ip_nat.h,v 2.1.2.2 1999/11/28 11:01:51 darrenr Exp $ + * $Id: ip_nat.h,v 2.1.2.3 2000/01/24 12:44:24 darrenr Exp $ */ #ifndef __IP_NAT_H__ @@ -186,6 +186,7 @@ typedef struct natlog { int nl_rule; U_QUAD_T nl_pkts; U_QUAD_T nl_bytes; + u_char nl_p; } natlog_t; diff --git a/contrib/ipfilter/ip_sfil.c b/contrib/ipfilter/ip_sfil.c index d4ae15a..b08525d5 100644 --- a/contrib/ipfilter/ip_sfil.c +++ b/contrib/ipfilter/ip_sfil.c @@ -9,7 +9,7 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.5 1999/12/11 05:31:10 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.6 2000/01/16 10:12:44 darrenr Exp $"; #endif #include @@ -498,13 +498,15 @@ caddr_t data; } if (!f) { - if (req != SIOCINAFR || req != SIOCINIFR) + if (req != SIOCINAFR && req != SIOCINIFR) while ((f = *ftail)) ftail = &f->fr_next; else { - if (fp->fr_hits) + if (fp->fr_hits) { + ftail = fprev; while (--fp->fr_hits && (f = *ftail)) ftail = &f->fr_next; + } f = NULL; } } diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c index 1503bb9..ad05e10 100644 --- a/contrib/ipfilter/ip_state.c +++ b/contrib/ipfilter/ip_state.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.16 1999/12/28 05:24:58 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.18 2000/01/27 08:51:30 darrenr Exp $"; #endif #include @@ -174,11 +174,10 @@ int which; delete = 1; break; case 1 : - if ((is->is_p == IPPROTO_TCP) && - (((is->is_state[0] <= TCPS_ESTABLISHED) && - (is->is_state[1] > TCPS_ESTABLISHED)) || - ((is->is_state[1] <= TCPS_ESTABLISHED) && - (is->is_state[0] > TCPS_ESTABLISHED)))) + if (is->is_p != IPPROTO_TCP) + break; + if ((is->is_state[0] != TCPS_ESTABLISHED) || + (is->is_state[1] != TCPS_ESTABLISHED)) delete = 1; break; } @@ -457,7 +456,7 @@ tcphdr_t *tcp; win = ntohs(tcp->th_win); end = seq + ip->ip_len - fin->fin_hlen - (tcp->th_off << 2) + ((tcp->th_flags & TH_SYN) ? 1 : 0) + - ((tcp->th_flags & TH_FIN) ? 1 : 0); + ((tcp->th_flags & TH_FIN) ? 1 : 0); if (fdata->td_end == 0) { /* @@ -471,6 +470,8 @@ tcphdr_t *tcp; if (!(tcp->th_flags & TH_ACK)) { /* Pretend an ack was sent */ ack = tdata->td_end; win = 1; + if ((tcp->th_flags == TH_SYN) && (tdata->td_maxwin == 0)) + tdata->td_maxwin = 1; } else if (((tcp->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) && (ack == 0)) { /* gross hack to get around certain broken tcp stacks */ @@ -486,7 +487,7 @@ tcphdr_t *tcp; #define SEQ_GE(a,b) ((int)((a) - (b)) >= 0) #define SEQ_GT(a,b) ((int)((a) - (b)) > 0) if ((SEQ_GE(fdata->td_maxend, end)) && - (SEQ_GE(seq + maxwin, fdata->td_end - maxwin)) && + (SEQ_GE(seq, fdata->td_end - maxwin)) && /* XXX what about big packets */ #define MAXACKWINDOW 66000 (ackskew >= -MAXACKWINDOW) && @@ -671,8 +672,8 @@ fr_info_t *fin; int type; u_int hv; - /* - * Does it at least have the return (basic) IP header ? + /* + * Does it at least have the return (basic) IP header ? * Only a basic IP header (no options) should be with * an ICMP error header. */ @@ -706,10 +707,10 @@ fr_info_t *fin; if ((icmp->icmp_type != ICMP_ECHO) && (icmp->icmp_type != ICMP_TSTAMP) && (icmp->icmp_type != ICMP_IREQ) && - (icmp->icmp_type != ICMP_MASKREQ)) + (icmp->icmp_type != ICMP_MASKREQ)) return NULL; - /* + /* * perform a lookup of the ICMP packet in the state table */ @@ -733,9 +734,9 @@ fr_info_t *fin; for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && fr_matchsrcdst(is, src, dst, &ofin, NULL)) { - /* + /* * in the state table ICMP query's are stored - * with the type of the corresponding ICMP + * with the type of the corresponding ICMP * response. Correct here */ if (((is->is_type == ICMP_ECHOREPLY) && @@ -745,7 +746,7 @@ fr_info_t *fin; (is->is_type - 1 == ic->icmp_type)) { ips_stats.iss_hits++; is->is_pkts++; - is->is_bytes += ip->ip_len; + is->is_bytes += ip->ip_len; fr = is->is_rule; RWLOCK_EXIT(&ipf_state); return fr; @@ -803,7 +804,7 @@ fr_info_t *fin; * comes the other way around */ is->is_pkts++; - is->is_bytes += ip->ip_len; + is->is_bytes += ip->ip_len; /* * we deliberately do not touch the timeouts * for the accompanying state table entry. @@ -1038,12 +1039,12 @@ void fr_timeoutstate() ips_num--; } else isp = &is->is_next; + RWLOCK_EXIT(&ipf_state); + SPL_X(s); if (fr_state_doflush) { (void) fr_state_flush(1); fr_state_doflush = 0; } - RWLOCK_EXIT(&ipf_state); - SPL_X(s); } @@ -1180,3 +1181,21 @@ u_int type; (void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1); } #endif + + +void ip_statesync(ifp) +void *ifp; +{ + register ipstate_t *is; + register int i; + + WRITE_ENTER(&ipf_state); + for (i = fr_statesize - 1; i >= 0; i--) + for (is = ips_table[i]; is != NULL; is = is->is_next) { + if (is->is_ifpin == ifp) + is->is_ifpin = NULL; + if (is->is_ifpout == ifp) + is->is_ifpout = NULL; + } + RWLOCK_EXIT(&ipf_state); +} diff --git a/contrib/ipfilter/ip_state.h b/contrib/ipfilter/ip_state.h index ae8b5c1..b20f286 100644 --- a/contrib/ipfilter/ip_state.h +++ b/contrib/ipfilter/ip_state.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed - * $Id: ip_state.h,v 2.1 1999/08/04 17:30:00 darrenr Exp $ + * $Id: ip_state.h,v 2.1.2.2 2000/01/24 13:13:52 darrenr Exp $ */ #ifndef __IP_STATE_H__ #define __IP_STATE_H__ @@ -151,6 +151,7 @@ extern int fr_stateinit __P((void)); extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *)); extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int)); extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *)); +extern void ip_statesync __P((void *)); extern void fr_timeoutstate __P((void)); extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int)); extern void fr_stateunload __P((void)); diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h index 741e1a5..6eb9b1a 100644 --- a/contrib/ipfilter/ipl.h +++ b/contrib/ipfilter/ipl.h @@ -11,6 +11,6 @@ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v3.3.6" +#define IPL_VERSION "IP Filter: v3.3.8" #endif diff --git a/contrib/ipfilter/ipmon.c b/contrib/ipfilter/ipmon.c index affba4d..b90b093 100644 --- a/contrib/ipfilter/ipmon.c +++ b/contrib/ipfilter/ipmon.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1998 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.3.2.3 1999/11/28 04:05:28 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.3.2.4 2000/01/24 12:45:25 darrenr Exp $"; #endif #ifndef SOLARIS @@ -361,6 +361,7 @@ int blen; char *t = line; struct tm *tm; int res, i, len; + char *proto; nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); res = (opts & OPT_RESOLVE) ? 1 : 0; @@ -387,14 +388,16 @@ int blen; sprintf(t, "Type: %d ", nl->nl_type); t += strlen(t); + proto = getproto(nl->nl_p); + (void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nl_inip), - portname(res, NULL, (u_int)nl->nl_inport)); + portname(res, proto, (u_int)nl->nl_inport)); t += strlen(t); (void) sprintf(t, "%s,%s ", hostname(res, nl->nl_outip), - portname(res, NULL, (u_int)nl->nl_outport)); + portname(res, proto, (u_int)nl->nl_outport)); t += strlen(t); (void) sprintf(t, "[%s,%s]", hostname(res, nl->nl_origip), - portname(res, NULL, (u_int)nl->nl_origport)); + portname(res, proto, (u_int)nl->nl_origport)); t += strlen(t); if (nl->nl_type == NL_EXPIRE) { #ifdef USE_QUAD_T diff --git a/contrib/ipfilter/ipt.c b/contrib/ipfilter/ipt.c index c87b5b2..ff251f1 100644 --- a/contrib/ipfilter/ipt.c +++ b/contrib/ipfilter/ipt.c @@ -55,7 +55,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipt.c,v 2.1 1999/08/04 17:30:08 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ipt.c,v 2.1.2.1 2000/01/24 14:49:11 darrenr Exp $"; #endif extern char *optarg; @@ -64,6 +64,7 @@ extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex; extern struct ifnet *get_unit __P((char *)); extern void init_ifp __P((void)); extern ipnat_t *natparse __P((char *, int)); +extern int fr_running; int opts = 0; int main __P((int, char *[])); @@ -134,6 +135,7 @@ char *argv[]; nat_init(); fr_stateinit(); initparse(); + fr_running = 1; if (rules) { char line[513], *s; diff --git a/contrib/ipfilter/man/ipf.5 b/contrib/ipfilter/man/ipf.5 index dab49b6..478d672 100644 --- a/contrib/ipfilter/man/ipf.5 +++ b/contrib/ipfilter/man/ipf.5 @@ -72,7 +72,8 @@ icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" | "inforep" | "maskreq" | "maskrep" | decnumber . icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" | "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | - "net-prohib" | "host-prohib" | "net-tos" | "host-tos" . + "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | + "filter-prohib" | "host-preced" | "cutoff-preced" . optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" . diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c index ef4b00f..3ae9a78 100644 --- a/contrib/ipfilter/mlf_ipl.c +++ b/contrib/ipfilter/mlf_ipl.c @@ -111,8 +111,8 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, &fr_ipfrttl, 0, ""); SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW, &ipl_unreach, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_inited, CTLFLAG_RD, - &ipl_inited, 0, ""); +SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, + &fr_running, 0, ""); SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD, &fr_authsize, 0, ""); SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, diff --git a/contrib/ipfilter/parse.c b/contrib/ipfilter/parse.c index 5ec1cca..3720561 100644 --- a/contrib/ipfilter/parse.c +++ b/contrib/ipfilter/parse.c @@ -41,7 +41,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: parse.c,v 2.1.2.5 1999/12/28 06:06:58 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: parse.c,v 2.1.2.8 2000/01/27 08:49:42 darrenr Exp $"; #endif extern struct ipopt_names ionames[], secclass[]; @@ -127,16 +127,25 @@ int linenum; if (!strcasecmp("block", *cpp)) { fil.fr_flags |= FR_BLOCK; - if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19)) + if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) && + (i = 19)) fil.fr_flags |= FR_FAKEICMP; - else if (!strncasecmp(*(cpp+1), "return-icmp", 11)) + else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11)) fil.fr_flags |= FR_RETICMP; if (fil.fr_flags & FR_RETICMP) { cpp++; - i = 11; - if ((strlen(*cpp) > i) && (*(*cpp + i) != '(')) - i = 19; - if (*(*cpp + i) == '(') { + if (strlen(*cpp) == i) { + if (*(cpp + 1) && **(cpp +1) == '(') { + cpp++; + i = 0; + } else + i = -1; + } + + /* + * The ICMP code is not required to follow in ()'s + */ + if ((i >= 0) && (*(*cpp + i) == '(')) { i++; j = icmpcode(*cpp + i); if (j == -1) { @@ -183,7 +192,11 @@ int linenum; fac = 0; pri = 0; - cpp++; + if (!*++cpp) { + fprintf(stderr, "%d: %s\n", linenum, + "missing identifier after level"); + return NULL; + } s = index(*cpp, '.'); if (s) { *s++ = '\0'; @@ -217,7 +230,10 @@ int linenum; fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); return NULL; } - cpp++; + if (!*++cpp) { + fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum); + return NULL; + } if (!strcasecmp("in", *cpp)) fil.fr_flags |= FR_INQUE; @@ -234,13 +250,11 @@ int linenum; linenum); return NULL; } - } else { - fprintf(stderr, "%d: missing 'in'/'out' keyword (%s)\n", - linenum, *cpp); - return NULL; } - if (!*++cpp) + if (!*++cpp) { + fprintf(stderr, "%d: missing source specification\n", linenum); return NULL; + } if (!strcasecmp("log", *cpp)) { if (!*++cpp) { @@ -252,15 +266,15 @@ int linenum; fil.fr_flags |= FR_LOGP; else if (fil.fr_flags & FR_BLOCK) fil.fr_flags |= FR_LOGB; - if (!strcasecmp(*cpp, "body")) { + if (*cpp && !strcasecmp(*cpp, "body")) { fil.fr_flags |= FR_LOGBODY; cpp++; } - if (!strcasecmp(*cpp, "first")) { + if (*cpp && !strcasecmp(*cpp, "first")) { fil.fr_flags |= FR_LOGFIRST; cpp++; } - if (!strcasecmp(*cpp, "or-block")) { + if (*cpp && !strcasecmp(*cpp, "or-block")) { if (!(fil.fr_flags & FR_PASS)) { fprintf(stderr, "%d: or-block must be used with pass\n", @@ -270,13 +284,17 @@ int linenum; fil.fr_flags |= FR_LOGORBLOCK; cpp++; } - if (!strcasecmp(*cpp, "level")) { + if (*cpp && !strcasecmp(*cpp, "level")) { int fac, pri; char *s; fac = 0; pri = 0; - cpp++; + if (!*++cpp) { + fprintf(stderr, "%d: %s\n", linenum, + "missing identifier after level"); + return NULL; + } s = index(*cpp, '.'); if (s) { *s++ = '\0'; @@ -305,7 +323,7 @@ int linenum; } } - if (!strcasecmp("quick", *cpp)) { + if (*cpp && !strcasecmp("quick", *cpp)) { cpp++; fil.fr_flags |= FR_QUICK; } @@ -337,12 +355,12 @@ int linenum; return NULL; cpp++; } - if (!strcasecmp(*cpp, "to") && *(cpp + 1)) { + if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) { cpp++; if (to_interface(&fil.fr_tif, *cpp, linenum)) return NULL; cpp++; - } else if (!strcasecmp(*cpp, "fastroute")) { + } else if (*cpp && !strcasecmp(*cpp, "fastroute")) { if (!(fil.fr_flags & FR_INQUE)) { fprintf(stderr, "can only use %s with 'in'\n", @@ -1222,12 +1240,13 @@ int linenum; } -#define MAX_ICMPCODE 12 +#define MAX_ICMPCODE 15 char *icmpcodes[] = { "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail", "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib", - "net-tos", "host-tos", NULL }; + "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff", + NULL }; /* * Return the number for the associated ICMP unreachable code. */ diff --git a/contrib/ipfilter/solaris.c b/contrib/ipfilter/solaris.c index 7960786..761ce55 100644 --- a/contrib/ipfilter/solaris.c +++ b/contrib/ipfilter/solaris.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ /* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ -#pragma ident "@(#)$Id: solaris.c,v 2.1.2.11 1999/12/04 03:33:59 darrenr Exp $" +#pragma ident "@(#)$Id: solaris.c,v 2.1.2.14 2000/01/25 15:32:03 darrenr Exp $" #include #include @@ -937,6 +937,8 @@ again: void ipf_synctimeout(arg) void *arg; { + if (fr_running < 0) + return; READ_ENTER(&ipf_solaris); ipfsync(); WRITE_ENTER(&ipfs_mutex); @@ -1327,8 +1329,10 @@ int ipfsync() /* * Resync. any NAT `connections' using this interface and its IP #. */ - for (il = ill_g_head; il; il = il->ill_next) + for (il = ill_g_head; il; il = il->ill_next) { ip_natsync((void *)il); + ip_statesync((void *)il); + } return 0; } @@ -1442,9 +1446,13 @@ frdest_t *fdp; * If there is another M_PROTO, we don't want it */ if (*mpp != mb) { + mp = *mpp; + (void) unlinkb(mp); + mp = (*mpp)->b_cont; (*mpp)->b_cont = NULL; (*mpp)->b_prev = NULL; freemsg(*mpp); + *mpp = mp; } ir = (ire_t *)fdp->fd_ifp; @@ -1537,6 +1545,7 @@ frdest_t *fdp; mb = mp2; } } + *mpp = mb; if (ir->ire_stq) q = ir->ire_stq; @@ -1544,6 +1553,7 @@ frdest_t *fdp; q = WR(ir->ire_rfq); if (q) { mb->b_prev = NULL; + mb->b_queue = q; RWLOCK_EXIT(&ipfs_mutex); RWLOCK_EXIT(&ipf_solaris); #if SOLARIS2 >= 6 -- cgit v1.1