summaryrefslogtreecommitdiff
path: root/sbin/pfctl
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-06-10 19:31:45 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-06-10 19:31:45 +0000
commit5bc3e3e63232c4932003f2dbcebffea80240fe91 (patch)
tree53bf13c9acd1856280cbd7c6abf20efbcc235848 /sbin/pfctl
parent9549035574ab92df691d9094064508bdf8bea0e3 (diff)
Allow ports to be specified in nat rules, useful later on for individual
proxy port ranges.
Diffstat (limited to 'sbin/pfctl')
-rw-r--r--sbin/pfctl/parse.y95
-rw-r--r--sbin/pfctl/pfctl_parser.c112
2 files changed, 87 insertions, 120 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 3bd7b4a2264..d40a4c3479e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.92 2002/06/10 16:51:37 dhartmei Exp $ */
+/* $OpenBSD: parse.y,v 1.93 2002/06/10 19:31:44 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -126,7 +126,8 @@ int yyparse(void);
void ipmask(struct pf_addr *, u_int8_t);
void expand_rdr(struct pf_rdr *, struct node_if *, struct node_host *,
struct node_host *);
-void expand_nat(struct pf_nat *, struct node_host *, struct node_host *);
+void expand_nat(struct pf_nat *, struct node_host *, struct node_port *,
+ struct node_host *, struct node_port *);
void expand_label_addr(const char *, char *, u_int8_t, struct node_host *);
void expand_label_port(const char *, char *, struct node_port *);
void expand_label_proto(const char *, char *, u_int8_t);
@@ -1168,7 +1169,7 @@ redirection : /* empty */ { $$ = NULL; }
}
;
-natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
+natrule : no NAT interface af proto fromto redirection
{
struct pf_nat nat;
@@ -1190,81 +1191,37 @@ natrule : no NAT interface af proto FROM ipspec TO ipspec redirection
nat.proto = $5->proto;
free($5);
}
- if ($7 != NULL && $9 != NULL && $7->af != $9->af) {
- yyerror("nat ip versions must match");
- YYERROR;
- }
- if ($7 != NULL) {
- if ($7->addr.addr_dyn != NULL) {
- if (!nat.af) {
- yyerror("address family (inet/"
- "inet6) undefined");
- YYERROR;
- }
- $7->af = nat.af;
- }
- if (nat.af && $7->af != nat.af) {
- yyerror("nat ip versions must match");
- YYERROR;
- }
- nat.af = $7->af;
- memcpy(&nat.src.addr, &$7->addr,
- sizeof(nat.src.addr));
- memcpy(&nat.src.mask, &$7->mask,
- sizeof(nat.src.mask));
- nat.src.not = $7->not;
- }
- if ($9 != NULL) {
- if ($9->addr.addr_dyn != NULL) {
- if (!nat.af) {
- yyerror("address family (inet/"
- "inet6) undefined");
- YYERROR;
- }
- $9->af = nat.af;
- }
- if (nat.af && $9->af != nat.af) {
- yyerror("nat ip versions must match");
- YYERROR;
- }
- nat.af = $9->af;
- memcpy(&nat.dst.addr, &$9->addr,
- sizeof(nat.dst.addr));
- memcpy(&nat.dst.mask, &$9->mask,
- sizeof(nat.dst.mask));
- nat.dst.not = $9->not;
- }
-
if (nat.no) {
- if ($10 != NULL) {
+ if ($7 != NULL) {
yyerror("'no nat' rule does not need '->'");
YYERROR;
}
} else {
- if ($10 == NULL || $10->address == NULL) {
+ if ($7 == NULL || $7->address == NULL) {
yyerror("'nat' rule requires '-> address'");
YYERROR;
}
- if ($10->address->addr.addr_dyn != NULL) {
+ if ($7->address->addr.addr_dyn != NULL) {
if (!nat.af) {
yyerror("address family (inet/"
"inet6) undefined");
YYERROR;
}
- $10->address->af = nat.af;
+ $7->address->af = nat.af;
}
- if (nat.af && $10->address->af != nat.af) {
+ if (nat.af && $7->address->af != nat.af) {
yyerror("nat ip versions must match");
YYERROR;
}
- nat.af = $10->address->af;
- memcpy(&nat.raddr, &$10->address->addr,
+ nat.af = $7->address->af;
+ memcpy(&nat.raddr, &$7->address->addr,
sizeof(nat.raddr));
- free($10->address);
- free($10);
+ free($7->address);
+ free($7);
}
- expand_nat(&nat, $7, $9);
+ expand_nat(&nat, $6.src.host, $6.src.port,
+ $6.dst.host, $6.dst.port);
}
;
@@ -1907,15 +1864,20 @@ expand_rule(struct pf_rule *r,
void
expand_nat(struct pf_nat *n, struct node_host *src_hosts,
- struct node_host *dst_hosts)
+ struct node_port *src_ports, struct node_host *dst_hosts,
+ struct node_port *dst_ports)
{
int af = n->af, added = 0;
CHECK_ROOT(struct node_host, src_hosts);
+ CHECK_ROOT(struct node_port, src_ports);
CHECK_ROOT(struct node_host, dst_hosts);
+ CHECK_ROOT(struct node_port, dst_ports);
LOOP_THROUGH(struct node_host, src_host, src_hosts,
+ LOOP_THROUGH(struct node_port, src_port, src_ports,
LOOP_THROUGH(struct node_host, dst_host, dst_hosts,
+ LOOP_THROUGH(struct node_port, dst_port, dst_ports,
n->af = af;
if ((n->af && src_host->af && n->af != src_host->af) ||
@@ -1930,15 +1892,28 @@ expand_nat(struct pf_nat *n, struct node_host *src_hosts,
n->src.addr = src_host->addr;
n->src.mask = src_host->mask;
+ n->src.noroute = src_host->noroute;
+ n->src.not = src_host->not;
+ n->src.port[0] = src_port->port[0];
+ n->src.port[1] = src_port->port[1];
+ n->src.port_op = src_port->op;
n->dst.addr = dst_host->addr;
n->dst.mask = dst_host->mask;
+ n->dst.noroute = dst_host->noroute;
+ n->dst.not = dst_host->not;
+ n->dst.port[0] = dst_port->port[0];
+ n->dst.port[1] = dst_port->port[1];
+ n->dst.port_op = dst_port->op;
pfctl_add_nat(pf, n);
added++;
- ));
+
+ ))));
FREE_LIST(struct node_host, src_hosts);
+ FREE_LIST(struct node_port, src_ports);
FREE_LIST(struct node_host, dst_hosts);
+ FREE_LIST(struct node_port, dst_ports);
if (!added)
yyerror("nat rule expands to no valid combinations");
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 4b07d78d39e..f3c0b8974fd 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.84 2002/06/09 20:20:58 dhartmei Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.85 2002/06/10 19:31:44 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -58,6 +58,8 @@ void print_port (u_int8_t, u_int16_t, u_int16_t, char *);
void print_uid (u_int8_t, uid_t, uid_t, const char *);
void print_gid (u_int8_t, gid_t, gid_t, const char *);
void print_flags (u_int8_t);
+void print_fromto(struct pf_rule_addr *, struct pf_rule_addr *,
+ u_int8_t, u_int8_t);
char *tcpflags = "FSRPAUEW";
@@ -347,6 +349,53 @@ print_flags(u_int8_t f)
}
void
+print_fromto(struct pf_rule_addr *src, struct pf_rule_addr *dst,
+ u_int8_t af, u_int8_t proto)
+{
+ if (PF_AZERO(&src->addr.addr, AF_INET6) &&
+ PF_AZERO(&src->mask, AF_INET6) &&
+ !src->noroute && !dst->noroute &&
+ !src->port_op && PF_AZERO(&dst->addr.addr, AF_INET6) &&
+ PF_AZERO(&dst->mask, AF_INET6) && !dst->port_op)
+ printf("all ");
+ else {
+ printf("from ");
+ if (src->noroute)
+ printf("no-route ");
+ else if (PF_AZERO(&src->addr.addr, AF_INET6) &&
+ PF_AZERO(&src->mask, AF_INET6))
+ printf("any ");
+ else {
+ if (src->not)
+ printf("! ");
+ print_addr(&src->addr, &src->mask, af);
+ printf(" ");
+ }
+ if (src->port_op)
+ print_port(src->port_op, src->port[0],
+ src->port[1],
+ proto == IPPROTO_TCP ? "tcp" : "udp");
+
+ printf("to ");
+ if (dst->noroute)
+ printf("no-route ");
+ else if (PF_AZERO(&dst->addr.addr, AF_INET6) &&
+ PF_AZERO(&dst->mask, AF_INET6))
+ printf("any ");
+ else {
+ if (dst->not)
+ printf("! ");
+ print_addr(&dst->addr, &dst->mask, af);
+ printf(" ");
+ }
+ if (dst->port_op)
+ print_port(dst->port_op, dst->port[0],
+ dst->port[1],
+ proto == IPPROTO_TCP ? "tcp" : "udp");
+ }
+}
+
+void
print_nat(struct pf_nat *n)
{
if (n->no)
@@ -372,24 +421,7 @@ print_nat(struct pf_nat *n)
else
printf("proto %u ", n->proto);
}
- printf("from ");
- if (!PF_AZERO(&n->src.addr.addr, n->af) ||
- !PF_AZERO(&n->src.mask, n->af)) {
- if (n->src.not)
- printf("! ");
- print_addr(&n->src.addr, &n->src.mask, n->af);
- printf(" ");
- } else
- printf("any ");
- printf("to ");
- if (!PF_AZERO(&n->dst.addr.addr, n->af) ||
- !PF_AZERO(&n->dst.mask, n->af)) {
- if (n->dst.not)
- printf("! ");
- print_addr(&n->dst.addr, &n->dst.mask, n->af);
- printf(" ");
- } else
- printf("any ");
+ print_fromto(&n->src, &n->dst, n->af, n->proto);
if (!n->no) {
printf("-> ");
print_addr(&n->raddr, NULL, n->af);
@@ -631,47 +663,7 @@ print_rule(struct pf_rule *r)
else
printf("proto %u ", r->proto);
}
- if (PF_AZERO(&r->src.addr.addr, AF_INET6) &&
- PF_AZERO(&r->src.mask, AF_INET6) &&
- !r->src.noroute && !r->dst.noroute &&
- !r->src.port_op && PF_AZERO(&r->dst.addr.addr, AF_INET6) &&
- PF_AZERO(&r->dst.mask, AF_INET6) && !r->dst.port_op)
- printf("all ");
- else {
- printf("from ");
- if (r->src.noroute)
- printf("no-route ");
- else if (PF_AZERO(&r->src.addr.addr, AF_INET6) &&
- PF_AZERO(&r->src.mask, AF_INET6))
- printf("any ");
- else {
- if (r->src.not)
- printf("! ");
- print_addr(&r->src.addr, &r->src.mask, r->af);
- printf(" ");
- }
- if (r->src.port_op)
- print_port(r->src.port_op, r->src.port[0],
- r->src.port[1],
- r->proto == IPPROTO_TCP ? "tcp" : "udp");
-
- printf("to ");
- if (r->dst.noroute)
- printf("no-route ");
- else if (PF_AZERO(&r->dst.addr.addr, AF_INET6) &&
- PF_AZERO(&r->dst.mask, AF_INET6))
- printf("any ");
- else {
- if (r->dst.not)
- printf("! ");
- print_addr(&r->dst.addr, &r->dst.mask, r->af);
- printf(" ");
- }
- if (r->dst.port_op)
- print_port(r->dst.port_op, r->dst.port[0],
- r->dst.port[1],
- r->proto == IPPROTO_TCP ? "tcp" : "udp");
- }
+ print_fromto(&r->src, &r->dst, r->af, r->proto);
if (r->uid.op)
print_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user");
if (r->gid.op)