-/* $OpenBSD: parse.y,v 1.676 2018/07/09 15:07:06 kn Exp $ */
+/* $OpenBSD: parse.y,v 1.677 2018/07/10 08:44:55 kn Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
int kw_casecmp(const void *, const void *);
int map_tos(char *string, int *);
int rdomain_exists(u_int);
+int filteropts_to_rule(struct pf_rule *, struct filter_opts *);
TAILQ_HEAD(loadanchorshead, loadanchors)
loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
r.direction = $3;
r.quick = $4.quick;
r.af = $6;
- r.prob = $9.prob;
- r.rtableid = $9.rtableid;
- r.pktrate.limit = $9.pktrate.limit;
- r.pktrate.seconds = $9.pktrate.seconds;
-
- if ($9.tag)
- if (strlcpy(r.tagname, $9.tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- if ($9.match_tag)
- if (strlcpy(r.match_tagname, $9.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- r.match_tag_not = $9.match_tag_not;
- if (rule_label(&r, $9.label))
- YYERROR;
- free($9.label);
- r.flags = $9.flags.b1;
- r.flagset = $9.flags.b2;
- if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
- yyerror("flags always false");
- YYERROR;
- }
+
if ($9.flags.b1 || $9.flags.b2 || $8.src_os) {
for (proto = $7; proto != NULL &&
proto->proto != IPPROTO_TCP;
}
}
- r.tos = $9.tos;
+ if (filteropts_to_rule(&r, &$9))
+ YYERROR;
if ($9.keep.action) {
yyerror("cannot specify state handling "
YYERROR;
}
- if ($9.match_tag)
- if (strlcpy(r.match_tagname, $9.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- r.match_tag_not = $9.match_tag_not;
- if ($9.marker & FOM_PRIO) {
- if ($9.prio == 0)
- r.prio = PF_PRIO_ZERO;
- else
- r.prio = $9.prio;
- }
- if ($9.marker & FOM_SETPRIO) {
- r.set_prio[0] = $9.set_prio[0];
- r.set_prio[1] = $9.set_prio[1];
- r.scrub_flags |= PFSTATE_SETPRIO;
- }
-
decide_address_family($8.src.host, &r.af);
decide_address_family($8.dst.host, &r.af);
r.log = $3.log;
r.logif = $3.logif;
r.quick = $3.quick;
- r.prob = $8.prob;
- r.rtableid = $8.rtableid;
-
- if ($8.nodf)
- r.scrub_flags |= PFSTATE_NODF;
- if ($8.randomid)
- r.scrub_flags |= PFSTATE_RANDOMID;
- if ($8.minttl)
- r.min_ttl = $8.minttl;
- if ($8.max_mss)
- r.max_mss = $8.max_mss;
- if ($8.marker & FOM_SETTOS) {
- r.scrub_flags |= PFSTATE_SETTOS;
- r.set_tos = $8.settos;
- }
- if ($8.marker & FOM_SCRUB_TCP)
- r.scrub_flags |= PFSTATE_SCRUB_TCP;
- if ($8.marker & FOM_PRIO) {
- if ($8.prio == 0)
- r.prio = PF_PRIO_ZERO;
- else
- r.prio = $8.prio;
- }
- if ($8.marker & FOM_SETPRIO) {
- r.set_prio[0] = $8.set_prio[0];
- r.set_prio[1] = $8.set_prio[1];
- r.scrub_flags |= PFSTATE_SETPRIO;
- }
+ r.af = $5;
+
+ if (filteropts_to_rule(&r, &$8))
+ YYERROR;
+
if ($8.marker & FOM_ONCE) {
if (r.action == PF_MATCH) {
yyerror("can't specify once for "
}
r.rule_flag |= PFRULE_ONCE;
}
- if ($8.marker & FOM_AFTO)
- r.rule_flag |= PFRULE_AFTO;
- if (($8.marker & FOM_AFTO) && r.direction != PF_IN) {
- yyerror("af-to can only be used with direction in");
- YYERROR;
- }
- if (($8.marker & FOM_AFTO) && $8.route.rt) {
- yyerror("af-to cannot be used together with "
- "route-to, reply-to, dup-to");
- YYERROR;
- }
- r.af = $5;
- if ($8.tag)
- if (strlcpy(r.tagname, $8.tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- if ($8.match_tag)
- if (strlcpy(r.match_tagname, $8.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- r.match_tag_not = $8.match_tag_not;
- if (rule_label(&r, $8.label))
- YYERROR;
- free($8.label);
- r.flags = $8.flags.b1;
- r.flagset = $8.flags.b2;
- if (($8.flags.b1 & $8.flags.b2) != $8.flags.b1) {
- yyerror("flags always false");
- YYERROR;
- }
if ($8.flags.b1 || $8.flags.b2 || $7.src_os) {
for (proto = $6; proto != NULL &&
proto->proto != IPPROTO_TCP;
}
}
- r.tos = $8.tos;
- r.pktrate.limit = $8.pktrate.limit;
- r.pktrate.seconds = $8.pktrate.seconds;
r.keep_state = $8.keep.action;
o = $8.keep.options;
if (r.keep_state && !statelock)
r.rule_flag |= default_statelock;
- if ($8.fragment)
- r.rule_flag |= PFRULE_FRAGMENT;
- r.allow_opts = $8.allowopts;
-
decide_address_family($7.src.host, &r.af);
decide_address_family($7.dst.host, &r.af);
err(1, "$8.rroute.rdr");
$8.rroute.rdr->host = $8.route.host;
}
- if ($8.queues.qname != NULL) {
- if (strlcpy(r.qname, $8.queues.qname,
- sizeof(r.qname)) >= sizeof(r.qname)) {
- yyerror("rule qname too long (max "
- "%d chars)", sizeof(r.qname)-1);
- YYERROR;
- }
- free($8.queues.qname);
- }
- if ($8.queues.pqname != NULL) {
- if (strlcpy(r.pqname, $8.queues.pqname,
- sizeof(r.pqname)) >= sizeof(r.pqname)) {
- yyerror("rule pqname too long (max "
- "%d chars)", sizeof(r.pqname)-1);
- YYERROR;
- }
- free($8.queues.pqname);
- }
+
if (expand_divertspec(&r, &$8.divert))
YYERROR;
/* rdomain is a table, but not an rdomain */
return 0;
}
+
+int
+filteropts_to_rule(struct pf_rule *r, struct filter_opts *opts)
+{
+
+ r->keep_state = opts->keep.action;
+ r->pktrate.limit = opts->pktrate.limit;
+ r->pktrate.seconds = opts->pktrate.seconds;
+ r->prob = opts->prob;
+ r->rtableid = opts->rtableid;
+ r->tos = opts->tos;
+
+ if (opts->nodf)
+ r->scrub_flags |= PFSTATE_NODF;
+ if (opts->randomid)
+ r->scrub_flags |= PFSTATE_RANDOMID;
+ if (opts->minttl)
+ r->min_ttl = opts->minttl;
+ if (opts->max_mss)
+ r->max_mss = opts->max_mss;
+
+ if (opts->tag)
+ if (strlcpy(r->tagname, opts->tag,
+ PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
+ yyerror("tag too long, max %u chars",
+ PF_TAG_NAME_SIZE - 1);
+ return (1);
+ }
+ if (opts->match_tag)
+ if (strlcpy(r->match_tagname, opts->match_tag,
+ PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
+ yyerror("tag too long, max %u chars",
+ PF_TAG_NAME_SIZE - 1);
+ return (1);
+ }
+ r->match_tag_not = opts->match_tag_not;
+
+ if (rule_label(r, opts->label))
+ return (1);
+ free(opts->label);
+
+ if (opts->marker & FOM_AFTO)
+ r->rule_flag |= PFRULE_AFTO;
+ if ((opts->marker & FOM_AFTO) && r->direction != PF_IN) {
+ yyerror("af-to can only be used with direction in");
+ return (1);
+ }
+ if ((opts->marker & FOM_AFTO) && opts->route.rt) {
+ yyerror("af-to cannot be used together with "
+ "route-to, reply-to, dup-to");
+ return (1);
+ }
+ if (opts->marker & FOM_SCRUB_TCP)
+ r->scrub_flags |= PFSTATE_SCRUB_TCP;
+ if (opts->marker & FOM_PRIO) {
+ if (opts->prio == 0)
+ r->prio = PF_PRIO_ZERO;
+ else
+ r->prio = opts->prio;
+ }
+ if (opts->marker & FOM_SETPRIO) {
+ r->set_prio[0] = opts->set_prio[0];
+ r->set_prio[1] = opts->set_prio[1];
+ r->scrub_flags |= PFSTATE_SETPRIO;
+ }
+ if (opts->marker & FOM_SETTOS) {
+ r->scrub_flags |= PFSTATE_SETTOS;
+ r->set_tos = opts->settos;
+ }
+ if (opts->marker & FOM_PRIO) {
+ if (opts->prio == 0)
+ r->prio = PF_PRIO_ZERO;
+ else
+ r->prio = opts->prio;
+ }
+ if (opts->marker & FOM_SETPRIO) {
+ r->set_prio[0] = opts->set_prio[0];
+ r->set_prio[1] = opts->set_prio[1];
+ r->scrub_flags |= PFSTATE_SETPRIO;
+ }
+
+ r->flags = opts->flags.b1;
+ r->flagset = opts->flags.b2;
+ if ((opts->flags.b1 & opts->flags.b2) != opts->flags.b1) {
+ yyerror("flags always false");
+ return (1);
+ }
+
+ if (opts->queues.qname != NULL) {
+ if (strlcpy(r->qname, opts->queues.qname,
+ sizeof(r->qname)) >= sizeof(r->qname)) {
+ yyerror("rule qname too long (max "
+ "%d chars)", sizeof(r->qname)-1);
+ return (1);
+ }
+ free(opts->queues.qname);
+ }
+ if (opts->queues.pqname != NULL) {
+ if (strlcpy(r->pqname, opts->queues.pqname,
+ sizeof(r->pqname)) >= sizeof(r->pqname)) {
+ yyerror("rule pqname too long (max "
+ "%d chars)", sizeof(r->pqname)-1);
+ return (1);
+ }
+ free(opts->queues.qname);
+ }
+
+ if (opts->fragment)
+ r->rule_flag |= PFRULE_FRAGMENT;
+ r->allow_opts = opts->allowopts;
+
+ return (0);
+}