fix conflicts from rcsids

This commit is contained in:
Darren Reed 2000-10-26 12:33:42 +00:00
parent 5b4d40c638
commit 60b88d9681
14 changed files with 605 additions and 184 deletions

View File

@ -277,6 +277,16 @@ fr_info_t *fin;
int minicmpsz = sizeof(struct icmp);
icmphdr_t *icmp;
if (fin->fin_dlen > 1)
fin->fin_data[0] = *(u_short *)tcp;
if ((!(plen >= hlen + minicmpsz) && !off) ||
(off && off < sizeof(struct icmp))) {
fi->fi_fl |= FI_SHORT;
if (fin->fin_dlen < 2)
break;
}
icmp = (icmphdr_t *)tcp;
if (!off && (icmp->icmp_type == ICMP_ECHOREPLY ||
@ -294,11 +304,6 @@ fr_info_t *fin;
icmp->icmp_type == ICMP_MASKREPLY))
minicmpsz = 12;
if ((!(plen >= hlen + minicmpsz) && !off) ||
(off && off < sizeof(struct icmp)))
fi->fi_fl |= FI_SHORT;
if (fin->fin_dlen > 1)
fin->fin_data[0] = *(u_short *)tcp;
break;
}
case IPPROTO_TCP :
@ -743,6 +748,7 @@ int out;
#ifdef _KERNEL
mb_t *mc = NULL;
int p, len;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
@ -767,13 +773,26 @@ int out;
}
# endif /* CSUM_DELAY_DATA */
# ifdef USE_INET6
if (v == 6) {
len = ntohs(((ip6_t*)ip)->ip6_plen);
p = ((ip6_t *)ip)->ip6_nxt;
} else
# endif
{
p = ip->ip_p;
len = ip->ip_len;
}
if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
ip->ip_p == IPPROTO_ICMP)) {
if ((p == IPPROTO_TCP || p == IPPROTO_UDP || p == IPPROTO_ICMP
# ifdef USE_INET6
|| (v == 6 && p == IPPROTO_ICMPV6)
# endif
)) {
int plen = 0;
if ((ip->ip_off & IP_OFFMASK) == 0)
switch(ip->ip_p)
if ((v == 6) || (ip->ip_off & IP_OFFMASK) == 0)
switch(p)
{
case IPPROTO_TCP:
plen = sizeof(tcphdr_t);
@ -783,10 +802,13 @@ int out;
break;
/* 96 - enough for complete ICMP error IP header */
case IPPROTO_ICMP:
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
# endif
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
}
up = MIN(hlen + plen, ip->ip_len);
up = MIN(hlen + plen, len);
if (up > m->m_len) {
# ifdef __sgi
@ -835,8 +857,8 @@ int out;
#endif
changed = 0;
fin->fin_v = v;
fin->fin_ifp = ifp;
fin->fin_v = v;
fin->fin_out = out;
fin->fin_mp = mp;
fr_makefrip(hlen, ip, fin);
@ -1383,7 +1405,7 @@ tcphdr_t *tcp;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.35.2.20 2000/08/13 04:15:43 darrenr Exp $
* $Id: fil.c,v 2.35.2.26 2000/10/24 11:58:17 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@ -1862,7 +1884,7 @@ size_t c;
int err;
#if SOLARIS
if (copyin(a, &ca, sizeof(ca)))
if (copyin(a, (char *)&ca, sizeof(ca)))
return EFAULT;
#else
bcopy(a, &ca, sizeof(ca));
@ -1882,7 +1904,7 @@ size_t c;
int err;
#if SOLARIS
if (copyin(b, &ca, sizeof(ca)))
if (copyin(b, (char *)&ca, sizeof(ca)))
return EFAULT;
#else
bcopy(b, &ca, sizeof(ca));
@ -1976,6 +1998,15 @@ friostat_t *fiop;
fiop->f_acctin6[1] = ipacct6[0][1];
fiop->f_acctout6[0] = ipacct6[1][0];
fiop->f_acctout6[1] = ipacct6[1][1];
#else
fiop->f_fin6[0] = NULL;
fiop->f_fin6[1] = NULL;
fiop->f_fout6[0] = NULL;
fiop->f_fout6[1] = NULL;
fiop->f_acctin6[0] = NULL;
fiop->f_acctin6[1] = NULL;
fiop->f_acctout6[0] = NULL;
fiop->f_acctout6[1] = NULL;
#endif
fiop->f_active = fr_active;
fiop->f_froute[0] = ipl_frouteok[0];

View File

@ -47,8 +47,6 @@ typedef struct fr_authstat {
extern frentry_t *ipauth;
extern struct fr_authstat fr_authstats;
extern int fr_defaultauthage;
extern int fr_authstart;
extern int fr_authend;
extern int fr_authsize;
extern int fr_authused;
extern int fr_auth_lock;

View File

@ -264,6 +264,12 @@ union i6addr {
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
# ifdef IPFILTER_LKM
# include <osreldate.h>
# define ACTUALLY_LKM_NOT_KERNEL
# else
# include <sys/osreldate.h>
# endif
# if __FreeBSD__ < 3
# include <machine/spl.h>
# else
@ -289,6 +295,19 @@ union i6addr {
# define ATOMIC_DEC32 ATOMIC_DEC
# define ATOMIC_DEC16 ATOMIC_DEC
#endif
#ifdef __sgi
# define hz HZ
# include <sys/ksynch.h>
# define IPF_LOCK_PL plhi
# include <sys/sema.h>
#undef kmutex_t
typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# undef MUTEX_INIT
# undef MUTEX_DESTROY
#endif
#ifdef KERNEL
# if SOLARIS
# if SOLARIS2 >= 6
@ -338,8 +357,8 @@ union i6addr {
# define MUTEX_DESTROY(x) mutex_destroy(x)
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
# define IWCOPY(a,b,c) copyout((a), (b), (c))
# define IRCOPY(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define IWCOPY(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
# define FREE_MB_T(m) freemsg(m)
@ -384,15 +403,6 @@ extern ill_t *get_unit __P((char *, int));
# define IFNAME(x) ((ill_t *)x)->ill_name
# else /* SOLARIS */
# if defined(__sgi)
# define hz HZ
# include <sys/ksynch.h>
# define IPF_LOCK_PL plhi
# include <sys/sema.h>
#undef kmutex_t
typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
@ -405,8 +415,8 @@ typedef struct {
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
# define MUTEX_INIT(x,y,z) (x).l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
# define MUTEX_DESTROY(x) LOCK_DEALLOC((x).l)
# define MUTEX_INIT(x,y,z) (x)->l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
# define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->l)
# else /* __sgi */
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--

View File

@ -173,6 +173,9 @@ struct callout_handle ipfr_slowtimer_ch;
# include <sys/callout.h>
struct callout ipfr_slowtimer_ch;
#endif
#if defined(__sgi) && defined(_KERNEL)
toid_t ipfr_slowtimer_ch;
#endif
#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
# include <sys/device.h>
@ -322,7 +325,7 @@ int iplattach()
callout_init(&ipfr_slowtimer_ch);
callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
# else
# if (__FreeBSD_version >= 300000) && defined(_KERNEL)
# if (__FreeBSD_version >= 300000) || defined(__sgi)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
@ -353,7 +356,7 @@ int ipldetach()
untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch);
# else
# ifdef __sgi
untimeout(ipfr_slowtimer);
untimeout(ipfr_slowtimer_ch);
# else
untimeout(ipfr_slowtimer, NULL);
# endif
@ -980,8 +983,10 @@ fr_info_t *fin;
if (m == NULL)
return -1;
if (tcp->th_flags & TH_SYN)
tlen = 1;
tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
#ifdef USE_INET6
hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t);
#else
@ -1002,11 +1007,16 @@ fr_info_t *fin;
tcp2->th_sport = tcp->th_dport;
tcp2->th_dport = tcp->th_sport;
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
if (tcp->th_flags & TH_ACK) {
tcp2->th_seq = tcp->th_ack;
tcp2->th_flags = TH_RST;
} else {
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
tcp2->th_flags = TH_RST|TH_ACK;
}
tcp2->th_off = sizeof(*tcp2) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
# ifdef USE_INET6
if (fin->fin_v == 6) {
ip6->ip6_plen = htons(sizeof(struct tcphdr));
@ -1148,7 +1158,12 @@ int dst;
m_freem(m);
return ENOBUFS;
}
# ifdef M_TRAILINGSPACE
m->m_len = 0;
avail = M_TRAILINGSPACE(m);
# else
avail = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
# endif
xtra = MIN(ntohs(oip6->ip6_plen) + sizeof(ip6_t),
avail - hlen - sizeof(*icmp) - max_linkhdr);
if (dst == 0) {
@ -1182,6 +1197,12 @@ int dst;
icmp->icmp_type = type;
icmp->icmp_code = fin->fin_icode;
icmp->icmp_cksum = 0;
#ifdef icmp_nextmtu
if (type == ICMP_UNREACH &&
fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp)
icmp->icmp_nextmtu = htons(((struct ifnet *) ifp)->if_mtu);
#endif
if (avail) {
bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
avail -= MIN(ohlen, avail);

View File

@ -215,7 +215,7 @@ u_int pass;
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
return -1;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
@ -232,7 +232,7 @@ nat_t *nat;
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
return -1;
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@ -329,13 +329,16 @@ fr_info_t *fin;
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
nat = ipf->ipfr_data;
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
if (nat->nat_ifp == fin->fin_ifp) {
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
} else
nat = NULL;
} else
nat = NULL;
RWLOCK_EXIT(&ipf_natfrag);

View File

@ -61,6 +61,6 @@ extern void ipfr_slowtimer __P((void *));
# endif
#else
extern int ipfr_slowtimer __P((void));
#endif
#endif /* (BSD >= 199306) || SOLARIS */
#endif /* __IP_FIL_H__ */

View File

@ -145,6 +145,7 @@ int dlen;
} else
return 0;
a5 >>= 8;
a5 &= 0xff;
/*
* Calculate new address parts for PORT command
*/
@ -213,7 +214,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2, 0);
fix_outcksum(&ip->ip_sum, sum2);
#endif
ip->ip_len += inc;
}
@ -440,7 +441,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2, 0);
fix_outcksum(&ip->ip_sum, sum2);
#endif /* SOLARIS || defined(__sgi) */
ip->ip_len += inc;
}
@ -669,15 +670,18 @@ int rv;
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;
if ((*rptr == '\r') && (rptr + 1 < wptr)) {
if (*(rptr + 1) == '\n') {
rptr += 2;
f->ftps_junk = 0;
if (*rptr == '\r') {
if (rptr + 1 < wptr) {
if (*(rptr + 1) == '\n') {
rptr += 2;
f->ftps_junk = 0;
} else
rptr++;
} else
rptr++;
break;
}
f->ftps_rptr = rptr;
}
f->ftps_rptr = rptr;
if (rptr == wptr) {
rptr = wptr = f->ftps_buf;
@ -761,5 +765,7 @@ char **ptr;
j += c - '0';
}
*ptr = s;
i &= 0xff;
j &= 0xff;
return (i << 8) | j;
}

View File

@ -119,6 +119,7 @@ u_int ipf_nattable_sz = NAT_TABLE_SZ;
u_int ipf_natrules_sz = NAT_SIZE;
u_int ipf_rdrrules_sz = RDR_SIZE;
u_int ipf_hostmap_sz = HOSTMAP_SIZE;
int nat_wilds = 0;
u_32_t nat_masks = 0;
u_32_t rdr_masks = 0;
ipnat_t **nat_rules = NULL;
@ -144,6 +145,7 @@ static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t));
static void nat_tabmove __P((nat_t *, u_int));
static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr));
@ -301,10 +303,9 @@ struct hostmap *hm;
}
void fix_outcksum(sp, n , len)
void fix_outcksum(sp, n)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
@ -327,10 +328,9 @@ int len;
}
void fix_incksum(sp, n , len)
void fix_incksum(sp, n)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
@ -357,6 +357,38 @@ int len;
}
/*
* fix_datacksum is used *only* for the adjustments of checksums in the data
* section of an IP packet.
*
* The only situation in which you need to do this is when NAT'ing an
* ICMP error message. Such a message, contains in its body the IP header
* of the original IP packet, that causes the error.
*
* You can't use fix_incksum or fix_outcksum in that case, because for the
* kernel the data section of the ICMP error is just data, and no special
* processing like hardware cksum or ntohs processing have been done by the
* kernel on the data section.
*/
void fix_datacksum(sp, n)
u_short *sp;
u_32_t n;
{
register u_short sumshort;
register u_32_t sum1;
if (!n)
return;
sum1 = (~ntohs(*sp)) & 0xffff;
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
/* Again */
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
sumshort = ~(u_short)sum1;
*(sp) = htons(sumshort);
}
/*
* How the NAT is organised and works.
*
@ -857,8 +889,8 @@ caddr_t data;
/*
* Initialize all these so that nat_delete() doesn't cause a crash.
*/
nat->nat_hstart[0] = NULL;
nat->nat_hstart[1] = NULL;
nat->nat_phnext[0] = NULL;
nat->nat_phnext[1] = NULL;
fr = nat->nat_fr;
nat->nat_fr = NULL;
aps = nat->nat_aps;
@ -970,22 +1002,16 @@ caddr_t data;
static void nat_delete(natd)
struct nat *natd;
{
register struct nat **natp, *nat;
struct ipnat *ipn;
for (natp = natd->nat_hstart[0]; natp && (nat = *natp);
natp = &nat->nat_hnext[0])
if (nat == natd) {
*natp = nat->nat_hnext[0];
break;
}
for (natp = natd->nat_hstart[1]; natp && (nat = *natp);
natp = &nat->nat_hnext[1])
if (nat == natd) {
*natp = nat->nat_hnext[1];
break;
}
if (natd->nat_flags & FI_WILDP)
nat_wilds--;
if (natd->nat_hnext[0])
natd->nat_hnext[0]->nat_phnext[0] = natd->nat_phnext[0];
*natd->nat_phnext[0] = natd->nat_hnext[0];
if (natd->nat_hnext[1])
natd->nat_hnext[1]->nat_phnext[1] = natd->nat_phnext[1];
*natd->nat_phnext[1] = natd->nat_hnext[1];
if (natd->nat_fr != NULL) {
ATOMIC_DEC32(natd->nat_fr->fr_ref);
@ -1030,7 +1056,7 @@ static int nat_flushtable()
{
register nat_t *nat, **natp;
register int j = 0;
/*
* ALL NAT mappings deleted, so lets just make the deletions
* quicker.
@ -1122,6 +1148,8 @@ int direction;
bzero((char *)nat, sizeof(*nat));
nat->nat_flags = flags;
if (flags & FI_WILDP)
nat_wilds++;
/*
* Search the current table for a match.
*/
@ -1444,16 +1472,22 @@ nat_t *nat;
nat->nat_next = nat_instances;
nat_instances = nat;
hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
ipf_nattable_sz);
natp = &nat_table[0][hv];
nat->nat_hstart[0] = natp;
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
nat->nat_phnext[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
ipf_nattable_sz);
natp = &nat_table[1][hv];
nat->nat_hstart[1] = natp;
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
nat->nat_phnext[1] = natp;
nat->nat_hnext[1] = *natp;
*natp = nat;
@ -1561,12 +1595,16 @@ int dir;
u_32_t sum1, sum2, sumd;
struct in_addr in;
icmphdr_t *icmp;
udphdr_t *udp;
nat_t *nat;
ip_t *oip;
int flags = 0;
if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK))
return NULL;
/*
* nat_icmplookup() will return NULL for `defective' packets.
*/
if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir)))
return NULL;
*nflags = IPN_ICMPERR;
@ -1576,16 +1614,33 @@ int dir;
flags = IPN_TCP;
else if (oip->ip_p == IPPROTO_UDP)
flags = IPN_UDP;
udp = (udphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
/*
* Need to adjust ICMP header to include the real IP#'s and
* port #'s. Only apply a checksum change relative to the
* IP address change is it will be modified again in ip_natout
* IP address change as it will be modified again in ip_natout
* for both address and port. Two checksum changes are
* necessary for the two header address changes. Be careful
* to only modify the checksum once for the port # and twice
* for the IP#.
*/
/*
* Step 1
* Fix the IP addresses in the offending IP packet. You also need
* to adjust the IP header checksum of that offending IP packet
* and the ICMP checksum of the ICMP error message itself.
*
* Unfortunately, for UDP and TCP, the IP addresses are also contained
* in the pseudo header that is used to compute the UDP resp. TCP
* checksum. So, we must compensate that as well. Even worse, the
* change in the UDP and TCP checksums require yet another
* adjustment of the ICMP checksum of the ICMP error message.
*
* For the moment we forget about TCP, because that checksum is not
* in the first 8 bytes, so it will not be available in most cases.
*/
if (nat->nat_dir == NAT_OUTBOUND) {
sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
in = nat->nat_inip;
@ -1601,19 +1656,117 @@ int dir;
CALC_SUMD(sum1, sum2, sumd);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_incksum(&oip->ip_sum, sumd, 0);
/*
* Fix IP checksum of the offending IP packet to adjust for
* the change in the IP address.
*
* Normally, you would expect that the ICMP checksum of the
* ICMP error message needs to be adjusted as well for the
* IP address change in oip.
* However, this is a NOP, because the ICMP checksum is
* calculated over the complete ICMP packet, which includes the
* changed oip IP addresses and oip->ip_sum. However, these
* two changes cancel each other out (if the delta for
* the IP address is x, then the delta for ip_sum is minus x),
* so no change in the icmp_cksum is necessary.
*
* Be careful that nat_dir refers to the direction of the
* offending IP packet (oip), not to its ICMP response (icmp)
*/
fix_datacksum(&oip->ip_sum, sumd);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
/*
* Fix UDP pseudo header checksum to compensate for the
* IP address change.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
/*
* The UDP checksum is optional, only adjust it
* if it has been set.
*/
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate the UDP
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
}
#if 0
/*
* Fix TCP pseudo header checksum to compensate for the
* IP address change. Before we can do the change, we
* must make sure that oip is sufficient large to hold
* the TCP checksum (normally it does not!).
*/
if (oip->ip_p == IPPROTO_TCP) {
}
#endif
} else {
fix_outcksum(&oip->ip_sum, sumd, 0);
/*
* Fix IP checksum of the offending IP packet to adjust for
* the change in the IP address.
*
* Normally, you would expect that the ICMP checksum of the
* ICMP error message needs to be adjusted as well for the
* IP address change in oip.
* However, this is a NOP, because the ICMP checksum is
* calculated over the complete ICMP packet, which includes the
* changed oip IP addresses and oip->ip_sum. However, these
* two changes cancel each other out (if the delta for
* the IP address is x, then the delta for ip_sum is minus x),
* so no change in the icmp_cksum is necessary.
*
* Be careful that nat_dir refers to the direction of the
* offending IP packet (oip), not to its ICMP response (icmp)
*/
fix_datacksum(&oip->ip_sum, sumd);
/* XXX FV : without having looked at Solaris source code, it seems unlikely
* that SOLARIS would compensate this in the kernel (a body of an IP packet
* in the data section of an ICMP packet). I have the feeling that this should
* be unconditional, but I'm not in a position to check.
*/
#if !SOLARIS && !defined(__sgi)
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_incksum(&icmp->icmp_cksum, sumd, 0);
/*
* Fix UDP pseudo header checksum to compensate for the
* IP address change.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
/*
* The UDP checksum is optional, only adjust it
* if it has been set
*/
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate the UDP
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
}
#if 0
/*
* Fix TCP pseudo header checksum to compensate for the
* IP address change. Before we can do the change, we
* must make sure that oip is sufficient large to hold
* the TCP checksum (normally it does not!).
*/
if (oip->ip_p == IPPROTO_TCP) {
};
#endif
#endif
}
@ -1624,23 +1777,98 @@ int dir;
* XXX - what if this is bogus hl and we go off the end ?
* In this case, nat_icmpinlookup() will have returned NULL.
*/
tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
tcp = (tcphdr_t *)udp;
/*
* Step 2 :
* For offending TCP/UDP IP packets, translate the ports as
* well, based on the NAT specification. Of course such
* a change must be reflected in the ICMP checksum as well.
*
* Advance notice : Now it becomes complicated :-)
*
* Since the port fields are part of the TCP/UDP checksum
* of the offending IP packet, you need to adjust that checksum
* as well... but, if you change, you must change the icmp
* checksum *again*, to reflect that change.
*
* To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not
* available (we might have to fix that if the encounter a
* device that returns more than 8 data bytes on icmp error)
*/
if (nat->nat_dir == NAT_OUTBOUND) {
if (tcp->th_sport != nat->nat_inport) {
/*
* Fix ICMP checksum to compensate port
* adjustment.
*/
sum1 = ntohs(tcp->th_sport);
sum2 = ntohs(nat->nat_inport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_sport = nat->nat_inport;
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
fix_outcksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
* adjustment. NOTE : the offending IP packet
* flows the other direction compared to the
* ICMP message.
*
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to
* compensate UDP checksum
* adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
}
}
} else {
if (tcp->th_dport != nat->nat_outport) {
/*
* Fix ICMP checksum to compensate port
* adjustment.
*/
sum1 = ntohs(tcp->th_dport);
sum2 = ntohs(nat->nat_outport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_dport = nat->nat_outport;
fix_incksum(&icmp->icmp_cksum, sumd, 0);
fix_incksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
* adjustment. NOTE : the offending IP
* packet flows the other direction compared
* to the ICMP message.
*
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
}
}
}
}
@ -1665,30 +1893,92 @@ register u_int flags, p;
struct in_addr src , mapdst;
u_32_t ports;
{
register u_short sport, mapdport;
register u_short sport, dport;
register nat_t *nat;
register int nflags;
register u_32_t dst;
u_int hv;
mapdport = ports >> 16;
dst = mapdst.s_addr;
dport = ports >> 16;
sport = ports & 0xffff;
flags &= IPN_TCPUDP;
hv = NAT_HASH_FN(mapdst.s_addr, mapdport, ipf_nattable_sz);
hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == mapdst.s_addr &&
nat->nat_outip.s_addr == dst &&
(((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
|| (p == nat->nat_p)) && (!flags ||
(((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == mapdport) ||
(nflags & FI_W_SPORT)))))
((nat->nat_outport == dport) || (nflags & FI_W_SPORT)))))
return nat;
}
return NULL;
if (!nat_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
hv = NAT_HASH_FN(dst, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
if (!(nflags & IPN_TCPUDP))
continue;
if (!(nflags & FI_WILDP))
continue;
if (nat->nat_oip.s_addr != src.s_addr ||
nat->nat_outip.s_addr != dst)
continue;
if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
nat_tabmove(nat, hv);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
return nat;
}
static void nat_tabmove(nat, hv)
nat_t *nat;
u_int hv;
{
nat_t **natp;
/*
* Remove the NAT entry from the old location
*/
if (nat->nat_hnext[0])
nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0];
*nat->nat_phnext[0] = nat->nat_hnext[0];
if (nat->nat_hnext[1])
nat->nat_hnext[0]->nat_phnext[1] = nat->nat_phnext[1];
*nat->nat_phnext[1] = nat->nat_hnext[1];
natp = &nat_table[0][hv];
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
nat->nat_phnext[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
/*
* Add into the NAT table in the new position
*/
natp = &nat_table[1][hv];
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
nat->nat_phnext[1] = natp;
nat->nat_hnext[1] = *natp;
*natp = nat;
}
@ -1707,19 +1997,21 @@ u_32_t ports;
register u_short sport, dport;
register nat_t *nat;
register int nflags;
u_32_t srcip;
u_int hv;
sport = ports & 0xffff;
dport = ports >> 16;
flags &= IPN_TCPUDP;
srcip = src.s_addr;
hv = NAT_HASH_FN(src.s_addr, sport, ipf_nattable_sz);
hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == src.s_addr &&
nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
(((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
|| (p == nat->nat_p)) && (!flags ||
@ -1727,7 +2019,32 @@ u_32_t ports;
(nat->nat_oport == dport || nflags & FI_W_DPORT))))
return nat;
}
return NULL;
if (!nat_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
if (!(nflags & IPN_TCPUDP))
continue;
if (!(nflags & FI_WILDP))
continue;
if ((nat->nat_inip.s_addr != srcip) ||
(nat->nat_oip.s_addr != dst.s_addr))
continue;
if (((nat->nat_inport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_SPORT))) {
hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
nat_tabmove(nat, hv);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
return nat;
}
@ -1863,6 +2180,7 @@ fr_info_t *fin;
nat->nat_outport = sport;
nat->nat_flags &= ~(FI_W_DPORT|FI_W_SPORT);
nflags = nat->nat_flags;
nat_wilds--;
}
} else {
RWLOCK_EXIT(&ipf_nat);
@ -1943,16 +2261,16 @@ fr_info_t *fin;
CALC_SUMD(s1, s2, sumd);
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, sumd, 0);
fix_incksum(&ip->ip_sum, sumd);
else
fix_outcksum(&ip->ip_sum, sumd, 0);
fix_outcksum(&ip->ip_sum, sumd);
}
#if SOLARIS || defined(__sgi)
else {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
}
#endif
ip->ip_src = nat->nat_outip;
@ -1996,11 +2314,9 @@ fr_info_t *fin;
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(csump, nat->nat_sumd[1],
ip->ip_len);
fix_outcksum(csump, nat->nat_sumd[1]);
else
fix_incksum(csump, nat->nat_sumd[1],
ip->ip_len);
fix_incksum(csump, nat->nat_sumd[1]);
}
}
@ -2077,6 +2393,7 @@ fr_info_t *fin;
nat->nat_outport = dport;
nat->nat_flags &= ~(FI_W_SPORT|FI_W_DPORT);
nflags = nat->nat_flags;
nat_wilds--;
}
} else {
RWLOCK_EXIT(&ipf_nat);
@ -2154,9 +2471,9 @@ fr_info_t *fin;
*/
#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if (!(ip->ip_off & IP_OFFMASK) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
@ -2197,11 +2514,9 @@ fr_info_t *fin;
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(csump, nat->nat_sumd[0],
0);
fix_incksum(csump, nat->nat_sumd[0]);
else
fix_outcksum(csump, nat->nat_sumd[0],
0);
fix_outcksum(csump, nat->nat_sumd[0]);
}
}
ATOMIC_INCL(nat_stats.ns_mapped[0]);

