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 | |
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')
-rw-r--r-- | sys/net/pf.c | 66 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 13 | ||||
-rw-r--r-- | sys/net/pfvar.h | 4 |
3 files changed, 68 insertions, 15 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) diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index 38de048815f..0436f6262c5 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.20 2002/02/26 07:25:33 dhartmei Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.21 2002/03/27 18:16:21 mickey Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -587,16 +587,19 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, 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) && + 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 (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, - &r->dst.addr, &r->dst.mask, + else if (r->dst.noroute && pf_routable(pd->dst, 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, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 051c40d2155..0c32f00293c 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.65 2002/03/25 22:03:01 frantzen Exp $ */ +/* $OpenBSD: pfvar.h,v 1.66 2002/03/27 18:16:21 mickey Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -187,6 +187,7 @@ struct pf_rule_addr { u_int16_t port[2]; u_int8_t not; u_int8_t port_op; + u_int8_t noroute; }; struct pf_rule { @@ -600,6 +601,7 @@ int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t); void pf_normalize_init(void); int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *); void pf_purge_expired_fragments(void); +int pf_routable(struct pf_addr *addr, int af); extern struct pf_rulequeue *pf_rules_active; extern struct pf_status pf_status; |