--- dns.c.orig 2011-02-13 22:50:59.000000000 -1000 +++ dns.c 2012-10-03 00:56:16.541123561 -1000 @@ -49,6 +49,12 @@ #include "dns.h" #include "net.h" +#ifdef ENABLE_IPV6 +#ifdef BSD +#include "/usr/src/lib/libc/resolv/res_private.h" +#endif +#endif + /* OSX Needs this. I don't know how to enable this for them automatically. * Should be easy with autoconf. Please submit a patch if you know * autoconf.... -- REW @@ -262,6 +268,9 @@ ip_t alignedip; ip_t localhost; +#ifdef ENABLE_IPV6 +ip_t localhost6; +#endif double sweeptime; @@ -298,6 +307,9 @@ struct sockaddr * from = (struct sockaddr *) &from_sastruct; int resfd; +#ifdef ENABLE_IPV6 +int resfd6; +#endif socklen_t fromlen = sizeof from_sastruct; char tempstring[16384+1+1]; @@ -454,9 +466,9 @@ char *strlongip(ip_t * ip) { #ifdef ENABLE_IPV6 - static char buf[INET6_ADDRSTRLEN]; + static char addrstr[INET6_ADDRSTRLEN]; - return (char *) inet_ntop( af, ip, buf, sizeof buf ); + return (char *) inet_ntop( af, ip, addrstr, sizeof addrstr ); #else return inet_ntoa( *ip ); #endif @@ -488,6 +500,12 @@ { return resfd; } +#ifdef ENABLE_IPV6 +int dns_waitfd6(void) +{ + return resfd6; +} +#endif void dns_open(void) @@ -501,21 +519,41 @@ exit(-1); } myres.options|= RES_RECURSE | RES_DEFNAMES | RES_DNSRCH; - for (i = 0;i < myres.nscount;i++) - myres.nsaddr_list[i].sin_family = AF_INET; resfd = socket(AF_INET, SOCK_DGRAM, 0); if (resfd == -1) { - fprintf(stderr,"Unable to allocate socket for nameserver communication: %s\n", + fprintf(stderr, + "Unable to allocate IPv4 socket for nameserver communication: %s\n", strerror(errno)); exit(-1); } +#ifdef ENABLE_IPV6 + resfd6 = socket(AF_INET6, SOCK_DGRAM, 0); + if (resfd6 == -1) { + fprintf(stderr, + "Unable to allocate IPv6 socket for nameserver communication: %s\n", + strerror(errno)); + exit(-1); + } +#endif option = 1; if (setsockopt(resfd,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) { - fprintf(stderr,"Unable to setsockopt() on nameserver communication socket: %s\n", + fprintf(stderr, + "Unable to setsockopt() on IPv4 nameserver communication socket: %s\n", + strerror(errno)); + exit(-1); + } +#ifdef ENABLE_IPV6 + if (setsockopt(resfd6,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) { + fprintf(stderr, + "Unable to setsockopt() on IPv6 nameserver communication socket: %s\n", strerror(errno)); exit(-1); } +#endif longipstr( "127.0.0.1", &localhost, AF_INET ); +#ifdef ENABLE_IPV6 + longipstr( "::1", &localhost6, AF_INET6 ); +#endif aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid(); for (i = 0;i < BashSize;i++) { idbash[i] = NULL; @@ -886,6 +924,10 @@ packetheader *hp; int r,i; unsigned char buf[MaxPacketsize]; +#ifdef ENABLE_IPV6 + int nscount6; + struct sockaddr_in6 *nssockaddr6; +#endif r = RES_MKQUERY(QUERY,s,C_IN,type,NULL,0,NULL,(unsigned char*)buf,MaxPacketsize); if (r == -1) { @@ -894,9 +936,27 @@ } hp = (packetheader *)buf; hp->id = id; /* htons() deliberately left out (redundant) */ +#ifdef ENABLE_IPV6 +#ifdef __GLIBC__ + nscount6 = myres._u._ext.nscount6; +#else + nscount6 = myres.nscount; +#endif + for (i = 0;i < nscount6;i++) { +#ifdef __GLIBC__ + nssockaddr6 = myres._u._ext.nsaddrs[i]; +#else + nssockaddr6 = &(myres._u._ext.ext->nsaddrs[i].sin6); +#endif + if (nssockaddr6->sin6_family == AF_INET6) + (void)sendto(resfd6,buf,r,0,(struct sockaddr *) nssockaddr6, + sizeof(struct sockaddr_in6)); + } +#endif for (i = 0;i < myres.nscount;i++) - (void)sendto(resfd,buf,r,0,(struct sockaddr *)&myres.nsaddr_list[i], - sizeof(struct sockaddr)); + if (myres.nsaddr_list[i].sin_family == AF_INET) + (void)sendto(resfd,buf,r,0,(struct sockaddr *)&myres.nsaddr_list[i], + sizeof(struct sockaddr)); } void resendrequest(struct resolve *rp,int type) @@ -1273,6 +1333,62 @@ restell(tempstring); } } +#ifdef ENABLE_IPV6 +void dns_ack6(void) +{ + int r,i; + static char addrstr[INET6_ADDRSTRLEN]; + int nscount6; + struct sockaddr_in6 *nssockaddr6; + + r = recvfrom(resfd6,(byte *)resrecvbuf,MaxPacketsize,0, + from, &fromlen); + if (r > 0) { + /* Check to see if this server is actually one we sent to */ +#ifdef __GLIBC__ + nscount6 = myres._u._ext.nscount6; +#else + nscount6 = myres.nscount; +#endif + if ( addrcmp( (void *) &(from6->sin6_addr), (void *) &localhost6, + (int) AF_INET6 ) == 0 ) { + for (i = 0;i < nscount6;i++) { +#ifdef __GLIBC__ + nssockaddr6 = myres._u._ext.nsaddrs[i]; +#else + nssockaddr6 = &(myres._u._ext.ext->nsaddrs[i].sin6); +#endif + if ( addrcmp( (void *) &(nssockaddr6->sin6_addr), + (void *) &(from6->sin6_addr), (int) AF_INET6 ) == 0 || + addrcmp( (void *) &(nssockaddr6->sin6_addr), + (void *) &unspec_addr, (int) AF_INET6 ) == 0 ) /* 0.0.0.0 replies as 127.0.0.1 */ + break; + } + } else + for (i = 0;i < nscount6;i++) { +#ifdef __GLIBC__ + nssockaddr6 = myres._u._ext.nsaddrs[i]; +#else + nssockaddr6 = &(myres._u._ext.ext->nsaddrs[i].sin6); +#endif + if ( addrcmp( (void *) &(nssockaddr6->sin6_addr), + (void *) &(from6->sin6_addr), AF_INET6 ) == 0 ) + break; + } + if (i == nscount6) { + snprintf(tempstring, sizeof(tempstring), + "Resolver error: Received reply from unknown source: %s", + inet_ntop( AF_INET6, &(from6->sin6_addr), addrstr, + sizeof addrstr )); + restell(tempstring); + } else + parserespacket((byte *)resrecvbuf,r); + } else { + snprintf(tempstring, sizeof(tempstring), "Resolver: Socket error: %s",strerror(errno)); + restell(tempstring); + } +} +#endif int istime(double x,double *sinterval) --- dns.h.orig 2011-02-13 22:50:59.000000000 -1000 +++ dns.h 2012-09-22 07:07:34.347608296 -1000 @@ -24,6 +24,10 @@ void dns_open(void); int dns_waitfd(void); void dns_ack(void); +#ifdef ENABLE_IPV6 +int dns_waitfd6(void); +void dns_ack6(void); +#endif void dns_events(double *sinterval); char *dns_lookup(ip_t * address); char *dns_lookup2(ip_t * address); --- gtk.c.orig 2011-02-13 22:50:59.000000000 -1000 +++ gtk.c 2012-09-22 08:18:51.784609405 -1000 @@ -603,6 +603,14 @@ gtk_redraw(); return TRUE; } +#ifdef ENABLE_IPV6 +gboolean gtk_dns_data6(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data) +{ + dns_ack6(); + gtk_redraw(); + return TRUE; +} +#endif void gtk_loop(void) @@ -613,6 +621,10 @@ net_iochannel = g_io_channel_unix_new(net_waitfd()); g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, NULL); +#ifdef ENABLE_IPV6 + dns_iochannel = g_io_channel_unix_new(dns_waitfd6()); + g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data6, NULL); +#endif dns_iochannel = g_io_channel_unix_new(dns_waitfd()); g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, NULL); --- select.c.orig 2011-12-02 03:11:21.000000000 -1000 +++ select.c 2012-09-22 08:07:25.206611325 -1000 @@ -48,6 +48,9 @@ int anyset = 0; int maxfd = 0; int dnsfd, netfd; +#ifdef ENABLE_IPV6 + int dnsfd6; +#endif int NumPing = 0; int paused = 0; struct timeval lasttime, thistime, selecttime; @@ -70,6 +73,14 @@ maxfd = 1; } +#ifdef ENABLE_IPV6 + if (dns) { + dnsfd6 = dns_waitfd6(); + FD_SET(dnsfd6, &readfd); + if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1; + } else + dnsfd6 = 0; +#endif if (dns) { dnsfd = dns_waitfd(); FD_SET(dnsfd, &readfd); @@ -148,6 +159,12 @@ } /* Have we finished a nameservice lookup? */ +#ifdef ENABLE_IPV6 + if(dns && FD_ISSET(dnsfd6, &readfd)) { + dns_ack6(); + anyset = 1; + } +#endif if(dns && FD_ISSET(dnsfd, &readfd)) { dns_ack(); anyset = 1;