IPv6 fixes around network routines.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 13 Mar 2002 21:00:55 +0000 (21:00 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 13 Mar 2002 21:00:55 +0000 (21:00 +0000)
CHANGES
TODO
lib/silcutil/silcnet.c
lib/silcutil/silcutil.c
lib/silcutil/unix/silcunixnet.c

diff --git a/CHANGES b/CHANGES
index 82b8c68dfa359de2eeed9b43d23ac59a3fb5e36a..2ad64b42cc15058eeed2a6cb5163bb3163f5ad89 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Wed Mar 13 21:38:26 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Added silc_hash_public_key and silc_hash_public_key_compare
diff --git a/TODO b/TODO
index 96edf53dcffc51d78a40a10fc7953452c12be482..322e71f0792fc5dee65317a83331b397127010e0 100644 (file)
--- 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
index c685e6375efc9a2c5b45bc08fe1fda234b73787d..07207030c044be91c64b6a814bc604bc1b681080 100644 (file)
@@ -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);
index ee7f2eea49d3aba9ac1c66984025809c60736bc4..ad6b45adac5540749f6eae31b30142efe478a4af 100644 (file)
@@ -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 {
index d209031a69a02e7073495f40bc7522e6f1ed6e61..31c11370a4a4a5a6d7d65d0246ebc464ed0c7538 100644 (file)
@@ -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 */
   }