summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/pfctl/parse.y39
-rw-r--r--sbin/pfctl/pf_print_state.c18
-rw-r--r--sys/net/pf.c40
-rw-r--r--sys/net/pfvar.h10
4 files changed, 101 insertions, 6 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index a491f3ead7d..0f14cf3b74c 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.519 2007/06/21 19:30:03 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.520 2007/08/30 09:28:49 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -1244,6 +1244,10 @@ table_opt : STRING {
switch (n->addr.type) {
case PF_ADDR_ADDRMASK:
continue; /* ok */
+ case PF_ADDR_RANGE:
+ yyerror("address ranges are not "
+ "permitted inside tables");
+ break;
case PF_ADDR_DYNIFTL:
yyerror("dynamic addresses are not "
"permitted inside tables");
@@ -2495,6 +2499,39 @@ host : STRING {
free($1);
}
+ | STRING '-' STRING {
+ struct node_host *b, *e;
+
+ if ((b = host($1)) == NULL || (e = host($3)) == NULL) {
+ free($1);
+ free($3);
+ yyerror("could not parse host specification");
+ YYERROR;
+ }
+ if (b->af != e->af ||
+ b->addr.type != PF_ADDR_ADDRMASK ||
+ e->addr.type != PF_ADDR_ADDRMASK ||
+ unmask(&b->addr.v.a.mask, b->af) !=
+ (b->af == AF_INET ? 32 : 128) ||
+ unmask(&e->addr.v.a.mask, e->af) !=
+ (e->af == AF_INET ? 32 : 128) ||
+ b->next != NULL || b->not ||
+ e->next != NULL || e->not) {
+ free(b);
+ free(e);
+ free($1);
+ free($3);
+ yyerror("invalid address range");
+ YYERROR;
+ }
+ memcpy(&b->addr.v.a.mask, &e->addr.v.a.addr,
+ sizeof(b->addr.v.a.mask));
+ b->addr.type = PF_ADDR_RANGE;
+ $$ = b;
+ free(e);
+ free($1);
+ free($3);
+ }
| STRING '/' number {
char *buf;
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
index e4830a1268f..8489c38c73a 100644
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_print_state.c,v 1.45 2007/05/31 04:13:37 mcbride Exp $ */
+/* $OpenBSD: pf_print_state.c,v 1.46 2007/08/30 09:28:49 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -79,6 +79,19 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
else
printf("<%s>", addr->v.tblname);
return;
+ case PF_ADDR_RANGE: {
+ char buf[48];
+
+ if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
+ printf("?");
+ else
+ printf("%s", buf);
+ if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
+ printf(" - ?");
+ else
+ printf(" - %s", buf);
+ break;
+ }
case PF_ADDR_ADDRMASK:
if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))
@@ -108,7 +121,8 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
}
/* mask if not _both_ address and mask are zero */
- if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
+ if (addr->type != PF_ADDR_RANGE &&
+ !(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))) {
int bits = unmask(&addr->v.a.mask, af);
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 7518038a2e8..c72f538d2bd 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.554 2007/08/28 16:09:12 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.555 2007/08/30 09:28:48 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1790,6 +1790,44 @@ pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
}
}
+/*
+ * Return 1 if b <= a <= e, otherwise return 0.
+ */
+int
+pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
+ struct pf_addr *a, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if ((a->addr32[0] < b->addr32[0]) ||
+ (a->addr32[0] > e->addr32[0]))
+ return (0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ int i;
+
+ /* check a >= b */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] > b->addr32[i])
+ break;
+ else if (a->addr32[i] < b->addr32[i])
+ return (0);
+ /* check a <= e */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] < e->addr32[i])
+ break;
+ else if (a->addr32[i] > e->addr32[i])
+ return (0);
+ break;
+ }
+#endif /* INET6 */
+ }
+ return (1);
+}
+
int
pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
{
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 1cea3385e15..db7175c0846 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.254 2007/07/13 09:17:48 markus Exp $ */
+/* $OpenBSD: pfvar.h,v 1.255 2007/08/30 09:28:48 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -112,7 +112,8 @@ enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
- PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED };
+ PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED,
+ PF_ADDR_RANGE };
#define PF_POOL_TYPEMASK 0x0f
#define PF_POOL_STICKYADDR 0x20
#define PF_WSCALE_FLAG 0x80
@@ -329,6 +330,9 @@ struct pfi_dynaddr {
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
((aw)->type == PF_ADDR_DYNIFTL && \
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
+ ((aw)->type == PF_ADDR_RANGE && \
+ !pf_match_addr_range(&(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af))) || \
((aw)->type == PF_ADDR_ADDRMASK && \
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
!PF_MATCHA(0, &(aw)->v.a.addr, \
@@ -1612,6 +1616,8 @@ int pflog_packet(struct pfi_kif *, struct mbuf *, sa_family_t, u_int8_t,
struct pf_pdesc *);
int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
struct pf_addr *, sa_family_t);
+int pf_match_addr_range(struct pf_addr *, struct pf_addr *,
+ struct pf_addr *, sa_family_t);
int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);