diff options
-rw-r--r-- | sbin/pfctl/parse.y | 208 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 225 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 118 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 19 |
4 files changed, 279 insertions, 291 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 3ad2d303837..aeac5d4592c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.259 2002/12/17 12:05:58 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.260 2002/12/17 12:36:59 mcbride Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -239,13 +239,13 @@ struct queue_opts { int yyerror(char *, ...); int rule_consistent(struct pf_rule *); -int nat_consistent(struct pf_nat *); -int rdr_consistent(struct pf_rdr *); +int nat_consistent(struct pf_rule *); +int rdr_consistent(struct pf_rule *); int yyparse(void); void set_ipmask(struct node_host *, u_int8_t); -void expand_rdr(struct pf_rdr *, struct node_if *, struct node_proto *, +void expand_rdr(struct pf_rule *, struct node_if *, struct node_proto *, struct node_host *, struct node_host *, struct node_host *); -void expand_nat(struct pf_nat *, struct node_if *, struct node_proto *, +void expand_nat(struct pf_rule *, struct node_if *, struct node_proto *, struct node_host *, struct node_port *, struct node_host *, struct node_port *, struct node_host *); void expand_label_if(const char *, char *, const char *); @@ -529,8 +529,9 @@ anchorrule : ANCHOR string dir interface af proto fromto { 0, 0, 0); } | NATANCHOR string interface af proto fromto { - struct pf_nat r; + struct pf_rule r; + r.action = PF_NAT; if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; @@ -545,8 +546,10 @@ anchorrule : ANCHOR string dir interface af proto fromto { $6.dst.host, $6.dst.port, NULL); } | RDRANCHOR string interface af proto fromto { - struct pf_rdr r; + struct pf_rule r; + r.action = PF_RDR; + if (check_rulestate(PFCTL_STATE_NAT)) if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; @@ -560,8 +563,9 @@ anchorrule : ANCHOR string dir interface af proto fromto { expand_rdr(&r, $3, $5, $6.src.host, $6.dst.host, NULL); } | BINATANCHOR string interface af proto fromto { - struct pf_binat r; + struct pf_rule r; + r.action = PF_NAT; if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; @@ -572,7 +576,7 @@ anchorrule : ANCHOR string dir interface af proto fromto { decide_address_family($6.src.host, &r.af); decide_address_family($6.dst.host, &r.af); - pfctl_add_binat(pf, &r); + pfctl_add_rule(pf, &r); } ; @@ -1036,7 +1040,7 @@ pfrule : action dir logquick interface route af proto fromto if ($5.rt) { r.rt = $5.rt; - r.rt_pool.opts = $5.pool_opts; + r.rpool.opts = $5.pool_opts; } if (r.rt && r.rt != PF_FASTROUTE) { @@ -1047,10 +1051,10 @@ pfrule : action dir logquick interface route af proto fromto YYERROR; } if ($5.host->next != NULL) { - if (r.rt_pool.opts == PF_POOL_NONE) - r.rt_pool.opts = + if (r.rpool.opts == PF_POOL_NONE) + r.rpool.opts = PF_POOL_ROUNDROBIN; - if (r.rt_pool.opts != + if (r.rpool.opts != PF_POOL_ROUNDROBIN) { yyerror("r.rt_pool.opts must " "be PF_POOL_ROUNDROBIN"); @@ -1918,13 +1922,13 @@ rport : STRING { if (($$.a = getservice($1)) == -1) YYERROR; $$.b = 0; - $$.t = PF_RPORT_RANGE; + $$.t = PF_OP_RRG; } else { *p++ = 0; if (($$.a = getservice($1)) == -1 || ($$.b = getservice(p)) == -1) YYERROR; - $$.t = PF_RPORT_RANGE; + $$.t = PF_OP_RRG; } } ; @@ -2039,14 +2043,17 @@ redirection : /* empty */ { $$ = NULL; } natrule : no NAT interface af proto fromto redirpool pooltype staticport { - struct pf_nat nat; + struct pf_rule nat; if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; memset(&nat, 0, sizeof(nat)); - nat.no = $1; + if ($1) + nat.action = PF_NONAT; + else + nat.action = PF_NAT; nat.af = $4; if (!nat.af) { @@ -2058,7 +2065,7 @@ natrule : no NAT interface af proto fromto redirpool pooltype staticport nat.af = $6.dst.host->af; } - if (nat.no) { + if (nat.action == PF_NONAT) { if ($7 != NULL) { yyerror("'no nat' rule does not need " "'->'"); @@ -2076,16 +2083,17 @@ natrule : no NAT interface af proto fromto redirpool pooltype staticport remove_invalid_hosts(&$7->host, &nat.af); if ($7->host == NULL) YYERROR; - nat.proxy_port[0] = ntohs($7->rport.a); - nat.proxy_port[1] = ntohs($7->rport.b); - if (!nat.proxy_port[0] && !nat.proxy_port[1]) { - nat.proxy_port[0] = + nat.rpool.proxy_port[0] = ntohs($7->rport.a); + nat.rpool.proxy_port[1] = ntohs($7->rport.b); + if (!nat.rpool.proxy_port[0] && + !nat.rpool.proxy_port[1]) { + nat.rpool.proxy_port[0] = PF_NAT_PROXY_PORT_LOW; - nat.proxy_port[1] = + nat.rpool.proxy_port[1] = PF_NAT_PROXY_PORT_HIGH; - } else if (!nat.proxy_port[1]) - nat.proxy_port[1] = nat.proxy_port[0]; - + } else if (!nat.rpool.proxy_port[1]) + nat.rpool.proxy_port[1] = + nat.rpool.proxy_port[0]; if ($7->host->next) { nat.rpool.opts = $8.type; if (nat.rpool.opts == PF_POOL_NONE) @@ -2130,14 +2138,20 @@ natrule : no NAT interface af proto fromto redirpool pooltype staticport binatrule : no BINAT interface af proto FROM host TO ipspec redirection { - struct pf_binat binat; + struct pf_rule binat; + struct pf_pooladdr *pa; if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; memset(&binat, 0, sizeof(binat)); - binat.no = $1; + if ($1) + binat.action = PF_NOBINAT; + else + binat.action = PF_BINAT; + binat.af = $4; + if ($3 != NULL) { memcpy(binat.ifname, $3->ifname, sizeof(binat.ifname)); @@ -2170,10 +2184,10 @@ binatrule : no BINAT interface af proto FROM host TO ipspec redirection YYERROR; } binat.af = $7->af; - memcpy(&binat.saddr.addr, &$7->addr.addr, - sizeof(binat.saddr.addr)); - memcpy(&binat.saddr.mask, &$7->addr.mask, - sizeof(binat.saddr.mask)); + memcpy(&binat.src.addr.addr, &$7->addr.addr, + sizeof(binat.src.addr.addr)); + memcpy(&binat.src.addr.mask, &$7->addr.mask, + sizeof(binat.src.addr.mask)); free($7); } if ($9 != NULL) { @@ -2194,15 +2208,15 @@ binatrule : no BINAT interface af proto FROM host TO ipspec redirection YYERROR; } binat.af = $9->af; - memcpy(&binat.daddr.addr, &$9->addr.addr, - sizeof(binat.daddr.addr)); - memcpy(&binat.daddr.mask, &$9->addr.mask, - sizeof(binat.daddr.mask)); - binat.dnot = $9->not; + memcpy(&binat.dst.addr.addr, &$9->addr.addr, + sizeof(binat.dst.addr.addr)); + memcpy(&binat.dst.addr.mask, &$9->addr.mask, + sizeof(binat.dst.addr.mask)); + binat.dst.not = $9->not; free($9); } - if (binat.no) { + if (binat.action == PF_NOBINAT) { if ($10 != NULL) { yyerror("'no binat' rule does not need" " '->'"); @@ -2223,64 +2237,78 @@ binatrule : no BINAT interface af proto FROM host TO ipspec redirection "address"); YYERROR; } - memcpy(&binat.raddr.addr, &$10->host->addr.addr, - sizeof(binat.raddr.addr)); - memcpy(&binat.raddr.mask, &$10->host->addr.mask, - sizeof(binat.raddr.mask)); - if (!PF_AZERO(&binat.saddr.mask, binat.af) && - !PF_AEQ(&binat.saddr.mask, - &binat.raddr.mask, binat.af)) { + + if (!PF_AZERO(&binat.src.addr.mask, binat.af) && + !PF_AEQ(&binat.src.addr.mask, + &$10->host->addr.mask, binat.af)) { yyerror("'binat' source mask and " "redirect mask must be the same"); YYERROR; } + + TAILQ_INIT(&binat.rpool.list); + pa = calloc(1, sizeof(struct pf_pooladdr)); + if (pa == NULL) { + yyerror("calloc"); + YYERROR; + } + pa->addr.addr = $10->host->addr; + pa->ifname[0] = 0; + TAILQ_INSERT_TAIL(&binat.rpool.list, + pa, entries); + free($10); } - pfctl_add_binat(pf, &binat); + pfctl_add_rule(pf, &binat); } ; rdrrule : no RDR interface af proto FROM ipspec TO ipspec dport redirpool pooltype { - struct pf_rdr rdr; + struct pf_rule rdr; if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; memset(&rdr, 0, sizeof(rdr)); - rdr.no = $1; + if ($1) + rdr.action = PF_NORDR; + else + rdr.action = PF_RDR; rdr.af = $4; + + rdr.action = PF_RDR; if ($7 != NULL) { - memcpy(&rdr.saddr.addr, &$7->addr.addr, - sizeof(rdr.saddr.addr)); - memcpy(&rdr.saddr.mask, &$7->addr.mask, - sizeof(rdr.saddr.mask)); - rdr.snot = $7->not; + memcpy(&rdr.src.addr.addr, &$7->addr.addr, + sizeof(rdr.src.addr.addr)); + memcpy(&rdr.src.addr.mask, &$7->addr.mask, + sizeof(rdr.src.addr.mask)); + rdr.src.not = $7->not; if (!rdr.af && !$7->ifindex) rdr.af = $7->af; } if ($9 != NULL) { - memcpy(&rdr.daddr.addr, &$9->addr.addr, - sizeof(rdr.daddr.addr)); - memcpy(&rdr.daddr.mask, &$9->addr.mask, - sizeof(rdr.daddr.mask)); - rdr.dnot = $9->not; + memcpy(&rdr.dst.addr.addr, &$9->addr.addr, + sizeof(rdr.dst.addr.addr)); + memcpy(&rdr.dst.addr.mask, &$9->addr.mask, + sizeof(rdr.dst.addr.mask)); + rdr.dst.not = $9->not; if (!rdr.af && !$9->ifindex) rdr.af = $9->af; } - rdr.dport = $10.a; - rdr.dport2 = $10.b; - rdr.opts |= $10.t; + rdr.dst.port[0] = $10.a; + rdr.dst.port[1] = $10.b; + rdr.dst.port_op |= $10.t; if ($12.type == PF_POOL_NONE) rdr.rpool.opts = PF_POOL_RANDOM; else rdr.rpool.opts = $12.type; - if (rdr.no) { + if (rdr.action == PF_NORDR) { if ($11 != NULL) { yyerror("'no rdr' rule does not need '->'"); YYERROR; @@ -2297,8 +2325,8 @@ rdrrule : no RDR interface af proto FROM ipspec TO ipspec dport redirpool poolt remove_invalid_hosts(&$11->host, &rdr.af); if ($11->host == NULL) YYERROR; - rdr.rport = $11->rport.a; - rdr.opts |= $11->rport.t; + rdr.rpool.proxy_port[0] = $11->rport.a; + rdr.rpool.port_op |= $11->rport.t; if ($11->host->next) { rdr.rpool.opts = $12.type; @@ -2350,13 +2378,14 @@ dport : /* empty */ { if (p == NULL) { if (($$.a = getservice($2)) == -1) YYERROR; - $$.b = $$.t = 0; + $$.b = 0; + $$.t = PF_OP_EQ; } else { *p++ = 0; if (($$.a = getservice($2)) == -1 || ($$.b = getservice(p)) == -1) YYERROR; - $$.t = PF_DPORT_RANGE; + $$.t = PF_OP_RRG; } } ; @@ -2550,14 +2579,14 @@ rule_consistent(struct pf_rule *r) } int -nat_consistent(struct pf_nat *r) +nat_consistent(struct pf_rule *r) { int problems = 0; struct pf_pooladdr *pa; if (!r->af) { TAILQ_FOREACH(pa, &r->rpool.list, entries) { - if (pa->addr.addr_dyn != NULL) { + if (pa->addr.addr.addr_dyn != NULL) { yyerror("dynamic addresses require " "address family (inet/inet6)"); problems++; @@ -2569,24 +2598,25 @@ nat_consistent(struct pf_nat *r) } int -rdr_consistent(struct pf_rdr *r) +rdr_consistent(struct pf_rule *r) { int problems = 0; struct pf_pooladdr *pa; if (r->proto != IPPROTO_TCP && r->proto != IPPROTO_UDP && - (r->dport || r->dport2 || r->rport)) { + (r->dst.port[0] || r->dst.port[1] || r->rpool.proxy_port[0])) { yyerror("port only applies to tcp/udp"); problems++; } if (!r->af) { - if (r->saddr.addr_dyn != NULL || r->daddr.addr_dyn != NULL) { + if (r->src.addr.addr_dyn != NULL || + r->dst.addr.addr_dyn != NULL) { yyerror("dynamic addresses require address family " "(inet/inet6)"); problems++; } else { TAILQ_FOREACH(pa, &r->rpool.list, entries) { - if (pa->addr.addr_dyn != NULL) { + if (pa->addr.addr.addr_dyn != NULL) { yyerror("dynamic addresses require " "address family (inet/inet6)"); problems++; @@ -2925,7 +2955,7 @@ expand_queue(struct pf_altq *a, struct node_queue *nqueues, void expand_rule(struct pf_rule *r, - struct node_if *interfaces, struct node_host *rt_pool_hosts, + struct node_if *interfaces, struct node_host *rpool_hosts, struct node_proto *protos, struct node_host *src_hosts, struct node_port *src_ports, struct node_host *dst_hosts, struct node_port *dst_ports, struct node_uid *uids, @@ -3017,19 +3047,19 @@ expand_rule(struct pf_rule *r, error++; } - TAILQ_INIT(&r->rt_pool.list); - for (h = rt_pool_hosts; h != NULL; h = h->next) { + TAILQ_INIT(&r->rpool.list); + for (h = rpool_hosts; h != NULL; h = h->next) { pa = calloc(1, sizeof(struct pf_pooladdr)); if (pa == NULL) { yyerror("calloc"); error++; } - pa->addr = h->addr; + pa->addr.addr = h->addr; if (h->ifname != NULL) strlcpy(pa->ifname, h->ifname, IFNAMSIZ); else pa->ifname[0] = 0; - TAILQ_INSERT_TAIL(&r->rt_pool.list, pa, entries); + TAILQ_INSERT_TAIL(&r->rpool.list, pa, entries); } if (rule_consistent(r) < 0 || error) @@ -3051,14 +3081,14 @@ expand_rule(struct pf_rule *r, FREE_LIST(struct node_uid, uids); FREE_LIST(struct node_gid, gids); FREE_LIST(struct node_icmp, icmp_types); - FREE_LIST(struct node_host, rt_pool_hosts); + FREE_LIST(struct node_host, rpool_hosts); if (!added) yyerror("rule expands to no valid combination"); } void -expand_nat(struct pf_nat *n, +expand_nat(struct pf_rule *n, struct node_if *interfaces, struct node_proto *protos, struct node_host *src_hosts, struct node_port *src_ports, struct node_host *dst_hosts, struct node_port *dst_ports, @@ -3124,7 +3154,7 @@ expand_nat(struct pf_nat *n, yyerror("calloc"); error++; } - pa->addr = h->addr; + pa->addr.addr = h->addr; pa->ifname[0] = 0; TAILQ_INSERT_TAIL(&n->rpool.list, pa, entries); } @@ -3132,7 +3162,7 @@ expand_nat(struct pf_nat *n, if (nat_consistent(n) < 0 || error) yyerror("skipping nat rule due to errors"); else { - pfctl_add_nat(pf, n); + pfctl_add_rule(pf, n); added++; } @@ -3151,7 +3181,7 @@ expand_nat(struct pf_nat *n, } void -expand_rdr(struct pf_rdr *r, struct node_if *interfaces, +expand_rdr(struct pf_rule *r, struct node_if *interfaces, struct node_proto *protos, struct node_host *src_hosts, struct node_host *dst_hosts, struct node_host *rpool_hosts) { @@ -3191,10 +3221,14 @@ expand_rdr(struct pf_rdr *r, struct node_if *interfaces, else memcpy(r->ifname, interface->ifname, sizeof(r->ifname)); - r->proto = proto->proto; r->ifnot = interface->not; - r->saddr = src_host->addr; - r->daddr = dst_host->addr; + r->proto = proto->proto; + r->src.addr = src_host->addr; + r->src.noroute = src_host->noroute; + r->src.not = src_host->not; + r->dst.addr = dst_host->addr; + r->dst.noroute = dst_host->noroute; + r->dst.not = dst_host->not; TAILQ_INIT(&r->rpool.list); for (h = rpool_hosts; h != NULL; h = h->next) { @@ -3203,7 +3237,7 @@ expand_rdr(struct pf_rdr *r, struct node_if *interfaces, yyerror("calloc"); error++; } - pa->addr = h->addr; + pa->addr.addr = h->addr; pa->ifname[0] = 0; TAILQ_INSERT_TAIL(&r->rpool.list, pa, entries); } @@ -3211,7 +3245,7 @@ expand_rdr(struct pf_rdr *r, struct node_if *interfaces, if (rdr_consistent(r) < 0 || error) yyerror("skipping rdr rule due to errors"); else { - pfctl_add_rdr(pf, r); + pfctl_add_rule(pf, r); added++; } diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index fc8f58dd545..d5dc35b74c1 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.103 2002/12/16 22:59:37 henning Exp $ */ +/* $OpenBSD: pfctl.c,v 1.104 2002/12/17 12:36:59 mcbride Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -238,6 +238,7 @@ pfctl_clear_rules(int dev, int opts) memset(&pr, 0, sizeof(pr)); memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset)); + pr.rule.action = PF_PASS; if (ioctl(dev, DIOCBEGINRULES, &pr)) err(1, "DIOCBEGINRULES"); else if (ioctl(dev, DIOCCOMMITRULES, &pr)) @@ -250,31 +251,26 @@ pfctl_clear_rules(int dev, int opts) int pfctl_clear_nat(int dev, int opts) { - struct pfioc_nat pn; - struct pfioc_binat pb; - struct pfioc_rdr pr; + struct pfioc_rule pr; - memset(&pn, 0, sizeof(pn)); - memset(&pb, 0, sizeof(pb)); memset(&pr, 0, sizeof(pr)); - memcpy(pn.anchor, anchorname, sizeof(pn.anchor)); - memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset)); - memcpy(pb.anchor, anchorname, sizeof(pb.anchor)); - memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset)); memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset)); - if (ioctl(dev, DIOCBEGINNATS, &pn)) - err(1, "DIOCBEGINNATS"); - else if (ioctl(dev, DIOCCOMMITNATS, &pn)) - err(1, "DIOCCOMMITNATS"); - if (ioctl(dev, DIOCBEGINBINATS, &pb)) - err(1, "DIOCBEGINBINATS"); - else if (ioctl(dev, DIOCCOMMITBINATS, &pb)) - err(1, "DIOCCOMMITBINATS"); - else if (ioctl(dev, DIOCBEGINRDRS, &pr)) - err(1, "DIOCBEGINRDRS"); - else if (ioctl(dev, DIOCCOMMITRDRS, &pr)) - err(1, "DIOCCOMMITRDRS"); + pr.rule.action = PF_NAT; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); + else if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); + pr.rule.action = PF_BINAT; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); + else if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); + pr.rule.action = PF_RDR; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); + else if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); if ((opts & PF_OPT_QUIET) == 0) fprintf(stderr, "nat cleared\n"); return (0); @@ -410,7 +406,7 @@ pfctl_kill_states(int dev, int opts) int pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr, - u_int32_t ticket, int id) + u_int32_t ticket, int r_action) { struct pfioc_pooladdr pp; struct pf_pooladdr *pa; @@ -419,7 +415,7 @@ pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr, memset(&pp, 0, sizeof(pp)); memcpy(pp.anchor, anchorname, sizeof(pp.anchor)); memcpy(pp.ruleset, rulesetname, sizeof(pp.ruleset)); - pp.r_id = id; + pp.r_action = r_action; pp.r_num = nr; pp.ticket = ticket; if (ioctl(dev, DIOCGETADDRS, &pp)) { @@ -466,6 +462,7 @@ pfctl_show_rules(int dev, int opts, int format) memset(&pr, 0, sizeof(pr)); memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset)); + pr.rule.action = PF_PASS; if (ioctl(dev, DIOCGETRULES, &pr)) { warn("DIOCGETRULES"); return (-1); @@ -478,8 +475,8 @@ pfctl_show_rules(int dev, int opts, int format) return (-1); } - if (pfctl_get_pool(dev, &pr.rule.rt_pool, - nr, pr.ticket, PF_POOL_RULE_RT) != 0) + if (pfctl_get_pool(dev, &pr.rule.rpool, + nr, pr.ticket, PF_PASS) != 0) return (-1); switch (format) { @@ -503,7 +500,7 @@ pfctl_show_rules(int dev, int opts, int format) pr.rule.evaluations, pr.rule.packets, pr.rule.bytes, pr.rule.states); } - pfctl_clear_pool(&pr.rule.rt_pool); + pfctl_clear_pool(&pr.rule.rpool); } return (0); } @@ -541,66 +538,61 @@ pfctl_show_altq(int dev) int pfctl_show_nat(int dev) { - struct pfioc_nat pn; - struct pfioc_rdr pr; - struct pfioc_binat pb; + struct pfioc_rule pr; u_int32_t mnr, nr; - memset(&pn, 0, sizeof(pn)); memset(&pr, 0, sizeof(pr)); - memset(&pb, 0, sizeof(pb)); - memcpy(pn.anchor, anchorname, sizeof(pn.anchor)); - memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset)); memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset)); - memcpy(pb.anchor, anchorname, sizeof(pb.anchor)); - memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset)); - if (ioctl(dev, DIOCGETNATS, &pn)) { - warn("DIOCGETNATS"); + pr.rule.action = PF_NAT; + if (ioctl(dev, DIOCGETRULES, &pr)) { + warn("DIOCGETRULES"); return (-1); } - mnr = pn.nr; + mnr = pr.nr; for (nr = 0; nr < mnr; ++nr) { - pn.nr = nr; - if (ioctl(dev, DIOCGETNAT, &pn)) { - warn("DIOCGETNAT"); + pr.nr = nr; + if (ioctl(dev, DIOCGETRULE, &pr)) { + warn("DIOCGETRULE"); return (-1); } - if (pfctl_get_pool(dev, &pn.nat.rpool, nr, - pn.ticket, PF_POOL_NAT_R) != 0) + if (pfctl_get_pool(dev, &pr.rule.rpool, nr, + pr.ticket, PF_NAT) != 0) return (-1); - print_nat(&pn.nat); - pfctl_clear_pool(&pn.nat.rpool); + print_nat(&pr.rule); + pfctl_clear_pool(&pr.rule.rpool); } - if (ioctl(dev, DIOCGETRDRS, &pr)) { - warn("DIOCGETRDRS"); + pr.rule.action = PF_RDR; + if (ioctl(dev, DIOCGETRULES, &pr)) { + warn("DIOCGETRULES"); return (-1); } mnr = pr.nr; for (nr = 0; nr < mnr; ++nr) { pr.nr = nr; - if (ioctl(dev, DIOCGETRDR, &pr)) { - warn("DIOCGETRDR"); + if (ioctl(dev, DIOCGETRULE, &pr)) { + warn("DIOCGETRULE"); return (-1); } - if (pfctl_get_pool(dev, &pr.rdr.rpool, nr, - pr.ticket, PF_POOL_RDR_R) != 0) + if (pfctl_get_pool(dev, &pr.rule.rpool, nr, + pr.ticket, PF_RDR) != 0) return (-1); - print_rdr(&pr.rdr); - pfctl_clear_pool(&pr.rdr.rpool); + print_rdr(&pr.rule); + pfctl_clear_pool(&pr.rule.rpool); } - if (ioctl(dev, DIOCGETBINATS, &pb)) { - warn("DIOCGETBINATS"); + pr.rule.action = PF_BINAT; + if (ioctl(dev, DIOCGETRULES, &pr)) { + warn("DIOCGETRULES"); return (-1); } - mnr = pb.nr; + mnr = pr.nr; for (nr = 0; nr < mnr; ++nr) { - pb.nr = nr; - if (ioctl(dev, DIOCGETBINAT, &pb)) { - warn("DIOCGETBINAT"); + pr.nr = nr; + if (ioctl(dev, DIOCGETRULE, &pr)) { + warn("DIOCGETRULE"); return (-1); } - print_binat(&pb.binat); + print_binat(&pr.rule); } return (0); } @@ -721,7 +713,7 @@ int pfctl_add_rule(struct pfctl *pf, struct pf_rule *r) { if ((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) { - if (pfctl_add_pool(pf, &r->rt_pool, r->af)) + if (pfctl_add_pool(pf, &r->rpool, r->af)) return (1); if ((pf->opts & PF_OPT_NOACTION) == 0) { memcpy(&pf->prule->rule, r, sizeof(pf->prule->rule)); @@ -731,60 +723,6 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r) } if (pf->opts & PF_OPT_VERBOSE) print_rule(r, pf->opts & PF_OPT_VERBOSE2); - pfctl_clear_pool(&r->rt_pool); - } - return (0); -} - -int -pfctl_add_nat(struct pfctl *pf, struct pf_nat *n) -{ - if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) { - if (pfctl_add_pool(pf, &n->rpool, n->af)) - return (1); - if ((pf->opts & PF_OPT_NOACTION) == 0) { - memcpy(&pf->pnat->nat, n, sizeof(pf->pnat->nat)); - pf->pnat->pool_ticket = pf->paddr.ticket; - if (ioctl(pf->dev, DIOCADDNAT, pf->pnat)) - err(1, "DIOCADDNAT"); - } - if (pf->opts & PF_OPT_VERBOSE) - print_nat(n); - pfctl_clear_pool(&n->rpool); - } - return (0); -} - -int -pfctl_add_binat(struct pfctl *pf, struct pf_binat *b) -{ - if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) { - if ((pf->opts & PF_OPT_NOACTION) == 0) { - memcpy(&pf->pbinat->binat, b, - sizeof(pf->pbinat->binat)); - if (ioctl(pf->dev, DIOCADDBINAT, pf->pbinat)) - err(1, "DIOCADDBINAT"); - } - if (pf->opts & PF_OPT_VERBOSE) - print_binat(b); - } - return (0); -} - -int -pfctl_add_rdr(struct pfctl *pf, struct pf_rdr *r) -{ - if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) { - if (pfctl_add_pool(pf, &r->rpool, r->af)) - return (1); - if ((pf->opts & PF_OPT_NOACTION) == 0) { - memcpy(&pf->prdr->rdr, r, sizeof(pf->prdr->rdr)); - pf->prdr->pool_ticket = pf->paddr.ticket; - if (ioctl(pf->dev, DIOCADDRDR, pf->prdr)) - err(1, "DIOCADDRDR"); - } - if (pf->opts & PF_OPT_VERBOSE) - print_rdr(r); pfctl_clear_pool(&r->rpool); } return (0); @@ -820,27 +758,15 @@ int pfctl_rules(int dev, char *filename, int opts) { FILE *fin; - struct pfioc_nat pn; - struct pfioc_binat pb; - struct pfioc_rdr pr; - struct pfioc_rule pl; + struct pfioc_rule pr; struct pfioc_altq pa; struct pfctl pf; - memset(&pn, 0, sizeof(pn)); - memset(&pb, 0, sizeof(pb)); memset(&pr, 0, sizeof(pr)); - memset(&pl, 0, sizeof(pl)); memset(&pa, 0, sizeof(pa)); memset(&pf, 0, sizeof(pf)); - memcpy(pn.anchor, anchorname, sizeof(pn.anchor)); - memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset)); - memcpy(pb.anchor, anchorname, sizeof(pb.anchor)); - memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset)); memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset)); - memcpy(pl.anchor, anchorname, sizeof(pl.anchor)); - memcpy(pl.ruleset, rulesetname, sizeof(pl.ruleset)); if (strcmp(filename, "-") == 0) { fin = stdin; infile = "stdin"; @@ -854,30 +780,31 @@ pfctl_rules(int dev, char *filename, int opts) } if ((opts & PF_OPT_NOACTION) == 0) { if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) { - if (ioctl(dev, DIOCBEGINNATS, &pn)) - err(1, "DIOCBEGINNATS"); - if (ioctl(dev, DIOCBEGINRDRS, &pr)) - err(1, "DIOCBEGINRDRS"); - if (ioctl(dev, DIOCBEGINBINATS, &pb)) - err(1, "DIOCBEGINBINATS"); + pr.rule.action = PF_NAT; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); + pr.rule.action = PF_RDR; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); + pr.rule.action = PF_BINAT; + if (ioctl(dev, DIOCBEGINRULES, &pr)) + err(1, "DIOCBEGINRULES"); } if (((altqsupport && loadopt & (PFCTL_FLAG_ALTQ | PFCTL_FLAG_ALL)) != 0) && ioctl(dev, DIOCBEGINALTQS, &pa.ticket)) { err(1, "DIOCBEGINALTQS"); } + pr.rule.action = PF_PASS; if (((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) && - ioctl(dev, DIOCBEGINRULES, &pl)) + ioctl(dev, DIOCBEGINRULES, &pr)) err(1, "DIOCBEGINRULES"); } /* fill in callback data */ pf.dev = dev; pf.opts = opts; - pf.pnat = &pn; - pf.pbinat = &pb; - pf.prdr = ≺ pf.paltq = &pa; - pf.prule = &pl; + pf.prule = ≺ pf.rule_nr = 0; if (parse_rules(fin, &pf, opts) < 0) errx(1, "Syntax error in file: pf rules not loaded"); @@ -886,19 +813,23 @@ pfctl_rules(int dev, char *filename, int opts) errx(1, "errors in altq config"); if ((opts & PF_OPT_NOACTION) == 0) { if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) { - if (ioctl(dev, DIOCCOMMITNATS, &pn)) - err(1, "DIOCCOMMITNATS"); - if (ioctl(dev, DIOCCOMMITRDRS, &pr)) - err(1, "DIOCCOMMITRDRS"); - if (ioctl(dev, DIOCCOMMITBINATS, &pb)) - err(1, "DIOCCOMMITBINATS"); + pr.rule.action = PF_NAT; + if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); + pr.rule.action = PF_RDR; + if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); + pr.rule.action = PF_BINAT; + if (ioctl(dev, DIOCCOMMITRULES, &pr)) + err(1, "DIOCCOMMITRULES"); } if (((altqsupport && loadopt & (PFCTL_FLAG_ALTQ | PFCTL_FLAG_ALL)) != 0) && ioctl(dev, DIOCCOMMITALTQS, &pa.ticket)) err(1, "DIOCCOMMITALTQS"); + pr.rule.action = PF_PASS; if (((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) && - ioctl(dev, DIOCCOMMITRULES, &pl)) + ioctl(dev, DIOCCOMMITRULES, &pr)) err(1, "DIOCCOMMITRULES"); #if 0 if ((opts & PF_OPT_QUIET) == 0) { diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index ff3c364a167..aeb65573d51 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.121 2002/12/13 21:51:25 henning Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.122 2002/12/17 12:36:59 mcbride Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -396,6 +396,31 @@ print_fromto(struct pf_rule_addr *src, struct pf_rule_addr *dst, } void +print_rule(struct pf_rule *r, int verbose) +{ + switch (r->action) { + case PF_NAT: + case PF_NONAT: + print_nat(r); + break; + case PF_BINAT: + case PF_NOBINAT: + print_binat(r); + break; + case PF_RDR: + case PF_NORDR: + print_rdr(r); + break; + default: + case PF_PASS: + case PF_DROP: + case PF_SCRUB: + print_filter(r, verbose); + break; + } +} + +void print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, sa_family_t af, int id) { @@ -406,19 +431,22 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, printf("{ "); TAILQ_FOREACH(pooladdr, &pool->list, entries){ switch (id) { - case PF_POOL_NAT_R: - case PF_POOL_RDR_R: - print_addr(&pooladdr->addr, af); + case PF_NAT: + case PF_RDR: + case PF_BINAT: + print_addr(&pooladdr->addr.addr, af); break; - case PF_POOL_RULE_RT: - if (PF_AZERO(&pooladdr->addr.addr, af)) + case PF_PASS: + if (PF_AZERO(&pooladdr->addr.addr.addr, af)) printf("%s", pooladdr->ifname); else { printf("(%s ", pooladdr->ifname); - print_addr(&pooladdr->addr, af); + print_addr(&pooladdr->addr.addr, af); printf(")"); } break; + default: + break; } if (TAILQ_NEXT(pooladdr, entries) != NULL) printf(", "); @@ -426,7 +454,7 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, printf(" }"); } switch (id) { - case PF_POOL_NAT_R: + case PF_NAT: if (p1 != PF_NAT_PROXY_PORT_LOW || p2 != PF_NAT_PROXY_PORT_HIGH) { if (p1 == p2) @@ -435,14 +463,13 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, printf(" port %u:%u", p1, p2); } break; - case PF_POOL_RDR_R: + case PF_RDR: if (p1) { printf(" port %u", ntohs(p1)); - if (p2 & PF_RPORT_RANGE) + if (p2 & PF_OP_RRG) printf(":*"); } break; - case PF_POOL_RULE_RT: default: break; } @@ -469,12 +496,12 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, } void -print_nat(struct pf_nat *n) +print_nat(struct pf_rule *n) { if (n->anchorname[0]) printf("nat-anchor %s ", n->anchorname); else { - if (n->no) + if (n->action == PF_NONAT) printf("no "); printf("nat "); } @@ -499,21 +526,21 @@ print_nat(struct pf_nat *n) printf("proto %u ", n->proto); } print_fromto(&n->src, &n->dst, n->af, n->proto); - if (!n->anchorname[0] && !n->no) { + if (!n->anchorname[0] && (n->action == PF_NAT)) { printf("-> "); - print_pool(&n->rpool, n->proxy_port[0], n->proxy_port[1], - n->af, PF_POOL_NAT_R); + print_pool(&n->rpool, n->rpool.proxy_port[0], + n->rpool.proxy_port[1], n->af, PF_NAT); } printf("\n"); } void -print_binat(struct pf_binat *b) +print_binat(struct pf_rule *b) { if (b->anchorname[0]) printf("binat-anchor %s ", b->anchorname); else { - if (b->no) + if (b->action == PF_NOBINAT) printf("no "); printf("binat "); } @@ -536,35 +563,35 @@ print_binat(struct pf_binat *b) printf("proto %u ", b->proto); } printf("from "); - if (!PF_AZERO(&b->saddr.addr, b->af) || - !PF_AZERO(&b->saddr.mask, b->af)) { - print_addr(&b->saddr, b->af); + if (!PF_AZERO(&b->src.addr.addr, b->af) || + !PF_AZERO(&b->src.addr.mask, b->af)) { + print_addr(&b->src.addr, b->af); printf(" "); } else printf("any "); printf("to "); - if (!PF_AZERO(&b->daddr.addr, b->af) || - !PF_AZERO(&b->daddr.mask, b->af)) { - if (b->dnot) + if (!PF_AZERO(&b->dst.addr.addr, b->af) || + !PF_AZERO(&b->dst.addr.mask, b->af)) { + if (b->dst.not) printf("! "); - print_addr(&b->daddr, b->af); + print_addr(&b->dst.addr, b->af); printf(" "); } else printf("any "); - if (!b->anchorname[0] && !b->no) { + if (!b->anchorname[0] && (b->action == PF_BINAT)) { printf("-> "); - print_addr(&b->raddr, b->af); + print_pool(&b->rpool, 0, 0, b->af, PF_BINAT); } printf("\n"); } void -print_rdr(struct pf_rdr *r) +print_rdr(struct pf_rule *r) { if (r->anchorname[0]) printf("rdr-anchor %s ", r->anchorname); else { - if (r->no) + if (r->action == PF_NORDR) printf("no "); printf("rdr "); } @@ -589,32 +616,33 @@ print_rdr(struct pf_rdr *r) printf("proto %u ", r->proto); } printf("from "); - if (!PF_AZERO(&r->saddr.addr, r->af) || - !PF_AZERO(&r->saddr.mask, r->af)) { - if (r->snot) + if (!PF_AZERO(&r->src.addr.addr, r->af) || + !PF_AZERO(&r->src.addr.mask, r->af)) { + if (r->src.not) printf("! "); - print_addr(&r->saddr, r->af); + print_addr(&r->src.addr, r->af); printf(" "); } else printf("any "); printf("to "); - if (!PF_AZERO(&r->daddr.addr, r->af) || - !PF_AZERO(&r->daddr.mask, r->af)) { - if (r->dnot) + if (!PF_AZERO(&r->dst.addr.addr, r->af) || + !PF_AZERO(&r->dst.addr.mask, r->af)) { + if (r->dst.not) printf("! "); - print_addr(&r->daddr, r->af); + print_addr(&r->dst.addr, r->af); printf(" "); } else printf("any "); - if (r->dport) { - printf("port %u", ntohs(r->dport)); - if (r->opts & PF_DPORT_RANGE) - printf(":%u", ntohs(r->dport2)); + if (r->dst.port[0]) { + printf("port %u", ntohs(r->dst.port[0])); + if (r->rpool.port_op & PF_OP_RRG) + printf(":%u", ntohs(r->dst.port[1])); printf(" "); } - if (!r->anchorname[0] && !r->no) { + if (!r->anchorname[0] && (r->action == PF_RDR)) { printf("-> "); - print_pool(&r->rpool, r->rport, r->opts, r->af, PF_POOL_RDR_R); + print_pool(&r->rpool, r->rpool.proxy_port[0], + r->rpool.port_op, r->af, PF_RDR); } printf("\n"); } @@ -703,7 +731,7 @@ print_status(struct pf_status *s) } void -print_rule(struct pf_rule *r, int verbose) +print_filter(struct pf_rule *r, int verbose) { int i, opts; @@ -787,7 +815,7 @@ print_rule(struct pf_rule *r, int verbose) else if (r->rt == PF_FASTROUTE) printf("fastroute "); if (r->rt != PF_FASTROUTE) { - print_pool(&r->rt_pool, 0, 0, r->af, PF_POOL_RULE_RT); + print_pool(&r->rpool, 0, 0, r->af, PF_PASS); printf(" "); } } diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index ae92996b9b7..60cbc649efb 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.33 2002/12/05 14:10:45 henning Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.34 2002/12/17 12:36:59 mcbride Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -57,20 +57,14 @@ struct pfctl { int dev; int opts; - u_int16_t rule_nr; + u_int32_t rule_nr; struct pfioc_pooladdr paddr; struct pfioc_rule *prule; - struct pfioc_nat *pnat; - struct pfioc_binat *pbinat; - struct pfioc_rdr *prdr; struct pfioc_altq *paltq; struct pfioc_queue *pqueue; }; int pfctl_add_rule(struct pfctl *, struct pf_rule *); -int pfctl_add_nat(struct pfctl *, struct pf_nat *); -int pfctl_add_binat(struct pfctl *, struct pf_binat *); -int pfctl_add_rdr(struct pfctl *, struct pf_rdr *); int pfctl_add_altq(struct pfctl *, struct pf_altq *); int pfctl_set_timeout(struct pfctl *, const char *, int); @@ -81,11 +75,12 @@ int pfctl_set_logif(struct pfctl *, char *); int parse_rules(FILE *, struct pfctl *, int); int parse_flags(char *); -void print_rule(struct pf_rule *, int); +void print_filter(struct pf_rule *, int); void print_pool(struct pf_pool *, u_int16_t, u_int16_t, sa_family_t, int); -void print_nat(struct pf_nat *); -void print_binat(struct pf_binat *); -void print_rdr(struct pf_rdr *); +void print_rule(struct pf_rule *, int); +void print_nat(struct pf_rule *); +void print_binat(struct pf_rule *); +void print_rdr(struct pf_rule *); void print_status(struct pf_status *); struct icmptypeent { |