From: Pekka Riikonen Date: Wed, 13 Mar 2002 21:00:55 +0000 (+0000) Subject: IPv6 fixes around network routines. X-Git-Tag: 1.2.beta1~1558 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=1a6aee188b05a46880d3362af24d9b36dadd12e3;p=crypto.git IPv6 fixes around network routines. --- diff --git a/CHANGES b/CHANGES index 82b8c68d..2ad64b42 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +Wed Mar 13 21:38:26 EET 2002 Pekka Riikonen + + * Fixed the silc_net_check_[host/local]_by_sock to support + IPv6 bound sockets as well. Now they can return IPv6 addresses + as well. Affected file lib/silcutil/silcnet.c. + + * Fixed silc_net_addr2bin to correctly convert IPv6 addresses. + Affected lib/silcutil/unix/silcunixnet.c. + + * Fixed ID rendering (at least on some platforms, not NetBSD) + for IPv6 addresses. Affected file lib/silcutil/silcutil.c. + Tue Mar 12 17:58:59 EET 2002 Pekka Riikonen * Added silc_hash_public_key and silc_hash_public_key_compare diff --git a/TODO b/TODO index 96edf53d..322e71f0 100644 --- a/TODO +++ b/TODO @@ -48,8 +48,6 @@ TODO/bugs In SILC Server o Add rehashing support. - o IPv6 support problems. - o If server send CUMODE_CHANGE notify (like setting founder) to router and router does not have founder on channel (founder is left or there's no founder on channel at all), the router will accept the server's diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index c685e637..07207030 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -281,12 +281,34 @@ void silc_net_gethostbyaddr_async(const char *addr, bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip) { - struct sockaddr_in remote; - struct hostent *dest; - char *host_ip = NULL; - char host_name[1024]; + char host[1024]; int rval, len; - int i; + +#ifdef HAVE_IPV6 + struct sockaddr_storage remote; + char s[NI_MAXHOST]; + + *hostname = NULL; + *ip = NULL; + + SILC_LOG_DEBUG(("Resolving remote hostname and IP address")); + + memset(&remote, 0, sizeof(remote)); + memset(&s, 0, sizeof(s)); + len = sizeof(remote); + rval = getpeername(sock, (struct sockaddr *)&remote, &len); + if (rval < 0) + return FALSE; + + if (getnameinfo((struct sockaddr *)&remote, len, s, sizeof(s), NULL, 0, + NI_NUMERICHOST)) + return FALSE; + + *ip = silc_memdup(s, strlen(s)); + if (*ip == NULL) + return FALSE; +#else + struct sockaddr_in remote; *hostname = NULL; *ip = NULL; @@ -303,41 +325,26 @@ bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip) if (!host_ip) return FALSE; - *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char)); - memcpy(*ip, host_ip, strlen(host_ip)); + *ip = silc_memdup(host_ip, strlen(host_ip)); + if (*ip == NULL) + return FALSE; +#endif /* Get host by address */ - dest = gethostbyaddr((char *)&remote.sin_addr, - sizeof(struct in_addr), AF_INET); - if (!dest) + if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) return FALSE; - /* Get same host by name to see that the remote host really is - the who it says it is */ - memset(host_name, 0, sizeof(host_name)); - memcpy(host_name, dest->h_name, strlen(dest->h_name)); - - *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char)); - memcpy(*hostname, host_name, strlen(host_name)); + *hostname = silc_memdup(host, strlen(host)); SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); - dest = gethostbyname(host_name); - if (!dest) + /* Reverse */ + if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) return FALSE; - /* Find the address from list */ - for (i = 0; dest->h_addr_list[i]; i++) - if (!memcmp(dest->h_addr_list[i], &remote.sin_addr, - sizeof(struct in_addr))) - break; - if (!dest->h_addr_list[i]) + if (strcmp(*ip, host)) return FALSE; - silc_free(*ip); - *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char)); - memcpy(*ip, host_ip, strlen(host_ip)); SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); - return TRUE; } @@ -346,12 +353,34 @@ bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip) bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip) { - struct sockaddr_in local; - struct hostent *dest; - char *host_ip = NULL; - char host_name[1024]; + char host[1024]; int rval, len; - int i; + +#ifdef HAVE_IPV6 + struct sockaddr_storage local; + char s[NI_MAXHOST]; + + *hostname = NULL; + *ip = NULL; + + SILC_LOG_DEBUG(("Resolving local hostname and IP address")); + + memset(&local, 0, sizeof(local)); + memset(&s, 0, sizeof(s)); + len = sizeof(local); + rval = getsockname(sock, (struct sockaddr *)&local, &len); + if (rval < 0) + return FALSE; + + if (getnameinfo((struct sockaddr *)&local, len, s, sizeof(s), NULL, 0, + NI_NUMERICHOST)) + return FALSE; + + *ip = silc_memdup(s, strlen(s)); + if (*ip == NULL) + return FALSE; +#else + struct sockaddr_in local; *hostname = NULL; *ip = NULL; @@ -368,41 +397,26 @@ bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip) if (!host_ip) return FALSE; - *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char)); - memcpy(*ip, host_ip, strlen(host_ip)); + *ip = silc_memdup(host_ip, strlen(host_ip)); + if (*ip == NULL) + return FALSE; +#endif /* Get host by address */ - dest = gethostbyaddr((char *)&local.sin_addr, - sizeof(struct in_addr), AF_INET); - if (!dest) + if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) return FALSE; - /* Get same host by name to see that the local host really is - the who it says it is */ - memset(host_name, 0, sizeof(host_name)); - memcpy(host_name, dest->h_name, strlen(dest->h_name)); - - *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char)); - memcpy(*hostname, host_name, strlen(host_name)); + *hostname = silc_memdup(host, strlen(host)); SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); - dest = gethostbyname(host_name); - if (!dest) + /* Reverse */ + if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) return FALSE; - /* Find the address from list */ - for (i = 0; dest->h_addr_list[i]; i++) - if (!memcmp(dest->h_addr_list[i], &local.sin_addr, - sizeof(struct in_addr))) - break; - if (!dest->h_addr_list[i]) + if (strcmp(*ip, host)) return FALSE; - silc_free(*ip); - *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char)); - memcpy(*ip, host_ip, strlen(host_ip)); SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); - return TRUE; } @@ -421,7 +435,7 @@ SilcUInt16 silc_net_get_remote_port(int sock) return 0; if (getnameinfo((struct sockaddr *)&remote, len, NULL, 0, s, sizeof(s), - NI_NUMERICSERV)) + NI_NUMERICSERV)) return 0; return atoi(s); @@ -453,7 +467,7 @@ SilcUInt16 silc_net_get_local_port(int sock) return 0; if (getnameinfo((struct sockaddr *)&local, len, NULL, 0, s, sizeof(s), - NI_NUMERICSERV)) + NI_NUMERICSERV)) return 0; return atoi(s); diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index ee7f2eea..ad6b45ad 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -395,9 +395,12 @@ char *silc_id_render(void *id, SilcUInt16 type) SilcServerID *server_id = (SilcServerID *)id; if (server_id->ip.data_len > 4) { #ifdef HAVE_IPV6 - struct in6_addr ipv6; - memmove(&ipv6, server_id->ip.data, sizeof(ipv6)); - if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + struct sockaddr_in6 ipv6; + memset(&ipv6, 0, sizeof(ipv6)); + ipv6.sin6_family = AF_INET6; + memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr)); + if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6), + tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST)) strcat(rid, tmp); #endif } else { @@ -420,9 +423,12 @@ char *silc_id_render(void *id, SilcUInt16 type) SilcClientID *client_id = (SilcClientID *)id; if (client_id->ip.data_len > 4) { #ifdef HAVE_IPV6 - struct in6_addr ipv6; - memmove(&ipv6, client_id->ip.data, sizeof(ipv6)); - if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + struct sockaddr_in6 ipv6; + memset(&ipv6, 0, sizeof(ipv6)); + ipv6.sin6_family = AF_INET6; + memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr)); + if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6), + tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST)) strcat(rid, tmp); #endif } else { @@ -446,9 +452,12 @@ char *silc_id_render(void *id, SilcUInt16 type) SilcChannelID *channel_id = (SilcChannelID *)id; if (channel_id->ip.data_len > 4) { #ifdef HAVE_IPV6 - struct in6_addr ipv6; - memmove(&ipv6, channel_id->ip.data, sizeof(ipv6)); - if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + struct sockaddr_in6 ipv6; + memset(&ipv6, 0, sizeof(ipv6)); + ipv6.sin6_family = AF_INET6; + memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr)); + if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6), + tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST)) strcat(rid, tmp); #endif } else { diff --git a/lib/silcutil/unix/silcunixnet.c b/lib/silcutil/unix/silcunixnet.c index d209031a..31c11370 100644 --- a/lib/silcutil/unix/silcunixnet.c +++ b/lib/silcutil/unix/silcunixnet.c @@ -321,11 +321,25 @@ bool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) memcpy(bin, (unsigned char *)&tmp.s_addr, 4); #ifdef HAVE_IPV6 } else { + struct addrinfo hints, *ai; + SilcSockaddr *s; + /* IPv6 address */ if (bin_len < 16) return FALSE; - ret = inet_pton(AF_INET6, addr, &bin); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + if (getaddrinfo(addr, NULL, &hints, &ai)) + return FALSE; + + if (ai) { + s = (SilcSockaddr *)ai->ai_addr; + memcpy(bin, &s->sin6.sin6_addr, sizeof(s->sin6.sin6_addr)); + freeaddrinfo(ai); + } + + ret = TRUE; #endif /* HAVE_IPV6 */ }