Changeset View
Changeset View
Standalone View
Standalone View
sbin/pfctl/parse.y
Show First 20 Lines • Show All 344 Lines • ▼ Show 20 Lines | void expand_label_addr(const char *, char *, size_t, u_int8_t, | ||||
struct pf_rule_addr *); | struct pf_rule_addr *); | ||||
void expand_label_port(const char *, char *, size_t, | void expand_label_port(const char *, char *, size_t, | ||||
struct pf_rule_addr *); | struct pf_rule_addr *); | ||||
void expand_label_proto(const char *, char *, size_t, u_int8_t); | void expand_label_proto(const char *, char *, size_t, u_int8_t); | ||||
void expand_label_nr(const char *, char *, size_t, | void expand_label_nr(const char *, char *, size_t, | ||||
struct pfctl_rule *); | struct pfctl_rule *); | ||||
void expand_eth_rule(struct pfctl_eth_rule *, | void expand_eth_rule(struct pfctl_eth_rule *, | ||||
struct node_if *, struct node_etherproto *, | struct node_if *, struct node_etherproto *, | ||||
struct node_mac *, struct node_mac *); | struct node_mac *, struct node_mac *, const char *); | ||||
void expand_rule(struct pfctl_rule *, struct node_if *, | void expand_rule(struct pfctl_rule *, struct node_if *, | ||||
struct node_host *, struct node_proto *, struct node_os *, | struct node_host *, struct node_proto *, struct node_os *, | ||||
struct node_host *, struct node_port *, struct node_host *, | struct node_host *, struct node_port *, struct node_host *, | ||||
struct node_port *, struct node_uid *, struct node_gid *, | struct node_port *, struct node_uid *, struct node_gid *, | ||||
struct node_icmp *, const char *); | struct node_icmp *, const char *); | ||||
int expand_altq(struct pf_altq *, struct node_if *, | int expand_altq(struct pf_altq *, struct node_if *, | ||||
struct node_queue *, struct node_queue_bw bwspec, | struct node_queue *, struct node_queue_bw bwspec, | ||||
struct node_queue_opt *); | struct node_queue_opt *); | ||||
int expand_queue(struct pf_altq *, struct node_if *, | int expand_queue(struct pf_altq *, struct node_if *, | ||||
struct node_queue *, struct node_queue_bw, | struct node_queue *, struct node_queue_bw, | ||||
struct node_queue_opt *); | struct node_queue_opt *); | ||||
int expand_skip_interface(struct node_if *); | int expand_skip_interface(struct node_if *); | ||||
int check_rulestate(int); | int check_rulestate(int); | ||||
int getservice(char *); | int getservice(char *); | ||||
int rule_label(struct pfctl_rule *, char *s[PF_RULE_MAX_LABEL_COUNT]); | int rule_label(struct pfctl_rule *, char *s[PF_RULE_MAX_LABEL_COUNT]); | ||||
int rt_tableid_max(void); | int rt_tableid_max(void); | ||||
void mv_rules(struct pfctl_ruleset *, struct pfctl_ruleset *); | void mv_rules(struct pfctl_ruleset *, struct pfctl_ruleset *); | ||||
void mv_eth_rules(struct pfctl_eth_ruleset *, struct pfctl_eth_ruleset *); | |||||
void decide_address_family(struct node_host *, sa_family_t *); | void decide_address_family(struct node_host *, sa_family_t *); | ||||
void remove_invalid_hosts(struct node_host **, sa_family_t *); | void remove_invalid_hosts(struct node_host **, sa_family_t *); | ||||
int invalid_redirect(struct node_host *, sa_family_t); | int invalid_redirect(struct node_host *, sa_family_t); | ||||
u_int16_t parseicmpspec(char *, sa_family_t); | u_int16_t parseicmpspec(char *, sa_family_t); | ||||
int kw_casecmp(const void *, const void *); | int kw_casecmp(const void *, const void *); | ||||
int map_tos(char *string, int *); | int map_tos(char *string, int *); | ||||
static TAILQ_HEAD(loadanchorshead, loadanchors) | static TAILQ_HEAD(loadanchorshead, loadanchors) | ||||
▲ Show 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | |||||
%type <v.mac> xmac mac mac_list macspec | %type <v.mac> xmac mac mac_list macspec | ||||
%% | %% | ||||
ruleset : /* empty */ | ruleset : /* empty */ | ||||
| ruleset include '\n' | | ruleset include '\n' | ||||
| ruleset '\n' | | ruleset '\n' | ||||
| ruleset option '\n' | | ruleset option '\n' | ||||
| ruleset etherrule '\n' | | ruleset etherrule '\n' | ||||
| ruleset etheranchorrule '\n' | |||||
| ruleset scrubrule '\n' | | ruleset scrubrule '\n' | ||||
| ruleset natrule '\n' | | ruleset natrule '\n' | ||||
| ruleset binatrule '\n' | | ruleset binatrule '\n' | ||||
| ruleset pfrule '\n' | | ruleset pfrule '\n' | ||||
| ruleset anchorrule '\n' | | ruleset anchorrule '\n' | ||||
| ruleset loadrule '\n' | | ruleset loadrule '\n' | ||||
| ruleset altqif '\n' | | ruleset altqif '\n' | ||||
| ruleset queuespec '\n' | | ruleset queuespec '\n' | ||||
▲ Show 20 Lines • Show All 614 Lines • ▼ Show 20 Lines | etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_opts | ||||
r.quick = $4.quick; | r.quick = $4.quick; | ||||
if ($8.tag != NULL) | if ($8.tag != NULL) | ||||
memcpy(&r.tagname, $8.tag, sizeof(r.tagname)); | memcpy(&r.tagname, $8.tag, sizeof(r.tagname)); | ||||
if ($8.queues.qname != NULL) | if ($8.queues.qname != NULL) | ||||
memcpy(&r.qname, $8.queues.qname, sizeof(r.qname)); | memcpy(&r.qname, $8.queues.qname, sizeof(r.qname)); | ||||
r.dnpipe = $8.dnpipe; | r.dnpipe = $8.dnpipe; | ||||
r.dnflags = $8.free_flags; | r.dnflags = $8.free_flags; | ||||
expand_eth_rule(&r, $5, $6, $7.src, $7.dst); | expand_eth_rule(&r, $5, $6, $7.src, $7.dst, ""); | ||||
} | } | ||||
; | ; | ||||
etherpfa_anchorlist : /* empty */ | |||||
| etherpfa_anchorlist '\n' | |||||
| etherpfa_anchorlist etherrule '\n' | |||||
| etherpfa_anchorlist etheranchorrule '\n' | |||||
; | |||||
etherpfa_anchor : '{' | |||||
{ | |||||
char ta[PF_ANCHOR_NAME_SIZE]; | |||||
struct pfctl_eth_ruleset *rs; | |||||
/* steping into a brace anchor */ | |||||
pf->asd++; | |||||
pf->bn++; | |||||
/* create a holding ruleset in the root */ | |||||
snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn); | |||||
rs = pf_find_or_create_eth_ruleset(ta); | |||||
if (rs == NULL) | |||||
err(1, "etherpfa_anchor: pf_find_or_create_eth_ruleset"); | |||||
pf->eastack[pf->asd] = rs->anchor; | |||||
pf->eanchor = rs->anchor; | |||||
} '\n' etherpfa_anchorlist '}' | |||||
{ | |||||
pf->ealast = pf->eanchor; | |||||
pf->asd--; | |||||
pf->eanchor = pf->eastack[pf->asd]; | |||||
} | |||||
| /* empty */ | |||||
; | |||||
etheranchorrule : ETHER ANCHOR anchorname dir quick interface etherproto etherfromto etherpfa_anchor | |||||
{ | |||||
struct pfctl_eth_rule r; | |||||
if (check_rulestate(PFCTL_STATE_ETHER)) { | |||||
free($3); | |||||
YYERROR; | |||||
} | |||||
if ($3 && ($3[0] == '_' || strstr($3, "/_") != NULL)) { | |||||
free($3); | |||||
yyerror("anchor names beginning with '_' " | |||||
"are reserved for internal use"); | |||||
YYERROR; | |||||
} | |||||
memset(&r, 0, sizeof(r)); | |||||
if (pf->eastack[pf->asd + 1]) { | |||||
/* move inline rules into relative location */ | |||||
pfctl_eth_anchor_setup(pf, &r, | |||||
&pf->eastack[pf->asd]->ruleset, | |||||
$3 ? $3 : pf->ealast->name); | |||||
if (r.anchor == NULL) | |||||
err(1, "etheranchorrule: unable to " | |||||
"create ruleset"); | |||||
if (pf->ealast != r.anchor) { | |||||
if (r.anchor->match) { | |||||
yyerror("inline anchor '%s' " | |||||
"already exists", | |||||
r.anchor->name); | |||||
YYERROR; | |||||
} | |||||
mv_eth_rules(&pf->ealast->ruleset, | |||||
&r.anchor->ruleset); | |||||
} | |||||
pf_remove_if_empty_eth_ruleset(&pf->ealast->ruleset); | |||||
pf->ealast = r.anchor; | |||||
} else { | |||||
if (!$3) { | |||||
yyerror("anchors without explicit " | |||||
"rules must specify a name"); | |||||
YYERROR; | |||||
} | |||||
} | |||||
r.direction = $4; | |||||
r.quick = $5.quick; | |||||
expand_eth_rule(&r, $6, $7, $8.src, $8.dst, | |||||
pf->eastack[pf->asd + 1] ? pf->ealast->name : $3); | |||||
free($3); | |||||
pf->eastack[pf->asd + 1] = NULL; | |||||
} | |||||
; | |||||
etherfilter_opts : { | etherfilter_opts : { | ||||
bzero(&filter_opts, sizeof filter_opts); | bzero(&filter_opts, sizeof filter_opts); | ||||
} | } | ||||
etherfilter_opts_l | etherfilter_opts_l | ||||
{ $$ = filter_opts; } | { $$ = filter_opts; } | ||||
| /* empty */ { | | /* empty */ { | ||||
bzero(&filter_opts, sizeof filter_opts); | bzero(&filter_opts, sizeof filter_opts); | ||||
$$ = filter_opts; | $$ = filter_opts; | ||||
▲ Show 20 Lines • Show All 4,424 Lines • ▼ Show 20 Lines | if (errs) | ||||
return (1); | return (1); | ||||
else | else | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
expand_eth_rule(struct pfctl_eth_rule *r, | expand_eth_rule(struct pfctl_eth_rule *r, | ||||
struct node_if *interfaces, struct node_etherproto *protos, | struct node_if *interfaces, struct node_etherproto *protos, | ||||
struct node_mac *srcs, struct node_mac *dsts) | struct node_mac *srcs, struct node_mac *dsts, const char *anchor_call) | ||||
{ | { | ||||
struct pfctl_eth_rule *rule; | |||||
LOOP_THROUGH(struct node_if, interface, interfaces, | LOOP_THROUGH(struct node_if, interface, interfaces, | ||||
LOOP_THROUGH(struct node_etherproto, proto, protos, | LOOP_THROUGH(struct node_etherproto, proto, protos, | ||||
LOOP_THROUGH(struct node_mac, src, srcs, | LOOP_THROUGH(struct node_mac, src, srcs, | ||||
LOOP_THROUGH(struct node_mac, dst, dsts, | LOOP_THROUGH(struct node_mac, dst, dsts, | ||||
r->nr = pf->eth_nr++; | |||||
strlcpy(r->ifname, interface->ifname, | strlcpy(r->ifname, interface->ifname, | ||||
sizeof(r->ifname)); | sizeof(r->ifname)); | ||||
r->ifnot = interface->not; | r->ifnot = interface->not; | ||||
r->proto = proto->proto; | r->proto = proto->proto; | ||||
bcopy(src->mac, r->src.addr, ETHER_ADDR_LEN); | bcopy(src->mac, r->src.addr, ETHER_ADDR_LEN); | ||||
r->src.neg = src->neg; | r->src.neg = src->neg; | ||||
bcopy(dst->mac, r->dst.addr, ETHER_ADDR_LEN); | bcopy(dst->mac, r->dst.addr, ETHER_ADDR_LEN); | ||||
r->dst.neg = dst->neg; | r->dst.neg = dst->neg; | ||||
r->nr = pf->eastack[pf->asd]->match++; | |||||
if ((rule = calloc(1, sizeof(*rule))) == NULL) | pfctl_append_eth_rule(pf, r, anchor_call); | ||||
err(1, "calloc"); | |||||
bcopy(r, rule, sizeof(*rule)); | |||||
TAILQ_INSERT_TAIL(&pf->eth_rules, rule, entries); | |||||
)))); | )))); | ||||
FREE_LIST(struct node_if, interfaces); | FREE_LIST(struct node_if, interfaces); | ||||
FREE_LIST(struct node_etherproto, protos); | FREE_LIST(struct node_etherproto, protos); | ||||
FREE_LIST(struct node_mac, srcs); | FREE_LIST(struct node_mac, srcs); | ||||
FREE_LIST(struct node_mac, dsts); | FREE_LIST(struct node_mac, dsts); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 844 Lines • ▼ Show 20 Lines | for (i = 0; i < PF_RULESET_MAX; ++i) { | ||||
src->anchor->match = 0; | src->anchor->match = 0; | ||||
while ((r = TAILQ_FIRST(src->rules[i].inactive.ptr)) | while ((r = TAILQ_FIRST(src->rules[i].inactive.ptr)) | ||||
!= NULL) { | != NULL) { | ||||
TAILQ_REMOVE(src->rules[i].inactive.ptr, r, entries); | TAILQ_REMOVE(src->rules[i].inactive.ptr, r, entries); | ||||
TAILQ_INSERT_TAIL(dst->rules[i].inactive.ptr, | TAILQ_INSERT_TAIL(dst->rules[i].inactive.ptr, | ||||
r, entries); | r, entries); | ||||
} | } | ||||
} | } | ||||
} | |||||
void | |||||
mv_eth_rules(struct pfctl_eth_ruleset *src, struct pfctl_eth_ruleset *dst) | |||||
{ | |||||
struct pfctl_eth_rule *r; | |||||
while ((r = TAILQ_FIRST(&src->rules)) != NULL) { | |||||
TAILQ_REMOVE(&src->rules, r, entries); | |||||
TAILQ_INSERT_TAIL(&dst->rules, r, entries); | |||||
dst->anchor->match++; | |||||
} | |||||
src->anchor->match = 0; | |||||
} | } | ||||
void | void | ||||
decide_address_family(struct node_host *n, sa_family_t *af) | decide_address_family(struct node_host *n, sa_family_t *af) | ||||
{ | { | ||||
if (*af != 0 || n == NULL) | if (*af != 0 || n == NULL) | ||||
return; | return; | ||||
*af = n->af; | *af = n->af; | ||||
▲ Show 20 Lines • Show All 271 Lines • Show Last 20 Lines |