summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2008-06-10 04:24:18 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2008-06-10 04:24:18 +0000
commit2e510c4c4b71f98c2f682f773200231536aa7640 (patch)
tree14cc0a1a938985e0fefa25a542f24bd3233aca4d /sys/net
parentedd2e3af730bd65c913477c070e35fd7532b3366 (diff)
implement a sloppy tcpstate tracker which does not look at sequence
numbers at all. scary consequences; only tobe used in very specific situations where you don't see all packets of a connection, e. g. asymmetric routing. ok ryan reyk theo
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_pfsync.c4
-rw-r--r--sys/net/pf.c69
-rw-r--r--sys/net/pf_ioctl.c3
-rw-r--r--sys/net/pfvar.h7
4 files changed, 74 insertions, 9 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index 705cb16549f..af4f0f8bb3c 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.93 2008/05/29 01:00:53 mcbride Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.94 2008/06/10 04:24:17 henning Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -344,6 +344,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
st->log = sp->log;
st->timeout = sp->timeout;
st->allow_opts = sp->allow_opts;
+ st->sloppy = sp->sloppy;
bcopy(sp->id, &st->id, sizeof(st->id));
st->creatorid = sp->creatorid;
@@ -1262,6 +1263,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
sp->direction = st->direction;
sp->log = st->log;
sp->allow_opts = st->allow_opts;
+ sp->sloppy = st->sloppy;
sp->timeout = st->timeout;
if (flags & PFSYNC_FLAG_STALE)
diff --git a/sys/net/pf.c b/sys/net/pf.c
index ad18ee0e632..daebc33c46d 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.582 2008/06/09 07:07:16 djm Exp $ */
+/* $OpenBSD: pf.c,v 1.583 2008/06/10 04:24:17 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -183,10 +183,13 @@ int pf_test_fragment(struct pf_rule **, int,
struct pfi_kif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_rule **,
struct pf_ruleset **);
-int pf_tcp_seqtrack_full(struct pf_state_peer *,
+int pf_tcp_track_full(struct pf_state_peer *,
struct pf_state_peer *, struct pf_state **,
struct pfi_kif *, struct mbuf *, int,
struct pf_pdesc *, u_short *, int *);
+int pf_tcp_track_sloppy(struct pf_state_peer *,
+ struct pf_state_peer *, struct pf_state **,
+ struct pf_pdesc *, u_short *);
int pf_test_state_tcp(struct pf_state **, int,
struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, u_short *);
@@ -3403,6 +3406,8 @@ cleanup:
s->anchor.ptr = a;
STATE_INC_COUNTERS(s);
s->allow_opts = r->allow_opts;
+ if (r->rule_flag & PFRULE_STATESLOPPY)
+ s->sloppy = 1;
s->log = r->log & PF_LOG_ALL;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
@@ -3648,7 +3653,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
}
int
-pf_tcp_seqtrack_full(struct pf_state_peer *src, struct pf_state_peer *dst,
+pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off,
struct pf_pdesc *pd, u_short *reason, int *copyback)
{
@@ -3976,6 +3981,53 @@ pf_tcp_seqtrack_full(struct pf_state_peer *src, struct pf_state_peer *dst,
}
int
+pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst,
+ struct pf_state **state, struct pf_pdesc *pd, u_short *reason)
+{
+ struct tcphdr *th = pd->hdr.tcp;
+
+ if (th->th_flags & TH_SYN)
+ if (src->state < TCPS_SYN_SENT)
+ src->state = TCPS_SYN_SENT;
+ if (th->th_flags & TH_FIN)
+ if (src->state < TCPS_CLOSING)
+ src->state = TCPS_CLOSING;
+ if (th->th_flags & TH_ACK) {
+ if (dst->state == TCPS_SYN_SENT) {
+ dst->state = TCPS_ESTABLISHED;
+ if (src->state == TCPS_ESTABLISHED &&
+ (*state)->src_node != NULL &&
+ pf_src_connlimit(state)) {
+ REASON_SET(reason, PFRES_SRCLIMIT);
+ return (PF_DROP);
+ }
+ } else if (dst->state == TCPS_CLOSING)
+ dst->state = TCPS_FIN_WAIT_2;
+ }
+ if (th->th_flags & TH_RST)
+ src->state = dst->state = TCPS_TIME_WAIT;
+
+ /* update expire time */
+ (*state)->expire = time_second;
+ if (src->state >= TCPS_FIN_WAIT_2 &&
+ dst->state >= TCPS_FIN_WAIT_2)
+ (*state)->timeout = PFTM_TCP_CLOSED;
+ else if (src->state >= TCPS_CLOSING &&
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_FIN_WAIT;
+ else if (src->state < TCPS_ESTABLISHED ||
+ dst->state < TCPS_ESTABLISHED)
+ (*state)->timeout = PFTM_TCP_OPENING;
+ else if (src->state >= TCPS_CLOSING ||
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_CLOSING;
+ else
+ (*state)->timeout = PFTM_TCP_ESTABLISHED;
+
+ return (PF_PASS);
+}
+
+int
pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
u_short *reason)
@@ -4110,9 +4162,14 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
return (PF_DROP);
}
- if (pf_tcp_seqtrack_full(src, dst, state, kif, m, off, pd, reason,
- &copyback) == PF_DROP)
- return (PF_DROP);
+ if ((*state)->sloppy) {
+ if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP)
+ return (PF_DROP);
+ } else {
+ if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason,
+ &copyback) == PF_DROP)
+ return (PF_DROP);
+ }
/* translate source/destination address, if necessary */
if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index ff1dc003a83..0712e075bf9 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.200 2008/05/30 14:22:48 henning Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.201 2008/06/10 04:24:17 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -882,6 +882,7 @@ pf_state_export(struct pfsync_state *sp, struct pf_state *s)
sp->expire = pf_state_expires(s);
sp->log = s->log;
sp->allow_opts = s->allow_opts;
+ sp->sloppy = s->sloppy;
sp->timeout = s->timeout;
if (s->src_node)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 8daa0b0918e..b164f7fb38f 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.270 2008/05/30 14:22:48 henning Exp $ */
+/* $OpenBSD: pfvar.h,v 1.271 2008/06/10 04:24:17 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -626,6 +626,7 @@ struct pf_rule {
/* rule flags again */
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
+#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
#define PFSTATE_HIWAT 10000 /* default state table size */
#define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */
@@ -761,6 +762,8 @@ struct pf_state {
u_int8_t allow_opts;
u_int8_t timeout;
u_int8_t sync_flags;
+ u_int8_t sloppy; /* fold into flag w allow_opts*/
+ u_int8_t pad2[3];
#define PFSTATE_NOSYNC 0x01
#define PFSTATE_FROMSYNC 0x02
#define PFSTATE_STALE 0x04
@@ -818,6 +821,8 @@ struct pfsync_state {
u_int8_t timeout;
u_int8_t sync_flags;
u_int8_t updates;
+ u_int8_t sloppy; /* fold into flag with allow_opts */
+ u_int8_t pad[3];
} __packed;
#define PFSYNC_FLAG_COMPRESS 0x01