summaryrefslogtreecommitdiff
path: root/sys/net
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
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')
-rw-r--r--sys/net/pf.c66
-rw-r--r--sys/net/pf_norm.c13
-rw-r--r--sys/net/pfvar.h4
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;