mirror of
https://github.com/rofl0r/proxychains-ng
synced 2025-02-08 22:03:09 +08:00
preliminary ipv6 support
only basic testing was done (with 2 socks5 proxies listening on ::1) but seems to work as intended. ipv6 support for the hostsreader (/etc/hosts) is not implemented so far.
This commit is contained in:
parent
9969dd3a22
commit
2237749567
@ -38,16 +38,16 @@ pthread_mutex_t internal_ips_lock;
|
|||||||
internal_ip_lookup_table *internal_ips = NULL;
|
internal_ip_lookup_table *internal_ips = NULL;
|
||||||
internal_ip_lookup_table internal_ips_buf;
|
internal_ip_lookup_table internal_ips_buf;
|
||||||
|
|
||||||
uint32_t index_from_internal_ip(ip_type internalip) {
|
uint32_t index_from_internal_ip(ip_type4 internalip) {
|
||||||
PFUNC();
|
PFUNC();
|
||||||
ip_type tmp = internalip;
|
ip_type4 tmp = internalip;
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
ret = tmp.octet[3] + (tmp.octet[2] << 8) + (tmp.octet[1] << 16);
|
ret = tmp.octet[3] + (tmp.octet[2] << 8) + (tmp.octet[1] << 16);
|
||||||
ret -= 1;
|
ret -= 1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *string_from_internal_ip(ip_type internalip) {
|
char *string_from_internal_ip(ip_type4 internalip) {
|
||||||
PFUNC();
|
PFUNC();
|
||||||
char *res = NULL;
|
char *res = NULL;
|
||||||
uint32_t index = index_from_internal_ip(internalip);
|
uint32_t index = index_from_internal_ip(internalip);
|
||||||
@ -57,11 +57,11 @@ char *string_from_internal_ip(ip_type internalip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned int remote_dns_subnet;
|
extern unsigned int remote_dns_subnet;
|
||||||
ip_type make_internal_ip(uint32_t index) {
|
ip_type4 make_internal_ip(uint32_t index) {
|
||||||
ip_type ret;
|
ip_type4 ret;
|
||||||
index++; // so we can start at .0.0.1
|
index++; // so we can start at .0.0.1
|
||||||
if(index > 0xFFFFFF)
|
if(index > 0xFFFFFF)
|
||||||
return ip_type_invalid;
|
return ip_type_invalid.addr.v4;
|
||||||
ret.octet[0] = remote_dns_subnet & 0xFF;
|
ret.octet[0] = remote_dns_subnet & 0xFF;
|
||||||
ret.octet[1] = (index & 0xFF0000) >> 16;
|
ret.octet[1] = (index & 0xFF0000) >> 16;
|
||||||
ret.octet[2] = (index & 0xFF00) >> 8;
|
ret.octet[2] = (index & 0xFF00) >> 8;
|
||||||
@ -69,10 +69,10 @@ ip_type make_internal_ip(uint32_t index) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ip_type ip_from_internal_list(char* name, size_t len) {
|
static ip_type4 ip_from_internal_list(char* name, size_t len) {
|
||||||
uint32_t hash = dalias_hash((char *) name);
|
uint32_t hash = dalias_hash((char *) name);
|
||||||
size_t i;
|
size_t i;
|
||||||
ip_type res;
|
ip_type4 res;
|
||||||
void* new_mem;
|
void* new_mem;
|
||||||
// see if we already have this dns entry saved.
|
// see if we already have this dns entry saved.
|
||||||
if(internal_ips->counter) {
|
if(internal_ips->counter) {
|
||||||
@ -99,7 +99,7 @@ static ip_type ip_from_internal_list(char* name, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = make_internal_ip(internal_ips->counter);
|
res = make_internal_ip(internal_ips->counter);
|
||||||
if(res.as_int == ip_type_invalid.as_int)
|
if(res.as_int == ip_type_invalid.addr.v4.as_int)
|
||||||
goto err_plus_unlock;
|
goto err_plus_unlock;
|
||||||
|
|
||||||
string_hash_tuple tmp = { 0 };
|
string_hash_tuple tmp = { 0 };
|
||||||
@ -128,7 +128,7 @@ static ip_type ip_from_internal_list(char* name, size_t len) {
|
|||||||
err_plus_unlock:
|
err_plus_unlock:
|
||||||
|
|
||||||
PDEBUG("return err\n");
|
PDEBUG("return err\n");
|
||||||
return ip_type_invalid;
|
return ip_type_invalid.addr.v4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stuff for communication with the allocator thread */
|
/* stuff for communication with the allocator thread */
|
||||||
@ -205,7 +205,7 @@ static void* threadfunc(void* x) {
|
|||||||
struct at_msghdr msg;
|
struct at_msghdr msg;
|
||||||
union {
|
union {
|
||||||
char host[MSG_LEN_MAX];
|
char host[MSG_LEN_MAX];
|
||||||
ip_type ip;
|
ip_type4 ip;
|
||||||
} readbuf;
|
} readbuf;
|
||||||
while((ret = getmessage(ATD_SERVER, &msg, &readbuf))) {
|
while((ret = getmessage(ATD_SERVER, &msg, &readbuf))) {
|
||||||
switch(msg.msgtype) {
|
switch(msg.msgtype) {
|
||||||
@ -213,7 +213,7 @@ static void* threadfunc(void* x) {
|
|||||||
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
|
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
|
||||||
* if not, create a new one. */
|
* if not, create a new one. */
|
||||||
readbuf.ip = ip_from_internal_list(readbuf.host, msg.datalen - 1);
|
readbuf.ip = ip_from_internal_list(readbuf.host, msg.datalen - 1);
|
||||||
msg.datalen = sizeof(ip_type);
|
msg.datalen = sizeof(ip_type4);
|
||||||
break;
|
break;
|
||||||
case ATM_GETNAME: {
|
case ATM_GETNAME: {
|
||||||
char *host = string_from_internal_ip(readbuf.ip);
|
char *host = string_from_internal_ip(readbuf.ip);
|
||||||
@ -237,8 +237,8 @@ static void* threadfunc(void* x) {
|
|||||||
|
|
||||||
/* API to access the internal ip mapping */
|
/* API to access the internal ip mapping */
|
||||||
|
|
||||||
ip_type at_get_ip_for_host(char* host, size_t len) {
|
ip_type4 at_get_ip_for_host(char* host, size_t len) {
|
||||||
ip_type readbuf;
|
ip_type4 readbuf;
|
||||||
MUTEX_LOCK(&internal_ips_lock);
|
MUTEX_LOCK(&internal_ips_lock);
|
||||||
if(len > MSG_LEN_MAX) goto inv;
|
if(len > MSG_LEN_MAX) goto inv;
|
||||||
struct at_msghdr msg = {.msgtype = ATM_GETIP, .datalen = len + 1 };
|
struct at_msghdr msg = {.msgtype = ATM_GETIP, .datalen = len + 1 };
|
||||||
@ -246,14 +246,14 @@ ip_type at_get_ip_for_host(char* host, size_t len) {
|
|||||||
getmessage(ATD_CLIENT, &msg, &readbuf));
|
getmessage(ATD_CLIENT, &msg, &readbuf));
|
||||||
else {
|
else {
|
||||||
inv:
|
inv:
|
||||||
readbuf = ip_type_invalid;
|
readbuf = ip_type_invalid.addr.v4;
|
||||||
}
|
}
|
||||||
MUTEX_UNLOCK(&internal_ips_lock);
|
MUTEX_UNLOCK(&internal_ips_lock);
|
||||||
return readbuf;
|
return readbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t at_get_host_for_ip(ip_type ip, char* readbuf) {
|
size_t at_get_host_for_ip(ip_type4 ip, char* readbuf) {
|
||||||
struct at_msghdr msg = {.msgtype = ATM_GETNAME, .datalen = sizeof(ip_type) };
|
struct at_msghdr msg = {.msgtype = ATM_GETNAME, .datalen = sizeof(ip_type4) };
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
MUTEX_LOCK(&internal_ips_lock);
|
MUTEX_LOCK(&internal_ips_lock);
|
||||||
if(sendmessage(ATD_SERVER, &msg, &ip) && getmessage(ATD_CLIENT, &msg, readbuf)) {
|
if(sendmessage(ATD_SERVER, &msg, &ip) && getmessage(ATD_CLIENT, &msg, readbuf)) {
|
||||||
|
@ -11,8 +11,8 @@ extern int resp_pipefd[2];
|
|||||||
|
|
||||||
void at_init(void);
|
void at_init(void);
|
||||||
void at_close(void);
|
void at_close(void);
|
||||||
size_t at_get_host_for_ip(ip_type ip, char* readbuf);
|
size_t at_get_host_for_ip(ip_type4 ip, char* readbuf);
|
||||||
ip_type at_get_ip_for_host(char* host, size_t len);
|
ip_type4 at_get_ip_for_host(char* host, size_t len);
|
||||||
|
|
||||||
//RcB: DEP "allocator_thread.c"
|
//RcB: DEP "allocator_thread.c"
|
||||||
#endif
|
#endif
|
||||||
|
75
src/core.c
75
src/core.c
@ -198,8 +198,8 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
||||||
// the results returned from gethostbyname et al.)
|
// the results returned from gethostbyname et al.)
|
||||||
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
|
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
|
||||||
if(ip.octet[0] == remote_dns_subnet) {
|
if(!ip.is_v6 && ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||||
dns_len = at_get_host_for_ip(ip, hostnamebuf);
|
dns_len = at_get_host_for_ip(ip.addr.v4, hostnamebuf);
|
||||||
if(!dns_len) goto err;
|
if(!dns_len) goto err;
|
||||||
else dns_name = hostnamebuf;
|
else dns_name = hostnamebuf;
|
||||||
}
|
}
|
||||||
@ -216,12 +216,16 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
|
|
||||||
int len;
|
int len;
|
||||||
unsigned char buff[BUFF_SIZE];
|
unsigned char buff[BUFF_SIZE];
|
||||||
char ip_buf[16];
|
char ip_buf[INET6_ADDRSTRLEN];
|
||||||
|
int v6 = ip.is_v6;
|
||||||
|
|
||||||
switch (pt) {
|
switch (pt) {
|
||||||
case HTTP_TYPE:{
|
case HTTP_TYPE:{
|
||||||
if(!dns_len) {
|
if(!dns_len) {
|
||||||
pc_stringfromipv4(&ip.octet[0], ip_buf);
|
if(!inet_ntop(v6?AF_INET6:AF_INET,ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
||||||
|
proxychains_write_log(LOG_PREFIX "error: ip address conversion failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
dns_name = ip_buf;
|
dns_name = ip_buf;
|
||||||
}
|
}
|
||||||
#define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1) /* 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator. */
|
#define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1) /* 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator. */
|
||||||
@ -264,16 +268,20 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SOCKS4_TYPE:{
|
case SOCKS4_TYPE:{
|
||||||
|
if(v6) {
|
||||||
|
proxychains_write_log(LOG_PREFIX "error: SOCKS4 doesnt support ipv6 addresses\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
buff[0] = 4; // socks version
|
buff[0] = 4; // socks version
|
||||||
buff[1] = 1; // connect command
|
buff[1] = 1; // connect command
|
||||||
memcpy(&buff[2], &port, 2); // dest port
|
memcpy(&buff[2], &port, 2); // dest port
|
||||||
if(dns_len) {
|
if(dns_len) {
|
||||||
ip.octet[0] = 0;
|
ip.addr.v4.octet[0] = 0;
|
||||||
ip.octet[1] = 0;
|
ip.addr.v4.octet[1] = 0;
|
||||||
ip.octet[2] = 0;
|
ip.addr.v4.octet[2] = 0;
|
||||||
ip.octet[3] = 1;
|
ip.addr.v4.octet[3] = 1;
|
||||||
}
|
}
|
||||||
memcpy(&buff[4], &ip, 4); // dest host
|
memcpy(&buff[4], &ip.addr.v4, 4); // dest host
|
||||||
len = ulen + 1; // username
|
len = ulen + 1; // username
|
||||||
if(len > 1)
|
if(len > 1)
|
||||||
memcpy(&buff[8], user, len);
|
memcpy(&buff[8], user, len);
|
||||||
@ -353,9 +361,9 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
buff[buff_iter++] = 0; // reserved
|
buff[buff_iter++] = 0; // reserved
|
||||||
|
|
||||||
if(!dns_len) {
|
if(!dns_len) {
|
||||||
buff[buff_iter++] = 1; // ip v4
|
buff[buff_iter++] = v6 ? 4 : 1; // ip v4/v6
|
||||||
memcpy(buff + buff_iter, &ip, 4); // dest host
|
memcpy(buff + buff_iter, ip.addr.v6, v6?16:4); // dest host
|
||||||
buff_iter += 4;
|
buff_iter += v6?16:4;
|
||||||
} else {
|
} else {
|
||||||
buff[buff_iter++] = 3; //dns
|
buff[buff_iter++] = 3; //dns
|
||||||
buff[buff_iter++] = dns_len & 0xFF;
|
buff[buff_iter++] = dns_len & 0xFF;
|
||||||
@ -411,21 +419,30 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
#define RRT "Round Robin chain"
|
#define RRT "Round Robin chain"
|
||||||
|
|
||||||
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
||||||
*fd = socket(PF_INET, SOCK_STREAM, 0);
|
int v6 = pd->ip.is_v6;
|
||||||
|
|
||||||
|
*fd = socket(v6?PF_INET6:PF_INET, SOCK_STREAM, 0);
|
||||||
if(*fd == -1)
|
if(*fd == -1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
char ip_buf[16];
|
char ip_buf[INET6_ADDRSTRLEN];
|
||||||
pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
|
if(!inet_ntop(v6?AF_INET6:AF_INET,pd->ip.addr.v6,ip_buf,sizeof ip_buf))
|
||||||
|
goto error;
|
||||||
|
|
||||||
proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ",
|
proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ",
|
||||||
begin_mark, ip_buf, htons(pd->port));
|
begin_mark, ip_buf, htons(pd->port));
|
||||||
pd->ps = PLAY_STATE;
|
pd->ps = PLAY_STATE;
|
||||||
struct sockaddr_in addr = {
|
struct sockaddr_in addr = {
|
||||||
.sin_family = AF_INET,
|
.sin_family = AF_INET,
|
||||||
.sin_port = pd->port,
|
.sin_port = pd->port,
|
||||||
.sin_addr.s_addr = (in_addr_t) pd->ip.as_int
|
.sin_addr.s_addr = (in_addr_t) pd->ip.addr.v4.as_int
|
||||||
};
|
};
|
||||||
if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr))) {
|
struct sockaddr_in6 addr6 = {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_port = pd->port,
|
||||||
|
};
|
||||||
|
if(v6) memcpy(&addr6.sin6_addr.s6_addr, pd->ip.addr.v6, 16);
|
||||||
|
if(timed_connect(*fd, (struct sockaddr *) (v6?(void*)&addr6:(void*)&addr), v6?sizeof(addr6):sizeof(addr))) {
|
||||||
pd->ps = DOWN_STATE;
|
pd->ps = DOWN_STATE;
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
@ -496,16 +513,22 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
int retcode = -1;
|
int retcode = -1;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char hostname_buf[MSG_LEN_MAX];
|
char hostname_buf[MSG_LEN_MAX];
|
||||||
char ip_buf[16];
|
char ip_buf[INET6_ADDRSTRLEN];
|
||||||
|
int v6 = pto->ip.is_v6;
|
||||||
|
|
||||||
PFUNC();
|
PFUNC();
|
||||||
|
|
||||||
if(pto->ip.octet[0] == remote_dns_subnet) {
|
if(!v6 && pto->ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||||
if(!at_get_host_for_ip(pto->ip, hostname_buf)) goto usenumericip;
|
if(!at_get_host_for_ip(pto->ip.addr.v4, hostname_buf)) goto usenumericip;
|
||||||
else hostname = hostname_buf;
|
else hostname = hostname_buf;
|
||||||
} else {
|
} else {
|
||||||
usenumericip:
|
usenumericip:
|
||||||
pc_stringfromipv4(&pto->ip.octet[0], ip_buf);
|
if(!inet_ntop(v6?AF_INET6:AF_INET,pto->ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
||||||
|
pto->ps = DOWN_STATE;
|
||||||
|
proxychains_write_log("<--ip conversion error!\n");
|
||||||
|
close(ns);
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
hostname = ip_buf;
|
hostname = ip_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +730,7 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char*
|
|||||||
data->hostent_space.h_name = data->addr_name;
|
data->hostent_space.h_name = data->addr_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern ip_type hostsreader_get_numeric_ip_for_name(const char* name);
|
extern ip_type4 hostsreader_get_numeric_ip_for_name(const char* name);
|
||||||
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
|
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
|
||||||
PFUNC();
|
PFUNC();
|
||||||
char buff[256];
|
char buff[256];
|
||||||
@ -728,19 +751,19 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
|||||||
if(!strcmp(buff, name)) {
|
if(!strcmp(buff, name)) {
|
||||||
data->resolved_addr = inet_addr(buff);
|
data->resolved_addr = inet_addr(buff);
|
||||||
if(data->resolved_addr == (in_addr_t) (-1))
|
if(data->resolved_addr == (in_addr_t) (-1))
|
||||||
data->resolved_addr = (in_addr_t) (ip_type_localhost.as_int);
|
data->resolved_addr = (in_addr_t) (ip_type_localhost.addr.v4.as_int);
|
||||||
goto retname;
|
goto retname;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this iterates over the "known hosts" db, usually /etc/hosts
|
// this iterates over the "known hosts" db, usually /etc/hosts
|
||||||
ip_type hdb_res = hostsreader_get_numeric_ip_for_name(name);
|
ip_type4 hdb_res = hostsreader_get_numeric_ip_for_name(name);
|
||||||
if(hdb_res.as_int != ip_type_invalid.as_int) {
|
if(hdb_res.as_int != ip_type_invalid.addr.v4.as_int) {
|
||||||
data->resolved_addr = hdb_res.as_int;
|
data->resolved_addr = hdb_res.as_int;
|
||||||
goto retname;
|
goto retname;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->resolved_addr = at_get_ip_for_host((char*) name, strlen(name)).as_int;
|
data->resolved_addr = at_get_ip_for_host((char*) name, strlen(name)).as_int;
|
||||||
if(data->resolved_addr == (in_addr_t) ip_type_invalid.as_int) return NULL;
|
if(data->resolved_addr == (in_addr_t) ip_type_invalid.addr.v4.as_int) return NULL;
|
||||||
|
|
||||||
retname:
|
retname:
|
||||||
|
|
||||||
|
@ -73,16 +73,16 @@ char* hostsreader_get_ip_for_name(const char* name, char* buf, size_t bufsize) {
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
ip_type hostsreader_get_numeric_ip_for_name(const char* name) {
|
ip_type4 hostsreader_get_numeric_ip_for_name(const char* name) {
|
||||||
char *hres;
|
char *hres;
|
||||||
char buf[320];
|
char buf[320];
|
||||||
if((hres = hostsreader_get_ip_for_name(name, buf, sizeof buf))) {
|
if((hres = hostsreader_get_ip_for_name(name, buf, sizeof buf))) {
|
||||||
struct in_addr c;
|
struct in_addr c;
|
||||||
inet_aton(hres, &c);
|
inet_aton(hres, &c);
|
||||||
ip_type res;
|
ip_type4 res;
|
||||||
memcpy(res.octet, &c.s_addr, 4);
|
memcpy(res.octet, &c.s_addr, 4);
|
||||||
return res;
|
return res;
|
||||||
} else return ip_type_invalid;
|
} else return ip_type_invalid.addr.v4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HOSTSREADER_TEST
|
#ifdef HOSTSREADER_TEST
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "ip_type.h"
|
#include "ip_type.h"
|
||||||
|
|
||||||
const ip_type ip_type_invalid = { .as_int = -1 };
|
const ip_type ip_type_invalid = { .addr.v4.as_int = -1 };
|
||||||
const ip_type ip_type_localhost = { {127, 0, 0, 1} };
|
const ip_type ip_type_localhost = { .addr.v4 = {127, 0, 0, 1} };
|
||||||
|
|
||||||
|
@ -6,6 +6,14 @@
|
|||||||
typedef union {
|
typedef union {
|
||||||
unsigned char octet[4];
|
unsigned char octet[4];
|
||||||
uint32_t as_int;
|
uint32_t as_int;
|
||||||
|
} ip_type4;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
ip_type4 v4;
|
||||||
|
unsigned char v6[16];
|
||||||
|
} addr;
|
||||||
|
char is_v6;
|
||||||
} ip_type;
|
} ip_type;
|
||||||
|
|
||||||
extern const ip_type ip_type_invalid;
|
extern const ip_type ip_type_invalid;
|
||||||
|
@ -189,13 +189,14 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr_t host_ip = inet_addr(host);
|
memset(&pd[count].ip, 0, sizeof(pd[count].ip));
|
||||||
if(host_ip == INADDR_NONE) {
|
pd[count].ip.is_v6 = !!strchr(host, ':');
|
||||||
|
pd[count].port = htons((unsigned short) port_n);
|
||||||
|
ip_type* host_ip = &pd[count].ip;
|
||||||
|
if(1 != inet_pton(host_ip->is_v6 ? AF_INET6 : AF_INET, host, host_ip->addr.v6)) {
|
||||||
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
|
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
pd[count].ip.as_int = (uint32_t) host_ip;
|
|
||||||
pd[count].port = htons((unsigned short) port_n);
|
|
||||||
|
|
||||||
if(!strcmp(type, "http")) {
|
if(!strcmp(type, "http")) {
|
||||||
pd[count].pt = HTTP_TYPE;
|
pd[count].pt = HTTP_TYPE;
|
||||||
@ -206,7 +207,7 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||||||
} else
|
} else
|
||||||
goto inv;
|
goto inv;
|
||||||
|
|
||||||
if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) - 1)
|
if(port_n)
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
if(strstr(buff, "[ProxyList]")) {
|
if(strstr(buff, "[ProxyList]")) {
|
||||||
@ -317,26 +318,32 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||||||
DEBUGDECL(char str[256]);
|
DEBUGDECL(char str[256]);
|
||||||
|
|
||||||
struct in_addr *p_addr_in;
|
struct in_addr *p_addr_in;
|
||||||
|
struct in6_addr *p_addr_in6;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
size_t i;
|
size_t i;
|
||||||
int remote_dns_connect = 0;
|
int remote_dns_connect = 0;
|
||||||
optlen = sizeof(socktype);
|
optlen = sizeof(socktype);
|
||||||
|
sa_family_t fam = SOCKFAMILY(*addr);
|
||||||
getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
||||||
if(!(SOCKFAMILY(*addr) == AF_INET && socktype == SOCK_STREAM))
|
if(!((fam == AF_INET || fam == AF_INET6) && socktype == SOCK_STREAM))
|
||||||
return true_connect(sock, addr, len);
|
return true_connect(sock, addr, len);
|
||||||
|
|
||||||
|
int v6 = dest_ip.is_v6 = fam == AF_INET6;
|
||||||
|
|
||||||
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
||||||
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
|
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);
|
||||||
|
|
||||||
// PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str)));
|
// 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)));
|
// PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str)));
|
||||||
PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str)));
|
PDEBUG("target: %s\n", inet_ntop(v6 ? AF_INET6 : AF_INET, v6 ? p_addr_in6 : p_addr_in, str, sizeof(str)));
|
||||||
PDEBUG("port: %d\n", port);
|
PDEBUG("port: %d\n", port);
|
||||||
|
|
||||||
// check if connect called from proxydns
|
// check if connect called from proxydns
|
||||||
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
remote_dns_connect = !v6 && (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
||||||
|
|
||||||
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
|
if (!v6) for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
|
||||||
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr)
|
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr)
|
||||||
== (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
== (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
||||||
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
|
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
|
||||||
@ -350,11 +357,11 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||||||
if(flags & O_NONBLOCK)
|
if(flags & O_NONBLOCK)
|
||||||
fcntl(sock, F_SETFL, !O_NONBLOCK);
|
fcntl(sock, F_SETFL, !O_NONBLOCK);
|
||||||
|
|
||||||
dest_ip.as_int = SOCKADDR(*addr);
|
memcpy(dest_ip.addr.v6, v6 ? (void*)p_addr_in6 : (void*)p_addr_in, v6?16:4);
|
||||||
|
|
||||||
ret = connect_proxy_chain(sock,
|
ret = connect_proxy_chain(sock,
|
||||||
dest_ip,
|
dest_ip,
|
||||||
SOCKPORT(*addr),
|
htons(port),
|
||||||
proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
|
proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
|
||||||
|
|
||||||
fcntl(sock, F_SETFL, flags);
|
fcntl(sock, F_SETFL, flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user