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.
This commit is contained in:
parent
070700595d
commit
ecae20848a
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 *));
|
||||
|
@ -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;
|
||||
}
|
||||
thseq = ntohl(tcp->th_seq);
|
||||
thack = ntohl(tcp->th_ack);
|
||||
|
||||
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];
|
||||
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) {
|
||||
return APR_ERR(1);
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user