diff --git a/README.md b/README.md index 179872d..6787504 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and ### MISC. INFO #### IPv6 -The data inside the tunnel is IPv4 only. +The data inside the tunnel may be IPv4 or IPv6. The server listens to both IPv4 and IPv6 for incoming requests by default. Use options `-4` or `-6` to only listen on one protocol. Raw mode will be @@ -141,6 +141,14 @@ to your DNS setup. Extending the example above would look like this: t1ns IN A 10.15.213.99 t1ns IN AAAA 2001:db8::1001:99 +On the server, specify -S followed by an IPv6 address that will be the server end +of the IPv6 pool to allocate to clients. The server only supports a /64 subnet +mask, which is assumed and can be omitted. The first 64 bits are the network from +which IPv6 addresses are allocated from. + +The client will automatically check for IPv6 capability on the server and +assign the allocated address to its tunnel interface. No flags are needed. + #### Routing It is possible to route all traffic through the DNS tunnel. To do this, first add a host route to the nameserver used by iodine over the wired/wireless diff --git a/src/client.c b/src/client.c index 8261b68..39ee20b 100644 --- a/src/client.c +++ b/src/client.c @@ -2440,44 +2440,49 @@ int handshake_check_v6(int dns_fd) { char in[4096]; - char server6[1024]; - char client6[1024]; + char server6[INET6_ADDRSTRLEN]; + char client6[INET6_ADDRSTRLEN]; int i; int read; int netmask6 = 0; + int length_recieved; fprintf(stderr, "Autoprobing server IPV6 tunnel support\n"); for (i = 0; running && i < 5; i++) { - send_v6_probe(dns_fd); + send_v6_probe(dns_fd); - read = handshake_waitdns(dns_fd, in, sizeof(in), 'g', 'G', i+1); + read = handshake_waitdns(dns_fd, in, sizeof(in), 'g', 'G', i+1); if (read > 0) { - /* - * including a terminating dash to allow for future IPv6 options, e.g. - * netmask. Currently assumes /64. MTU is taken from the IPv4 handshake. - * A future IPv6-only implementation would need to pass mtu - * in the IPV6 handshake. - */ + /* + * including a terminating dash to allow for future IPv6 options, e.g. + * netmask. Currently assumes /64. MTU is taken from the IPv4 handshake. + * A future IPv6-only implementation would need to pass mtu + * in the IPV6 handshake. + */ - if (sscanf(in, "%512[^-]-%512[^-]-%d", server6, client6, &netmask6) == 3) { + if (sscanf(in, "%512[^-]-%512[^-]-%d", server6, client6, &netmask6) == 3) { - fprintf(stderr, "Server tunnel IPv6 is %s\n", server6); - fprintf(stderr, "Local tunnel IPv6 is %s\n", client6); + fprintf(stderr, "Server tunnel IPv6 is %s\n", server6); + fprintf(stderr, "Local tunnel IPv6 is %s\n", client6); - if (tun_setip6(client6, server6, netmask6) == 0) { + length_recieved = strlen(client6); + if (length_recieved > 2) { + if (tun_setip6(client6, server6, netmask6) == 0) { - use_v6 = true; - return 0; - } else { - errx(4, "Failed to set IPv6 tunnel address"); - } - } else { - fprintf(stderr, "Received bad IPv6 tunnel handshake\n"); - } + use_v6 = true; + return 0; + + } else { + errx(4, "Failed to set IPv6 tunnel address"); + } + } else { + fprintf(stderr, "Received bad IPv6 tunnel handshake\n"); + } + } } fprintf(stderr, "Retrying IPv6 tunnel handshake...\n"); diff --git a/src/iodined.c b/src/iodined.c index cb6f803..9add3ad 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -90,8 +90,8 @@ static int my_mtu; static in_addr_t my_ip; char display_ip6[INET6_ADDRSTRLEN]; -char *display_ip6_buffer; -char *ip6_netmask_buffer; +char *display_ip6_buffer = NULL; +char *ip6_netmask_buffer = NULL; static struct in6_addr my_ip6; static int netmask; @@ -2590,21 +2590,25 @@ main(int argc, char **argv) } - ip6_netmask_buffer = strchr(display_ip6_buffer, '/'); - if (ip6_netmask_buffer) { - if (atoi(ip6_netmask_buffer+1) != ip6_netmask) { - warnx("IPv6 address must be a 64-bit mask."); - usage(); + if (display_ip6_buffer != NULL) { + + ip6_netmask_buffer = strchr(display_ip6_buffer, '/'); + + if (ip6_netmask_buffer != NULL) { + if (atoi(ip6_netmask_buffer+1) != ip6_netmask) { + warnx("IPv6 address must be a 64-bit mask."); + usage(); } /* remove masklen */ memcpy(display_ip6, display_ip6_buffer, strlen(display_ip6_buffer) - strlen(ip6_netmask_buffer)); display_ip6[strlen(display_ip6)+1] = '\0'; - } + } - /* IPV6 address sanity check */ - if (inet_pton(AF_INET6, display_ip6, &my_ip6) != 1) { + /* IPV6 address sanity check */ + if (inet_pton(AF_INET6, display_ip6, &my_ip6) != 1) { warnx("Bad IPv6 address to use inside tunnel."); usage(); + } } topdomain = strdup(argv[1]); @@ -2753,10 +2757,11 @@ main(int argc, char **argv) } - if (tun_setip6(display_ip6, display_other_ip6, ip6_netmask) != 0 ) { - retval = 1; - goto cleanup; - + if (display_ip6_buffer != NULL) { + if (tun_setip6(display_ip6, display_other_ip6, ip6_netmask) != 0 ) { + retval = 1; + goto cleanup; + } } if ((mtu < 1280) && (sizeof(display_ip6)) != 0) {