View File

@ -82,7 +82,7 @@ typedef struct nat {
struct hostmap *nat_hm;
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_hstart[2];
struct nat **nat_phnext[2];
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
@ -142,6 +142,11 @@ typedef struct ipnat {
#define NAT_REDIRECT 0x02
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
#define NAT_MAPBLK 0x04
/* 0x100 reserved for FI_W_SPORT */
/* 0x200 reserved for FI_W_DPORT */
/* 0x400 reserved for FI_W_SADDR */
/* 0x800 reserved for FI_W_DADDR */
/* 0x1000 reserved for FI_W_NEWFR */
#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */
#define USABLE_PORTS (65536 - MAPBLK_MINPORT)
@ -294,7 +299,8 @@ extern int ip_natout __P((ip_t *, fr_info_t *));
extern int ip_natin __P((ip_t *, fr_info_t *));
extern void ip_natunload __P((void)), ip_natexpire __P((void));
extern void nat_log __P((struct nat *, u_int));
extern void fix_incksum __P((u_short *, u_32_t, int));
extern void fix_outcksum __P((u_short *, u_32_t, int));
extern void fix_incksum __P((u_short *, u_32_t));
extern void fix_outcksum __P((u_short *, u_32_t));
extern void fix_datacksum __P((u_short *, u_32_t));
#endif /* __IP_NAT_H__ */

View File

@ -171,8 +171,8 @@ nat_t *nat;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
struct in_addr swa, swb;
u_int a1, a2, a3, a4;
int off, dlen, slen;
int a1, a2, a3, a4;
u_short sp, dp;
fr_info_t fi;
tcp_seq seq;

View File

@ -106,6 +106,7 @@ static const char rcsid[] = "@(#)$FreeBSD$";
static ipstate_t **ips_table = NULL;
static ipstate_t *ips_list = NULL;
static int ips_num = 0;
static int ips_wild = 0;
static ips_stat_t ips_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern KRWLOCK_T ipf_state, ipf_mutex;
@ -123,6 +124,7 @@ static int fr_state_flush __P((int));
static ips_stat_t *fr_statetstats __P((void));
static void fr_delstate __P((ipstate_t *));
static int fr_state_remove __P((caddr_t));
static void fr_ipsmove __P((ipstate_t **, ipstate_t *, u_int));
int fr_stputent __P((caddr_t));
int fr_stgetent __P((caddr_t));
void fr_stinsert __P((ipstate_t *));
@ -135,7 +137,8 @@ u_long fr_tcpidletimeout = FIVE_DAYS,
fr_tcpclosewait = 2 * TCP_MSL,
fr_tcplastack = 2 * TCP_MSL,
fr_tcptimeout = 2 * TCP_MSL,
fr_tcpclosed = 1,
fr_tcpclosed = 120,
fr_tcphalfclosed = 2 * 2 * 3600, /* 2 hours */
fr_udptimeout = 240,
fr_icmptimeout = 120;
int fr_statemax = IPSTATE_MAX,
@ -240,9 +243,12 @@ caddr_t data;
for (sp = ips_list; sp; sp = sp->is_next)
if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
!bcmp(&sp->is_src, &st.is_src, sizeof(st.is_src)) &&
!bcmp(&sp->is_dst, &st.is_src, sizeof(st.is_dst)) &&
!bcmp(&sp->is_ps, &st.is_ps, sizeof(st.is_ps))) {
!bcmp((char *)&sp->is_src, (char *)&st.is_src,
sizeof(st.is_src)) &&
!bcmp((char *)&sp->is_dst, (char *)&st.is_src,
sizeof(st.is_dst)) &&
!bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
sizeof(st.is_ps))) {
WRITE_ENTER(&ipf_state);
#ifdef IPFILTER_LOG
ipstate_log(sp, ISL_REMOVE);
@ -590,8 +596,8 @@ u_int flags;
hv += tcp->th_dport;
hv += tcp->th_sport;
}
is->is_send = ntohl(tcp->th_seq) + ip->ip_len -
fin->fin_hlen - (tcp->th_off << 2) +
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
(tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
is->is_maxsend = is->is_send;
@ -660,6 +666,8 @@ u_int flags;
is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
is->is_flags |= FI_CMP << 4;
is->is_flags |= flags & (FI_WILDP|FI_WILDA);
if (flags & (FI_WILDP|FI_WILDA))
ips_wild++;
is->is_ifp[1 - out] = NULL;
is->is_ifp[out] = fin->fin_ifp;
#ifdef _KERNEL
@ -718,6 +726,7 @@ tcphdr_t *tcp;
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
MUTEX_ENTER(&is->is_lock);
if (fdata->td_end == 0) {
/*
* Must be a (outgoing) SYN-ACK in reply to a SYN.
@ -783,12 +792,11 @@ tcphdr_t *tcp;
/*
* Nearing end of connection, start timeout.
*/
MUTEX_ENTER(&is->is_lock);
/* source ? 0 : 1 -> !source */
fr_tcp_age(&is->is_age, is->is_state, fin, !source);
MUTEX_EXIT(&is->is_lock);
ret = 1;
}
MUTEX_EXIT(&is->is_lock);
return ret;
}
@ -892,6 +900,7 @@ tcphdr_t *tcp;
is->is_maxdend = is->is_dend + 1;
}
is->is_flags &= ~(FI_W_SPORT|FI_W_DPORT);
ips_wild--;
}
ret = -1;
@ -983,7 +992,7 @@ fr_info_t *fin;
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
if (((ip->ip_v != 4) && (ip->ip_hl != 5)) ||
if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
(fin->fin_plen < ICMPERR_MINPKTLEN))
return NULL;
ic = (struct icmp *)fin->fin_dp;
@ -1037,8 +1046,8 @@ fr_info_t *fin;
* the IP6EQ and IP6NEQ macros produce the wrong results because
* of the 'junk' in the unused part of the union
*/
bzero(&src, sizeof(src));
bzero(&dst, sizeof(dst));
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
if (oip->ip_p == IPPROTO_ICMP) {
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
@ -1158,6 +1167,38 @@ fr_info_t *fin;
return NULL;
}
static void fr_ipsmove(isp, is, hv)
ipstate_t **isp, *is;
u_int hv;
{
u_int hvm;
hvm = is->is_hv;
/*
* Remove the hash from the old location...
*/
if (is->is_hnext)
is->is_hnext->is_phnext = isp;
*isp = is->is_hnext;
if (ips_table[hvm] == NULL)
ips_stats.iss_inuse--;
/*
* ...and put the hash in the new one.
*/
hvm = hv % fr_statesize;
isp = &ips_table[hvm];
if (*isp)
(*isp)->is_phnext = &is->is_hnext;
else
ips_stats.iss_inuse++;
is->is_phnext = isp;
is->is_hnext = *isp;
*isp = is;
}
/*
* Check if a packet has a registered state.
*/
@ -1240,7 +1281,7 @@ fr_info_t *fin;
break;
case IPPROTO_TCP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
register u_short dport, sport;
register int i;
i = tcp->th_flags;
@ -1250,57 +1291,42 @@ fr_info_t *fin;
if ((i & TH_RST) &&
((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
break;
tryagain = 0;
retry_tcp:
hvm = hv % fr_statesize;
WRITE_ENTER(&ipf_state);
for (isp = &ips_table[hvm]; (is = *isp);
isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
if (fr_tcpstate(is, fin, ip, tcp))
break;
is = NULL;
break;
}
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
hv += dport;
hv += sport;
if (tryagain == 0) {
tryagain = 1;
goto retry_tcp;
}
break;
}
case IPPROTO_UDP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
dport = tcp->th_dport;
sport = tcp->th_sport;
tryagain = 0;
retry_udp:
hvm = hv % fr_statesize;
/*
* Nothing else to match on but ports. and IP#'s
*/
READ_ENTER(&ipf_state);
for (is = ips_table[hvm]; is; is = is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
is->is_age = fr_udptimeout;
break;
}
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
hv += dport;
hv += sport;
if (tryagain == 0) {
READ_ENTER(&ipf_state);
retry_tcpudp:
hvm = hv % fr_statesize;
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
if ((pr == IPPROTO_TCP)) {
if (!fr_tcpstate(is, fin, ip, tcp)) {
continue;
}
}
break;
}
if (is != NULL) {
if (tryagain &&
!(is->is_flags & (FI_WILDP|FI_WILDA))) {
hv += dport;
hv += sport;
fr_ipsmove(isp, is, hv);
MUTEX_DOWNGRADE(&ipf_state);
}
break;
}
RWLOCK_EXIT(&ipf_state);
if (!tryagain && ips_wild) {
hv -= dport;
hv -= sport;
tryagain = 1;
goto retry_udp;
WRITE_ENTER(&ipf_state);
goto retry_tcpudp;
}
break;
}
@ -1357,6 +1383,8 @@ ipstate_t *is;
{
frentry_t *fr;
if (is->is_flags & (FI_WILDP|FI_WILDA))
ips_wild--;
if (is->is_next)
is->is_next->is_pnext = is->is_pnext;
*is->is_pnext = is->is_next;
@ -1566,7 +1594,7 @@ int dir;
* SYN_RECEIVED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout; /* or fr_tcptimeout? */
*age = fr_tcpidletimeout;
}
break;
@ -1578,7 +1606,7 @@ int dir;
* ESTABLISHED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
} else if (flags & TH_ACK) {
/* an ACK, should we exclude other flags here? */
if (ostate == TCPS_FIN_WAIT_1) {
@ -1590,7 +1618,7 @@ int dir;
* a half-closed connection
*/
state[dir] = TCPS_CLOSE_WAIT;
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
} else if (ostate < TCPS_CLOSE_WAIT)
/*
* Still a fully established connection,
@ -1614,7 +1642,7 @@ int dir;
* closed already and we did not close our side yet;
* reset timeout
*/
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
}
break;
@ -1638,7 +1666,7 @@ int dir;
* other side is still active (ESTABLISHED/CLOSE_WAIT);
* continue with this half-closed connection
*/
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
break;
case TCPS_CLOSING: /* 7 */

View File

@ -174,6 +174,7 @@ extern u_long fr_tcpclosewait;
extern u_long fr_tcplastack;
extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_tcphalfclosed;
extern u_long fr_udptimeout;
extern u_long fr_icmptimeout;
extern int fr_state_lock;

View File

@ -12,6 +12,6 @@
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.4.9"
#define IPL_VERSION "IP Filter: v3.4.12"
#endif

View File

@ -65,6 +65,8 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
&fr_tcptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
&fr_tcpclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,