Skip to content

Commit

Permalink
connect6 tool
Browse files Browse the repository at this point in the history
  • Loading branch information
vanhauser-thc committed Jan 16, 2018
1 parent 354aab5 commit 8dba5f2
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -3,6 +3,8 @@ CHANGELOG

v3.5-dev
* ... your patch? :)
* added new tool: connect6, useful for tcp6 connect pings
* added -w timeout option to thcping6


v3.4/v3.3-dev
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -8,7 +8,7 @@ CFLAGS+=$(if $(HAVE_SSL),-D_HAVE_SSL,)
LDFLAGS+=-lpcap $(if $(HAVE_SSL),-lssl -lcrypto,)
STATIC=
#-static
PROGRAMS=parasite6 dos-new-ip6 detect-new-ip6 fake_router6 fake_advertise6 fake_solicitate6 fake_mld6 fake_mld26 fake_mldrouter6 flood_mldrouter6 fake_mipv6 redir6 smurf6 alive6 toobig6 rsmurf6 implementation6 implementation6d sendpees6 sendpeesmp6 randicmp6 fuzz_ip6 flood_mld6 flood_mld26 flood_router6 flood_advertise6 flood_solicitate6 trace6 exploit6 denial6 fake_dhcps6 flood_dhcpc6 fake_dns6d fragmentation6 kill_router6 fake_dnsupdate6 ndpexhaust6 detect_sniffer6 dump_router6 fake_router26 flood_router26 passive_discovery6 dnsrevenum6 inverse_lookup6 node_query6 address6 covert_send6 covert_send6d inject_alive6 firewall6 ndpexhaust26 fake_pim6 thcsyn6 redirsniff6 flood_redir6 four2six dump_dhcp6 flood_rs6 fuzz_dhcps6 fuzz_dhcpc6 toobigsniff6 flood_unreach6
PROGRAMS=parasite6 dos-new-ip6 detect-new-ip6 fake_router6 fake_advertise6 fake_solicitate6 fake_mld6 fake_mld26 fake_mldrouter6 flood_mldrouter6 fake_mipv6 redir6 smurf6 alive6 toobig6 rsmurf6 implementation6 implementation6d sendpees6 sendpeesmp6 randicmp6 fuzz_ip6 flood_mld6 flood_mld26 flood_router6 flood_advertise6 flood_solicitate6 trace6 exploit6 denial6 fake_dhcps6 flood_dhcpc6 fake_dns6d fragmentation6 kill_router6 fake_dnsupdate6 ndpexhaust6 detect_sniffer6 dump_router6 fake_router26 flood_router26 passive_discovery6 dnsrevenum6 inverse_lookup6 node_query6 address6 covert_send6 covert_send6d inject_alive6 firewall6 ndpexhaust26 fake_pim6 thcsyn6 redirsniff6 flood_redir6 four2six dump_dhcp6 flood_rs6 fuzz_dhcps6 fuzz_dhcpc6 toobigsniff6 flood_unreach6 connect6
EXTRA=dnssecwalk dnsdict6 thcping6 fragrouter6 connsplit6
LIBS=thc-ipv6-lib.o
STRIP=strip
Expand Down
253 changes: 253 additions & 0 deletions connect6.c
@@ -0,0 +1,253 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include "thc-ipv6.h"

#define PROGRAM "connect6"

#ifndef in6_pktinfo
struct in6_pktinfo {
struct in6_addr ipi6_addr;
int ipi6_ifindex;
};
#endif
char *prg;

void help() {
printf("%s %s (c) 2018 by %s %s\n\n", PROGRAM, VERSION, AUTHOR, RESOURCE);
printf("Syntax: %s [-a | -A type] [-i] target-ip target-port\n\n", prg);
printf("Options:\n");
printf(" -a send Hop-by-Hop Router Alert option\n");
printf(" -A type like -a but lets you define the alarmtype (number)\n");
printf(" -i interactive mode (like telnet)\n");
printf(" -I end a linefeed, wait for a string, print it\n");
printf(" -O try TCP Fast Open connection\n");
printf(" -w ms wait time for connect in ms (default: 1000)\n");
printf(" -p ping mode\n");
printf("You can supply a %%interface identifier to the target-ip\n");
printf("Returns 0 on successful connect, 1 on timeout/reset\n");
exit(-1);
}

void myalarm(int signal) {
return;
}

