Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/rofl0r/proxychains-ng.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrofl0r <retnyg@gmx.net>2019-04-25 16:36:03 +0300
committerrofl0r <retnyg@gmx.net>2019-04-25 16:36:08 +0300
commit5ad7c2a1839b960ec96cb19a4923ae289315dc72 (patch)
tree6ec59c19672ba20f1ef5407b1537c3abbb708ac2
parent067885694dede9fc31da258b482d0983b980ef4d (diff)
proxy_getaddrinfo: implement support for numeric ipv6
closes #282
-rw-r--r--src/core.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/core.c b/src/core.c
index 0c4de57..ef8794f 100644
--- a/src/core.c
+++ b/src/core.c
@@ -789,7 +789,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
struct addrinfo_data {
struct addrinfo addrinfo_space;
- struct sockaddr sockaddr_space;
+ struct sockaddr_storage sockaddr_space;
char addr_name[256];
};
@@ -822,6 +822,33 @@ static int mygetservbyname_r(const char* name, const char* proto, struct servent
return ret;
}
+static int looks_like_numeric_ipv6(const char *node)
+{
+ if(!strchr(node, ':')) return 0;
+ const char* p= node;
+ while(1) switch(*(p++)) {
+ case 0: return 1;
+ case ':': case '.':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ break;
+ default: return 0;
+ }
+}
+
+static int my_inet_aton(const char *node, struct addrinfo_data* space)
+{
+ int ret;
+ ((struct sockaddr_in *) &space->sockaddr_space)->sin_family = AF_INET;
+ ret = inet_aton(node, &((struct sockaddr_in *) &space->sockaddr_space)->sin_addr);
+ if(ret || !looks_like_numeric_ipv6(node)) return ret;
+ ret = inet_pton(AF_INET6, node, &((struct sockaddr_in6 *) &space->sockaddr_space)->sin6_addr);
+ if(ret) ((struct sockaddr_in6 *) &space->sockaddr_space)->sin6_family = AF_INET6;
+ return ret;
+}
+
int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
struct gethostbyname_data ghdata;
struct addrinfo_data *space;
@@ -830,14 +857,14 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
struct servent se_buf;
struct addrinfo *p;
char buf[1024];
- int port;
+ int port, af = AF_INET;
PFUNC();
// printf("proxy_getaddrinfo node %s service %s\n",node,service);
space = calloc(1, sizeof(struct addrinfo_data));
if(!space) goto err1;
- if(node && !inet_aton(node, &((struct sockaddr_in *) &space->sockaddr_space)->sin_addr)) {
+ if(node && !my_inet_aton(node, space)) {
/* some folks (nmap) use getaddrinfo() with AI_NUMERICHOST to check whether a string
containing a numeric ip was passed. we must return failure in that case. */
if(hints && (hints->ai_flags & AI_NUMERICHOST)) {
@@ -850,21 +877,26 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
*(hp->h_addr_list), sizeof(in_addr_t));
else
goto err2;
+ } else if(node) {
+ af = ((struct sockaddr_in *) &space->sockaddr_space)->sin_family;
}
if(service) mygetservbyname_r(service, NULL, &se_buf, buf, sizeof(buf), &se);
port = se ? se->s_port : htons(atoi(service ? service : "0"));
- ((struct sockaddr_in *) &space->sockaddr_space)->sin_port = port;
+ if(af == AF_INET)
+ ((struct sockaddr_in *) &space->sockaddr_space)->sin_port = port;
+ else
+ ((struct sockaddr_in6 *) &space->sockaddr_space)->sin6_port = port;
*res = p = &space->addrinfo_space;
assert((size_t)p == (size_t) space);
- p->ai_addr = &space->sockaddr_space;
+ p->ai_addr = (void*) &space->sockaddr_space;
if(node)
snprintf(space->addr_name, sizeof(space->addr_name), "%s", node);
p->ai_canonname = space->addr_name;
p->ai_next = NULL;
- p->ai_family = space->sockaddr_space.sa_family = AF_INET;
+ p->ai_family = space->sockaddr_space.ss_family = af;
p->ai_addrlen = sizeof(space->sockaddr_space);
if(hints) {