--- include/irc.h Tue Oct 31 14:52:19 2000 +++ include/irc.h Sat Oct 21 00:48:06 2000 @@ -139,6 +139,8 @@ extern char comma[]; extern struct in_addr LocalHostAddr; +extern struct in6_addr LocalHostAddr6; +extern int LocalHostFamily; extern fd_set readables; extern time_t start_time; extern time_t idle_time; --- source/irc.c Tue Oct 31 14:51:14 2000 +++ source/irc.c Sat Oct 21 11:34:01 2000 @@ -160,7 +160,9 @@ * If that happens, outbound connections will fail, and its not my fault. */ char *LocalHostName = NULL; +int LocalHostFamily = AF_INET; struct in_addr LocalHostAddr; +struct in6_addr LocalHostAddr6; int inbound_line_mangler = 0, outbound_line_mangler = 0; @@ -706,9 +708,17 @@ memset(&LocalHostAddr, 0, sizeof(LocalHostAddr)); if ((hp = gethostbyname(tmp_hostname))) { - memmove((void *)&LocalHostAddr, hp->h_addr, sizeof(LocalHostAddr)); - fprintf(stderr, "Ok. I'll buy that.\n"); - LocalHostName = m_strdup(tmp_hostname); + if (hp->h_addrtype == AF_INET) { + memmove((void *)&LocalHostAddr, hp->h_addr, sizeof(LocalHostAddr)); + fprintf(stderr, "Ok. I'll buy that.\n"); + LocalHostName = m_strdup(tmp_hostname); + LocalHostFamily = AF_INET; + } else { + memmove((void *)&LocalHostAddr6, hp->h_addr, sizeof(LocalHostAddr6)); + fprintf(stderr, "Setting ipv6 hostname\n"); + LocalHostName = m_strdup(tmp_hostname); + LocalHostFamily = AF_INET6; + } } else fprintf(stderr, "I can't configure for that address! (Trying normal hostname...)\n"); --- source/network.c Tue Oct 31 14:51:41 2000 +++ source/network.c Sat Oct 21 11:33:29 2000 @@ -10,6 +10,7 @@ #include "ircaux.h" #include "vars.h" #include "newio.h" +#include #ifdef HAVE_SYS_UN_H #include @@ -58,22 +59,21 @@ { int fd = -1; int is_unix = (hostn && *hostn == '/'); - int sock_type, proto_type; + int proto_type; - sock_type = (is_unix) ? AF_UNIX : AF_INET; proto_type = (protocol == PROTOCOL_TCP) ? SOCK_STREAM : SOCK_DGRAM; - if ((fd = socket(sock_type, proto_type, 0)) < 0) - return -1; - - set_socket_options (fd); - /* Unix domain server */ #ifdef HAVE_SYS_UN_H if (is_unix) { struct sockaddr_un name; + if ((fd = socket(AF_UNIX, proto_type, 0)) < 0) { + return -1; + } + set_socket_options(fd); + memset(&name, 0, sizeof(struct sockaddr_un)); name.sun_family = AF_UNIX; strlcpy(name.sun_path, hostn, sizeof(name.sun_path)); @@ -117,6 +117,11 @@ int ports; struct sockaddr_in name; + if ((fd = socket(AF_INET, proto_type, 0)) < 0) { + return -1; + } + set_socket_options(fd); + memset(&name, 0, sizeof(struct sockaddr_in)); name.sin_family = AF_INET; name.sin_addr.s_addr = htonl(INADDR_ANY); @@ -149,10 +154,18 @@ else if (!is_unix && (service == SERVICE_CLIENT)) { struct sockaddr_in server; + struct sockaddr_in6 server6; struct sockaddr_in localaddr; + struct sockaddr_in6 localaddr6; struct in_addr remoteaddr; + struct in6_addr remoteaddr6; struct hostent *hp; + struct sockaddr * serveraddr; + int localfamily, remotefamily, serverfamily; + int serversize; + char junk[256]; + junk[0]='\0'; /* * Doing this bind is bad news unless you are sure that * the hostname is valid. This is not true for me at home, @@ -160,16 +173,36 @@ */ if (LocalHostName) { - memset(&localaddr, 0, sizeof(struct sockaddr_in)); - localaddr.sin_family = AF_INET; - localaddr.sin_addr = LocalHostAddr; - localaddr.sin_port = 0; - if (bind(fd, (struct sockaddr *)&localaddr, sizeof(localaddr))) - return close(fd), -2; + if ((fd = socket(LocalHostFamily, proto_type, 0)) < 0) { + return -1; + } + set_socket_options(fd); + + if (LocalHostFamily == AF_INET) { + memset(&localaddr, 0, sizeof(struct sockaddr_in)); + localaddr.sin_family = AF_INET; + localaddr.sin_addr = LocalHostAddr; + localaddr.sin_port = 0; + if (bind(fd, (struct sockaddr *)&localaddr, sizeof(localaddr))) { + return close(fd), -2; + } + localfamily = AF_INET; + } else { + memset(&localaddr6, 0, sizeof(struct sockaddr_in6)); + localaddr6.sin6_family = AF_INET6; + localaddr6.sin6_addr = LocalHostAddr6; + localaddr6.sin6_port = 0; + if (bind(fd, (struct sockaddr *)&localaddr6, sizeof(localaddr6))) { + return close(fd), -2; + } + localfamily = AF_INET6; + } } memset(&server, 0, sizeof(struct sockaddr_in)); + memset(&server6, 0, sizeof(struct sockaddr_in6)); memset(&remoteaddr, 0, sizeof(remoteaddr)); + memset(&remoteaddr6, 0, sizeof(remoteaddr6)); /* * If this is an IP we're looking up, dont do a full resolve, @@ -182,9 +215,25 @@ */ if (isdigit(hostn[strlen(hostn)-1])) { - inet_aton(hostn, &remoteaddr); - memmove(&server.sin_addr, - &remoteaddr, sizeof(remoteaddr)); + if (index(hostn,':')) { + inet_pton(AF_INET6, hostn, &remoteaddr6); + serverfamily = AF_INET6; + memmove(&server6.sin6_addr, + &remoteaddr6, sizeof(remoteaddr6)); + server.sin_family = AF_INET; + server.sin_port = htons(*portnum); + serversize = sizeof(server6); + serveraddr = (struct sockaddr *)&server6; + } else { + inet_aton(hostn, &remoteaddr); + serverfamily = AF_INET; + memmove(&server.sin_addr, + &remoteaddr, sizeof(remoteaddr)); + server.sin_family = AF_INET; + server.sin_port = htons(*portnum); + serversize = sizeof(server); + serveraddr = (struct sockaddr*)&server; + } } else { @@ -193,14 +242,32 @@ errno = -1; return close(fd), -6; } - memmove(&(server.sin_addr), hp->h_addr, hp->h_length); + if (hp->h_addrtype == AF_INET) { + memmove(&(server.sin_addr), hp->h_addr, hp->h_length); + serverfamily = AF_INET; + server.sin_family = AF_INET; + server.sin_port = htons(*portnum); + serversize = sizeof(server); + serveraddr = (struct sockaddr *)&server; + } else { + memmove(&(server6.sin6_addr), hp->h_addr_list[0], hp->h_length); + serverfamily = AF_INET6; + server6.sin6_family = AF_INET6; + server6.sin6_port = htons(*portnum); + serversize = sizeof(server6); + serveraddr = (struct sockaddr *)&server6; + } } - server.sin_family = AF_INET; - server.sin_port = htons(*portnum); + if (fd < 0) { + if ((fd = socket(serverfamily, proto_type, 0)) < 0) { + return -1; + } + set_socket_options(fd); + } alarm(get_int_var(CONNECT_TIMEOUT_VAR)); - if (connect (fd, (struct sockaddr *)&server, sizeof(server)) < 0) + if (connect(fd, serveraddr, serversize) < 0) { alarm(0); return close(fd), -4; @@ -251,7 +318,7 @@ { struct hostent *hep; - alarm(1); + alarm(2); hep = gethostbyname(host); alarm(0); return hep; @@ -260,30 +327,40 @@ char * host_to_ip (const char *host) { struct hostent *hep = lookup_host(host); - static char ip[256]; + static char ipaddr[256]; + if (hep) { + if (!inet_ntop(hep->h_addrtype, hep->h_addr, ipaddr, + hep->h_length)) { + return empty_string; + } + } + return ipaddr; - return (hep ? - sprintf(ip,"%u.%u.%u.%u", hep->h_addr[0] & 0xff, - hep->h_addr[1] & 0xff, - hep->h_addr[2] & 0xff, - hep->h_addr[3] & 0xff), - ip : empty_string); } static struct hostent *lookup_ip (const char *ip) { int b1 = 0, b2 = 0, b3 = 0, b4 = 0; - char foo[4]; struct hostent *hep; + char foo[16]; + int af, len; - sscanf(ip,"%d.%d.%d.%d", &b1, &b2, &b3, &b4); - foo[0] = b1; - foo[1] = b2; - foo[2] = b3; - foo[3] = b4; + if (index(ip,':')) { + if (!inet_pton(AF_INET6, ip, foo)) { + return(NULL); + } + af = AF_INET6; + len = 16; + } else { + if (!inet_pton(AF_INET, ip, foo)) { + return(NULL); + } + af = AF_INET; + len = 4; + } alarm(1); - hep = gethostbyaddr(foo, 4, AF_INET); + hep = gethostbyaddr(foo,len,af); alarm(0); return hep;