+/**
+ * wget_sockaddr_get_port
+ *
+ * This function only return the port from the input structure
+ * Unsuported adress family will abort the whole programm.
+ *
+ * Require:
+ * that the IP-Protocol already is set.
+ *
+ * Input:
+ * wget_sockaddr* Information where to get the port
+ *
+ * Output:
+ * unsigned short Port Number in host order.
+ */
+unsigned short
+wget_sockaddr_get_port (const wget_sockaddr *sa)
+{
+ if (sa->sa.sa_family == AF_INET)
+ return htons (sa->sin.sin_port);
+#ifdef INET6
+ if (sa->sa.sa_family == AF_INET6)
+ return htons (sa->sin6.sin6_port);
+#endif
+ abort();
+ /* do not complain about return nothing */
+ return -1;
+}
+
+/**
+ * sockaddr_len
+ *
+ * This function return the length of the sockaddr corresponding to
+ * the acutall prefered protocol for (bind, connect etc...)
+ * Unsuported adress family will abort the whole programm.
+ *
+ * Require:
+ * that the IP-Protocol already is set.
+ *
+ * Input:
+ * - Public IP-Family Information
+ *
+ * Output:
+ * int structure length for socket options
+ */
+int
+sockaddr_len ()
+{
+ if (ip_default_family == AF_INET)
+ return sizeof (struct sockaddr_in);
+#ifdef INET6
+ if (ip_default_family == AF_INET6)
+ return sizeof (struct sockaddr_in6);
+#endif
+ abort();
+ /* do not complain about return nothing */
+ return 0;
+}
+
+/**
+ * Map an IPv4 adress to the internal adress format.
+ */
+void
+map_ipv4_to_ip (ip4_address *ipv4, ip_address *ip)
+{
+#ifdef INET6
+ static unsigned char ipv64[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
+ memcpy ((char *)ip + 12, ipv4 , 4);
+ memcpy ((char *)ip + 0, ipv64, 12);
+#else
+ if ((char *)ip != (char *)ipv4)
+ memcpy (ip, ipv4, 4);
+#endif
+}
+
+/* Detect whether an IP adress represents an IPv4 address and, if so,
+ copy it to IPV4. 0 is returned on failure.
+ This operation always succeeds when Wget is compiled without IPv6.
+ If IPV4 is NULL, don't copy, just detect. */
+
+int
+map_ip_to_ipv4 (ip_address *ip, ip4_address *ipv4)
+{
+#ifdef INET6
+ static unsigned char ipv64[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
+ if (0 != memcmp (ip, ipv64, 12))
+ return 0;
+ if (ipv4)
+ memcpy (ipv4, (char *)ip + 12, 4);
+#else
+ if (ipv4)
+ memcpy (ipv4, (char *)ip, 4);
+#endif
+ return 1;
+}
+\f
+/* Pretty-print ADDR. When compiled without IPv6, this is the same as
+ inet_ntoa. With IPv6, it either prints an IPv6 address or an IPv4
+ address. */
+
+char *
+pretty_print_address (ip_address *addr)
+{
+#ifdef INET6
+ ip4_address addr4;
+ static char buf[128];
+
+ if (map_ip_to_ipv4 (addr, &addr4))
+ return inet_ntoa (*(struct in_addr *)&addr4);
+
+ if (!inet_ntop (AF_INET6, addr, buf, sizeof (buf)))
+ return "<unknown>";
+ return buf;
+#endif
+ return inet_ntoa (*(struct in_addr *)addr);
+}
+
+/* Add host name HOST with the address ADDR_TEXT to the cache.
+ ADDR_LIST is a NULL-terminated list of addresses, as in struct
+ hostent. */
+
+static void
+cache_host_lookup (const char *host, struct address_list *al)
+{
+ if (!host_name_addresses_map)
+ host_name_addresses_map = make_nocase_string_hash_table (0);
+
+ ++al->refcount;
+ hash_table_put (host_name_addresses_map, xstrdup_lower (host), al);
+
+#ifdef DEBUG
+ if (opt.debug)
+ {
+ int i;
+ debug_logprintf ("Caching %s =>", host);
+ for (i = 0; i < al->count; i++)
+ debug_logprintf (" %s", pretty_print_address (al->addresses + i));
+ debug_logprintf ("\n");
+ }
+#endif
+}
+
+struct address_list *
+lookup_host (const char *host, int silent)
+{
+ struct address_list *al = NULL;
+ unsigned long addr_ipv4; /* #### use a 32-bit type here. */
+ ip_address addr;
+
+ /* First, try to check whether the address is already a numeric
+ address. */
+
+#ifdef INET6
+ if (inet_pton (AF_INET6, host, &addr) > 0)
+ return address_list_new_one (&addr);
+#endif
+
+ addr_ipv4 = (unsigned long)inet_addr (host);
+ if ((int)addr_ipv4 != -1)