@@ -198,8 +198,8 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
198
198
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
199
199
// the results returned from gethostbyname et al.)
200
200
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
201
- if (ip .octet [0 ] == remote_dns_subnet ) {
202
- dns_len = at_get_host_for_ip (ip , hostnamebuf );
201
+ if (! ip . is_v6 && ip . addr . v4 .octet [0 ] == remote_dns_subnet ) {
202
+ dns_len = at_get_host_for_ip (ip . addr . v4 , hostnamebuf );
203
203
if (!dns_len ) goto err ;
204
204
else dns_name = hostnamebuf ;
205
205
}
@@ -216,12 +216,16 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
216
216
217
217
int len ;
218
218
unsigned char buff [BUFF_SIZE ];
219
- char ip_buf [16 ];
219
+ char ip_buf [INET6_ADDRSTRLEN ];
220
+ int v6 = ip .is_v6 ;
220
221
221
222
switch (pt ) {
222
223
case HTTP_TYPE :{
223
224
if (!dns_len ) {
224
- pc_stringfromipv4 (& ip .octet [0 ], ip_buf );
225
+ if (!inet_ntop (v6 ?AF_INET6 :AF_INET ,ip .addr .v6 ,ip_buf ,sizeof ip_buf )) {
226
+ proxychains_write_log (LOG_PREFIX "error: ip address conversion failed\n" );
227
+ goto err ;
228
+ }
225
229
dns_name = ip_buf ;
226
230
}
227
231
#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
264
268
}
265
269
break ;
266
270
case SOCKS4_TYPE :{
271
+ if (v6 ) {
272
+ proxychains_write_log (LOG_PREFIX "error: SOCKS4 doesnt support ipv6 addresses\n" );
273
+ goto err ;
274
+ }
267
275
buff [0 ] = 4 ; // socks version
268
276
buff [1 ] = 1 ; // connect command
269
277
memcpy (& buff [2 ], & port , 2 ); // dest port
270
278
if (dns_len ) {
271
- ip .octet [0 ] = 0 ;
272
- ip .octet [1 ] = 0 ;
273
- ip .octet [2 ] = 0 ;
274
- ip .octet [3 ] = 1 ;
279
+ ip .addr . v4 . octet [0 ] = 0 ;
280
+ ip .addr . v4 . octet [1 ] = 0 ;
281
+ ip .addr . v4 . octet [2 ] = 0 ;
282
+ ip .addr . v4 . octet [3 ] = 1 ;
275
283
}
276
- memcpy (& buff [4 ], & ip , 4 ); // dest host
284
+ memcpy (& buff [4 ], & ip . addr . v4 , 4 ); // dest host
277
285
len = ulen + 1 ; // username
278
286
if (len > 1 )
279
287
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
353
361
buff [buff_iter ++ ] = 0 ; // reserved
354
362
355
363
if (!dns_len ) {
356
- buff [buff_iter ++ ] = 1 ; // ip v4
357
- memcpy (buff + buff_iter , & ip , 4 ); // dest host
358
- buff_iter += 4 ;
364
+ buff [buff_iter ++ ] = v6 ? 4 : 1 ; // ip v4/v6
365
+ memcpy (buff + buff_iter , ip . addr . v6 , v6 ? 16 : 4 ); // dest host
366
+ buff_iter += v6 ? 16 : 4 ;
359
367
} else {
360
368
buff [buff_iter ++ ] = 3 ; //dns
361
369
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
411
419
#define RRT "Round Robin chain"
412
420
413
421
static int start_chain (int * fd , proxy_data * pd , char * begin_mark ) {
414
- * fd = socket (PF_INET , SOCK_STREAM , 0 );
422
+ int v6 = pd -> ip .is_v6 ;
423
+
424
+ * fd = socket (v6 ?PF_INET6 :PF_INET , SOCK_STREAM , 0 );
415
425
if (* fd == -1 )
416
426
goto error ;
417
427
418
- char ip_buf [16 ];
419
- pc_stringfromipv4 (& pd -> ip .octet [0 ], ip_buf );
428
+ char ip_buf [INET6_ADDRSTRLEN ];
429
+ if (!inet_ntop (v6 ?AF_INET6 :AF_INET ,pd -> ip .addr .v6 ,ip_buf ,sizeof ip_buf ))
430
+ goto error ;
431
+
420
432
proxychains_write_log (LOG_PREFIX "%s " TP " %s:%d " ,
421
433
begin_mark , ip_buf , htons (pd -> port ));
422
434
pd -> ps = PLAY_STATE ;
423
435
struct sockaddr_in addr = {
424
436
.sin_family = AF_INET ,
425
437
.sin_port = pd -> port ,
426
- .sin_addr .s_addr = (in_addr_t ) pd -> ip .as_int
438
+ .sin_addr .s_addr = (in_addr_t ) pd -> ip .addr .v4 .as_int
439
+ };
440
+ struct sockaddr_in6 addr6 = {
441
+ .sin6_family = AF_INET6 ,
442
+ .sin6_port = pd -> port ,
427
443
};
428
- if (timed_connect (* fd , (struct sockaddr * ) & addr , sizeof (addr ))) {
444
+ if (v6 ) memcpy (& addr6 .sin6_addr .s6_addr , pd -> ip .addr .v6 , 16 );
445
+ if (timed_connect (* fd , (struct sockaddr * ) (v6 ?(void * )& addr6 :(void * )& addr ), v6 ?sizeof (addr6 ):sizeof (addr ))) {
429
446
pd -> ps = DOWN_STATE ;
430
447
goto error1 ;
431
448
}
@@ -496,16 +513,22 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
496
513
int retcode = -1 ;
497
514
char * hostname ;
498
515
char hostname_buf [MSG_LEN_MAX ];
499
- char ip_buf [16 ];
516
+ char ip_buf [INET6_ADDRSTRLEN ];
517
+ int v6 = pto -> ip .is_v6 ;
500
518
501
519
PFUNC ();
502
520
503
- if (pto -> ip .octet [0 ] == remote_dns_subnet ) {
504
- if (!at_get_host_for_ip (pto -> ip , hostname_buf )) goto usenumericip ;
521
+ if (! v6 && pto -> ip . addr . v4 .octet [0 ] == remote_dns_subnet ) {
522
+ if (!at_get_host_for_ip (pto -> ip . addr . v4 , hostname_buf )) goto usenumericip ;
505
523
else hostname = hostname_buf ;
506
524
} else {
507
525
usenumericip :
508
- pc_stringfromipv4 (& pto -> ip .octet [0 ], ip_buf );
526
+ if (!inet_ntop (v6 ?AF_INET6 :AF_INET ,pto -> ip .addr .v6 ,ip_buf ,sizeof ip_buf )) {
527
+ pto -> ps = DOWN_STATE ;
528
+ proxychains_write_log ("<--ip conversion error!\n" );
529
+ close (ns );
530
+ return SOCKET_ERROR ;
531
+ }
509
532
hostname = ip_buf ;
510
533
}
511
534
@@ -707,7 +730,7 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char*
707
730
data -> hostent_space .h_name = data -> addr_name ;
708
731
}
709
732
710
- extern ip_type hostsreader_get_numeric_ip_for_name (const char * name );
733
+ extern ip_type4 hostsreader_get_numeric_ip_for_name (const char * name );
711
734
struct hostent * proxy_gethostbyname (const char * name , struct gethostbyname_data * data ) {
712
735
PFUNC ();
713
736
char buff [256 ];
@@ -728,19 +751,19 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
728
751
if (!strcmp (buff , name )) {
729
752
data -> resolved_addr = inet_addr (buff );
730
753
if (data -> resolved_addr == (in_addr_t ) (-1 ))
731
- data -> resolved_addr = (in_addr_t ) (ip_type_localhost .as_int );
754
+ data -> resolved_addr = (in_addr_t ) (ip_type_localhost .addr . v4 . as_int );
732
755
goto retname ;
733
756
}
734
757
735
758
// this iterates over the "known hosts" db, usually /etc/hosts
736
- ip_type hdb_res = hostsreader_get_numeric_ip_for_name (name );
737
- if (hdb_res .as_int != ip_type_invalid .as_int ) {
759
+ ip_type4 hdb_res = hostsreader_get_numeric_ip_for_name (name );
760
+ if (hdb_res .as_int != ip_type_invalid .addr . v4 . as_int ) {
738
761
data -> resolved_addr = hdb_res .as_int ;
739
762
goto retname ;
740
763
}
741
764
742
765
data -> resolved_addr = at_get_ip_for_host ((char * ) name , strlen (name )).as_int ;
743
- if (data -> resolved_addr == (in_addr_t ) ip_type_invalid .as_int ) return NULL ;
766
+ if (data -> resolved_addr == (in_addr_t ) ip_type_invalid .addr . v4 . as_int ) return NULL ;
744
767
745
768
retname :
746
769
0 commit comments