Ticket #107: diff

File diff, 24.3 KB (added by guest, 19 months ago)

IPv6 patch

  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/client.c iodine-0.6.0-rc1/src/client.c
    old new  
    5858static int running; 
    5959static const char *password; 
    6060 
    61 static struct sockaddr_in nameserv; 
    62 static struct sockaddr_in raw_serv; 
     61static struct sockaddr_in6 nameserv; 
     62static struct sockaddr_in6 raw_serv; 
    6363static const char *topdomain; 
    6464 
    6565static uint16_t rand_seed; 
     
    148148void 
    149149client_set_nameserver(const char *cp, int port)  
    150150{ 
    151         struct in_addr addr; 
     151        struct in6_addr addr; 
    152152 
    153         if (inet_aton(cp, &addr) != 1) { 
     153        if (inet_pton(AF_INET6, cp, &addr) != 1) { 
    154154                /* try resolving if a domain is given */ 
    155                 struct hostent *host; 
     155                struct addrinfo *res; 
    156156                const char *err; 
    157                 host = gethostbyname(cp); 
    158                 if (host != NULL && h_errno > 0) { 
    159                         int i = 0; 
    160                         while (host->h_addr_list[i] != 0) { 
    161                                 addr = *(struct in_addr *) host->h_addr_list[i++]; 
    162                                 fprintf(stderr, "Resolved %s to %s\n", cp, inet_ntoa(addr)); 
     157                int error = getaddrinfo(cp, NULL, NULL, &res); 
     158                if (!error) { 
     159                        struct addrinfo *rp; 
     160                        for (rp = res; rp != NULL; rp = rp->ai_next) { 
     161                                if (rp->ai_family == AF_INET6) 
     162                                        addr = ((struct sockaddr_in6 *)(rp->ai_addr))->sin6_addr; 
     163                                else { 
     164                                        addr.s6_addr32[0] = 0; 
     165                                        addr.s6_addr32[1] = 0; 
     166                                        addr.s6_addr32[2] = htonl(0xffff); 
     167                                        addr.s6_addr32[3] = ((struct sockaddr_in *)(rp->ai_addr))->sin_addr.s_addr; 
     168                                } 
     169                                fprintf(stderr, "Resolved %s to %s\n", cp, inet6_ntoa(addr)); 
    163170                                goto setaddr; 
    164171                        } 
    165172                } 
    166173#ifndef WINDOWS32 
    167                 err = hstrerror(h_errno); 
     174                err = gai_strerror(error); 
    168175#else 
    169176                { 
    170177                        DWORD wserr = WSAGetLastError(); 
     
    186193 
    187194setaddr: 
    188195        memset(&nameserv, 0, sizeof(nameserv)); 
    189         nameserv.sin_family = AF_INET; 
    190         nameserv.sin_port = htons(port); 
    191         nameserv.sin_addr = addr; 
     196        nameserv.sin6_family = AF_INET6; 
     197        nameserv.sin6_port = htons(port); 
     198        nameserv.sin6_addr = addr; 
    192199} 
    193200 
    194201void 
     
    272279const char * 
    273280client_get_raw_addr() 
    274281{ 
    275         return inet_ntoa(raw_serv.sin_addr); 
     282        return inet6_ntoa(raw_serv.sin6_addr); 
    276283} 
    277284 
    278285static void 
     
    601608        socklen_t addrlen; 
    602609        int r; 
    603610 
    604         addrlen = sizeof(struct sockaddr); 
     611        addrlen = sizeof(struct sockaddr_in6); 
    605612        if ((r = recvfrom(dns_fd, data, sizeof(data), 0,  
    606613                          (struct sockaddr*)&from, &addrlen)) < 0) { 
    607614                warn("recvfrom"); 
     
    15221529        int r; 
    15231530        int len; 
    15241531        unsigned remoteaddr = 0; 
    1525         struct in_addr server; 
     1532        struct in6_addr server; 
    15261533 
    15271534        fprintf(stderr, "Testing raw UDP data to the server (skip with -r)"); 
    15281535        for (i=0; running && i<3 ;i++) { 
     
    15411548                                remoteaddr |= (in[3] & 0xff); 
    15421549                                remoteaddr <<= 8; 
    15431550                                remoteaddr |= (in[4] & 0xff); 
    1544                                 server.s_addr = ntohl(remoteaddr); 
     1551                                server.s6_addr32[0] = 0; 
     1552                                server.s6_addr32[1] = 0; 
     1553                                server.s6_addr32[2] = ntohl(0xffff); 
     1554                                server.s6_addr32[3] = ntohl(remoteaddr); 
    15451555                                break; 
     1556                        } else if (len == 17 && in[0] == 'I') { 
     1557                                remoteaddr = -1; 
     1558                                memcpy(&server, in + 1, sizeof(struct in6_addr)); 
    15461559                        } 
    15471560                /*XXX END adjust indent 1 tab back*/ 
    15481561 
     
    15571570                fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n"); 
    15581571                return 0; 
    15591572        } 
    1560         fprintf(stderr, "Server is at %s, trying raw login: ", inet_ntoa(server)); 
     1573        fprintf(stderr, "Server is at %s, trying raw login: ", inet6_ntoa(server)); 
    15611574        fflush(stderr); 
    15621575 
    15631576        /* Store address to iodined server */ 
    15641577        memset(&raw_serv, 0, sizeof(raw_serv)); 
    1565         raw_serv.sin_family = AF_INET; 
    1566         raw_serv.sin_port = htons(53); 
    1567         raw_serv.sin_addr = server; 
     1578        raw_serv.sin6_family = AF_INET6; 
     1579        raw_serv.sin6_port = htons(53); 
     1580        raw_serv.sin6_addr = server; 
    15681581 
    15691582        /* do login against port 53 on remote server  
    15701583         * based on the old seed. If reply received, 
  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/common.c iodine-0.6.0-rc1/src/common.c
    old new  
    5353/* The raw header used when not using DNS protocol */ 
    5454const unsigned char raw_header[RAW_HDR_LEN] = { 0x10, 0xd1, 0x9e, 0x00 }; 
    5555 
     56/* Transparent socket */ 
     57struct sockaddr_in6 tsock; 
     58 
    5659/* daemon(3) exists only in 4.4BSD or later, and in GNU libc */ 
    5760#if !defined(WINDOWS32) && !(defined(BSD) && (BSD >= 199306)) && !defined(__GLIBC__) 
    5861static int daemon(int nochdir, int noclose) 
     
    112115} 
    113116 
    114117int  
    115 open_dns(int localport, in_addr_t listen_ip)  
     118open_dns(int localport, struct in6_addr listen_ip)  
    116119{ 
    117         struct sockaddr_in addr; 
     120        struct sockaddr_in6 addr; 
    118121        int flag = 1; 
    119122        int fd; 
    120123 
    121124        memset(&addr, 0, sizeof(addr)); 
    122         addr.sin_family = AF_INET; 
    123         addr.sin_port = htons(localport); 
     125        addr.sin6_family = AF_INET6; 
     126        addr.sin6_port = htons(localport); 
    124127        /* listen_ip already in network byte order from inet_addr, or 0 */ 
    125         addr.sin_addr.s_addr = listen_ip;  
     128        addr.sin6_addr = listen_ip;  
    126129 
    127         if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 
     130        if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 
    128131                fprintf(stderr, "got fd %d\n", fd); 
    129132                err(1, "socket"); 
    130133        } 
     
    138141#ifndef WINDOWS32 
    139142        /* To get destination address from each UDP datagram, see iodined.c:read_dns() */ 
    140143        setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag)); 
     144        setsockopt(fd, IPPROTO_IPV6, IPV6_RECVORIGDSTADDR, (const void*) &flag, sizeof(flag)); 
     145#ifdef IP_TRANSPARENT 
     146        /* To be able to use TPROXY in incoming queries */ 
     147        if (localport && localport != DNS_PORT) { 
     148                setsockopt(fd, SOL_IP, IP_TRANSPARENT, (const void*) &flag, sizeof(flag)); 
     149                tsock = addr; 
     150        } 
     151#endif 
    141152#endif 
    142153 
    143154#ifdef IP_OPT_DONT_FRAG 
     
    348359        } 
    349360        return 0; 
    350361} 
     362 
     363char *inet6_ntoa(struct in6_addr src) { 
     364        static char dst[INET6_ADDRSTRLEN]; 
     365 
     366        if (IN6_IS_ADDR_V4MAPPED(&src)) 
     367        { 
     368                struct in_addr ia; 
     369                ia.s_addr = src.s6_addr32[3]; 
     370                inet_ntop(AF_INET, &ia, dst, sizeof(dst)); 
     371        } else 
     372                inet_ntop(AF_INET6, &src, dst, sizeof(dst)); 
     373 
     374        return dst; 
     375} 
     376 
     377int  
     378sendto_tproxy(int sockfd, const void *buf, size_t len, int flags, 
     379                struct sockaddr_in6 *s_addr, 
     380                const struct sockaddr *dest_addr, socklen_t daddrlen) 
     381{ 
     382        int fd; 
     383#ifdef IP_TRANSPARENT 
     384        static int tfd = -1; 
     385        if (tsock.sin6_family && (tsock.sin6_port != s_addr->sin6_port)) { 
     386                static struct sockaddr_in6 src_addr; 
     387                int flag = 1; 
     388 
     389                if (memcmp(&src_addr, s_addr, sizeof(src_addr))) { 
     390                        if (tfd >= 0) 
     391                                close(tfd); 
     392 
     393                        src_addr = *s_addr; 
     394 
     395                        if ((tfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 
     396                                fprintf(stderr, "got fd %d\n", tfd); 
     397                                err(1, "socket"); 
     398                        } 
     399 
     400#ifdef SO_REUSEPORT 
     401                        setsockopt(tfd, SOL_SOCKET, SO_REUSEPORT, (const void*) &flag, sizeof(flag)); 
     402#endif 
     403                        setsockopt(tfd, SOL_SOCKET, SO_REUSEADDR, (const void*) &flag, sizeof(flag)); 
     404 
     405                        setsockopt(tfd, SOL_SOCKET, SO_BROADCAST, (const void*) &flag, sizeof(flag)); 
     406                        setsockopt(tfd, SOL_IP, IP_TRANSPARENT, (const void*) &flag, sizeof(flag)); 
     407 
     408#ifdef IP_OPT_DONT_FRAG 
     409                        /* Set dont-fragment ip header flag */ 
     410                        flag = DONT_FRAG_VALUE; 
     411                        setsockopt(tfd, IPPROTO_IP, IP_OPT_DONT_FRAG, (const void*) &flag, sizeof(flag)); 
     412#endif 
     413                        if(bind(tfd, (struct sockaddr*)&src_addr, sizeof(src_addr)) < 0)  
     414                                err(1, "bind"); 
     415                } 
     416                fd = tfd; 
     417        } else 
     418#endif 
     419                fd = sockfd; 
     420 
     421        return sendto(fd, buf, len, flags, dest_addr, daddrlen); 
     422} 
  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/common.h iodine-0.6.0-rc1/src/common.h
    old new  
    5252 
    5353#define QUERY_NAME_SIZE 256 
    5454 
    55 #if defined IP_RECVDSTADDR  
     55#if defined IP_RECVORIGDSTADDR 
     56# define IPV6_RECVORIGDSTADDR   74 
     57# define DSTADDR_SOCKOPT IP_RECVORIGDSTADDR  
     58# define dstaddr(x) (&(((struct sockaddr_in *)(CMSG_DATA(x)))->sin_addr.s_addr)) 
     59# define dstport(x) (((struct sockaddr_in *)(CMSG_DATA(x)))->sin_port) 
     60# define dstsock6(x) ((struct sockaddr_in6 *)(CMSG_DATA(x))) 
     61#elif defined IP_RECVDSTADDR  
    5662# define DSTADDR_SOCKOPT IP_RECVDSTADDR  
    5763# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x))  
     64# define dstport(x) (DNS_PORT) 
    5865#elif defined IP_PKTINFO  
    5966# define DSTADDR_SOCKOPT IP_PKTINFO  
    6067# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))  
     68# define dstport(x) (DNS_PORT) 
    6169#endif 
    6270 
    6371#if defined IP_MTU_DISCOVER 
     
    92100        unsigned short type; 
    93101        unsigned short rcode; 
    94102        unsigned short id; 
    95         struct in_addr destination; 
    96         struct sockaddr from; 
     103        struct sockaddr_in6 destination; 
     104        struct sockaddr_in6 from; 
    97105        int fromlen; 
    98106        unsigned short id2; 
    99         struct sockaddr from2; 
     107        struct sockaddr_in6 from2; 
    100108        int fromlen2; 
    101109}; 
    102110 
     
    107115}; 
    108116 
    109117void check_superuser(void (*usage_fn)(void)); 
    110 int open_dns(int, in_addr_t); 
     118int open_dns(int, struct in6_addr); 
    111119void close_dns(int); 
    112120 
    113121void do_chroot(char *); 
     
    129137#endif 
    130138 
    131139int recent_seqno(int , int); 
     140char *inet6_ntoa(struct in6_addr src); 
     141int sendto_tproxy(int sockfd, const void *buf, size_t len, int flags, 
     142                struct sockaddr_in6 *s_addr, 
     143                const struct sockaddr *dest_addr, socklen_t daddrlen); 
    132144 
    133145#endif 
  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/iodine.c iodine-0.6.0-rc1/src/iodine.c
    old new  
    317317                retval = 1; 
    318318                goto cleanup1; 
    319319        } 
    320         if ((dns_fd = open_dns(0, INADDR_ANY)) == -1) { 
     320        if ((dns_fd = open_dns(0, in6addr_any)) == -1) { 
    321321                retval = 1; 
    322322                goto cleanup2; 
    323323        } 
  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/iodined.c iodine-0.6.0-rc1/src/iodined.c
    old new  
    8080static in_addr_t my_ip; 
    8181static int netmask; 
    8282 
    83 static in_addr_t ns_ip; 
     83static struct in6_addr ns_ip; 
    8484 
    8585static int bind_port; 
    8686static int debug; 
     
    119119static int 
    120120check_user_and_ip(int userid, struct query *q) 
    121121{ 
    122         struct sockaddr_in *tempin; 
     122        struct sockaddr_in6 *tempin; 
    123123 
    124124        /* Note: duplicate in handle_raw_login() except IP-address check */ 
    125125 
     
    138138                return 0; 
    139139        } 
    140140 
    141         tempin = (struct sockaddr_in *) &(q->from); 
    142         return memcmp(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 
     141        tempin = (struct sockaddr_in6 *) &(q->from); 
     142        return (!IN6_ARE_ADDR_EQUAL(&users[userid].host, &tempin->sin6_addr)); 
    143143} 
    144144 
    145145static void 
     
    159159        packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 
    160160 
    161161        if (debug >= 2) { 
    162                 struct sockaddr_in *tempin; 
    163                 tempin = (struct sockaddr_in *) &(q->from); 
     162                struct sockaddr_in6 *tempin; 
     163                tempin = (struct sockaddr_in6 *) &(q->from); 
    164164                fprintf(stderr, "TX-raw: client %s, cmd %d, %d bytes\n",  
    165                         inet_ntoa(tempin->sin_addr), cmd, len); 
     165                        inet6_ntoa(tempin->sin6_addr), cmd, len); 
    166166        } 
    167167 
    168         sendto(fd, packet, len, 0, &q->from, q->fromlen); 
     168        sendto_tproxy(fd, packet, len, 0, &q->destination, (struct sockaddr *)&q->from, q->fromlen); 
    169169} 
    170170 
    171171 
     
    698698                        userid = find_available_user(); 
    699699                        if (userid >= 0) { 
    700700                                int i; 
    701                                 struct sockaddr_in *tempin; 
     701                                struct sockaddr_in6 *tempin; 
    702702 
    703703                                users[userid].seed = rand(); 
    704704                                /* Store remote IP number */ 
    705                                 tempin = (struct sockaddr_in *) &(q->from); 
    706                                 memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 
     705                                tempin = (struct sockaddr_in6 *) &(q->from); 
     706                                memcpy(&(users[userid].host), &(tempin->sin6_addr), sizeof(struct in6_addr)); 
    707707                                 
    708708                                memcpy(&(users[userid].q), q, sizeof(struct query)); 
    709709                                users[userid].encoder = get_base32_encoder(); 
    710710                                users[userid].downenc = 'T'; 
    711711                                send_version_response(dns_fd, VERSION_ACK, users[userid].seed, userid, q); 
    712712                                syslog(LOG_INFO, "accepted version for user #%d from %s", 
    713                                         userid, inet_ntoa(tempin->sin_addr)); 
     713                                        userid, inet6_ntoa(tempin->sin6_addr)); 
    714714                                users[userid].q.id = 0; 
    715715                                users[userid].q.id2 = 0; 
    716716                                users[userid].q_sendrealsoon.id = 0; 
     
    752752                                /* No space for another user */ 
    753753                                send_version_response(dns_fd, VERSION_FULL, created_users, 0, q); 
    754754                                syslog(LOG_INFO, "dropped user from %s, server full",  
    755                                         inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); 
     755                                        inet6_ntoa(((struct sockaddr_in6 *) &q->from)->sin6_addr)); 
    756756                        } 
    757757                } else { 
    758758                        send_version_response(dns_fd, VERSION_NACK, VERSION, 0, q); 
    759759                        syslog(LOG_INFO, "dropped user from %s, sent bad version %08X",  
    760                                 inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr), version); 
     760                                inet6_ntoa(((struct sockaddr_in6 *) &q->from)->sin6_addr), version); 
    761761                } 
    762762                return; 
    763763        } else if(in[0] == 'L' || in[0] == 'l') { 
     
    773773                if (check_user_and_ip(userid, q) != 0) { 
    774774                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    775775                        syslog(LOG_WARNING, "dropped login request from user #%d from unexpected source %s", 
    776                                 userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); 
     776                                userid, inet6_ntoa(((struct sockaddr_in6 *) &q->from)->sin6_addr)); 
    777777                        return; 
    778778                } else { 
    779779                        users[userid].last_pkt = time(NULL); 
     
    799799                        } else { 
    800800                                write_dns(dns_fd, q, "LNAK", 4, 'T'); 
    801801                                syslog(LOG_WARNING, "rejected login request from user #%d from %s, bad password", 
    802                                         userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); 
     802                                        userid, inet6_ntoa(((struct sockaddr_in6 *) &q->from)->sin6_addr)); 
    803803                        } 
    804804                } 
    805805                return; 
    806806        } else if(in[0] == 'I' || in[0] == 'i') { 
    807807                /* Request for IP number */ 
    808                 in_addr_t replyaddr; 
     808                struct in6_addr replyaddr; 
    809809                unsigned addr; 
    810810                char reply[5]; 
    811811                 
     
    815815                        return; /* illegal id */ 
    816816                } 
    817817 
    818                 if (ns_ip != INADDR_ANY) { 
     818                if (!IN6_IS_ADDR_UNSPECIFIED(&ns_ip)) { 
    819819                        /* If set, use assigned external ip (-n option) */ 
    820820                        replyaddr = ns_ip; 
    821821                } else { 
    822822                        /* otherwise return destination ip from packet */ 
    823                         memcpy(&replyaddr, &q->destination.s_addr, sizeof(in_addr_t)); 
     823                        replyaddr = q->destination.sin6_addr; 
    824824                } 
    825825 
    826                 addr = htonl(replyaddr); 
    827                 reply[0] = 'I'; 
    828                 reply[1] = (addr >> 24) & 0xFF; 
    829                 reply[2] = (addr >> 16) & 0xFF; 
    830                 reply[3] = (addr >>  8) & 0xFF; 
    831                 reply[4] = (addr >>  0) & 0xFF; 
    832                 write_dns(dns_fd, q, reply, sizeof(reply), 'T'); 
     826                if (!IN6_IS_ADDR_V4MAPPED(&replyaddr)) 
     827                { 
     828                        char reply[17]; 
     829                        reply[0] = 'I'; 
     830                        memcpy(reply+1, &replyaddr, sizeof(struct in6_addr)); 
     831                        write_dns(dns_fd, q, reply, sizeof(reply), 'T'); 
     832                } else { 
     833                        addr = htonl(replyaddr.s6_addr32[3]); 
     834                        reply[0] = 'I'; 
     835                        reply[1] = (addr >> 24) & 0xFF; 
     836                        reply[2] = (addr >> 16) & 0xFF; 
     837                        reply[3] = (addr >>  8) & 0xFF; 
     838                        reply[4] = (addr >>  0) & 0xFF; 
     839                        write_dns(dns_fd, q, reply, sizeof(reply), 'T'); 
     840                } 
    833841        } else if(in[0] == 'Z' || in[0] == 'z') { 
    834842                /* Check for case conservation and chars not allowed according to RFC */ 
    835843 
     
    14241432        char buf[64*1024]; 
    14251433        int len; 
    14261434 
    1427         if (ns_ip != INADDR_ANY) { 
     1435        if (!IN6_IS_ADDR_UNSPECIFIED(&ns_ip)) { 
    14281436                /* If ns_ip set, overwrite destination addr with it. 
    14291437                 * Destination addr will be sent as additional record (A, IN) */ 
    1430                 memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t)); 
     1438                q->destination.sin6_family = AF_INET6; 
     1439                q->destination.sin6_addr = ns_ip; 
     1440                q->destination.sin6_port = htons(DNS_PORT);  
    14311441        } 
    14321442 
    14331443        len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain); 
     
    14371447        } 
    14381448         
    14391449        if (debug >= 2) { 
    1440                 struct sockaddr_in *tempin; 
    1441                 tempin = (struct sockaddr_in *) &(q->from); 
     1450                struct sockaddr_in6 *tempin; 
     1451                tempin = (struct sockaddr_in6 *) &(q->from); 
    14421452                fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes NS reply\n",  
    1443                         inet_ntoa(tempin->sin_addr), q->type, q->name, len); 
     1453                        inet6_ntoa(tempin->sin6_addr), q->type, q->name, len); 
    14441454        } 
    1445         if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) { 
     1455        if (sendto_tproxy(dns_fd, buf, len, 0, &q->destination, (struct sockaddr*)&q->from, q->fromlen) <= 0) { 
    14461456                warn("ns reply send error"); 
    14471457        } 
    14481458} 
     
    14551465        int len; 
    14561466 
    14571467        if (fakeip) { 
    1458                 in_addr_t ip = inet_addr("127.0.0.1"); 
    1459                 memcpy(&q->destination.s_addr, &ip, sizeof(in_addr_t)); 
     1468                inet_pton(AF_INET6,"::FFFF:127.0.0.1",&q->destination.sin6_addr); 
     1469                q->destination.sin6_family = AF_INET6; 
     1470                q->destination.sin6_port = htons(DNS_PORT);  
    14601471 
    1461         } else if (ns_ip != INADDR_ANY) { 
     1472        } else if (!IN6_IS_ADDR_UNSPECIFIED(&ns_ip)) { 
    14621473                /* If ns_ip set, overwrite destination addr with it. 
    14631474                 * Destination addr will be sent as additional record (A, IN) */ 
    1464                 memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t)); 
     1475                q->destination.sin6_family = AF_INET6; 
     1476                q->destination.sin6_addr = ns_ip; 
     1477                q->destination.sin6_port = htons(DNS_PORT);  
    14651478        } 
    14661479 
    14671480        len = dns_encode_a_response(buf, sizeof(buf), q); 
     
    14711484        } 
    14721485         
    14731486        if (debug >= 2) { 
    1474                 struct sockaddr_in *tempin; 
    1475                 tempin = (struct sockaddr_in *) &(q->from); 
     1487                struct sockaddr_in6 *tempin; 
     1488                tempin = (struct sockaddr_in6 *) &(q->from); 
    14761489                fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes A reply\n", 
    1477                         inet_ntoa(tempin->sin_addr), q->type, q->name, len); 
     1490                        inet6_ntoa(tempin->sin6_addr), q->type, q->name, len); 
    14781491        } 
    1479         if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) { 
     1492        if (sendto_tproxy(dns_fd, buf, len, 0, &q->destination, (struct sockaddr*)&q->from, q->fromlen) <= 0) { 
    14801493                warn("a reply send error"); 
    14811494        } 
    14821495} 
     
    14871500        char buf[64*1024]; 
    14881501        int len; 
    14891502        struct fw_query fwq; 
    1490         struct sockaddr_in *myaddr; 
    1491         in_addr_t newaddr; 
     1503        struct sockaddr_in6 *myaddr; 
    14921504 
    14931505        len = dns_encode(buf, sizeof(buf), q, QR_QUERY, q->name, strlen(q->name)); 
    14941506        if (len < 1) { 
     
    15021514        fwq.id = q->id; 
    15031515        fw_query_put(&fwq); 
    15041516 
    1505         newaddr = inet_addr("127.0.0.1"); 
    1506         myaddr = (struct sockaddr_in *) &(q->from); 
    1507         memcpy(&(myaddr->sin_addr), &newaddr, sizeof(in_addr_t)); 
    1508         myaddr->sin_port = htons(bind_port); 
     1517        myaddr = (struct sockaddr_in6 *) &(q->from); 
     1518        inet_pton(AF_INET6,"::FFFF:127.0.0.1",&(myaddr->sin6_addr)); 
     1519        myaddr->sin6_port = htons(bind_port); 
    15091520         
    15101521        if (debug >= 2) { 
    15111522                fprintf(stderr, "TX: NS reply \n"); 
     
    15201531tunnel_bind(int bind_fd, int dns_fd) 
    15211532{ 
    15221533        char packet[64*1024]; 
    1523         struct sockaddr_in from; 
     1534        struct sockaddr_in6 from; 
    15241535        socklen_t fromlen; 
    15251536        struct fw_query *query; 
    15261537        unsigned short id; 
    15271538        int r; 
    15281539 
    1529         fromlen = sizeof(struct sockaddr); 
     1540        fromlen = sizeof(struct sockaddr_in6); 
    15301541        r = recvfrom(bind_fd, packet, sizeof(packet), 0,  
    15311542                (struct sockaddr*)&from, &fromlen); 
    15321543 
     
    15471558        } 
    15481559 
    15491560        if (debug >= 2) { 
    1550                 struct sockaddr_in *in; 
    1551                 in = (struct sockaddr_in *) &(query->addr); 
     1561                struct sockaddr_in6 *in; 
     1562                in = (struct sockaddr_in6 *) &(query->addr); 
    15521563                fprintf(stderr, "TX: client %s id %u, %d bytes\n", 
    1553                         inet_ntoa(in->sin_addr), (id & 0xffff), r); 
     1564                        inet6_ntoa(in->sin6_addr), (id & 0xffff), r); 
    15541565        } 
    15551566         
    15561567        if (sendto(dns_fd, packet, r, 0, (const struct sockaddr *) &(query->addr),  
     
    15731584                return 0; 
    15741585 
    15751586        if (debug >= 2) { 
    1576                 struct sockaddr_in *tempin; 
    1577                 tempin = (struct sockaddr_in *) &(q.from); 
     1587                struct sockaddr_in6 *tempin; 
     1588                tempin = (struct sockaddr_in6 *) &(q.from); 
    15781589                fprintf(stderr, "RX: client %s, type %d, name %s\n",  
    1579                         inet_ntoa(tempin->sin_addr), q.type, q.name); 
     1590                        inet6_ntoa(tempin->sin6_addr), q.type, q.name); 
    15801591        } 
    15811592 
    15821593        domain_len = strlen(q.name) - strlen(topdomain); 
     
    17991810        /* User sends hash of seed + 1 */ 
    18001811        login_calculate(myhash, 16, password, users[userid].seed + 1); 
    18011812        if (memcmp(packet, myhash, 16) == 0) { 
    1802                 struct sockaddr_in *tempin; 
     1813                struct sockaddr_in6 *tempin; 
    18031814 
    18041815                /* Update query and time info for user */ 
    18051816                users[userid].last_pkt = time(NULL); 
    18061817                memcpy(&(users[userid].q), q, sizeof(struct query)); 
    18071818 
    18081819                /* Store remote IP number */ 
    1809                 tempin = (struct sockaddr_in *) &(q->from); 
    1810                 memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 
     1820                tempin = (struct sockaddr_in6 *) &(q->from); 
     1821                memcpy(&(users[userid].host), &(tempin->sin6_addr), sizeof(struct in6_addr)); 
    18111822                  
    18121823                /* Correct hash, reply with hash of seed - 1 */ 
    18131824                user_set_conn_type(userid, CONN_RAW_UDP); 
     
    18931904static int 
    18941905read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw_decode() below */ 
    18951906{ 
    1896         struct sockaddr_in from; 
     1907        struct sockaddr_in6 from; 
    18971908        socklen_t addrlen; 
    18981909        char packet[64*1024]; 
    18991910        int r; 
     
    19031914        struct iovec iov; 
    19041915        struct cmsghdr *cmsg; 
    19051916 
    1906         addrlen = sizeof(struct sockaddr); 
     1917        addrlen = sizeof(struct sockaddr_in6); 
    19071918        iov.iov_base = packet; 
    19081919        iov.iov_len = sizeof(packet); 
    19091920 
     
    19171928         
    19181929        r = recvmsg(fd, &msg, 0); 
    19191930#else 
    1920         addrlen = sizeof(struct sockaddr); 
     1931        addrlen = sizeof(struct sockaddr_in6); 
    19211932        r = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &addrlen); 
    19221933#endif /* !WINDOWS32 */ 
    19231934 
     
    19401951                        if (cmsg->cmsg_level == IPPROTO_IP &&  
    19411952                                cmsg->cmsg_type == DSTADDR_SOCKOPT) {  
    19421953                                 
    1943                                 q->destination = *dstaddr(cmsg);  
     1954                                q->destination.sin6_family = AF_INET6; 
     1955                                q->destination.sin6_addr.s6_addr32[0] = 0; 
     1956                                q->destination.sin6_addr.s6_addr32[1] = 0; 
     1957                                q->destination.sin6_addr.s6_addr32[2] = htonl(0xffff); 
     1958                                q->destination.sin6_addr.s6_addr32[3] = *dstaddr(cmsg);  
     1959                                q->destination.sin6_port = dstport(cmsg);  
     1960                                break; 
     1961                        } else if (cmsg->cmsg_level == IPPROTO_IPV6 &&  
     1962                                cmsg->cmsg_type == IPV6_RECVORIGDSTADDR) {  
     1963 
     1964                                memcpy(&q->destination, dstsock6(cmsg), sizeof(struct sockaddr_in6)); 
    19441965                                break; 
    19451966                        }  
    19461967                } 
     
    21062127        } 
    21072128         
    21082129        if (debug >= 2) { 
    2109                 struct sockaddr_in *tempin; 
    2110                 tempin = (struct sockaddr_in *) &(q->from); 
     2130                struct sockaddr_in6 *tempin; 
     2131                tempin = (struct sockaddr_in6 *) &(q->from); 
    21112132                fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes data\n",  
    2112                         inet_ntoa(tempin->sin_addr), q->type, q->name, datalen); 
     2133                        inet6_ntoa(tempin->sin6_addr), q->type, q->name, datalen); 
    21132134        } 
    21142135 
    2115         sendto(fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen); 
     2136        sendto_tproxy(fd, buf, len, 0, &q->destination, (struct sockaddr*)&q->from, q->fromlen); 
    21162137} 
    21172138 
    21182139static void 
     
    21732194main(int argc, char **argv) 
    21742195{ 
    21752196        extern char *__progname; 
    2176         in_addr_t listen_ip; 
     2197        struct in6_addr listen_ip; 
    21772198#ifndef WINDOWS32 
    21782199        struct passwd *pw; 
    21792200#endif 
     
    22102231        bind_fd = 0; 
    22112232        mtu = 1130;     /* Very many relays give fragsize 1150 or slightly 
    22122233                           higher for NULL; tun/zlib adds ~17 bytes. */ 
    2213         listen_ip = INADDR_ANY; 
     2234        listen_ip = in6addr_any; 
    22142235        port = 53; 
    2215         ns_ip = INADDR_ANY; 
     2236        ns_ip = in6addr_any; 
    22162237        check_ip = 1; 
    22172238        skipipconfig = 0; 
    22182239        debug = 0; 
     
    22752296                        mtu = atoi(optarg); 
    22762297                        break; 
    22772298                case 'l': 
    2278                         listen_ip = inet_addr(optarg); 
     2299                        if (!inet_pton(AF_INET6, optarg, &listen_ip)) { 
     2300                                warnx("Bad IP address to listen on."); 
     2301                                usage(); 
     2302                        } 
    22792303                        break; 
    22802304                case 'p': 
    22812305                        port = atoi(optarg); 
    22822306                        break; 
    22832307                case 'n': 
    2284                         ns_ip = inet_addr(optarg); 
     2308                        if (!inet_pton(AF_INET, optarg, &ns_ip)) { 
     2309                                warnx("Bad IP address to return as nameserver."); 
     2310                                usage(); 
     2311                        } 
    22852312                        break; 
    22862313                case 'b': 
    22872314                        bind_enable = 1; 
     
    23212348                netmask = atoi(netsize); 
    23222349        } 
    23232350 
    2324         my_ip = inet_addr(argv[0]); 
    2325          
    2326         if (my_ip == INADDR_NONE) { 
     2351        if (!inet_pton(AF_INET, argv[0], &my_ip)) { 
    23272352                warnx("Bad IP address to use inside tunnel."); 
    23282353                usage(); 
    23292354        } 
     
    23462371                        usage(); 
    23472372                } 
    23482373#endif 
     2374                if (port != DNS_PORT) { 
     2375                        warnx("setuid and tproxy options incompatible!"); 
     2376                        usage(); 
     2377                } 
    23492378        } 
    23502379 
    23512380        if (mtu <= 0) { 
     
    23652394                        /* NOTREACHED */ 
    23662395                } 
    23672396                /* Avoid forwarding loops */ 
    2368                 if (bind_port == port && (listen_ip == INADDR_ANY || listen_ip == htonl(0x7f000001L))) { 
     2397                if (bind_port == port && (IN6_IS_ADDR_UNSPECIFIED(&listen_ip) || IN6_IS_ADDR_LOOPBACK(&listen_ip))) { 
    23692398                        warnx("Forward port is same as listen port (%d), will create a loop!", bind_port); 
    23702399                        fprintf(stderr, "Use -l to set listen ip to avoid this.\n"); 
    23712400                        usage(); 
     
    23862415                foreground = 1; 
    23872416        } 
    23882417 
    2389         if (listen_ip == INADDR_NONE) { 
    2390                 warnx("Bad IP address to listen on."); 
    2391                 usage(); 
    2392         } 
    2393          
    2394         if (ns_ip == INADDR_NONE) { 
    2395                 warnx("Bad IP address to return as nameserver."); 
    2396                 usage(); 
    2397         } 
    23982418        if (netmask > 30 || netmask < 8) { 
    23992419                warnx("Bad netmask (%d bits). Use 8-30 bits.", netmask); 
    24002420                usage(); 
     
    24242444                goto cleanup2; 
    24252445        } 
    24262446        if (bind_enable) { 
    2427                 if ((bind_fd = open_dns(0, INADDR_ANY)) == -1) { 
     2447                if ((bind_fd = open_dns(0, in6addr_any)) == -1) { 
    24282448                        retval = 1; 
    24292449                        goto cleanup3; 
    24302450                } 
  • iodine-0.6.0-rc1

    diff -ur iodine-0.6.0-rc1.ORIG/src/user.h iodine-0.6.0-rc1/src/user.h
    old new  
    4040        time_t last_pkt; 
    4141        int seed; 
    4242        in_addr_t tun_ip; 
    43         struct in_addr host; 
     43        struct in6_addr host; 
    4444        struct query q; 
    4545        struct query q_sendrealsoon; 
    4646        int q_sendrealsoon_new;