diff options
Diffstat (limited to 'slirp')
-rw-r--r-- | slirp/ip6.h | 6 | ||||
-rw-r--r-- | slirp/slirp.c | 3 | ||||
-rw-r--r-- | slirp/slirp.h | 1 | ||||
-rw-r--r-- | slirp/socket.c | 32 |
4 files changed, 41 insertions, 1 deletions
diff --git a/slirp/ip6.h b/slirp/ip6.h index 731ee72d77..8ddfa242c4 100644 --- a/slirp/ip6.h +++ b/slirp/ip6.h @@ -72,7 +72,11 @@ static inline bool in6_equal_mach(const struct in6_addr *a, || (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_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\ + || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\ + && in6_equal_mach(a, &slirp->vnameserver_addr6, 64))) #define in6_equal_host(a)\ (in6_equal_router(a) || in6_equal_dns(a)) diff --git a/slirp/slirp.c b/slirp/slirp.c index 50b36f4126..7a47bb60a9 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -231,10 +231,13 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, slirp->vprefix_len = 64; slirp->vhost_addr6 = slirp->vprefix_addr6; slirp->vhost_addr6.s6_addr[15] = 0x2; + slirp->vnameserver_addr6 = slirp->vprefix_addr6; + slirp->vnameserver_addr6.s6_addr[15] = 0x3; #else inet_pton(AF_INET6, "fec0::0", &slirp->vprefix_addr6); slirp->vprefix_len = 64; inet_pton(AF_INET6, "fec0::2", &slirp->vhost_addr6); + inet_pton(AF_INET6, "fec0::3", &slirp->vnameserver_addr6); #endif if (vhostname) { pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname), diff --git a/slirp/slirp.h b/slirp/slirp.h index 2850ef1665..71f2439461 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -212,6 +212,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 8df9252544..b836c42b8e 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -771,6 +771,7 @@ 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: @@ -791,6 +792,19 @@ 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; } @@ -800,6 +814,7 @@ 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: @@ -816,6 +831,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; } @@ -837,6 +862,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; } |