aboutsummaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/ip_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_state.c')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 2e8b8f3f7e1b..a6d1773b5ba9 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -93,7 +93,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.66 2002/04/15 12:14:03 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.70 2002/04/27 16:06:15 darrenr Exp $";
#endif
#ifndef MIN
@@ -683,11 +683,18 @@ u_int flags;
hv += is->is_sport;
hv += is->is_dport;
}
- is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
- (off = (tcp->th_off << 2)) +
- ((tcp->th_flags & TH_SYN) ? 1 : 0) +
- ((tcp->th_flags & TH_FIN) ? 1 : 0);
- is->is_maxsend = is->is_send;
+ if ((flags & FI_IGNOREPKT) == 0) {
+ is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
+ (off = (tcp->th_off << 2)) +
+ ((tcp->th_flags & TH_SYN) ? 1 : 0) +
+ ((tcp->th_flags & TH_FIN) ? 1 : 0);
+ is->is_maxsend = is->is_send;
+
+ if ((tcp->th_flags & TH_SYN) &&
+ ((tcp->th_off << 2) >= (sizeof(*tcp) + 4)))
+ is->is_swscale = fr_tcpoptions(tcp);
+ }
+
is->is_maxdwin = 1;
is->is_maxswin = ntohs(tcp->th_win);
if (is->is_maxswin == 0)
@@ -696,10 +703,6 @@ u_int flags;
if ((tcp->th_flags & TH_OPENING) == TH_SYN)
is->is_fsm = 1;
- if ((tcp->th_flags & TH_SYN) &&
- ((tcp->th_off << 2) >= (sizeof(*tcp) + 4)))
- is->is_swscale = fr_tcpoptions(tcp);
-
/*
* If we're creating state for a starting connection, start the
* timer on it as we'll never see an error if it fails to
@@ -970,7 +973,7 @@ tcphdr_t *tcp;
}
}
MUTEX_EXIT(&is->is_lock);
- if ((ret == 0) && (tcp->th_flags != TH_SYN))
+ if ((ret == 0) && ((tcp->th_flags & TH_OPENING) != TH_SYN))
fin->fin_misc |= FM_BADSTATE;
return ret;
}
@@ -1224,6 +1227,10 @@ fr_info_t *fin;
*/
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
+ bzero((char *)&ofin, sizeof(ofin));
+ ofin.fin_ifp = fin->fin_ifp;
+ ofin.fin_out = !fin->fin_out;
+ ofin.fin_v = 4;
fr = NULL;
switch (oip->ip_p)
@@ -1258,12 +1265,8 @@ fr_info_t *fin;
savelen = oip->ip_len;
oip->ip_len = len;
- ofin.fin_v = 4;
fr_makefrip(ohlen, oip, &ofin);
oip->ip_len = savelen;
- ofin.fin_ifp = fin->fin_ifp;
- ofin.fin_out = !fin->fin_out;
- ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
@@ -1312,12 +1315,8 @@ fr_info_t *fin;
*/
savelen = oip->ip_len;
oip->ip_len = len;
- ofin.fin_v = 4;
fr_makefrip(ohlen, oip, &ofin);
oip->ip_len = savelen;
- ofin.fin_ifp = fin->fin_ifp;
- ofin.fin_out = !fin->fin_out;
- ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
/*
@@ -1847,7 +1846,7 @@ int dir, fsm;
break;
case TCPS_SYN_SENT: /* 2 */
- if (flags == TH_SYN) {
+ if ((flags & ~(TH_ECN|TH_CWR)) == TH_SYN) {
/*
* A retransmitted SYN packet. We do not reset the
* timeout here to fr_tcptimeout because a connection
@@ -1893,6 +1892,12 @@ int dir, fsm;
*/
state[dir] = TCPS_ESTABLISHED;
newage = fr_tcpidletimeout;
+ } else if ((flags & ~(TH_ECN|TH_CWR)) == TH_OPENING) {
+ /*
+ * We see an SA from 'dir' which is already in
+ * SYN_RECEIVED state.
+ */
+ newage = fr_tcptimeout;
} else if (flags & TH_FIN) {
/*
* We see an F from 'dir' which is in SYN_RECEIVED
@@ -1987,6 +1992,8 @@ int dir, fsm;
* timeout
*/
newage = fr_tcplastack;
+ else
+ newage = *age;
}
/*
* We cannot detect when we go out of LAST_ACK state to CLOSED
@@ -2094,6 +2101,15 @@ fr_info_t *fin;
if (fin->fin_plen < sizeof(*oip))
return NULL;
+ if ((oip->ip6_nxt != IPPROTO_TCP) && (oip->ip6_nxt != IPPROTO_UDP) &&
+ (oip->ip6_nxt != IPPROTO_ICMPV6))
+ return NULL;
+
+ bzero((char *)&ofin, sizeof(ofin));
+ ofin.fin_out = !fin->fin_out;
+ ofin.fin_ifp = fin->fin_ifp;
+ ofin.fin_v = 6;
+
if (oip->ip6_nxt == IPPROTO_ICMPV6) {
oic = (struct icmp6_hdr *)(oip + 1);
/*
@@ -2119,12 +2135,8 @@ fr_info_t *fin;
hv %= fr_statesize;
oip->ip6_plen = ntohs(oip->ip6_plen);
- ofin.fin_v = 6;
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
oip->ip6_plen = htons(oip->ip6_plen);
- ofin.fin_ifp = fin->fin_ifp;
- ofin.fin_out = !fin->fin_out;
- ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
@@ -2149,10 +2161,8 @@ fr_info_t *fin;
RWLOCK_EXIT(&ipf_state);
return NULL;
- };
+ }
- if ((oip->ip6_nxt != IPPROTO_TCP) && (oip->ip6_nxt != IPPROTO_UDP))
- return NULL;
tcp = (tcphdr_t *)(oip + 1);
dport = tcp->th_dport;
sport = tcp->th_sport;
@@ -2183,12 +2193,8 @@ fr_info_t *fin;
*/
savelen = oip->ip6_plen;
oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
- ofin.fin_v = 6;
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
oip->ip6_plen = savelen;
- ofin.fin_ifp = fin->fin_ifp;
- ofin.fin_out = !fin->fin_out;
- ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
/*