summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2008-05-09 02:44:56 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2008-05-09 02:44:56 +0000
commit6b5278216d3e945e7764e8fb4d6084731d9c1d42 (patch)
treee16579e8549035c8a3ce6525cf6278091980d103 /sbin
parentbf10d8a20a778604168423fc81c27ee72bc63285 (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.y50
-rw-r--r--sbin/pfctl/pfctl_parser.c18
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(" -> ");