summaryrefslogtreecommitdiff
path: root/sbin/pfctl/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/pfctl/parse.y')
-rw-r--r--sbin/pfctl/parse.y54
1 files changed, 41 insertions, 13 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 42eae280fad..6fae5cf5f3e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.586 2010/01/12 19:18:55 mcbride Exp $ */
+/* $OpenBSD: parse.y,v 1.587 2010/01/13 00:56:13 mcbride Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -2019,11 +2019,6 @@ pfrule : action dir logquick interface af proto fromto
}
if (r.rt && r.rt != PF_FASTROUTE) {
decide_address_family($8.route.host, &r.af);
- if ($8.route.host == NULL) {
- yyerror("no routing address with "
- "matching address family found.");
- YYERROR;
- }
if ((r.route.opts & PF_POOL_TYPEMASK) ==
PF_POOL_NONE && ($8.route.host->next != NULL ||
$8.route.host->addr.type == PF_ADDR_TABLE ||
@@ -3735,6 +3730,20 @@ route_host : STRING {
$$->tail = $$;
}
}
+ | STRING '/' STRING {
+ char *buf;
+
+ if (asprintf(&buf, "%s/%s", $1, $3) == -1)
+ err(1, "host: asprintf");
+ free($1);
+ if (($$ = host(buf)) == NULL) {
+ /* error. "any" is handled elsewhere */
+ free(buf);
+ yyerror("could not parse host specification");
+ YYERROR;
+ }
+ free(buf);
+ }
| '<' STRING '>' {
if (strlen($2) >= PF_TABLE_NAME_SIZE) {
yyerror("table name '%s' too long", $2);
@@ -3753,8 +3762,16 @@ route_host : STRING {
$$->next = NULL;
$$->tail = $$;
}
- | dynaddr {
+ | dynaddr '/' NUMBER {
+ struct node_host *n;
+
+ if ($3 < 0 || $3 > 128) {
+ yyerror("bit number too big");
+ YYERROR;
+ }
$$ = $1;
+ for (n = $1; n != NULL; n = n->next)
+ set_ipmask(n, $3);
}
| '(' STRING host ')' {
struct node_host *n;
@@ -4511,7 +4528,8 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r,
struct pf_rule_addr ra;
int i = 0;
- if (!rs || !rs->rdr) {
+
+ if (!rs || !rs->rdr || rs->rdr->host == NULL) {
rpool->addr.type = PF_ADDR_NONE;
return (0);
}
@@ -4525,9 +4543,11 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r,
}
}
- if (i == 0) /* no pool address */
- return (0);
- else if (i == 1) { /* only one address */
+ if (i == 0) { /* no pool address */
+ yyerror("af mismatch in %s spec",
+ allow_if ? "routing" : "translation");
+ return (1);
+ } else if (i == 1) { /* only one address */
for (h = rs->rdr->host; h != NULL; h = h->next)
if (!h->af || !r->af || r->af == h->af)
break;
@@ -4816,8 +4836,10 @@ expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces,
disallow_alias(src_host, "invalid use of interface "
"(%s) as the source address of a binat-to rule")) {
error++;
- } else if ((src_host->addr.type != PF_ADDR_ADDRMASK &&
- src_host->addr.type != PF_ADDR_DYNIFTL)) {
+ } else if ((r->src.addr.type != PF_ADDR_ADDRMASK &&
+ r->src.addr.type != PF_ADDR_DYNIFTL) ||
+ (r->nat.addr.type != PF_ADDR_ADDRMASK &&
+ r->nat.addr.type != PF_ADDR_DYNIFTL)) {
yyerror("binat-to requires a specified "
"source and redirect address");
error++;
@@ -4828,6 +4850,12 @@ expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces,
":0 in a binat-to rule");
error++;
}
+ if (PF_AZERO(&r->src.addr.v.a.mask, af) ||
+ PF_AZERO(&r->nat.addr.v.a.mask, af)) {
+ yyerror ("source and redir addresess must have "
+ "a matching network mask in binat-rule");
+ error++;
+ }
if (r->nat.addr.type == PF_ADDR_TABLE) {
yyerror ("tables cannot be used as the redirect "
"address of a binat-to rule");