diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-03-27 18:16:24 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-03-27 18:16:24 +0000 |
commit | f5b5f9a9d79ac00b898f03754f8633d88a7da65e (patch) | |
tree | 7b2124304dd57c38560864fefe926e31ef5f4fde /sys/net/pf.c | |
parent | 0383b042ec78518838e9c7faf713ed09c8414734 (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.c | 66 |
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) |