diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2008-06-10 04:24:18 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2008-06-10 04:24:18 +0000 |
commit | 2e510c4c4b71f98c2f682f773200231536aa7640 (patch) | |
tree | 14cc0a1a938985e0fefa25a542f24bd3233aca4d /sys/net | |
parent | edd2e3af730bd65c913477c070e35fd7532b3366 (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.c | 4 | ||||
-rw-r--r-- | sys/net/pf.c | 69 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 3 | ||||
-rw-r--r-- | sys/net/pfvar.h | 7 |
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, - ©back) == 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, + ©back) == 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 |