diff --git a/Makefile b/Makefile index 2857b9d..31337ef 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ cross-android-dist: @zip -r iodine-latest-android.zip iodine-latest-android cross-mingw: - @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all) + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc all) cross-mingw-dist: cross-mingw @rm -rf iodine-latest-win32* diff --git a/src/common.c b/src/common.c index 6a40924..1edd087 100644 --- a/src/common.c +++ b/src/common.c @@ -113,6 +113,31 @@ check_superuser(void (*usage_fn)(void)) #endif } +char * +format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len) +{ + static char dst[INET6_ADDRSTRLEN + 1]; + + memset(dst, 0, sizeof(dst)); + if (sockaddr->ss_family == AF_INET && sockaddr_len >= sizeof(struct sockaddr_in)) { + struct sockaddr_in *addr = (struct sockaddr_in *) sockaddr; + inet_ntop(addr->sin_family, &addr->sin_addr, dst, sizeof(dst) - 1); + } else if (sockaddr->ss_family == AF_INET6 && sockaddr_len >= sizeof(struct sockaddr_in6)) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) sockaddr; + if (IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) { + struct in_addr ia; + /* Get mapped v4 addr from last 32bit field */ + memcpy(&ia.s_addr, &addr->sin6_addr.s6_addr[12], sizeof(ia)); + inet_ntop(AF_INET, &ia, dst, sizeof(dst) - 1); + } else { + inet_ntop(addr->sin6_family, &addr->sin6_addr, dst, sizeof(dst) - 1); + } + } else { + dst[0] = '?'; + } + return dst; +} + int get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_storage *out) { diff --git a/src/common.h b/src/common.h index 9163834..bbadc9f 100644 --- a/src/common.h +++ b/src/common.h @@ -107,6 +107,7 @@ enum connection { }; void check_superuser(void (*usage_fn)(void)); +char *format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len); int get_addr(char *, int, int, int, struct sockaddr_storage *); int open_dns(struct sockaddr_storage *, size_t); int open_dns_from_host(char *host, int port, int addr_family, int flags); diff --git a/src/fw_query.h b/src/fw_query.h index 7568a5f..f274a5a 100644 --- a/src/fw_query.h +++ b/src/fw_query.h @@ -28,7 +28,7 @@ #define FW_QUERY_CACHE_SIZE 16 struct fw_query { - struct sockaddr addr; + struct sockaddr_storage addr; int addrlen; unsigned short id; }; diff --git a/src/iodine.c b/src/iodine.c index eb4185e..d1a3b18 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -346,7 +346,7 @@ main(int argc, char **argv) signal(SIGTERM, sighandler); fprintf(stderr, "Sending DNS queries for %s to %s\n", - topdomain, nameserv_host); + topdomain, format_addr(&nameservaddr, nameservaddr_len)); if (client_handshake(dns_fd, raw_mode, autodetect_frag_size, max_downstream_frag_size)) { retval = 1; diff --git a/src/iodined.c b/src/iodined.c index d83893c..a6ccb58 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -215,10 +215,8 @@ send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q) packet[RAW_HDR_CMD] = cmd | (user & 0x0F); if (debug >= 2) { - struct sockaddr_in *tempin; - tempin = (struct sockaddr_in *) &(q->from); fprintf(stderr, "TX-raw: client %s, cmd %d, %d bytes\n", - inet_ntoa(tempin->sin_addr), cmd, len); + format_addr(&q->from, q->fromlen), cmd, len); } sendto(fd, packet, len, 0, (struct sockaddr *) &q->from, q->fromlen); @@ -766,7 +764,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) users[userid].downenc = 'T'; send_version_response(dns_fd, VERSION_ACK, users[userid].seed, userid, q); syslog(LOG_INFO, "accepted version for user #%d from %s", - userid, inet_ntoa(tempin->sin_addr)); + userid, format_addr(&q->from, q->fromlen)); users[userid].q.id = 0; users[userid].q.id2 = 0; users[userid].q_sendrealsoon.id = 0; @@ -808,12 +806,12 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) /* No space for another user */ send_version_response(dns_fd, VERSION_FULL, created_users, 0, q); syslog(LOG_INFO, "dropped user from %s, server full", - inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); + format_addr(&q->from, q->fromlen)); } } else { send_version_response(dns_fd, VERSION_NACK, VERSION, 0, q); syslog(LOG_INFO, "dropped user from %s, sent bad version %08X", - inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr), version); + format_addr(&q->from, q->fromlen), version); } return; } else if(in[0] == 'L' || in[0] == 'l') { @@ -829,7 +827,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) if (check_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); syslog(LOG_WARNING, "dropped login request from user #%d from unexpected source %s", - userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); + userid, format_addr(&q->from, q->fromlen)); return; } else { users[userid].last_pkt = time(NULL); @@ -855,7 +853,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) } else { write_dns(dns_fd, q, "LNAK", 4, 'T'); syslog(LOG_WARNING, "rejected login request from user #%d from %s, bad password", - userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); + userid, format_addr(&q->from, q->fromlen)); } } return; @@ -1493,10 +1491,8 @@ handle_ns_request(int dns_fd, struct query *q) } if (debug >= 2) { - struct sockaddr_in *tempin; - tempin = (struct sockaddr_in *) &(q->from); fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes NS reply\n", - inet_ntoa(tempin->sin_addr), q->type, q->name, len); + format_addr(&q->from, q->fromlen), q->type, q->name, len); } if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) { warn("ns reply send error"); @@ -1527,10 +1523,8 @@ handle_a_request(int dns_fd, struct query *q, int fakeip) } if (debug >= 2) { - struct sockaddr_in *tempin; - tempin = (struct sockaddr_in *) &(q->from); fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes A reply\n", - inet_ntoa(tempin->sin_addr), q->type, q->name, len); + format_addr(&q->from, q->fromlen), q->type, q->name, len); } if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) { warn("a reply send error"); @@ -1576,7 +1570,7 @@ static int tunnel_bind(int bind_fd, int dns_fd) { char packet[64*1024]; - struct sockaddr_in from; + struct sockaddr_storage from; socklen_t fromlen; struct fw_query *query; unsigned short id; @@ -1603,10 +1597,8 @@ tunnel_bind(int bind_fd, int dns_fd) } if (debug >= 2) { - struct sockaddr_in *in; - in = (struct sockaddr_in *) &(query->addr); fprintf(stderr, "TX: client %s id %u, %d bytes\n", - inet_ntoa(in->sin_addr), (id & 0xffff), r); + format_addr(&query->addr, query->addrlen), (id & 0xffff), r); } if (sendto(dns_fd, packet, r, 0, (const struct sockaddr *) &(query->addr), @@ -1629,10 +1621,8 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd) return 0; if (debug >= 2) { - struct sockaddr_in *tempin; - tempin = (struct sockaddr_in *) &(q.from); fprintf(stderr, "RX: client %s, type %d, name %s\n", - inet_ntoa(tempin->sin_addr), q.type, q.name); + format_addr(&q.from, q.fromlen), q.type, q.name); } domain_len = strlen(q.name) - strlen(topdomain); @@ -2173,10 +2163,8 @@ write_dns(int fd, struct query *q, char *data, int datalen, char downenc) } if (debug >= 2) { - struct sockaddr_in *tempin; - tempin = (struct sockaddr_in *) &(q->from); fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes data\n", - inet_ntoa(tempin->sin_addr), q->type, q->name, datalen); + format_addr(&q->from, q->fromlen), q->type, q->name, datalen); } sendto(fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen);