diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -525,7 +525,7 @@ %token STICKYADDRESS ENDPI MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW ALLOW_RELATED %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS -%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE AFTO +%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE AFTO NATTO RDRTO %token STRING %token NUMBER %token PORTBINARY @@ -3011,6 +3011,20 @@ filter_opts.marker |= FOM_SCRUB_TCP; filter_opts.marker |= $3.marker; } + | NATTO port_redirspec { + if (filter_opts.nat) { + yyerror("cannot respecify nat-to/binat-to"); + YYERROR; + } + filter_opts.nat = $2; + } + | RDRTO port_redirspec { + if (filter_opts.rdr) { + yyerror("cannot respecify rdr-to"); + YYERROR; + } + filter_opts.rdr = $2; + } | AFTO af FROM port_redirspec { if (filter_opts.nat) { yyerror("cannot respecify af-to"); @@ -6292,17 +6306,20 @@ if (r->action == PF_RDR) { error += apply_rdr_ports(r, &(r->rdr), rdr); + error += apply_redirspec(&(r->rdr), rdr); } else if (r->action == PF_NAT) { error += apply_nat_ports(&(r->rdr), rdr); + error += apply_redirspec(&(r->rdr), rdr); + } else { + error += apply_redirspec(&(r->route), route); + + error += apply_nat_ports(&(r->nat), nat); + error += apply_redirspec(&(r->nat), nat); + + error += apply_rdr_ports(r, &(r->rdr), rdr); + error += apply_redirspec(&(r->rdr), rdr); } - error += apply_redirspec(&(r->nat), nat); - error += apply_redirspec(&(r->rdr), rdr); - error += apply_redirspec(&(r->route), route); - - r->nat.proxy_port[0] = PF_NAT_PROXY_PORT_LOW; - r->nat.proxy_port[1] = PF_NAT_PROXY_PORT_HIGH; - if (rule_consistent(r, anchor_call[0]) < 0 || error) yyerror("skipping rule due to errors"); else { @@ -6491,6 +6508,7 @@ { "modulate", MODULATE}, { "nat", NAT}, { "nat-anchor", NATANCHOR}, + { "nat-to", NATTO}, { "no", NO}, { "no-df", NODF}, { "no-route", NOROUTE}, @@ -6515,6 +6533,7 @@ { "random-id", RANDOMID}, { "rdr", RDR}, { "rdr-anchor", RDRANCHOR}, + { "rdr-to", RDRTO}, { "realtime", REALTIME}, { "reassemble", REASSEMBLE}, { "received-on", RECEIVEDON}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1240,25 +1240,34 @@ } #endif } - if (!anchor_call[0] && ! TAILQ_EMPTY(&r->nat.list) && - r->rule_flag & PFRULE_AFTO) { - printf(" af-to %s from ", r->naf == AF_INET ? "inet" : "inet6"); - print_pool(&r->nat, r->nat.proxy_port[0], r->nat.proxy_port[1], - r->naf ? r->naf : r->af, PF_NAT); + if (anchor_call[0]) + return; + if (r->action == PF_NAT || r->action == PF_BINAT || r->action == PF_RDR) { + printf(" -> "); + print_pool(&r->rdr, r->rdr.proxy_port[0], + r->rdr.proxy_port[1], r->af, r->action); + } else { + if (!TAILQ_EMPTY(&r->nat.list)) { + if (r->rule_flag & PFRULE_AFTO) { + printf(" af-to %s from ", r->naf == AF_INET ? "inet" : "inet6"); + } else { + printf(" nat-to "); + } + print_pool(&r->nat, r->nat.proxy_port[0], + r->nat.proxy_port[1], r->naf ? r->naf : r->af, + PF_NAT); + } if (!TAILQ_EMPTY(&r->rdr.list)) { - printf(" to "); + if (r->rule_flag & PFRULE_AFTO) { + printf(" to "); + } else { + printf(" rdr-to "); + } print_pool(&r->rdr, r->rdr.proxy_port[0], r->rdr.proxy_port[1], r->naf ? r->naf : r->af, PF_RDR); } } - if (!anchor_call[0] && - (r->action == PF_NAT || r->action == PF_BINAT || - r->action == PF_RDR)) { - printf(" -> "); - print_pool(&r->rdr, r->rdr.proxy_port[0], - r->rdr.proxy_port[1], r->af, r->action); - } } void