int main(int argc, char *argv[]) {
int i, t = -1, conn_len, do_alert = 0, interactive = 0, optval, optlen, fastopen = 0;
unsigned long int ping = 0, waitms = 1000;
char buf[1033], *interface, *target;
struct addrinfo *res, *aip, *aip_saved = NULL;
struct addrinfo hints;
struct sockaddr_in6 conn;
unsigned short rtalert_code = 0; // alert type, 0 = MLD, 1 = RSVP, 2 = Active Network

prg = argv[0];
if (argc < 3 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--h", 3) == 0)
help();

setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
signal(SIGALRM, myalarm);

if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL)
printf("WARNING: %s is not working with injection!\n", argv[0]);

while ((i = getopt(argc, argv, "paA:iIOw:")) >= 0) {
switch (i) {
case 'w':
waitms = atoi(optarg);
case 'p':
ping = 1;
break;
case 'a':
do_alert = 1;
break;
case 'O':
fastopen = 1;
break;
case 'A':
do_alert = 1;
rtalert_code = atoi(optarg);
break;
case 'i':
interactive = 1;
break;
case 'I':
interactive = 2;
break;
default:
fprintf(stderr, "Error: invalid option %c\n", i);
exit(-1);
}
}

memset((char *) &hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET6;

target = argv[optind];
if ((interface = index(target, '%')) != NULL)
#ifdef SO_BINDTODEVICE
*interface++ = 0;
#else
{
fprintf(stderr, "Error: your operating system does not support SO_BINDTODEVICE, so I can't bind to an interface!\n");
exit(-1);
}
#endif
else if (strncmp(target, "fe80", 4) == 0) {
fprintf(stderr, "Error: to connect to an fe80:: link local address, you must specify an interface, e.g. fe80::1%%eth0\n");
exit(-1);
}

if ((i = getaddrinfo(target, argv[optind + 1], &hints, &res)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(i));
return -1;
}

conn_len = sizeof(conn);

for (aip = res; aip != NULL; aip = aip->ai_next) {
if (t == -1) {
t = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
if (t == -1) {
perror("socket");
freeaddrinfo(res);
return (-1);
}
#ifdef SO_BINDTODEVICE
if (interface != NULL)
if (setsockopt(t, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface) + 1) < 0)
fprintf(stderr, "Warning: could not bind to device %s\n", interface);
#endif
memset(buf, 0, 8);
if (do_alert) {
buf[2] = 5;
buf[3] = 2;
buf[4] = rtalert_code / 256;
buf[5] = rtalert_code % 256;
if (setsockopt(t, IPPROTO_IPV6, IPV6_HOPOPTS, buf, 8) != 0) {
perror("setsockopt");
if (ping == 0)
exit(-1);
}
}
if (fastopen) {
printf("go\n");
if (sendto(t, buf, 0, 0, aip->ai_addr, aip->ai_addrlen) < 0) {
printf("error!\n");
perror("sendto");
(void) close(t);
t = -1;
continue;
}
printf("done\n");
} else {
if (waitms < 2000)
alarm(2);
else
alarm(waitms / 1000);
if (connect(t, aip->ai_addr, aip->ai_addrlen) == -1) {
perror("connect");
(void) close(t);
t = -1;
continue;
} else
aip_saved = aip;
alarm(0);
}
break;
}
}

if (t < 0) {
fprintf(stderr, "Error: can not connect to target\n");
exit(1);
}

if (ping == 0) {
printf("Connected.\n");

i = getsockopt(t, IPPROTO_IPV6, IPV6_MTU, &optval, &optlen);
printf("MTU to target is %d (return code from getsockopt was %d)\n", optval, i);
if (interactive == 1) {
fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
fcntl(t, F_SETFL, O_NONBLOCK);
while (1) {
if ((i = recv(t, buf, sizeof(buf), 0)) > 0)
fwrite(buf, 1, i, stdout);
if ((i = read(fileno(stdin), buf, sizeof(buf))) > 0)
send(t, buf, i, 0);
usleep(10);
}
} else if (interactive == 2) {
snprintf(buf, sizeof(buf), "\r\n"); // do something else than enter maybe
send(t, buf, strlen(buf), 0);
alarm(3);
if ((i = recv(t, buf, sizeof(buf), 0)) < 0) {
close(t);
return 0;
}
printf("%s\n", buf);
}
} else {
fd_set myset;
struct timeval tv;
unsigned long int diff;

close(t);
printf("Connected seq=%lu\n", ping);
while (1) {
if ((t = socket(aip_saved->ai_family, aip_saved->ai_socktype, aip_saved->ai_protocol)) >= 0) {
#ifdef SO_BINDTODEVICE
if (interface != NULL)
if (setsockopt(t, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface) + 1) < 0)
fprintf(stderr, "Warning: could not bind to device %s\n", interface);
#endif
memset(buf, 0, 8);
if (do_alert) {
buf[2] = 5;
buf[3] = 2;
buf[4] = rtalert_code / 256;
buf[5] = rtalert_code % 256;
if (setsockopt(t, IPPROTO_IPV6, IPV6_HOPOPTS, buf, 8) != 0)
perror("setsockopt");
}
fcntl(t, F_SETFL, O_NONBLOCK);
ping++;
connect(t, aip->ai_addr, aip->ai_addrlen);
FD_ZERO(&myset);
FD_SET(t, &myset);
tv.tv_sec = waitms / 1000;
tv.tv_usec = (waitms % 1000) * 1000;
if (select(t + 1, NULL, &myset, NULL, &tv) > 0) {
diff = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
printf("Connected seq=%lu %ds %dms\n", ping, (waitms - diff) / 1000, (waitms - diff) % 1000);
}
// wait for rest of timeout
close(t);
select(t + 1, NULL, NULL, NULL, &tv);
}
}
}
return 0;
}

0 comments on commit 8dba5f2

Please sign in to comment.