summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2002-03-27 18:16:24 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2002-03-27 18:16:24 +0000
commitf5b5f9a9d79ac00b898f03754f8633d88a7da65e (patch)
tree7b2124304dd57c38560864fefe926e31ef5f4fde /sys/net/pf.c
parent0383b042ec78518838e9c7faf713ed09c8414734 (diff)
implement a "no-route" keyword.
usage semantics are analogous w/ "any", meaning is "any ip address for which there is no route in the current routing table", could be used in both from and to. typical usage would be (assuming symmetrical routing): block in from no-route to any also doc "any" in the pf.conf.5, include in regress, etc. tested by me on i386 and sparc. dhartmei@ and frantzen@ ok
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index e98c6a10e39..956d70a903b 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.197 2002/03/26 20:24:51 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.198 2002/03/27 18:16:21 mickey Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -2983,13 +2983,19 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF];
else if (r->proto && r->proto != IPPROTO_TCP)
r = r->skip[PF_SKIP_PROTO];
- else if (!PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
+ else if (r->src.noroute && pf_routable(saddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->src.noroute &&
+ !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
&r->src.addr, &r->src.mask, saddr, af))
r = r->skip[PF_SKIP_SRC_ADDR];
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT];
- else if (!PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
+ else if (r->dst.noroute && pf_routable(daddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->dst.noroute &&
+ !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
&r->dst.addr, &r->dst.mask, daddr, af))
r = r->skip[PF_SKIP_DST_ADDR];
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
@@ -3209,14 +3215,20 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF];
else if (r->proto && r->proto != IPPROTO_UDP)
r = r->skip[PF_SKIP_PROTO];
- else if (!PF_AZERO(&r->src.mask, af) &&
+ else if (r->src.noroute && pf_routable(saddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->src.noroute &&
+ !PF_AZERO(&r->src.mask, af) &&
!PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask,
saddr, af))
r = r->skip[PF_SKIP_SRC_ADDR];
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], uh->uh_sport))
r = r->skip[PF_SKIP_SRC_PORT];
- else if (!PF_AZERO(&r->dst.mask, af) &&
+ else if (r->dst.noroute && pf_routable(daddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->dst.noroute &&
+ !PF_AZERO(&r->dst.mask, af) &&
!PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask,
daddr, af))
r = r->skip[PF_SKIP_DST_ADDR];
@@ -3479,10 +3491,16 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF];
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO];
- else if (!PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
+ else if (r->src.noroute && pf_routable(saddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->src.noroute &&
+ !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
&r->src.addr, &r->src.mask, saddr, af))
r = r->skip[PF_SKIP_SRC_ADDR];
- else if (!PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
+ else if (r->dst.noroute && pf_routable(daddr, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->dst.noroute &&
+ !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
&r->dst.addr, &r->dst.mask, daddr, af))
r = r->skip[PF_SKIP_DST_ADDR];
else if (r->ifp != NULL && r->ifp != ifp)
@@ -3682,10 +3700,16 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF];
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO];
- else if (!PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
+ else if (r->src.noroute && pf_routable(pd->src, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->src.noroute &&
+ !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not,
&r->src.addr, &r->src.mask, pd->src, af))
r = r->skip[PF_SKIP_SRC_ADDR];
- else if (!PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
+ else if (r->dst.noroute && pf_routable(pd->dst, af))
+ r = TAILQ_NEXT(r, entries);
+ else if (!r->src.noroute &&
+ !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
&r->dst.addr, &r->dst.mask, pd->dst, af))
r = r->skip[PF_SKIP_DST_ADDR];
else {
@@ -4712,6 +4736,30 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
return (p);
}
+int
+pf_routable(addr, af)
+ struct pf_addr *addr;
+ int af;
+{
+ struct sockaddr_in *dst;
+ struct route ro;
+ int ret = 0;
+
+ bzero(&ro, sizeof(ro));
+ dst = satosin(&ro.ro_dst);
+ dst->sin_family = af;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = addr->v4;
+ rtalloc_noclone(&ro, NO_CLONING);
+
+ if (ro.ro_rt != NULL) {
+ ret = 1;
+ RTFREE(ro.ro_rt);
+ }
+
+ return (ret);
+}
+
#ifdef INET
void
pf_route(struct mbuf **m, struct pf_rule *r, int dir)