summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/relayd')
-rw-r--r--usr.sbin/relayd/parse.y30
-rw-r--r--usr.sbin/relayd/relay.c20
-rw-r--r--usr.sbin/relayd/relayd.c53
-rw-r--r--usr.sbin/relayd/relayd.conf.536
-rw-r--r--usr.sbin/relayd/relayd.h5
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);