diff options
author | darrenr <darrenr@FreeBSD.org> | 2002-08-28 13:41:36 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 2002-08-28 13:41:36 +0000 |
commit | 18a0c3053aaaa535b8ff6da16c42213ecab93518 (patch) | |
tree | d760c34d75d7a81e785d8267825f11a1a4366ccf /sys/contrib/ipfilter/netinet | |
parent | 48e119b242336566da7864ada622c107c141b403 (diff) | |
download | FreeBSD-src-18a0c3053aaaa535b8ff6da16c42213ecab93518.zip FreeBSD-src-18a0c3053aaaa535b8ff6da16c42213ecab93518.tar.gz |
Finally merge in the changes from ipfilter 3.4.29 to freebsd-current.
Main changes here are related to the ftp proxy and making that work better.
Diffstat (limited to 'sys/contrib/ipfilter/netinet')
-rw-r--r-- | sys/contrib/ipfilter/netinet/fil.c | 15 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_compat.h | 3 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_fil.c | 19 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_frag.c | 17 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_frag.h | 4 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_ftp_pxy.c | 188 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_nat.c | 11 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_nat.h | 1 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_proxy.c | 92 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_proxy.h | 2 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_state.c | 14 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_state.h | 3 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ipl.h | 2 |
13 files changed, 298 insertions, 73 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index 28eb05b..1f8f435 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -1087,7 +1087,7 @@ int out; fin->fin_fr = fr; if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) { if (fin->fin_fl & FI_FRAG) { - if (ipfr_newfrag(ip, fin, pass) == -1) { + if (ipfr_newfrag(ip, fin) == -1) { ATOMIC_INCL(frstats[out].fr_bnfr); } else { ATOMIC_INCL(frstats[out].fr_nfr); @@ -1207,7 +1207,16 @@ logit: * some operating systems. */ if (!out) { - if (pass & FR_RETICMP) { + if (changed == -1) + /* + * If a packet results in a NAT error, do not + * send a reset or ICMP error as it may disrupt + * an existing flow. This is the proxy saying + * the content is bad so just drop the packet + * silently. + */ + ; + else if (pass & FR_RETICMP) { int dst; if ((pass & FR_RETMASK) == FR_FAKEICMP) @@ -1517,7 +1526,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.35.2.61 2002/06/05 08:18:09 darrenr Exp $ + * $Id: fil.c,v 2.35.2.63 2002/08/28 12:40:08 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h index 608424a..1a43238 100644 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ b/sys/contrib/ipfilter/netinet/ip_compat.h @@ -187,6 +187,9 @@ typedef struct qif { */ size_t qf_hl; /* header length */ int qf_sap; +# if SOLARIS2 >= 8 + int qf_tunoff; /* tunnel offset */ +#endif size_t qf_incnt; size_t qf_outcnt; } qif_t; diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c index 6305663..f7f6352 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.c +++ b/sys/contrib/ipfilter/netinet/ip_fil.c @@ -160,6 +160,7 @@ static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **, fr_info_t *, frdest_t *)); # endif # ifdef __sgi +extern int tcp_mtudisc; extern kmutex_t ipf_rw; extern KRWLOCK_T ipf_mutex; # endif @@ -529,7 +530,8 @@ int ipldetach() printf("%s unloaded\n", ipfilter_version); fr_checkp = fr_savep; - i = frflush(IPL_LOGIPF, i); + i = frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE|FR_INACTIVE); + i += frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE); fr_running = 0; # ifdef NETBSD_PF @@ -1250,7 +1252,17 @@ struct mbuf **mp; ip->ip_v = IPVERSION; ip->ip_tos = oip->ip_tos; ip->ip_id = oip->ip_id; - ip->ip_off = 0; + +# if defined(__NetBSD__) || defined(__OpenBSD__) + if (ip_mtudisc != 0) + ip->ip_off = IP_DF; +# else +# if defined(__sgi) + if (ip->ip_p == IPPROTO_TCP && tcp_mtudisc != 0) + ip->ip_off = IP_DF; +# endif +# endif + # if (BSD < 199306) || defined(__sgi) ip->ip_ttl = tcp_ttl; # else @@ -1677,7 +1689,8 @@ frdest_t *fdp; */ if (ip->ip_len <= ifp->if_mtu) { # ifndef sparc -# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510)) +# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510)) && \ + !(__NetBSD_Version__ >= 105110000) ip->ip_id = htons(ip->ip_id); # endif ip->ip_len = htons(ip->ip_len); diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c index a32f3c4..e789860 100644 --- a/sys/contrib/ipfilter/netinet/ip_frag.c +++ b/sys/contrib/ipfilter/netinet/ip_frag.c @@ -120,7 +120,7 @@ extern kmutex_t ipf_rw; #endif -static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, u_int, ipfr_t **)); +static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, ipfr_t **)); static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, ipfr_t **)); static void ipfr_delete __P((ipfr_t *)); @@ -138,10 +138,9 @@ ipfrstat_t *ipfr_fragstats() * add a new entry to the fragment cache, registering it as having come * through this box, with the result of the filter operation. */ -static ipfr_t *ipfr_new(ip, fin, pass, table) +static ipfr_t *ipfr_new(ip, fin, table) ip_t *ip; fr_info_t *fin; -u_int pass; ipfr_t *table[]; { ipfr_t **fp, *fra, frag; @@ -198,7 +197,7 @@ ipfr_t *table[]; /* * Instert the fragment into the fragment table, copy the struct used * in the search using bcopy rather than reassign each field. - * Set the ttl to the default and mask out logging from "pass" + * Set the ttl to the default. */ if ((fra->ipfr_next = table[idx])) table[idx]->ipfr_prev = fra; @@ -220,17 +219,16 @@ ipfr_t *table[]; } -int ipfr_newfrag(ip, fin, pass) +int ipfr_newfrag(ip, fin) ip_t *ip; fr_info_t *fin; -u_int pass; { ipfr_t *ipf; if ((ip->ip_v != 4) || (fr_frag_lock)) return -1; WRITE_ENTER(&ipf_frag); - ipf = ipfr_new(ip, fin, pass, ipfr_heads); + ipf = ipfr_new(ip, fin, ipfr_heads); RWLOCK_EXIT(&ipf_frag); if (ipf == NULL) { ATOMIC_INCL(frstats[fin->fin_out].fr_bnfr); @@ -241,10 +239,9 @@ u_int pass; } -int ipfr_nat_newfrag(ip, fin, pass, nat) +int ipfr_nat_newfrag(ip, fin, nat) ip_t *ip; fr_info_t *fin; -u_int pass; nat_t *nat; { ipfr_t *ipf; @@ -259,7 +256,7 @@ nat_t *nat; return -1; WRITE_ENTER(&ipf_natfrag); - ipf = ipfr_new(ip, fin, pass, ipfr_nattab); + ipf = ipfr_new(ip, fin, ipfr_nattab); if (ipf != NULL) { ipf->ipfr_data = nat; nat->nat_data = ipf; diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h index 63df648..fc737c7 100644 --- a/sys/contrib/ipfilter/netinet/ip_frag.h +++ b/sys/contrib/ipfilter/netinet/ip_frag.h @@ -49,8 +49,8 @@ typedef struct ipfrstat { extern int fr_ipfrttl; extern int fr_frag_lock; extern ipfrstat_t *ipfr_fragstats __P((void)); -extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int)); -extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *)); +extern int ipfr_newfrag __P((ip_t *, fr_info_t *)); +extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, struct nat *)); extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *)); extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *)); extern void ipfr_forget __P((void *)); diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c index 68a3455..b6644b9 100644 --- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c @@ -294,7 +294,7 @@ int dlen; ip->ip_len = slen; ip->ip_src = swip; } - return APR_INC(inc); + return inc; } @@ -577,7 +577,7 @@ int dlen; wptr = f->ftps_wptr; if (!isdigit(*rptr) || !isdigit(*(rptr + 1)) || !isdigit(*(rptr + 2))) - return inc; + return 0; if (ftp->ftp_passok == FTPXY_GO) { if (!strncmp(rptr, "227 ", 4)) inc = ippr_ftp_pasv(fin, ip, nat, f, dlen); @@ -717,6 +717,10 @@ size_t len; } +/* + * rv == 0 for outbound processing, + * rv == 1 for inbound processing. + */ int ippr_ftp_process(fin, ip, nat, ftp, rv) fr_info_t *fin; ip_t *ip; @@ -724,15 +728,16 @@ nat_t *nat; ftpinfo_t *ftp; int rv; { - int mlen, len, off, inc, i, sel; + int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff; + u_32_t thseq, thack; char *rptr, *wptr; + ap_session_t *aps; ftpside_t *f, *t; tcphdr_t *tcp; mb_t *m; tcp = (tcphdr_t *)fin->fin_dp; off = fin->fin_hlen + (tcp->th_off << 2); - #if SOLARIS && defined(_KERNEL) m = fin->fin_qfm; #else @@ -750,46 +755,149 @@ int rv; #endif mlen -= off; + aps = nat->nat_aps; t = &ftp->ftp_side[1 - rv]; f = &ftp->ftp_side[rv]; - if (!mlen) { - if (!t->ftps_seq || - (int)ntohl(tcp->th_ack) - (int)t->ftps_seq > 0) - t->ftps_seq = ntohl(tcp->th_ack); - f->ftps_len = 0; - return 0; - } - - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - - i = 0; - sel = nat->nat_aps->aps_sel[1 - rv]; - if (rv) { - if (nat->nat_aps->aps_ackmin[sel] < ntohl(tcp->th_seq)) - i = nat->nat_aps->aps_ackoff[sel]; + thseq = ntohl(tcp->th_seq); + thack = ntohl(tcp->th_ack); + + sel = aps->aps_sel[1 - rv]; + sel2 = aps->aps_sel[rv]; + if (rv == 0) { + seqoff = aps->aps_seqoff[sel]; + if (aps->aps_seqmin[sel] > seqoff + thseq) + seqoff = aps->aps_seqoff[!sel]; + ackoff = aps->aps_ackoff[sel2]; + if (aps->aps_ackmin[sel2] > ackoff + thack) + ackoff = aps->aps_ackoff[!sel2]; } else { - if (nat->nat_aps->aps_seqmin[sel] < ntohl(tcp->th_seq)) - i = nat->nat_aps->aps_seqoff[sel]; +#if PROXY_DEBUG + printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq, + aps->aps_ackmin[sel]); +#endif + seqoff = aps->aps_ackoff[sel]; + if (aps->aps_ackmin[sel] > seqoff + thseq) + seqoff = aps->aps_ackoff[!sel]; + +#if PROXY_DEBUG + printf("ackoff %d thack %x seqmin %x\n", ackoff, thack, + aps->aps_seqmin[sel2]); +#endif + ackoff = aps->aps_seqoff[sel2]; + if (ackoff > 0) { + if (aps->aps_seqmin[sel2] > ackoff + thack) + ackoff = aps->aps_seqoff[!sel2]; + } else { + if (aps->aps_seqmin[sel2] > thack) + ackoff = aps->aps_seqoff[!sel2]; + } } +#if PROXY_DEBUG + printf("%s: %x seq %x/%d ack %x/%d len %d\n", rv ? "IN" : "OUT", + tcp->th_flags, thseq, seqoff, thack, ackoff, mlen); + printf("sel %d seqmin %x/%x offset %d/%d\n", sel, + aps->aps_seqmin[sel], aps->aps_seqmin[sel2], + aps->aps_seqoff[sel], aps->aps_seqoff[sel2]); + printf("sel %d ackmin %x/%x offset %d/%d\n", sel2, + aps->aps_ackmin[sel], aps->aps_ackmin[sel2], + aps->aps_ackoff[sel], aps->aps_ackoff[sel2]); +#endif + /* * XXX - Ideally, this packet should get dropped because we now know * that it is out of order (and there is no real danger in doing so * apart from causing packets to go through here ordered). */ - if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq)) - f->ftps_seq = ntohl(tcp->th_seq); +#if PROXY_DEBUG + printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n", + rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff); +#endif + + ok = 0; + if (t->ftps_seq[0] == 0) + t->ftps_seq[0] = thack, ok = 1; else { - inc = ntohl(tcp->th_seq) - f->ftps_seq; - if (inc < 0) - inc = -inc; - if (i < 0) - i = -i; - if (inc > i) { + if (ackoff == 0) { + if (t->ftps_seq[0] == thack) + ok = 1; + else if (t->ftps_seq[1] == thack) { + t->ftps_seq[0] = thack; + ok = 1; + } + } else { + if (t->ftps_seq[0] + ackoff == thack) + ok = 1; + else if (t->ftps_seq[0] == thack + ackoff) + ok = 1; + else if (t->ftps_seq[1] + ackoff == thack) { + t->ftps_seq[0] = thack - ackoff; + ok = 1; + } else if (t->ftps_seq[1] == thack + ackoff) { + t->ftps_seq[0] = thack - ackoff; + ok = 1; + } + } + } + +#if PROXY_DEBUG + if (!ok) + printf("not ok\n"); +#endif + + if (!mlen) { + if (t->ftps_seq[0] + ackoff != thack) return APR_ERR(1); + +#if PROXY_DEBUG + printf("f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]); +#endif + if (tcp->th_flags & TH_FIN) { + if (thseq + seqoff == f->ftps_seq[0] + 1 || + f->ftps_seq[0] + seqoff + 1 == thseq || + thseq + seqoff == f->ftps_seq[0] || + thseq == f->ftps_seq[0] + seqoff) + ; + else { +#if PROXY_DEBUG + printf("FIN: thseq %x seqoff %d ftps_seq %x\n", + thseq, seqoff, f->ftps_seq[0]); +#endif + return APR_ERR(1); + } } + f->ftps_len = 0; + return 0; } + + ok = 0; + if (thseq == f->ftps_seq[0] || thseq == f->ftps_seq[1]) + ok = 1; + /* + * Retransmitted data packet. + */ + else if (thseq + mlen == f->ftps_seq[0] || + thseq + mlen == f->ftps_seq[1]) + ok = 1; + if (ok == 0) { + inc = thseq - f->ftps_seq[0]; +#if PROXY_DEBUG + printf("inc %d sel %d rv %d\n", inc, sel, rv); + printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0], + f->ftps_seq[1]); + printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel], + aps->aps_ackoff[sel]); + printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel], + aps->aps_seqoff[sel]); +#endif + + return APR_ERR(1); + } + inc = 0; + rptr = f->ftps_rptr; + wptr = f->ftps_wptr; + f->ftps_seq[0] = thseq; + f->ftps_seq[1] = f->ftps_seq[0] + mlen; f->ftps_len = mlen; while (mlen > 0) { @@ -833,6 +941,7 @@ int rv; * ftp proxy for this connection. */ if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) { + /* f->ftps_seq[1] += inc; */ return APR_ERR(2); } @@ -873,7 +982,24 @@ int rv; } } - t->ftps_seq = ntohl(tcp->th_ack); + /* f->ftps_seq[1] += inc; */ + if (tcp->th_flags & TH_FIN) + f->ftps_seq[1]++; +#ifndef _KERNEL + mlen = mbuflen(m); +#else +# if SOLARIS + mlen = msgdsize(m); +# else + mlen = mbufchainlen(m); +# endif +#endif + off = fin->fin_hlen + (tcp->th_off << 2); + mlen -= off; +#if PROXY_DEBUG + printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen); +#endif + f->ftps_rptr = rptr; f->ftps_wptr = wptr; return APR_INC(inc); diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index ce6574f..ef109b1 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -2267,8 +2267,8 @@ register natlookup_t *np; fr_info_t fi; bzero((char *)&fi, sizeof(fi)); - fi.fin_data[0] = np->nl_inport; - fi.fin_data[1] = np->nl_outport; + fi.fin_data[0] = ntohs(np->nl_inport); + fi.fin_data[1] = ntohs(np->nl_outport); /* * If nl_inip is non null, this is a lookup based on the real @@ -2450,7 +2450,7 @@ maskloop: if (nat) { np = nat->nat_ptr; if (natadd && (fin->fin_fl & FI_FRAG) && np) - ipfr_nat_newfrag(ip, fin, 0, nat); + ipfr_nat_newfrag(ip, fin, nat); MUTEX_ENTER(&nat->nat_lock); if (fin->fin_p != IPPROTO_TCP) { if (np && np->in_age[1]) @@ -2542,6 +2542,8 @@ maskloop: i = appr_check(ip, fin, nat); if (i == 0) i = 1; + else if (i == -1) + nat->nat_drop[1]++; } else i = 1; ATOMIC_INCL(nat_stats.ns_mapped[1]); @@ -2666,11 +2668,12 @@ maskloop: np = nat->nat_ptr; fin->fin_fr = nat->nat_fr; if (natadd && (fin->fin_fl & FI_FRAG) && np) - ipfr_nat_newfrag(ip, fin, 0, nat); + ipfr_nat_newfrag(ip, fin, nat); if (np && (np->in_apr != NULL) && (np->in_dport == 0 || (tcp != NULL && sport == np->in_dport))) { i = appr_check(ip, fin, nat); if (i == -1) { + nat->nat_drop[0]++; RWLOCK_EXIT(&ipf_nat); return i; } diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h index f1258be..2462e61 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.h +++ b/sys/contrib/ipfilter/netinet/ip_nat.h @@ -78,6 +78,7 @@ typedef struct nat { struct in_addr nat_oip; /* other ip */ U_QUAD_T nat_pkts; U_QUAD_T nat_bytes; + u_int nat_drop[2]; u_short nat_oport; /* other port */ u_short nat_inport; u_short nat_outport; diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c index 9212582..332835d 100644 --- a/sys/contrib/ipfilter/netinet/ip_proxy.c +++ b/sys/contrib/ipfilter/netinet/ip_proxy.c @@ -91,6 +91,8 @@ extern KRWLOCK_T ipf_nat, ipf_state; static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); +#define PROXY_DEBUG 0 + #define AP_SESS_SIZE 53 #include "netinet/ip_ftp_pxy.c" @@ -314,9 +316,19 @@ nat_t *nat; sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp); #endif if (sum != tcp->th_sum) { +#if PROXY_DEBUG + printf("proxy tcp checksum failure\n"); +#endif frstats[fin->fin_out].fr_tcpbad++; return -1; } + + /* + * Don't both the proxy with these...or in fact, should + * we free up proxy stuff when seen? + */ + if ((tcp->th_flags & TH_RST) != 0) + return 0; } apr = aps->aps_apr; @@ -330,9 +342,16 @@ nat_t *nat; } rv = APR_EXIT(err); - if (rv == 1) + if (rv == 1) { +#if PROXY_DEBUG + printf("proxy says bad packet received\n"); +#endif return -1; + } if (rv == 2) { +#if PROXY_DEBUG + printf("proxy says free app proxy data\n"); +#endif appr_free(apr); nat->nat_aps = NULL; return -1; @@ -413,6 +432,9 @@ ap_session_t *aps; } +/* + * returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise + */ static int appr_fixseqack(fin, ip, aps, inc) fr_info_t *fin; ip_t *ip; @@ -426,8 +448,12 @@ int inc; tcp = (tcphdr_t *)fin->fin_dp; out = fin->fin_out; + /* + * ip_len has already been adjusted by 'inc'. + */ nlen = ip->ip_len; nlen -= (ip->ip_hl << 2) + (tcp->th_off << 2); + inc2 = inc; inc = (int)inc2; @@ -437,8 +463,13 @@ int inc; /* switch to other set ? */ if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && - (seq1 > aps->aps_seqmin[!sel])) + (seq1 > aps->aps_seqmin[!sel])) { +#if PROXY_DEBUG + printf("proxy out switch set seq %d -> %d %x > %x\n", + sel, !sel, seq1, aps->aps_seqmin[!sel]); +#endif sel = aps->aps_sel[out] = !sel; +} if (aps->aps_seqoff[sel]) { seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel]; @@ -451,8 +482,13 @@ int inc; } if (inc && (seq1 > aps->aps_seqmin[!sel])) { - aps->aps_seqmin[!sel] = seq1 + nlen - 1; - aps->aps_seqoff[!sel] = aps->aps_seqoff[sel] + inc; + aps->aps_seqmin[sel] = seq1 + nlen - 1; + aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc; +#if PROXY_DEBUG + printf("proxy seq set %d at %x to %d + %d\n", sel, + aps->aps_seqmin[sel], aps->aps_seqoff[sel], + inc); +#endif } /***/ @@ -462,8 +498,13 @@ int inc; /* switch to other set ? */ if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && - (seq1 > aps->aps_ackmin[!sel])) + (seq1 > aps->aps_ackmin[!sel])) { +#if PROXY_DEBUG + printf("proxy out switch set ack %d -> %d %x > %x\n", + sel, !sel, seq1, aps->aps_ackmin[!sel]); +#endif sel = aps->aps_sel[1 - out] = !sel; +} if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) { seq2 = aps->aps_ackoff[sel]; @@ -476,12 +517,16 @@ int inc; /* switch to other set ? */ if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && - (seq1 > aps->aps_ackmin[!sel])) + (seq1 > aps->aps_ackmin[!sel])) { +#if PROXY_DEBUG + printf("proxy in switch set ack %d -> %d %x > %x\n", + sel, !sel, seq1, aps->aps_ackmin[!sel]); +#endif sel = aps->aps_sel[out] = !sel; +} if (aps->aps_ackoff[sel]) { - seq2 = aps->aps_ackmin[sel] - - aps->aps_ackoff[sel]; + seq2 = aps->aps_ackmin[sel] - aps->aps_ackoff[sel]; if (seq1 > seq2) { seq2 = aps->aps_ackoff[sel]; seq1 += seq2; @@ -493,6 +538,11 @@ int inc; if (inc && (seq1 > aps->aps_ackmin[!sel])) { aps->aps_ackmin[!sel] = seq1 + nlen - 1; aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; +#if PROXY_DEBUG + printf("proxy ack set %d at %x to %d + %d\n", !sel, + aps->aps_seqmin[!sel], aps->aps_seqoff[sel], + inc); +#endif } /***/ @@ -502,15 +552,31 @@ int inc; /* switch to other set ? */ if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && - (seq1 > aps->aps_seqmin[!sel])) + (seq1 > aps->aps_seqmin[!sel])) { +#if PROXY_DEBUG + printf("proxy in switch set seq %d -> %d %x > %x\n", + sel, !sel, seq1, aps->aps_seqmin[!sel]); +#endif sel = aps->aps_sel[1 - out] = !sel; +} - if (aps->aps_seqoff[sel] && (seq1 > aps->aps_seqmin[sel])) { - seq2 = aps->aps_seqoff[sel]; - tcp->th_ack = htonl(seq1 - seq2); - ch = 1; + if (aps->aps_seqoff[sel] != 0) { +#if PROXY_DEBUG + printf("sel %d seqoff %d seq1 %x seqmin %x\n", sel, + aps->aps_seqoff[sel], seq1, + aps->aps_seqmin[sel]); +#endif + if (seq1 > aps->aps_seqmin[sel]) { + seq2 = aps->aps_seqoff[sel]; + tcp->th_ack = htonl(seq1 - seq2); + ch = 1; + } } } +#if PROXY_DEBUG + printf("appr_fixseqack: seq %x ack %x\n", ntohl(tcp->th_seq), + ntohl(tcp->th_ack)); +#endif return ch ? 2 : 0; } diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h index f38974e..d293f17 100644 --- a/sys/contrib/ipfilter/netinet/ip_proxy.h +++ b/sys/contrib/ipfilter/netinet/ip_proxy.h @@ -96,7 +96,7 @@ typedef struct aproxy { typedef struct ftpside { char *ftps_rptr; char *ftps_wptr; - u_32_t ftps_seq; + u_32_t ftps_seq[2]; u_32_t ftps_len; int ftps_junk; int ftps_cmds; diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c index 619c46b..b649058 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ b/sys/contrib/ipfilter/netinet/ip_state.c @@ -743,6 +743,7 @@ u_int flags; is->is_hv = hv; is->is_rule = fin->fin_fr; if (is->is_rule != NULL) { + is->is_group = is->is_rule->fr_group; ATOMIC_INC32(is->is_rule->fr_ref); pass = is->is_rule->fr_flags; is->is_frage[0] = is->is_rule->fr_age[0]; @@ -811,8 +812,8 @@ u_int flags; #endif RWLOCK_EXIT(&ipf_state); fin->fin_rev = IP6NEQ(is->is_dst, fin->fin_fi.fi_dst); - if ((fin->fin_fi.fi_fl & FI_FRAG) && (pass & FR_KEEPFRAG)) - ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); + if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG)) + ipfr_newfrag(ip, fin); return is; } @@ -1068,7 +1069,7 @@ tcphdr_t *tcp; } else { is->is_src = fin->fin_fi.fi_dst; } - } else if ((flags & FI_W_DPORT) != 0) { + } else if ((flags & FI_W_DADDR) != 0) { if (rev == 0) { is->is_dst = fin->fin_fi.fi_dst; } else { @@ -1404,7 +1405,8 @@ fr_info_t *fin; tcphdr_t *tcp; int rev; - if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT)) + if ((ips_list == NULL) || (fin->fin_off != 0) || fr_state_lock || + (fin->fin_fl & FI_SHORT)) return NULL; is = NULL; @@ -1635,7 +1637,7 @@ retry_tcpudp: pass = is->is_pass; RWLOCK_EXIT(&ipf_state); if ((fin->fin_fl & FI_FRAG) && (pass & FR_KEEPFRAG)) - ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); + ipfr_newfrag(ip, fin); #ifndef _KERNEL if ((tcp != NULL) && (tcp->th_flags & TCP_CLOSE)) fr_delstate(is); @@ -2046,6 +2048,8 @@ u_int type; ipsl.isl_p = is->is_p; ipsl.isl_v = is->is_v; ipsl.isl_flags = is->is_flags; + ipsl.isl_rulen = is->is_rulen; + ipsl.isl_group = is->is_group; if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) { ipsl.isl_sport = is->is_sport; ipsl.isl_dport = is->is_dport; diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h index 780e30b..bd21cbc 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.h +++ b/sys/contrib/ipfilter/netinet/ip_state.h @@ -87,6 +87,7 @@ typedef struct ipstate { tcpstate_t is_ts; udpstate_t is_us; } is_ps; + u_32_t is_group; char is_ifname[4][IFNAMSIZ]; #if SOLARIS || defined(__sgi) kmutex_t is_lock; @@ -148,6 +149,8 @@ typedef struct ipslog { u_char isl_p; u_char isl_flags; u_char isl_state[2]; + u_32_t isl_rulen; + u_32_t isl_group; } ipslog_t; #define isl_sport isl_ps.isl_ports[0] diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h index 24245b0..d1d69a5 100644 --- a/sys/contrib/ipfilter/netinet/ipl.h +++ b/sys/contrib/ipfilter/netinet/ipl.h @@ -10,6 +10,6 @@ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v3.4.28" +#define IPL_VERSION "IP Filter: v3.4.29" #endif |