diff options
author | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2007-10-25 21:36:22 +0000 |
---|---|---|
committer | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2007-10-25 21:36:22 +0000 |
commit | cf48ace55424a7884a2f2fd871d784ecdc0acfa5 (patch) | |
tree | e604ab7d9c6396d5dea6dffe48a8c910a17d6551 | |
parent | 9aa76eb1b15f97fde2bfcaf1834116a1f9a54a17 (diff) |
Fix probability rules w/ numbers (e.g probability 0.4).
Add support for probablities of 0% and 100%.
With and OK deraadt@
-rw-r--r-- | sbin/pfctl/parse.y | 50 | ||||
-rw-r--r-- | sys/net/pf.c | 8 |
2 files changed, 37 insertions, 21 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index e5375f5cfb6..dddd199d80f 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.532 2007/10/22 16:35:33 pyr Exp $ */ +/* $OpenBSD: parse.y,v 1.533 2007/10/25 21:36:21 mpf Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -341,6 +341,7 @@ struct loadanchors { typedef struct { union { int64_t number; + double probability; int i; char *string; u_int rtableid; @@ -437,6 +438,7 @@ typedef struct { %type <v.interface> interface if_list if_item_not if_item %type <v.number> icmptype icmp6type uid gid %type <v.number> tos not yesno +%type <v.probability> probability %type <v.i> no dir af fragcache optimizer %type <v.i> sourcetrack flush unaryop statelock %type <v.b> action nataction natpasslog scrubaction @@ -2190,27 +2192,17 @@ filter_opt : USER uids { filter_opts.match_tag = $3; filter_opts.match_tag_not = $1; } - | PROBABILITY STRING { - char *e; - double p = strtod($2, &e); + | PROBABILITY probability { + double p; - if (*e == '%') { - p *= 0.01; - e++; - } - if (*e) { - yyerror("invalid probability: %s", $2); - free($2); - YYERROR; - } - p = floor(p * (UINT_MAX+1.0) + 0.5); - if (p < 1.0 || p >= (UINT_MAX+1.0)) { - yyerror("invalid probability: %s", $2); - free($2); + p = floor($2 * UINT_MAX + 0.5); + if (p < 0.0 || p > UINT_MAX) { + yyerror("invalid probability: %lf", p); YYERROR; } filter_opts.prob = (u_int32_t)p; - free($2); + if (filter_opts.prob == 0) + filter_opts.prob = 1; } | RTABLE NUMBER { if ($2 < 0 || $2 > RT_TABLEID_MAX) { @@ -2221,6 +2213,28 @@ filter_opt : USER uids { } ; +probability : STRING { + char *e; + double p = strtod($1, &e); + + if (*e == '%') { + p *= 0.01; + e++; + } + if (*e) { + yyerror("invalid probability: %s", $1); + free($1); + YYERROR; + } + free($1); + $$ = p; + } + | NUMBER { + $$ = (double)$1; + } + ; + + action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; } | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; } ; diff --git a/sys/net/pf.c b/sys/net/pf.c index 66aa25cd515..3a12517ea9e 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.559 2007/09/18 18:45:59 markus Exp $ */ +/* $OpenBSD: pf.c,v 1.560 2007/10/25 21:36:21 mpf Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -3113,7 +3113,8 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], pd->lookup.gid)) r = TAILQ_NEXT(r, entries); - else if (r->prob && r->prob <= arc4random()) + else if (r->prob && r->prob <= + (arc4random() % (UINT_MAX - 1) + 1)) r = TAILQ_NEXT(r, entries); else if (r->match_tag && !pf_match_tag(m, r, &tag)) r = TAILQ_NEXT(r, entries); @@ -3563,7 +3564,8 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, r->flagset || r->type || r->code || r->os_fingerprint != PF_OSFP_ANY) r = TAILQ_NEXT(r, entries); - else if (r->prob && r->prob <= arc4random()) + else if (r->prob && r->prob <= + (arc4random() % (UINT_MAX - 1) + 1)) r = TAILQ_NEXT(r, entries); else if (r->match_tag && !pf_match_tag(m, r, &tag)) r = TAILQ_NEXT(r, entries); |