summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Wooding <kjell@cvs.openbsd.org>2002-06-08 09:41:53 +0000
committerKjell Wooding <kjell@cvs.openbsd.org>2002-06-08 09:41:53 +0000
commit55669dcabc31d563cc17941f50e1ab574003341a (patch)
tree450347cdf3d83c39b6bd5904ac0cb359628ed6ff
parent5a29a6ee5a05d9701e6985ef51b417bfe76050d2 (diff)
add list expansion to src/dest in NAT rules. i.e.
nat on fxp0 from { 10.0.0.0/24, 10.0.1.0/24 } to \ { 172.6.1.1, 172.14.1.2/32 } -> fxp0 ok theo, dhartmei@
-rw-r--r--sbin/pfctl/parse.y55
1 files changed, 43 insertions, 12 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 9e64ab1b925..c6c07a114d3 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.83 2002/06/08 08:44:09 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.84 2002/06/08 09:41:52 kjell Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -124,6 +124,7 @@ struct peer {
int rule_consistent(struct pf_rule *);
int yyparse(void);
void ipmask(struct pf_addr *, u_int8_t);
+void expand_nat(struct pf_nat *, struct node_host *, struct node_host *);
void expand_label_addr(const char *, char *, u_int8_t, struct node_host *);
void expand_label_port(const char *, char *, u_int8_t, struct node_port *);
void expand_label_proto(const char *, char *, u_int8_t);
@@ -1178,10 +1179,6 @@ natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
YYERROR;
}
if ($7 != NULL) {
- if ($7->next) {
- yyerror("multiple nat ip addresses");
- YYERROR;
- }
if ($7->addr.addr_dyn != NULL) {
if (!nat.af) {
yyerror("address family (inet/"
@@ -1200,13 +1197,8 @@ natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
memcpy(&nat.smask, &$7->mask,
sizeof(nat.smask));
nat.snot = $7->not;
- free($7);
}
if ($9 != NULL) {
- if ($9->next) {
- yyerror("multiple nat ip addresses");
- YYERROR;
- }
if ($9->addr.addr_dyn != NULL) {
if (!nat.af) {
yyerror("address family (inet/"
@@ -1225,7 +1217,6 @@ natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
memcpy(&nat.dmask, &$9->mask,
sizeof(nat.dmask));
nat.dnot = $9->not;
- free($9);
}
if (nat.no) {
@@ -1257,7 +1248,7 @@ natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
free($10);
}
- pfctl_add_nat(pf, &nat);
+ expand_nat(&nat, $7, $9);
}
;
@@ -1952,6 +1943,46 @@ expand_rule(struct pf_rule *r,
yyerror("rule expands to no valid combination");
}
+void
+expand_nat(struct pf_nat *n, struct node_host *src_hosts,
+ struct node_host *dst_hosts)
+{
+ int af = n->af, added = 0;
+
+ CHECK_ROOT(struct node_host, src_hosts)
+; CHECK_ROOT(struct node_host, dst_hosts);
+
+ LOOP_THROUGH(struct node_host, src_host, src_hosts,
+ LOOP_THROUGH(struct node_host, dst_host, dst_hosts,
+
+ n->af = af;
+ if ((n->af && src_host->af && n->af != src_host->af) ||
+ (n->af && dst_host->af && n->af != dst_host->af) ||
+ (src_host->af && dst_host->af &&
+ src_host->af != dst_host->af))
+ continue;
+ if (!n->af && src_host->af)
+ n->af = src_host->af;
+ else if (!n->af && dst_host->af)
+ n->af = dst_host->af;
+
+ n->saddr = src_host->addr;
+ n->smask = src_host->mask;
+ n->daddr = dst_host->addr;
+ n->dmask = dst_host->mask;
+
+ pfctl_add_nat(pf, n);
+ added++;
+ ));
+
+ FREE_LIST(struct node_host, src_hosts);
+ FREE_LIST(struct node_host, dst_hosts);
+
+ if (!added)
+ yyerror("nat rule expands to no valid AF combination");
+}
+
+
#undef FREE_LIST
#undef CHECK_ROOT
#undef LOOP_THROUGH