diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-03-25 23:33:14 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-03-25 23:33:14 +0000 |
commit | 6e6a295279b77b960cd441b14d3c2316a7d3aa0d (patch) | |
tree | b9cfb0fbddd2d5124dbfbc4c2b8e3f4c13f82dd4 /sys/net | |
parent | 49bd9ea3b12e5eddf3a1c7f631eda894724162c5 (diff) |
Ignore 'keep state' for ICMP errors whose inner headers mismatch state
but are passed by rules. Found by Henning Brauer.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pf.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index bfaad4e126c..0ada5f5b391 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.195 2002/03/25 22:03:01 frantzen Exp $ */ +/* $OpenBSD: pf.c,v 1.196 2002/03/25 23:33:13 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -3344,6 +3344,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, u_short reason; u_int16_t icmpid, af = pd->af; u_int8_t icmptype, icmpcode; + int state_icmp = 0; #ifdef INET6 int rewrite = 0; #endif /* INET6 */ @@ -3356,6 +3357,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, icmptype = pd->hdr.icmp->icmp_type; icmpcode = pd->hdr.icmp->icmp_code; icmpid = pd->hdr.icmp->icmp_id; + + if (icmptype == ICMP_UNREACH || + icmptype == ICMP_SOURCEQUENCH || + icmptype == ICMP_REDIRECT || + icmptype == ICMP_TIMXCEED || + icmptype == ICMP_PARAMPROB) + state_icmp++; break; #endif /* INET */ #ifdef INET6 @@ -3363,6 +3371,12 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, icmptype = pd->hdr.icmp6->icmp6_type; icmpcode = pd->hdr.icmp6->icmp6_code; icmpid = pd->hdr.icmp6->icmp6_id; + + if (icmptype == ICMP6_DST_UNREACH || + icmptype == ICMP6_PACKET_TOO_BIG || + icmptype == ICMP6_TIME_EXCEEDED || + icmptype == ICMP6_PARAM_PROB) + state_icmp++; break; #endif /* INET6 */ } @@ -3502,8 +3516,8 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, return (PF_DROP); } - if ((*rm != NULL && (*rm)->keep_state) || nat != NULL || - rdr != NULL || binat != NULL) { + if (!state_icmp && ((*rm != NULL && (*rm)->keep_state) || + nat != NULL || rdr != NULL || binat != NULL)) { /* create new state */ struct pf_state *s; |