diff options
Diffstat (limited to 'usr.sbin/relayd')
-rw-r--r-- | usr.sbin/relayd/parse.y | 30 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 20 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.c | 53 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 36 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 5 |
5 files changed, 131 insertions, 13 deletions
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index b8812cac4c8..1fa08a74550 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.121 2008/07/19 11:38:54 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.122 2008/07/22 23:17:37 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -130,7 +130,7 @@ typedef struct { %token ON PATH PORT PREFORK PROTO QUERYSTR REAL REDIRECT RELAY REMOVE TRAP %token REQUEST RESPONSE RETRY RETURN ROUNDROBIN SACK SCRIPT SEND SESSION %token SOCKET SSL STICKYADDR STYLE TABLE TAG TCP TIMEOUT TO UPDATES URL -%token VIRTUAL WITH ERROR ROUTE TRANSPARENT PARENT +%token VIRTUAL WITH ERROR ROUTE TRANSPARENT PARENT INET INET6 %token <v.string> STRING %token <v.number> NUMBER %type <v.string> interface hostname table @@ -1136,7 +1136,7 @@ relayoptsl : LISTEN ON STRING port optssl { } tableport = h->port; } - | forwardmode TO forwardspec interface { + | forwardmode TO forwardspec interface dstaf { rlay->rl_conf.fwdmode = $1; switch ($1) { case FWD_NORMAL: @@ -1234,6 +1234,28 @@ dstmode : /* empty */ { $$ = RELAY_DSTMODE_DEFAULT; } | HASH { $$ = RELAY_DSTMODE_HASH; } ; +dstaf : /* empty */ { + rlay->rl_conf.dstaf.ss_family = AF_UNSPEC; + } + | INET { + rlay->rl_conf.dstaf.ss_family = AF_INET; + } + | INET6 STRING { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)&rlay->rl_conf.dstaf; + if (inet_pton(AF_INET6, $2, &sin6->sin6_addr) == -1) { + yyerror("invalid ipv6 address %s", $2); + free($2); + YYERROR; + } + free($2); + + sin6->sin6_family = AF_INET6; + sin6->sin6_len = sizeof(*sin6); + } + ; + interface : /*empty*/ { $$ = NULL; } | INTERFACE STRING { $$ = $2; } ; @@ -1373,6 +1395,8 @@ lookup(char *s) { "host", HOST }, { "icmp", ICMP }, { "include", INCLUDE }, + { "inet", INET }, + { "inet6", INET6 }, { "interface", INTERFACE }, { "interval", INTERVAL }, { "ip", IP }, diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index 21cbc69750e..f1dc6b066c4 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.94 2008/07/16 15:02:19 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.95 2008/07/22 23:17:37 reyk Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -2186,7 +2186,7 @@ int relay_connect(struct session *con) { struct relay *rlay = (struct relay *)con->se_relay; - int bnds = -1; + int bnds = -1, ret; if (gettimeofday(&con->se_tv_start, NULL)) return (-1); @@ -2208,6 +2208,22 @@ relay_connect(struct session *con) bnds = con->se_bnds; } + /* Do the IPv4-to-IPv6 or IPv6-to-IPv4 translation if requested */ + if (rlay->rl_conf.dstaf.ss_family != AF_UNSPEC) { + if (con->se_out.ss.ss_family == AF_INET && + rlay->rl_conf.dstaf.ss_family == AF_INET6) + ret = map4to6(&con->se_out.ss, &rlay->rl_conf.dstaf); + else if (con->se_out.ss.ss_family == AF_INET6 && + rlay->rl_conf.dstaf.ss_family == AF_INET) + ret = map6to4(&con->se_out.ss); + else + ret = 0; + if (ret != 0) { + log_debug("relay_connect: mapped to invalid address"); + return (-1); + } + } + retry: if ((con->se_out.s = relay_socket_connect(&con->se_out.ss, con->se_out.port, rlay->rl_proto, bnds)) == -1) { diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c index fad7f12692d..accff773de0 100644 --- a/usr.sbin/relayd/relayd.c +++ b/usr.sbin/relayd/relayd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.c,v 1.78 2008/07/09 14:06:44 reyk Exp $ */ +/* $OpenBSD: relayd.c,v 1.79 2008/07/22 23:17:37 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -1199,3 +1199,54 @@ bindany(struct ctl_bindany *bnd) close(s); return (-1); } + +int +map6to4(struct sockaddr_storage *in6) +{ + struct sockaddr_storage out4; + struct sockaddr_in *sin4 = (struct sockaddr_in *)&out4; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)in6; + + bzero(sin4, sizeof(*sin4)); + sin4->sin_len = sizeof(*sin4); + sin4->sin_family = AF_INET; + sin4->sin_port = sin6->sin6_port; + + bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr, + sizeof(sin4->sin_addr)); + + if (sin4->sin_addr.s_addr == INADDR_ANY || + sin4->sin_addr.s_addr == INADDR_BROADCAST || + IN_MULTICAST(ntohl(sin4->sin_addr.s_addr))) + return (-1); + + bcopy(&out4, in6, sizeof(*in6)); + + return (0); +} + +int +map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map) +{ + struct sockaddr_storage out6; + struct sockaddr_in *sin4 = (struct sockaddr_in *)in4; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&out6; + struct sockaddr_in6 *map6 = (struct sockaddr_in6 *)map; + + if (sin4->sin_addr.s_addr == INADDR_ANY || + sin4->sin_addr.s_addr == INADDR_BROADCAST || + IN_MULTICAST(ntohl(sin4->sin_addr.s_addr))) + return (-1); + + bcopy(map6, sin6, sizeof(*sin6)); + sin6->sin6_len = sizeof(*sin6); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = sin4->sin_port; + + bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12], + sizeof(sin4->sin_addr)); + + bcopy(&out6, in4, sizeof(*in4)); + + return (0); +} diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index 8314273a2b1..19956ae7564 100644 --- a/usr.sbin/relayd/relayd.conf.5 +++ b/usr.sbin/relayd/relayd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: relayd.conf.5,v 1.90 2008/07/19 16:35:50 jmc Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.91 2008/07/22 23:17:37 reyk Exp $ .\" .\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org> .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 19 2008 $ +.Dd $Mdocdate: July 22 2008 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -489,7 +489,7 @@ Start the relay but immediately close any accepted connections. .Ic forward to .Ar address .Op Ic port Ar port -.Op Ic retry Ar number +.Ar options ... .Xc Specify the address and port of the target host to connect to. If the @@ -497,16 +497,40 @@ If the option is not specified, the port from the .Ic listen on directive will be used. -.Pp Use the .Ic transparent keyword to enable fully-transparent mode; the source address of the client will be retained in this case. .Pp -The optional host retry option will be used as a tolerance for failed +The following options may be specified for forward directives: +.Pp +.Bl -tag -width Ds +.It Ic retry Ar number +The optional host +.Ic retry +option will be used as a tolerance for failed host connections; the connection will be retried for .Ar number more times. +.It Ic inet +If the requested destination is an IPv6 address, +.Xr relayd 8 +will forward the connection to an IPv4 address which is determined by +the last 4 octets of the original IPv6 destination. +For example, if the original IPv6 destination address is +2001:db8:7395:ffff::a01:101, the session is relayed to the IPv4 +address 10.1.1.1 (a01:101). +.It Ic inet6 Ar address-prefix +If the requested destination is an IPv4 address, +.Xr relayd 8 +will forward the connection to an IPv6 address which is determined by +setting the last 4 octets of the specified IPv6 +.Ar address-prefix +to the 4 octets of the original IPv4 destination. +For example, if the original IPv4 destination address is 10.1.1.1 and +the specified address prefix is 2001:db8:7395:ffff::, the session is +relayed to the IPv6 address 2001:db8:7395:ffff::a01:101. +.El .It Xo .Ic forward to .Aq Ar table @@ -520,7 +544,7 @@ section above for information about table options. .It Xo .Ic forward to .Ic nat lookup -.Op Ic retry Ar number +.Ar options ... .Xc When redirecting connections with an .Ar rdr diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index c6ebf8eb955..30143f13b9f 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.108 2008/07/19 11:38:54 reyk Exp $ */ +/* $OpenBSD: relayd.h,v 1.109 2008/07/22 23:17:37 reyk Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -590,6 +590,7 @@ struct relay_config { objid_t dsttable; struct sockaddr_storage ss; struct sockaddr_storage dstss; + struct sockaddr_storage dstaf; struct timeval timeout; enum forwardmode fwdmode; }; @@ -863,6 +864,8 @@ struct protonode *protonode_header(enum direction, struct protocol *, struct protonode *); int protonode_add(enum direction, struct protocol *, struct protonode *); +int map6to4(struct sockaddr_storage *); +int map4to6(struct sockaddr_storage *, struct sockaddr_storage *); /* carp.c */ int carp_demote_init(char *, int); |