diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2008-05-09 02:44:56 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2008-05-09 02:44:56 +0000 |
commit | 6b5278216d3e945e7764e8fb4d6084731d9c1d42 (patch) | |
tree | e16579e8549035c8a3ce6525cf6278091980d103 /sbin | |
parent | bf10d8a20a778604168423fc81c27ee72bc63285 (diff) |
divert packets to local socket without modifying the ip header;
makes transparent proxies much easier; ok beck@, feedback claudio@
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/pfctl/parse.y | 50 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 18 |
2 files changed, 66 insertions, 2 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index be585533527..2c4a2ce81d7 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.543 2008/05/08 08:08:36 deraadt Exp $ */ +/* $OpenBSD: parse.y,v 1.544 2008/05/09 02:44:54 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -232,6 +232,10 @@ struct filter_opts { char *match_tag; u_int8_t match_tag_not; u_int rtableid; + struct { + struct node_host *addr; + u_int16_t port; + } divert; } filter_opts; struct antispoof_opts { @@ -436,6 +440,7 @@ typedef struct { %token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH %token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE SETTOS +%token DIVERTTO DIVERTREPLY %token <v.string> STRING %token <v.number> NUMBER %token <v.i> PORTBINARY @@ -2177,6 +2182,30 @@ pfrule : action dir logquick interface route af proto fromto } free($9.queues.pqname); } + if ((r.divert.port = htons($9.divert.port))) { + if (r.direction == PF_OUT) { + if ($9.divert.addr) { + yyerror("address specified " + "for outgoing divert"); + YYERROR; + } + bzero(&r.divert.addr, + sizeof(r.divert.addr)); + } else { + if (!$9.divert.addr) { + yyerror("no address specified " + "for incoming divert"); + YYERROR; + } + if ($9.divert.addr->af != r.af) { + yyerror("address family " + "mismatch for divert"); + YYERROR; + } + r.divert.addr = + $9.divert.addr->addr.v.a.addr; + } + } expand_rule(&r, $4, $5.host, $7, $8.src_os, $8.src.host, $8.src.port, $8.dst.host, $8.dst.port, @@ -2293,6 +2322,23 @@ filter_opt : USER uids { } filter_opts.rtableid = $2; } + | DIVERTTO STRING number { + if ((filter_opts.divert.addr = host($2)) == NULL) { + yyerror("could not parse divert address: %s", + $2); + free($2); + YYERROR; + } + free($2); + filter_opts.divert.port = $3; + if (!filter_opts.divert.port) { + yyerror("invalid divert port: %d", $3); + YYERROR; + } + } + | DIVERTREPLY { + filter_opts.divert.port = 1; /* some random value */ + } ; probability : STRING { @@ -5173,6 +5219,8 @@ lookup(char *s) { "code", CODE}, { "crop", FRAGCROP}, { "debug", DEBUG}, + { "divert-reply", DIVERTREPLY}, + { "divert-to", DIVERTTO}, { "drop", DROP}, { "drop-ovl", FRAGDROP}, { "dup-to", DUPTO}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 59dac6f9a60..932eb357b0f 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.236 2008/05/07 06:23:30 markus Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.237 2008/05/09 02:44:55 markus Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -983,6 +983,22 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose) } if (r->rtableid != -1) printf(" rtable %u", r->rtableid); + if (r->divert.port) { + if (PF_AZERO(&r->divert.addr, r->af)) { + printf(" divert-reply"); + } else { + /* XXX cut&paste from print_addr */ + char buf[48]; + + printf(" divert-to "); + if (inet_ntop(r->af, &r->divert.addr, buf, + sizeof(buf)) == NULL) + printf("?"); + else + printf("%s", buf); + printf(" %u", ntohs(r->divert.port)); + } + } if (!anchor_call[0] && (r->action == PF_NAT || r->action == PF_BINAT || r->action == PF_RDR)) { printf(" -> "); |