+ if (silc_net_is_ip4(addr))
+ return TRUE;
+ return silc_net_is_ip6(addr);
+}
+
+/* Resolves IP address for hostname. */
+
+bool silc_net_gethostbyname(const char *name, char *address,
+ uint32 address_len)
+{
+#ifdef HAVE_IPV6
+ struct addrinfo hints, *ai;
+ char hbuf[NI_MAXHOST];
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ if (getaddrinfo(name, NULL, &hints, &ai))
+ return FALSE;
+
+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf,
+ sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
+ return FALSE;
+
+ if (!inet_ntop(ai->ai_family, ai->ai_addr, address, address_len))
+ return FALSE;
+
+ freeaddrinfo(ai);
+#else
+ struct hostent *hp;
+ struct in_addr ip;
+ char *tmp;
+
+ hp = gethostbyname(name);
+ if (!hp)
+ return FALSE;
+
+ memcpy(&ip.s_addr, hp->h_addr_list[0], 4);
+ tmp = inet_ntoa(ip);
+ if (!tmp)
+ return FALSE;
+ if (address_len < strlen(tmp))
+ return FALSE;
+ memset(address, 0, address_len);
+ strncpy(address, tmp, strlen(tmp));
+#endif
+
+ return TRUE;
+}
+
+/* Resolves hostname by IP address. */
+
+bool silc_net_gethostbyaddr(const char *addr, char *name, uint32 name_len)
+{
+#ifdef HAVE_IPV6
+ struct addrinfo req, *ai;
+
+ memset(&req, 0, sizeof(req));
+ req.ai_socktype = SOCK_STREAM;
+ req.ai_flags = AI_CANONNAME;
+
+ if (getaddrinfo(addr, NULL, &req, &ai))
+ return FALSE;
+ if (name_len < strlen(ai->ai_canonname))
+ return FALSE;
+ memset(name, 0, name_len);
+ strncpy(name, ai->ai_canonname, strlen(ai->ai_canonname));
+
+ freeaddrinfo(ai);
+#else
+ struct hostent *hp;
+
+ hp = gethostbyaddr(addr, strlen(addr), AF_INET);
+ if (!hp)
+ return FALSE;
+ if (name_len < strlen(hp->h_name))
+ return FALSE;
+ memset(name, 0, name_len);
+ strncpy(name, hp->h_name, strlen(hp->h_name));
+#endif
+
+ return TRUE;