diff --git a/CHANGELOG b/CHANGELOG index ebafcb3..fa5aae9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,11 @@ CHANGES: - Upstream data is now Base64 encoded if relay server preserves case and supports the plus (+) character in domain names, fixes #16. - Fixed problem in client when DNS trans. ID has highest bit set (#37) + - IP addresses are now assigned within the netmask, so iodined can + use any address for itself, fixes #28. + - Netmask size is now adjustable. Setting a small net will reduce the + number of users. Use x.x.x.x/n notation on iodined tunnel ip. + This fixes #27. 2008-08-06: 0.4.2 "Opened Zone" - Applied a few small patches from Maxim Bourmistrov and Gregor Herrmann diff --git a/doc/proto_00000403.txt b/doc/proto_00000403.txt index cf05d94..ee72313 100644 --- a/doc/proto_00000403.txt +++ b/doc/proto_00000403.txt @@ -26,7 +26,7 @@ Client sends: CMC Server replies: LNAK means not accepted - x.x.x.x-y.y.y.y-mtu means accepted (server ip, client ip, mtu) + x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits) Case check: Client sends: diff --git a/man/iodine.8 b/man/iodine.8 index 08bbd57..18863f7 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -45,6 +45,9 @@ iodine, iodined \- tunnel IPv4 over DNS .I password .B ] .I tunnel_ip +.B [ +.I /netmask +.B ] .I topdomain .SH DESCRIPTION .B iodine @@ -133,10 +136,12 @@ is the iodined server, then the topdomain can be chosen freely. This argument must be the same on both the client and the server. .SS Server Arguments: .TP -.B tunnel_ip +.B tunnel_ip[/netmask] This is the servers ip address on the tunnel interface. The client will be given the next ip number in the range. It is recommended to use the -10.0.0.0/8 or 172.16.0.0/12 ranges. +10.0.0.0 or 172.16.0.0 ranges. The default netmask is /27, can be overriden +by specifying it here. Using a smaller network will limit the number of +concurrent users. .TP .B topdomain The dns traffic will is expected to be sent as querys of type NULL for diff --git a/src/iodine.c b/src/iodine.c index 4fb7ddc..44ddb7b 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -488,15 +488,16 @@ perform_login: } if (read > 0) { + int netmask; if (strncmp("LNAK", in, 4) == 0) { printf("Bad password\n"); return 1; - } else if (sscanf(in, "%64[^-]-%64[^-]-%d", - server, client, &mtu) == 3) { + } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d", + server, client, &mtu, &netmask) == 4) { server[64] = 0; client[64] = 0; - if (tun_setip(client) == 0 && + if (tun_setip(client, netmask) == 0 && tun_setmtu(mtu) == 0) { goto perform_case_check; } else { diff --git a/src/iodined.c b/src/iodined.c index e5a8393..5db94a0 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -56,10 +56,12 @@ static int running = 1; static char *topdomain; static char password[33]; static struct encoder *b32; +static int created_users; static int check_ip; static int my_mtu; static in_addr_t my_ip; +static int netmask; static in_addr_t ns_ip; @@ -230,7 +232,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) users[userid].q.id = 0; } else { /* No space for another user */ - send_version_response(dns_fd, VERSION_FULL, USERS, 0, q); + send_version_response(dns_fd, VERSION_FULL, created_users, 0, q); } } else { send_version_response(dns_fd, VERSION_NACK, VERSION, 0, q); @@ -251,15 +253,15 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) write_dns(dns_fd, q, "BADIP", 5); } else { if (read >= 18 && (memcmp(logindata, unpacked+1, 16) == 0)) { - /* Login ok, send ip/mtu info */ + /* Login ok, send ip/mtu/netmask info */ tempip.s_addr = my_ip; tmp[0] = strdup(inet_ntoa(tempip)); tempip.s_addr = users[userid].tun_ip; tmp[1] = strdup(inet_ntoa(tempip)); - read = snprintf(out, sizeof(out), "%s-%s-%d", - tmp[0], tmp[1], my_mtu); + read = snprintf(out, sizeof(out), "%s-%s-%d-%d", + tmp[0], tmp[1], my_mtu, netmask); write_dns(dns_fd, q, out, read); q->id = 0; @@ -726,7 +728,7 @@ usage() { printf("Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] " "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip topdomain\n", __progname); + " tunnel_ip[/netmask] topdomain\n", __progname); exit(2); } @@ -738,7 +740,7 @@ help() { printf("Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] " "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip topdomain\n", __progname); + " tunnel_ip[/netmask] topdomain\n", __progname); printf(" -v to print version info and exit\n"); printf(" -h to print this help and exit\n"); printf(" -c to disable check of client IP/port on each request\n"); @@ -757,6 +759,7 @@ help() { printf(" -b port to forward normal DNS queries to (on localhost)\n"); printf(" -P password used for authentication (max 32 chars will be used)\n"); printf("tunnel_ip is the IP number of the local tunnel interface.\n"); + printf(" /netmask sets the size of the tunnel network.\n"); printf("topdomain is the FQDN that is delegated to this server.\n"); exit(0); } @@ -791,8 +794,7 @@ main(int argc, char **argv) int port; int mtu; int skipipconfig; - int netmask; - int created_users; + char *netsize; username = NULL; newroot = NULL; @@ -892,6 +894,13 @@ main(int argc, char **argv) if (argc != 2) usage(); + netsize = strchr(argv[0], '/'); + if (netsize) { + *netsize = 0; + netsize++; + netmask = atoi(netsize); + } + my_ip = inet_addr(argv[0]); if (my_ip == INADDR_NONE) { @@ -968,7 +977,7 @@ main(int argc, char **argv) if ((tun_fd = open_tun(device)) == -1) goto cleanup0; if (!skipipconfig) - if (tun_setip(argv[0]) != 0 || tun_setmtu(mtu) != 0) + if (tun_setip(argv[0], netmask) != 0 || tun_setmtu(mtu) != 0) goto cleanup1; if ((dnsd_fd = open_dns(port, listen_ip)) == -1) goto cleanup2; diff --git a/src/tun.c b/src/tun.c index 8edccf0..55de5b4 100644 --- a/src/tun.c +++ b/src/tun.c @@ -181,19 +181,30 @@ read_tun(int tun_fd, char *buf, size_t len) } int -tun_setip(const char *ip) +tun_setip(const char *ip, int netbits) { char cmdline[512]; + int netmask; + struct in_addr net; + int i; + #ifndef LINUX - int r; + int r; #endif + netmask = 0; + for (i = 0; i < netbits; i++) { + netmask = (netmask << 1) | 1; + } + netmask <<= (32 - netbits); + net.s_addr = htonl(netmask); if (inet_addr(ip) != INADDR_NONE) { snprintf(cmdline, sizeof(cmdline), - "/sbin/ifconfig %s %s %s netmask 255.255.255.0", + "/sbin/ifconfig %s %s %s netmask %s", if_name, ip, - ip); + ip, + inet_ntoa(net)); printf("Setting IP of %s to %s\n", if_name, ip); #ifndef LINUX @@ -202,10 +213,10 @@ tun_setip(const char *ip) return r; } else { snprintf(cmdline, sizeof(cmdline), - "/sbin/route add %s/24 %s", - ip, ip); + "/sbin/route add %s/%d %s", + ip, netbits, ip); } - printf("Adding route %s/24 to %s\n", ip, ip); + printf("Adding route %s/%d to %s\n", ip, netbits, ip); #endif return system(cmdline); } else { diff --git a/src/tun.h b/src/tun.h index 5c8d9a3..2f1faa4 100644 --- a/src/tun.h +++ b/src/tun.h @@ -21,7 +21,7 @@ int open_tun(const char *); void close_tun(int); int write_tun(int, char *, size_t); ssize_t read_tun(int, char *, size_t); -int tun_setip(const char *); +int tun_setip(const char *, int); int tun_setmtu(const size_t); #endif /* _TUN_H_ */