diff options
author | rofl0r <retnyg@gmx.net> | 2015-09-15 23:16:20 +0300 |
---|---|---|
committer | rofl0r <retnyg@gmx.net> | 2015-09-15 23:19:51 +0300 |
commit | 32df7ff152f90a8510c0199faa032ce93474c2e9 (patch) | |
tree | 82903178b2d6ddc5f83a27037d98ac72a303586a | |
parent | 097c7f91253d309acb8d94cd4097f0f28909a67a (diff) |
connect(): handle ipv4-mapped ipv6 addresses
if an ipv4-mapped ipv6 address is detected, the ip is converted
into v4 format because it may actually be one of our remote dns ips.
it was reported that a program called "maven", when getting handed our
fake ips in the remote dns subnet, converts the ip to v6 prior to calling
connect():
[proxychains] Strict chain ... 127.0.0.1:1080 ... ::ffff:224.0.0.1:443
<--socket error or timeout!
fixes #77
-rw-r--r-- | src/libproxychains.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/libproxychains.c b/src/libproxychains.c index f5580b9..f35b74e 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -307,7 +307,10 @@ int close(int fd) { errno = EBADF; return -1; } - +static int is_v4inv6(const struct in6_addr *a) { + return a->s6_addr32[0] == 0 && a->s6_addr32[1] == 0 && + a->s6_addr16[4] == 0 && a->s6_addr16[5] == 0xffff; +} int connect(int sock, const struct sockaddr *addr, unsigned int len) { INIT(); PFUNC(); @@ -334,6 +337,12 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) { p_addr_in6 = &((struct sockaddr_in6 *) addr)->sin6_addr; port = !v6 ? ntohs(((struct sockaddr_in *) addr)->sin_port) : ntohs(((struct sockaddr_in6 *) addr)->sin6_port); + struct in_addr v4inv6; + if(v6 && is_v4inv6(p_addr_in6)) { + memcpy(&v4inv6.s_addr, &p_addr_in6->s6_addr32[3], 4); + v6 = dest_ip.is_v6 = 0; + p_addr_in = &v4inv6; + } // PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str))); // PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str))); |