From: Guillaume Subiron <maet...@subiron.org> This patch adds an IPv6 address to the DNS relay. in6_equal_dns() is developed using this Slirp attribute. sotranslate_in/out/accept() are also updated to manage the IPv6 case so the guest can be able to join the host using one of the Slirp addresses.
Signed-off-by: Guillaume Subiron <maet...@subiron.org> Signed-off-by: Samuel Thibault <samuel.thiba...@ens-lyon.org> --- slirp/ip6.h | 5 ++++- slirp/slirp.c | 2 ++ slirp/slirp.h | 1 + slirp/socket.c | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/slirp/ip6.h b/slirp/ip6.h index 9e65acd..c799421 100644 --- a/slirp/ip6.h +++ b/slirp/ip6.h @@ -74,7 +74,10 @@ static inline int in6_equal_mach(struct in6_addr a, struct in6_addr b, || (in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64)\ && in6_equal_mach(a, slirp->vhost_addr6, 64))) -#define in6_equal_dns(a) 0 +#define in6_equal_dns(a)\ + ((in6_equal_net(a, slirp->vprefix_addr6, slirp->vprefix_len)\ + || in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64))\ + && in6_equal_mach(a, slirp->vnameserver_addr6, slirp->vprefix_len)) #define in6_equal_host(a)\ (in6_equal_router(a) || in6_equal_dns(a)) diff --git a/slirp/slirp.c b/slirp/slirp.c index d8a4de0..b7c5f2c 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -234,6 +234,8 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, slirp->bootp_filename = g_strdup(bootfile); slirp->vdhcp_startaddr = vdhcp_start; slirp->vnameserver_addr = vnameserver; + /* :TODO:maethor:130311: Use a parameter passed to the function */ + inet_pton(AF_INET6, "fec0::3", &slirp->vnameserver_addr6); if (vdnssearch) { translate_dnssearch(slirp, vdnssearch); diff --git a/slirp/slirp.h b/slirp/slirp.h index 1c3acb5..3400712 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -236,6 +236,7 @@ struct Slirp { struct in6_addr vhost_addr6; struct in_addr vdhcp_startaddr; struct in_addr vnameserver_addr; + struct in6_addr vnameserver_addr6; struct in_addr client_ipaddr; char client_hostname[33]; diff --git a/slirp/socket.c b/slirp/socket.c index 6960b47..3244ea9 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -741,12 +741,12 @@ sofwdrain(struct socket *so) /* * Translate addr in host addr when it is a virtual address - * :TODO:maethor:130314: Manage IPv6 */ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr) { Slirp *slirp = so->slirp; struct sockaddr_in *sin = (struct sockaddr_in *)addr; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; switch (addr->ss_family) { case AF_INET: @@ -767,16 +767,29 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr) ntohs(sin->sin_port), inet_ntoa(sin->sin_addr))); break; + case AF_INET6: + if (in6_equal_net(so->so_faddr6, slirp->vprefix_addr6, + slirp->vprefix_len)) { + if (in6_equal(so->so_faddr6, slirp->vnameserver_addr6)) { + /*if (get_dns_addr(&addr) < 0) {*/ /* TODO */ + sin6->sin6_addr = in6addr_loopback; + /*}*/ + } else { + sin6->sin6_addr = in6addr_loopback; + } + } + break; + default: break; } } -/* :TODO:maethor:130314: IPv6 */ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) { Slirp *slirp = so->slirp; struct sockaddr_in *sin = (struct sockaddr_in *)addr; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; switch (addr->ss_family) { case AF_INET: @@ -793,6 +806,16 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) } break; + case AF_INET6: + if (in6_equal_net(so->so_faddr6, slirp->vprefix_addr6, + slirp->vprefix_len)) { + if (in6_equal(sin6->sin6_addr, in6addr_loopback) + || !in6_equal(so->so_faddr6, slirp->vhost_addr6)) { + sin6->sin6_addr = so->so_faddr6; + } + } + break; + default: break; } @@ -800,7 +823,6 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) /* * Translate connections from localhost to the real hostname - * :TODO: IPv6 */ void sotranslate_accept(struct socket *so) { @@ -815,6 +837,13 @@ void sotranslate_accept(struct socket *so) } break; + case AF_INET6: + if (in6_equal(so->so_faddr6, in6addr_any) || + in6_equal(so->so_faddr6, in6addr_loopback)) { + so->so_faddr6 = slirp->vhost_addr6; + } + break; + default: break; } -- 2.6.2