From 672bf7661d7d9c5a66a5f4f2bbb835757b58024e Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 6 Dec 2015 13:01:56 +0000 Subject: [PATCH] getnameinfo: support ipv6 as well --- src/libproxychains.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/libproxychains.c b/src/libproxychains.c index 686ea6e..4c12511 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -423,17 +423,34 @@ int pc_getnameinfo(const struct sockaddr *sa, socklen_t salen, INIT(); PFUNC(); - char ip_buf[16]; - if(!proxychains_resolver) { return true_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } else { - if(salen < sizeof(struct sockaddr_in) || SOCKFAMILY(*sa) != AF_INET) + if(!salen || !(SOCKFAMILY(*sa) == AF_INET || SOCKFAMILY(*sa) == AF_INET6)) + return EAI_FAMILY; + int v6 = SOCKFAMILY(*sa) == AF_INET6; + if(salen < (v6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))) return EAI_FAMILY; if(hostlen) { - pc_stringfromipv4((unsigned char*) &(SOCKADDR_2(*sa)), ip_buf); - if(snprintf(host, hostlen, "%s", ip_buf) >= hostlen) + unsigned char v4inv6buf[4]; + const void *ip = v6 ? (void*)&((struct sockaddr_in6*)sa)->sin6_addr + : (void*)&((struct sockaddr_in*)sa)->sin_addr; + unsigned scopeid = 0; + if(v6) { + if(is_v4inv6(&((struct sockaddr_in6*)sa)->sin6_addr)) { + memcpy(v4inv6buf, &((struct sockaddr_in6*)sa)->sin6_addr.s6_addr32[3], 4); + ip = v4inv6buf; + v6 = 0; + } else + scopeid = ((struct sockaddr_in6 *)sa)->sin6_scope_id; + } + if(!inet_ntop(v6?AF_INET6:AF_INET,ip,host,hostlen)) return EAI_OVERFLOW; + if(scopeid) { + size_t l = strlen(host); + if(snprintf(host+l, hostlen-l, "%%%u", scopeid) >= hostlen-l) + return EAI_OVERFLOW; + } } if(servlen) { if(snprintf(serv, servlen, "%d", ntohs(SOCKPORT(*sa))) >= servlen)