diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2009-04-06 12:05:56 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2009-04-06 12:05:56 +0000 |
commit | 63f618ffc13737b6d73b157c8b7921c7b0e4be29 (patch) | |
tree | 0a1338ce99c5274fd3ecdcef7b8e017b3df9e461 /sbin/pfctl | |
parent | 4b3aad969b68381a5f8dc7beb977b479929205ec (diff) |
1) scrub rules are completely gone.
2) packet reassembly: only one method remains, full reassembly. crop
and drop-ovl are gone.
. set reassemble yes|no [no-df]
if no-df is given fragments (and only fragments!) with the df bit set
have it cleared before entering the fragment cache, and thus the
reassembled packet doesn't have df set either. it does NOT touch
non-fragmented packets.
3) regular rules can have scrub options.
. pass scrub(no-df, min-ttl 64, max-mss 1400, set-tos lowdelay)
. match scrub(reassemble tcp, random-id)
of course all options are optional. the individual options still do
what they used to do on scrub rules, but everything is stateful now.
4) match rules
"match" is a new action, just like pass and block are, and can be used
like they do. opposed to pass or block, they do NOT change the
pass/block state of a packet. i. e.
. pass
. match
passes the packet, and
. block
. match
blocks it.
Every time (!) a match rule matches, i. e. not only when it is the
last matching rule, the following actions are set:
-queue assignment. can be overwritten later, the last rule that set a
queue wins. note how this is different from the last matching rule
wins, if the last matching rule has no queue assignments and the
second last matching rule was a match rule with queue assignments,
these assignments are taken.
-rtable assignments. works the same as queue assignments.
-set-tos, min-ttl, max-mss, no-df, random-id, reassemble tcp, all work
like the above
-logging. every matching rule causes the packet to be logged. this
means a single packet can get logged more than once (think multiple log
interfaces with different receivers, like pflogd and spamlogd)
.
almost entirely hacked at n2k9 in basel, could not be committed close to
release. this really should have been multiple diffs, but splitting them
now is not feasible any more. input from mcbride and dlg, and frantzen
about the fragment handling.
speedup around 7% for the common case, the more the more scrub rules
were in use.
manpage not up to date, being worked on.
Diffstat (limited to 'sbin/pfctl')
-rw-r--r-- | sbin/pfctl/parse.y | 205 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 83 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 52 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 5 |
4 files changed, 151 insertions, 194 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 9c627390fce..3c3b9a67c85 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.555 2009/02/19 17:08:42 deraadt Exp $ */ +/* $OpenBSD: parse.y,v 1.556 2009/04/06 12:05:55 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -108,7 +108,6 @@ int atoul(char *, u_long *); enum { PFCTL_STATE_NONE, PFCTL_STATE_OPTION, - PFCTL_STATE_SCRUB, PFCTL_STATE_QUEUE, PFCTL_STATE_NAT, PFCTL_STATE_FILTER @@ -205,11 +204,15 @@ struct node_qassign { struct filter_opts { int marker; -#define FOM_FLAGS 0x01 -#define FOM_ICMP 0x02 -#define FOM_TOS 0x04 -#define FOM_KEEP 0x08 -#define FOM_SRCTRACK 0x10 +#define FOM_FLAGS 0x0001 +#define FOM_ICMP 0x0002 +#define FOM_TOS 0x0004 +#define FOM_KEEP 0x0008 +#define FOM_SRCTRACK 0x0010 +#define FOM_MINTTL 0x0020 +#define FOM_MAXMSS 0x0040 +#define FOM_SETTOS 0x0100 +#define FOM_SCRUB_TCP 0x0200 struct node_uid *uid; struct node_gid *gid; struct { @@ -237,6 +240,13 @@ struct filter_opts { struct node_host *addr; u_int16_t port; } divert; + + /* scrub opts */ + int nodf; + int minttl; + int settos; + int randomid; + int max_mss; } filter_opts; struct antispoof_opts { @@ -246,20 +256,12 @@ struct antispoof_opts { struct scrub_opts { int marker; -#define SOM_MINTTL 0x01 -#define SOM_MAXMSS 0x02 -#define SOM_FRAGCACHE 0x04 -#define SOM_SETTOS 0x08 int nodf; int minttl; int maxmss; int settos; - int fragcache; int randomid; int reassemble_tcp; - char *match_tag; - u_int8_t match_tag_not; - u_int rtableid; } scrub_opts; struct queue_opts { @@ -430,7 +432,7 @@ int parseport(char *, struct range *r, int); %} -%token PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS +%token PASS BLOCK MATCH SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS %token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE %token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF %token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL @@ -452,11 +454,11 @@ int parseport(char *, struct range *r, int); %token <v.i> PORTBINARY %type <v.interface> interface if_list if_item_not if_item %type <v.number> number icmptype icmp6type uid gid -%type <v.number> tos not yesno +%type <v.number> tos not yesno optnodf %type <v.probability> probability -%type <v.i> no dir af fragcache optimizer +%type <v.i> no dir af optimizer %type <v.i> sourcetrack flush unaryop statelock -%type <v.b> action nataction natpasslog scrubaction +%type <v.b> action nataction natpasslog %type <v.b> flags flag blockspec %type <v.range> portplain portstar portrange %type <v.hashkey> hashkey @@ -504,7 +506,6 @@ ruleset : /* empty */ | ruleset include '\n' | ruleset '\n' | ruleset option '\n' - | ruleset scrubrule '\n' | ruleset natrule '\n' | ruleset binatrule '\n' | ruleset pfrule '\n' @@ -560,7 +561,16 @@ optimizer : string { } ; -option : SET OPTIMIZATION STRING { +optnodf : /* empty */ { $$ = 0; } + | NODF { $$ = 1; } + ; + +option : SET REASSEMBLE yesno optnodf { + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + pfctl_set_reassembly(pf, $3, $4); + } + | SET OPTIMIZATION STRING { if (check_rulestate(PFCTL_STATE_OPTION)) { free($3); YYERROR; @@ -1018,87 +1028,18 @@ loadrule : LOAD ANCHOR string FROM string { free($5); }; -scrubaction : no SCRUB { - $$.b2 = $$.w = 0; - if ($1) - $$.b1 = PF_NOSCRUB; - else - $$.b1 = PF_SCRUB; - } - ; - -scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts - { - struct pf_rule r; - - if (check_rulestate(PFCTL_STATE_SCRUB)) - YYERROR; - - memset(&r, 0, sizeof(r)); - - r.action = $1.b1; - r.direction = $2; - - r.log = $3.log; - r.logif = $3.logif; - if ($3.quick) { - yyerror("scrub rules do not support 'quick'"); - YYERROR; - } - - r.af = $5; - if ($8.nodf) - r.rule_flag |= PFRULE_NODF; - if ($8.randomid) - r.rule_flag |= PFRULE_RANDOMID; - if ($8.reassemble_tcp) { - if (r.direction != PF_INOUT) { - yyerror("reassemble tcp rules can not " - "specify direction"); - YYERROR; - } - r.rule_flag |= PFRULE_REASSEMBLE_TCP; - } - if ($8.minttl) - r.min_ttl = $8.minttl; - if ($8.maxmss) - r.max_mss = $8.maxmss; - if ($8.marker & SOM_SETTOS) { - r.rule_flag |= PFRULE_SET_TOS; - r.set_tos = $8.settos; - } - if ($8.fragcache) - r.rule_flag |= $8.fragcache; - 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; - r.rtableid = $8.rtableid; - - expand_rule(&r, $4, NULL, $6, $7.src_os, - $7.src.host, $7.src.port, $7.dst.host, $7.dst.port, - NULL, NULL, NULL, ""); - } - ; - scrub_opts : { bzero(&scrub_opts, sizeof scrub_opts); - scrub_opts.rtableid = -1; } scrub_opts_l { $$ = scrub_opts; } | /* empty */ { bzero(&scrub_opts, sizeof scrub_opts); - scrub_opts.rtableid = -1; $$ = scrub_opts; } ; -scrub_opts_l : scrub_opts_l scrub_opt +scrub_opts_l : scrub_opts_l comma scrub_opt | scrub_opt ; @@ -1110,7 +1051,7 @@ scrub_opt : NODF { scrub_opts.nodf = 1; } | MINTTL NUMBER { - if (scrub_opts.marker & SOM_MINTTL) { + if (scrub_opts.marker & FOM_MINTTL) { yyerror("min-ttl cannot be respecified"); YYERROR; } @@ -1118,11 +1059,11 @@ scrub_opt : NODF { yyerror("illegal min-ttl value %d", $2); YYERROR; } - scrub_opts.marker |= SOM_MINTTL; + scrub_opts.marker |= FOM_MINTTL; scrub_opts.minttl = $2; } | MAXMSS NUMBER { - if (scrub_opts.marker & SOM_MAXMSS) { + if (scrub_opts.marker & FOM_MAXMSS) { yyerror("max-mss cannot be respecified"); YYERROR; } @@ -1130,25 +1071,17 @@ scrub_opt : NODF { yyerror("illegal max-mss value %d", $2); YYERROR; } - scrub_opts.marker |= SOM_MAXMSS; + scrub_opts.marker |= FOM_MAXMSS; scrub_opts.maxmss = $2; } | SETTOS tos { - if (scrub_opts.marker & SOM_SETTOS) { + if (scrub_opts.marker & FOM_SETTOS) { yyerror("set-tos cannot be respecified"); YYERROR; } - scrub_opts.marker |= SOM_SETTOS; + scrub_opts.marker |= FOM_SETTOS; scrub_opts.settos = $2; } - | fragcache { - if (scrub_opts.marker & SOM_FRAGCACHE) { - yyerror("fragcache cannot be respecified"); - YYERROR; - } - scrub_opts.marker |= SOM_FRAGCACHE; - scrub_opts.fragcache = $1; - } | REASSEMBLE STRING { if (strcasecmp($2, "tcp") != 0) { yyerror("scrub reassemble supports only tcp, " @@ -1170,22 +1103,6 @@ scrub_opt : NODF { } scrub_opts.randomid = 1; } - | RTABLE NUMBER { - if ($2 < 0 || $2 > RT_TABLEID_MAX) { - yyerror("invalid rtable id"); - YYERROR; - } - scrub_opts.rtableid = $2; - } - | not TAGGED string { - scrub_opts.match_tag = $3; - scrub_opts.match_tag_not = $1; - } - ; - -fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ } - | FRAGMENT FRAGCROP { $$ = PFRULE_FRAGCROP; } - | FRAGMENT FRAGDROP { $$ = PFRULE_FRAGDROP; } ; antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts { @@ -1872,6 +1789,21 @@ pfrule : action dir logquick interface route af proto fromto r.prob = $9.prob; r.rtableid = $9.rtableid; + if ($9.nodf) + r.scrub_flags |= PFSTATE_NODF; + if ($9.randomid) + r.scrub_flags |= PFSTATE_RANDOMID; + if ($9.minttl) + r.min_ttl = $9.minttl; + if ($9.max_mss) + r.max_mss = $9.max_mss; + if ($9.marker & FOM_SETTOS) { + r.scrub_flags |= PFSTATE_SETTOS; + r.set_tos = $9.settos; + } + if ($9.marker & FOM_SCRUB_TCP) + r.scrub_flags |= PFSTATE_SCRUB_TCP; + r.af = $6; if ($9.tag) if (strlcpy(r.tagname, $9.tag, @@ -2377,6 +2309,16 @@ filter_opt : USER uids { | DIVERTREPLY { filter_opts.divert.port = 1; /* some random value */ } + | SCRUB '(' scrub_opts ')' { + filter_opts.nodf = $3.nodf; + filter_opts.minttl = $3.minttl; + filter_opts.settos = $3.settos; + filter_opts.randomid = $3.randomid; + filter_opts.max_mss = $3.maxmss; + if ($3.reassemble_tcp) + filter_opts.marker |= FOM_SCRUB_TCP; + filter_opts.marker |= $3.marker; + } ; probability : STRING { @@ -2402,6 +2344,7 @@ probability : STRING { action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; } + | MATCH { $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; } | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; } ; @@ -4364,9 +4307,8 @@ rule_consistent(struct pf_rule *r, int anchor_call) switch (r->action) { case PF_PASS: + case PF_MATCH: case PF_DROP: - case PF_SCRUB: - case PF_NOSCRUB: problems = filter_consistent(r, anchor_call); break; case PF_NAT: @@ -4434,8 +4376,8 @@ filter_consistent(struct pf_rule *r, int anchor_call) yyerror("max-src-nodes requires 'source-track rule'"); problems++; } - if (r->action == PF_DROP && r->keep_state) { - yyerror("keep state on block rules doesn't make sense"); + if (r->action != PF_PASS && r->keep_state) { + yyerror("keep state is great, but only for pass rules"); problems++; } if (r->rule_flag & PFRULE_STATESLOPPY && @@ -4445,6 +4387,18 @@ filter_consistent(struct pf_rule *r, int anchor_call) "synproxy state or modulate state"); problems++; } + /* match rules rules */ + if (r->action == PF_MATCH) { + if (r->divert.port) { + yyerror("divert is not supported on match rules"); + problems++; + } + if (r->rt) { + yyerror("route-to, reply-to, dup-to and fastroute " + "must not be used on match rules"); + problems++; + } + } return (-problems); } @@ -5267,6 +5221,7 @@ lookup(char *s) { "load", LOAD}, { "log", LOG}, { "loginterface", LOGINTERFACE}, + { "match", MATCH}, { "max", MAXIMUM}, { "max-mss", MAXMSS}, { "max-src-conn", MAXSRCCONN}, diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 12f59517c7f..ff03a04d02d 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.280 2009/02/23 06:58:30 deraadt Exp $ */ +/* $OpenBSD: pfctl.c,v 1.281 2009/04/06 12:05:55 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -78,6 +78,7 @@ int pfctl_load_timeout(struct pfctl *, unsigned int, unsigned int); int pfctl_load_debug(struct pfctl *, unsigned int); int pfctl_load_logif(struct pfctl *, char *); int pfctl_load_hostid(struct pfctl *, unsigned int); +int pfctl_load_reassembly(struct pfctl *, u_int32_t); int pfctl_get_pool(int, struct pf_pool *, u_int32_t, u_int32_t, int, char *); void pfctl_print_rule_counters(struct pf_rule *, int); @@ -310,8 +311,7 @@ pfctl_clear_rules(int dev, int opts, char *anchorname) memset(&t, 0, sizeof(t)); t.pfrb_type = PFRB_TRANS; - if (pfctl_add_trans(&t, PF_RULESET_SCRUB, anchorname) || - pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) || + if (pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) || pfctl_trans(dev, &t, DIOCXBEGIN, 0) || pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) err(1, "pfctl_clear_rules"); @@ -835,47 +835,15 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, } header++; } - pr.rule.action = PF_SCRUB; - if (ioctl(dev, DIOCGETRULES, &pr)) { - warn("DIOCGETRULES"); - goto error; - } if (opts & PF_OPT_SHOWALL) { if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header)) pfctl_print_title("FILTER RULES:"); else if (format == PFCTL_SHOW_LABELS && labels) pfctl_print_title("LABEL COUNTERS:"); } - mnr = pr.nr; if (opts & PF_OPT_CLRRULECTRS) pr.action = PF_GET_CLR_CNTR; - for (nr = 0; nr < mnr; ++nr) { - pr.nr = nr; - if (ioctl(dev, DIOCGETRULE, &pr)) { - warn("DIOCGETRULE"); - goto error; - } - - if (pfctl_get_pool(dev, &pr.rule.rpool, - nr, pr.ticket, PF_SCRUB, path) != 0) - goto error; - - switch (format) { - case PFCTL_SHOW_LABELS: - break; - case PFCTL_SHOW_RULES: - if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL)) - labels = 1; - print_rule(&pr.rule, pr.anchor_call, rule_numbers); - printf("\n"); - pfctl_print_rule_counters(&pr.rule, opts); - break; - case PFCTL_SHOW_NOTHING: - break; - } - pfctl_clear_pool(&pr.rule.rpool); - } pr.rule.action = PF_PASS; if (ioctl(dev, DIOCGETRULES, &pr)) { warn("DIOCGETRULES"); @@ -1180,7 +1148,8 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call) struct pf_ruleset *rs; char *p; - rs_num = pf_get_ruleset_number(r->action); + rs_num = pf_get_ruleset_number(r->action == PF_MATCH ? PF_PASS : + r->action); if (rs_num == PF_RULESET_MAX) errx(1, "Invalid rule type %d", r->action); @@ -1236,8 +1205,7 @@ pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pf_anchor *a) return (2); } if ((pf->loadopt & PFCTL_FLAG_FILTER) != 0) { - if (pfctl_add_trans(pf->trans, PF_RULESET_SCRUB, path) || - pfctl_add_trans(pf->trans, PF_RULESET_FILTER, path)) + if (pfctl_add_trans(pf->trans, PF_RULESET_FILTER, path)) return (3); } if (pf->loadopt & PFCTL_FLAG_TABLE) @@ -1470,9 +1438,7 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, goto _error; } - if ((pf.loadopt & PFCTL_FLAG_FILTER && - (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_SCRUB, 0))) || - (pf.loadopt & PFCTL_FLAG_NAT && + if ((pf.loadopt & PFCTL_FLAG_NAT && (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_NAT, 0) || pfctl_load_ruleset(&pf, path, rs, PF_RULESET_RDR, 0) || pfctl_load_ruleset(&pf, path, rs, PF_RULESET_BINAT, 0))) || @@ -1636,6 +1602,11 @@ pfctl_load_options(struct pfctl *pf) if (pfctl_load_hostid(pf, pf->hostid)) error = 1; + /* load reassembly settings */ + if (!(pf->opts & PF_OPT_MERGE) || pf->reass_set) + if (pfctl_load_reassembly(pf, pf->reassemble)) + error = 1; + return (error); } @@ -1725,6 +1696,26 @@ pfctl_load_timeout(struct pfctl *pf, unsigned int timeout, unsigned int seconds) } int +pfctl_set_reassembly(struct pfctl *pf, int on, int nodf) +{ + if ((loadopt & PFCTL_FLAG_OPTION) == 0) + return (0); + + pf->reass_set = 1; + if (on) { + pf->reassemble = PF_REASS_ENABLED; + if (nodf) + pf->reassemble &= PF_REASS_NODF; + } + + if (pf->opts & PF_OPT_VERBOSE) + printf("set reassemble %s %s\n", on ? "yes" : "no", + nodf ? "no-df" : ""); + + return (0); +} + +int pfctl_set_optimization(struct pfctl *pf, const char *opt) { const struct pf_hint *hint; @@ -1823,6 +1814,16 @@ pfctl_load_hostid(struct pfctl *pf, u_int32_t hostid) } int +pfctl_load_reassembly(struct pfctl *pf, u_int32_t reassembly) +{ + if (ioctl(dev, DIOCSETREASS, &reassembly)) { + warnx("DIOCSETREASS"); + return (1); + } + return (0); +} + +int pfctl_set_debug(struct pfctl *pf, char *d) { u_int32_t level; diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 86c5f90ffeb..e31f83e92d1 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.241 2008/09/09 13:56:38 henning Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.242 2009/04/06 12:05:55 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -413,6 +413,7 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, print_addr(&pooladdr->addr, af, 0); break; case PF_PASS: + case PF_MATCH: if (PF_AZERO(&pooladdr->addr.v.a.addr, af)) printf("%s", pooladdr->ifname); else { @@ -651,6 +652,7 @@ print_src_node(struct pf_src_node *sn, int opts) printf(", rdr rule %u", sn->rule.nr); break; case PF_PASS: + case PF_MATCH: if (sn->rule.nr != -1) printf(", filter rule %u", sn->rule.nr); break; @@ -663,7 +665,8 @@ void print_rule(struct pf_rule *r, const char *anchor_call, int verbose) { static const char *actiontypes[] = { "pass", "block", "scrub", - "no scrub", "nat", "no nat", "binat", "no binat", "rdr", "no rdr" }; + "no scrub", "nat", "no nat", "binat", "no binat", "rdr", "no rdr", + "", "", "match"}; static const char *anchortypes[] = { "anchor", "anchor", "anchor", "anchor", "nat-anchor", "nat-anchor", "binat-anchor", "binat-anchor", "rdr-anchor", "rdr-anchor" }; @@ -671,7 +674,7 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose) if (verbose) printf("@%d ", r->nr); - if (r->action > PF_NORDR) + if (r->action > PF_MATCH) printf("action(%d)", r->action); else if (anchor_call[0]) { if (anchor_call[0] == '_') { @@ -799,7 +802,7 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose) print_flags(r->flags); printf("/"); print_flags(r->flagset); - } else if (r->action == PF_PASS && + } else if ((r->action == PF_PASS || r->action == PF_MATCH) && (!r->proto || r->proto == IPPROTO_TCP) && !(r->rule_flag & PFRULE_FRAGMENT) && !anchor_call[0] && r->keep_state) @@ -957,31 +960,26 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose) } printf(")"); } - if (r->rule_flag & PFRULE_FRAGMENT) - printf(" fragment"); - if (r->rule_flag & PFRULE_NODF) - printf(" no-df"); - if (r->rule_flag & PFRULE_RANDOMID) - printf(" random-id"); - if (r->min_ttl) - printf(" min-ttl %d", r->min_ttl); - if (r->max_mss) - printf(" max-mss %d", r->max_mss); - if (r->rule_flag & PFRULE_SET_TOS) - printf(" set-tos 0x%2.2x", r->set_tos); - if (r->allow_opts) - printf(" allow-opts"); - if (r->action == PF_SCRUB) { - if (r->rule_flag & PFRULE_REASSEMBLE_TCP) - printf(" reassemble tcp"); - if (r->rule_flag & PFRULE_FRAGDROP) - printf(" fragment drop-ovl"); - else if (r->rule_flag & PFRULE_FRAGCROP) - printf(" fragment crop"); - else - printf(" fragment reassemble"); + if (r->scrub_flags & PFSTATE_NODF || r->min_ttl || r->max_mss) { + printf(" scrub("); + if (r->scrub_flags & PFSTATE_NODF) + printf(" no-df"); + if (r->scrub_flags & PFSTATE_RANDOMID) + printf(" random-id"); + if (r->min_ttl) + printf(" min-ttl %d", r->min_ttl); + if (r->scrub_flags & PFSTATE_SETTOS) + printf(" set-tos 0x%2.2x", r->set_tos); + if (r->scrub_flags & PFSTATE_SCRUB_TCP) + printf(" reassemble tcp"); + if (r->max_mss) + printf(" max-mss %d", r->max_mss); + printf(")"); } + + if (r->allow_opts) + printf(" allow-opts"); if (r->label[0]) printf(" label \"%s\"", r->label); if (r->qname[0] && r->pqname[0]) diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 97b0325ddc7..758c576b4c4 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.87 2007/10/13 16:35:18 deraadt Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.88 2009/04/06 12:05:55 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -91,6 +91,7 @@ struct pfctl { u_int32_t limit[PF_LIMIT_MAX]; u_int32_t debug; u_int32_t hostid; + u_int32_t reassemble; char *ifname; u_int8_t timeout_set[PFTM_MAX]; @@ -98,6 +99,7 @@ struct pfctl { u_int8_t debug_set; u_int8_t hostid_set; u_int8_t ifname_set; + u_int8_t reass_set; }; struct node_if { @@ -197,6 +199,7 @@ void pfctl_move_pool(struct pf_pool *, struct pf_pool *); void pfctl_clear_pool(struct pf_pool *); int pfctl_set_timeout(struct pfctl *, const char *, int, int); +int pfctl_set_reassembly(struct pfctl *, int, int); int pfctl_set_optimization(struct pfctl *, const char *); int pfctl_set_limit(struct pfctl *, const char *, unsigned int); int pfctl_set_logif(struct pfctl *, char *); |