From 23db43abdb5740287bbb7cbf5cc99eb22e121298 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 18 Sep 2021 21:11:01 +0200 Subject: Use the exact sockaddr size in getnameinfo call On NetBSD, the sockaddr size passed to getnameinfo must match the family. (reworked from the patch suggestion from Yorick Hardy) Fixes #52 --- src/tcp_subr.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/tcp_subr.c b/src/tcp_subr.c index 600cfa1..7c63f49 100644 --- a/src/tcp_subr.c +++ b/src/tcp_subr.c @@ -464,7 +464,7 @@ void tcp_connect(struct socket *inso) Slirp *slirp = inso->slirp; struct socket *so; struct sockaddr_storage addr; - socklen_t addrlen = sizeof(struct sockaddr_storage); + socklen_t addrlen; struct tcpcb *tp; int s, opt, ret; /* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */ @@ -473,7 +473,17 @@ void tcp_connect(struct socket *inso) DEBUG_CALL("tcp_connect"); DEBUG_ARG("inso = %p", inso); - ret = getnameinfo((const struct sockaddr *) &inso->lhost.ss, sizeof(inso->lhost.ss), addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); + switch (inso->lhost.ss.ss_family) { + case AF_INET: + addrlen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrlen = sizeof(struct sockaddr_in6); + break; + default: + g_assert_not_reached(); + } + ret = getnameinfo((const struct sockaddr *) &inso->lhost.ss, addrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); g_assert(ret == 0); DEBUG_ARG("ip = [%s]:%s", addrstr, portstr); DEBUG_ARG("so_state = 0x%x", inso->so_state); @@ -494,6 +504,7 @@ void tcp_connect(struct socket *inso) * us again until the guest address is available. */ DEBUG_MISC(" guest address not available yet"); + addrlen = sizeof(addr); s = accept(inso->s, (struct sockaddr *)&addr, &addrlen); if (s >= 0) { close(s); @@ -518,6 +529,7 @@ void tcp_connect(struct socket *inso) tcp_mss(sototcpcb(so), 0); + addrlen = sizeof(addr); s = accept(inso->s, (struct sockaddr *)&addr, &addrlen); if (s < 0) { tcp_close(sototcpcb(so)); /* This will sofree() as well */ -- cgit v1.1