mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Simplify the ip_address data union. Always use inet_ntop for printing
IP addresses when IPv6 is enabled.
This commit is contained in:
parent
254ed12b8f
commit
481443d337
@ -1,3 +1,10 @@
|
|||||||
|
2005-08-10 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
|
* host.c (print_address): Always use inet_ntop when IPv6 is
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
* host.h (ip_address): Simplify the data union.
|
||||||
|
|
||||||
2005-08-09 Hrvoje Niksic <hniksic@xemacs.org>
|
2005-08-09 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* mswindows.c (inet_ntop): Also handle IPv4 addresses for
|
* mswindows.c (inet_ntop): Also handle IPv4 addresses for
|
||||||
|
@ -73,27 +73,27 @@ so, delete this exception statement from your version. */
|
|||||||
static void
|
static void
|
||||||
sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
|
sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
|
||||||
{
|
{
|
||||||
switch (ip->type)
|
switch (ip->family)
|
||||||
{
|
{
|
||||||
case IPV4_ADDRESS:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||||
xzero (*sin);
|
xzero (*sin);
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_port = htons (port);
|
sin->sin_port = htons (port);
|
||||||
sin->sin_addr = ADDRESS_IPV4_IN_ADDR (ip);
|
sin->sin_addr = ip->data.d4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
case IPV6_ADDRESS:
|
case AF_INET6:
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||||
xzero (*sin6);
|
xzero (*sin6);
|
||||||
sin6->sin6_family = AF_INET6;
|
sin6->sin6_family = AF_INET6;
|
||||||
sin6->sin6_port = htons (port);
|
sin6->sin6_port = htons (port);
|
||||||
sin6->sin6_addr = ADDRESS_IPV6_IN6_ADDR (ip);
|
sin6->sin6_addr = ip->data.d6;
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
sin6->sin6_scope_id = ADDRESS_IPV6_SCOPE (ip);
|
sin6->sin6_scope_id = ip->ipv6_scope;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -117,8 +117,8 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
|
|||||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||||
if (ip)
|
if (ip)
|
||||||
{
|
{
|
||||||
ip->type = IPV4_ADDRESS;
|
ip->family = AF_INET;
|
||||||
ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr;
|
ip->data.d4 = sin->sin_addr;
|
||||||
}
|
}
|
||||||
if (port)
|
if (port)
|
||||||
*port = ntohs (sin->sin_port);
|
*port = ntohs (sin->sin_port);
|
||||||
@ -130,10 +130,10 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
|
|||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||||
if (ip)
|
if (ip)
|
||||||
{
|
{
|
||||||
ip->type = IPV6_ADDRESS;
|
ip->family = AF_INET6;
|
||||||
ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr;
|
ip->data.d6 = sin6->sin6_addr;
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id;
|
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (port)
|
if (port)
|
||||||
@ -415,7 +415,6 @@ int
|
|||||||
bind_local (const ip_address *bind_address, int *port)
|
bind_local (const ip_address *bind_address, int *port)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
int family = AF_INET;
|
|
||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
struct sockaddr *sa = (struct sockaddr *)&ss;
|
struct sockaddr *sa = (struct sockaddr *)&ss;
|
||||||
|
|
||||||
@ -424,12 +423,7 @@ bind_local (const ip_address *bind_address, int *port)
|
|||||||
void *setopt_ptr = (void *)&setopt_val;
|
void *setopt_ptr = (void *)&setopt_val;
|
||||||
socklen_t setopt_size = sizeof (setopt_val);
|
socklen_t setopt_size = sizeof (setopt_val);
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
sock = socket (bind_address->family, SOCK_STREAM, 0);
|
||||||
if (bind_address->type == IPV6_ADDRESS)
|
|
||||||
family = AF_INET6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sock = socket (family, SOCK_STREAM, 0);
|
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -529,16 +523,16 @@ socket_ip_address (int sock, ip_address *ip, int endpoint)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
ip->family = sockaddr->sa_family;
|
||||||
switch (sockaddr->sa_family)
|
switch (sockaddr->sa_family)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
|
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
|
||||||
ip->type = IPV6_ADDRESS;
|
ip->data.d6 = sa6->sin6_addr;
|
||||||
ADDRESS_IPV6_IN6_ADDR (ip) = sa6->sin6_addr;
|
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
ADDRESS_IPV6_SCOPE (ip) = sa6->sin6_scope_id;
|
ip->ipv6_scope = sa6->sin6_scope_id;
|
||||||
#endif
|
#endif
|
||||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||||
return true;
|
return true;
|
||||||
@ -547,8 +541,7 @@ socket_ip_address (int sock, ip_address *ip, int endpoint)
|
|||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
|
struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
|
||||||
ip->type = IPV4_ADDRESS;
|
ip->data.d4 = sa->sin_addr;
|
||||||
ADDRESS_IPV4_IN_ADDR (ip) = sa->sin_addr;
|
|
||||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -250,13 +250,11 @@ ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
|
|||||||
{
|
{
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
|
||||||
assert (addr != NULL);
|
assert (addr->family == AF_INET);
|
||||||
assert (addr->type == IPV4_ADDRESS);
|
|
||||||
assert (buf != NULL);
|
|
||||||
/* buf must contain the argument of PORT (of the form a,b,c,d,e,f). */
|
/* buf must contain the argument of PORT (of the form a,b,c,d,e,f). */
|
||||||
assert (buflen >= 6 * 4);
|
assert (buflen >= 6 * 4);
|
||||||
|
|
||||||
ptr = ADDRESS_IPV4_DATA (addr);
|
ptr = IP_INADDR_DATA (addr);
|
||||||
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d", ptr[0], ptr[1],
|
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d", ptr[0], ptr[1],
|
||||||
ptr[2], ptr[3], (port & 0xff00) >> 8, port & 0xff);
|
ptr[2], ptr[3], (port & 0xff00) >> 8, port & 0xff);
|
||||||
buf[buflen - 1] = '\0';
|
buf[buflen - 1] = '\0';
|
||||||
@ -280,7 +278,7 @@ ftp_port (int csock, int *local_sock)
|
|||||||
if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL))
|
if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL))
|
||||||
return FTPSYSERR;
|
return FTPSYSERR;
|
||||||
|
|
||||||
assert (addr.type == IPV4_ADDRESS);
|
assert (addr.family == AF_INET);
|
||||||
|
|
||||||
/* Setting port to 0 lets the system choose a free port. */
|
/* Setting port to 0 lets the system choose a free port. */
|
||||||
port = 0;
|
port = 0;
|
||||||
@ -326,32 +324,29 @@ static void
|
|||||||
ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
|
ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
|
||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
unsigned char *ptr;
|
unsigned char *ptr = IP_INADDR_DATA (addr);
|
||||||
|
|
||||||
assert (addr != NULL);
|
|
||||||
assert (addr->type == IPV4_ADDRESS || addr->type == IPV6_ADDRESS);
|
|
||||||
assert (buf != NULL);
|
|
||||||
/* buf must contain the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
|
/* buf must contain the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
|
||||||
assert (buflen >= 21 * 4);
|
assert (buflen >= 21 * 4);
|
||||||
|
|
||||||
/* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
|
/* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
|
||||||
switch (addr->type)
|
switch (addr->family)
|
||||||
{
|
{
|
||||||
case IPV4_ADDRESS:
|
case AF_INET:
|
||||||
ptr = ADDRESS_IPV4_DATA (addr);
|
|
||||||
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
|
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
|
||||||
ptr[0], ptr[1], ptr[2], ptr[3], 2,
|
ptr[0], ptr[1], ptr[2], ptr[3], 2,
|
||||||
(port & 0xff00) >> 8, port & 0xff);
|
(port & 0xff00) >> 8, port & 0xff);
|
||||||
buf[buflen - 1] = '\0';
|
|
||||||
break;
|
break;
|
||||||
case IPV6_ADDRESS:
|
case AF_INET6:
|
||||||
ptr = ADDRESS_IPV6_DATA (addr);
|
snprintf (buf, buflen,
|
||||||
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||||||
6, 16, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
|
6, 16,
|
||||||
ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], 2,
|
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
|
||||||
(port & 0xff00) >> 8, port & 0xff);
|
ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15],
|
||||||
buf[buflen - 1] = '\0';
|
2, (port & 0xff00) >> 8, port & 0xff);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +368,7 @@ ftp_lprt (int csock, int *local_sock)
|
|||||||
if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL))
|
if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL))
|
||||||
return FTPSYSERR;
|
return FTPSYSERR;
|
||||||
|
|
||||||
assert (addr.type == IPV4_ADDRESS || addr.type == IPV6_ADDRESS);
|
assert (addr.family == AF_INET || addr.family == AF_INET6);
|
||||||
|
|
||||||
/* Setting port to 0 lets the system choose a free port. */
|
/* Setting port to 0 lets the system choose a free port. */
|
||||||
port = 0;
|
port = 0;
|
||||||
@ -425,7 +420,7 @@ ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf,
|
|||||||
assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5);
|
assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5);
|
||||||
|
|
||||||
/* Construct the argument of EPRT (of the form |af|addr|port|). */
|
/* Construct the argument of EPRT (of the form |af|addr|port|). */
|
||||||
afnum = (addr->type == IPV4_ADDRESS ? 1 : 2);
|
afnum = (addr->family == AF_INET ? 1 : 2);
|
||||||
snprintf (buf, buflen, "|%d|%s|%d|", afnum, print_address (addr), port);
|
snprintf (buf, buflen, "|%d|%s|%d|", afnum, print_address (addr), port);
|
||||||
buf[buflen - 1] = '\0';
|
buf[buflen - 1] = '\0';
|
||||||
}
|
}
|
||||||
@ -546,8 +541,8 @@ ftp_pasv (int csock, ip_address *addr, int *port)
|
|||||||
}
|
}
|
||||||
xfree (respline);
|
xfree (respline);
|
||||||
|
|
||||||
addr->type = IPV4_ADDRESS;
|
addr->family = AF_INET;
|
||||||
memcpy (ADDRESS_IPV4_DATA (addr), tmp, 4);
|
memcpy (IP_INADDR_DATA (addr), tmp, 4);
|
||||||
*port = ((tmp[4] << 8) & 0xff00) + tmp[5];
|
*port = ((tmp[4] << 8) & 0xff00) + tmp[5];
|
||||||
|
|
||||||
return FTPOK;
|
return FTPOK;
|
||||||
@ -692,8 +687,8 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
|
|||||||
|
|
||||||
if (af == 4)
|
if (af == 4)
|
||||||
{
|
{
|
||||||
addr->type = IPV4_ADDRESS;
|
addr->family = AF_INET;
|
||||||
memcpy (ADDRESS_IPV4_DATA (addr), tmp, 4);
|
memcpy (IP_INADDR_DATA (addr), tmp, 4);
|
||||||
*port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1];
|
*port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1];
|
||||||
DEBUGP (("lpsv addr is: %s\n", print_address(addr)));
|
DEBUGP (("lpsv addr is: %s\n", print_address(addr)));
|
||||||
DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0]));
|
DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0]));
|
||||||
@ -703,8 +698,8 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert (af == 6);
|
assert (af == 6);
|
||||||
addr->type = IPV6_ADDRESS;
|
addr->family = AF_INET6;
|
||||||
memcpy (ADDRESS_IPV6_DATA (addr), tmp, 16);
|
memcpy (IP_INADDR_DATA (addr), tmp, 16);
|
||||||
*port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1];
|
*port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1];
|
||||||
DEBUGP (("lpsv addr is: %s\n", print_address(addr)));
|
DEBUGP (("lpsv addr is: %s\n", print_address(addr)));
|
||||||
DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0]));
|
DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0]));
|
||||||
@ -735,7 +730,7 @@ ftp_epsv (int csock, ip_address *ip, int *port)
|
|||||||
|
|
||||||
/* Form the request. */
|
/* Form the request. */
|
||||||
/* EPSV 1 means that we ask for IPv4 and EPSV 2 means that we ask for IPv6. */
|
/* EPSV 1 means that we ask for IPv4 and EPSV 2 means that we ask for IPv6. */
|
||||||
request = ftp_request ("EPSV", (ip->type == IPV4_ADDRESS ? "1" : "2"));
|
request = ftp_request ("EPSV", (ip->family == AF_INET ? "1" : "2"));
|
||||||
|
|
||||||
/* And send it. */
|
/* And send it. */
|
||||||
nwritten = fd_write (csock, request, strlen (request), -1);
|
nwritten = fd_write (csock, request, strlen (request), -1);
|
||||||
|
12
src/ftp.c
12
src/ftp.c
@ -116,14 +116,14 @@ ftp_do_pasv (int csock, ip_address *addr, int *port)
|
|||||||
/* If our control connection is over IPv6, then we first try EPSV and then
|
/* If our control connection is over IPv6, then we first try EPSV and then
|
||||||
* LPSV if the former is not supported. If the control connection is over
|
* LPSV if the former is not supported. If the control connection is over
|
||||||
* IPv4, we simply issue the good old PASV request. */
|
* IPv4, we simply issue the good old PASV request. */
|
||||||
switch (addr->type)
|
switch (addr->family)
|
||||||
{
|
{
|
||||||
case IPV4_ADDRESS:
|
case AF_INET:
|
||||||
if (!opt.server_response)
|
if (!opt.server_response)
|
||||||
logputs (LOG_VERBOSE, "==> PASV ... ");
|
logputs (LOG_VERBOSE, "==> PASV ... ");
|
||||||
err = ftp_pasv (csock, addr, port);
|
err = ftp_pasv (csock, addr, port);
|
||||||
break;
|
break;
|
||||||
case IPV6_ADDRESS:
|
case AF_INET6:
|
||||||
if (!opt.server_response)
|
if (!opt.server_response)
|
||||||
logputs (LOG_VERBOSE, "==> EPSV ... ");
|
logputs (LOG_VERBOSE, "==> EPSV ... ");
|
||||||
err = ftp_epsv (csock, addr, port);
|
err = ftp_epsv (csock, addr, port);
|
||||||
@ -159,14 +159,14 @@ ftp_do_port (int csock, int *local_sock)
|
|||||||
/* If our control connection is over IPv6, then we first try EPRT and then
|
/* If our control connection is over IPv6, then we first try EPRT and then
|
||||||
* LPRT if the former is not supported. If the control connection is over
|
* LPRT if the former is not supported. If the control connection is over
|
||||||
* IPv4, we simply issue the good old PORT request. */
|
* IPv4, we simply issue the good old PORT request. */
|
||||||
switch (cip.type)
|
switch (cip.family)
|
||||||
{
|
{
|
||||||
case IPV4_ADDRESS:
|
case AF_INET:
|
||||||
if (!opt.server_response)
|
if (!opt.server_response)
|
||||||
logputs (LOG_VERBOSE, "==> PORT ... ");
|
logputs (LOG_VERBOSE, "==> PORT ... ");
|
||||||
err = ftp_port (csock, local_sock);
|
err = ftp_port (csock, local_sock);
|
||||||
break;
|
break;
|
||||||
case IPV6_ADDRESS:
|
case AF_INET6:
|
||||||
if (!opt.server_response)
|
if (!opt.server_response)
|
||||||
logputs (LOG_VERBOSE, "==> EPRT ... ");
|
logputs (LOG_VERBOSE, "==> EPRT ... ");
|
||||||
err = ftp_eprt (csock, local_sock);
|
err = ftp_eprt (csock, local_sock);
|
||||||
|
55
src/host.c
55
src/host.c
@ -98,30 +98,27 @@ bool
|
|||||||
address_list_contains (const struct address_list *al, const ip_address *ip)
|
address_list_contains (const struct address_list *al, const ip_address *ip)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
switch (ip->type)
|
switch (ip->family)
|
||||||
{
|
{
|
||||||
case IPV4_ADDRESS:
|
case AF_INET:
|
||||||
for (i = 0; i < al->count; i++)
|
for (i = 0; i < al->count; i++)
|
||||||
{
|
{
|
||||||
ip_address *cur = al->addresses + i;
|
ip_address *cur = al->addresses + i;
|
||||||
if (cur->type == IPV4_ADDRESS
|
if (cur->family == AF_INET
|
||||||
&& (ADDRESS_IPV4_IN_ADDR (cur).s_addr
|
&& (cur->data.d4.s_addr == ip->data.d4.s_addr))
|
||||||
==
|
|
||||||
ADDRESS_IPV4_IN_ADDR (ip).s_addr))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
case IPV6_ADDRESS:
|
case AF_INET6:
|
||||||
for (i = 0; i < al->count; i++)
|
for (i = 0; i < al->count; i++)
|
||||||
{
|
{
|
||||||
ip_address *cur = al->addresses + i;
|
ip_address *cur = al->addresses + i;
|
||||||
if (cur->type == IPV6_ADDRESS
|
if (cur->family == AF_INET6
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
&& ADDRESS_IPV6_SCOPE (cur) == ADDRESS_IPV6_SCOPE (ip)
|
&& cur->ipv6_scope == ip->ipv6_scope
|
||||||
#endif
|
#endif
|
||||||
&& IN6_ARE_ADDR_EQUAL (&ADDRESS_IPV6_IN6_ADDR (cur),
|
&& IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6))
|
||||||
&ADDRESS_IPV6_IN6_ADDR (ip)))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -199,10 +196,10 @@ address_list_from_addrinfo (const struct addrinfo *ai)
|
|||||||
{
|
{
|
||||||
const struct sockaddr_in6 *sin6 =
|
const struct sockaddr_in6 *sin6 =
|
||||||
(const struct sockaddr_in6 *)ptr->ai_addr;
|
(const struct sockaddr_in6 *)ptr->ai_addr;
|
||||||
ip->type = IPV6_ADDRESS;
|
ip->family = AF_INET6;
|
||||||
ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr;
|
ip->data.d6 = sin6->sin6_addr;
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id;
|
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||||
#endif
|
#endif
|
||||||
++ip;
|
++ip;
|
||||||
}
|
}
|
||||||
@ -210,17 +207,17 @@ address_list_from_addrinfo (const struct addrinfo *ai)
|
|||||||
{
|
{
|
||||||
const struct sockaddr_in *sin =
|
const struct sockaddr_in *sin =
|
||||||
(const struct sockaddr_in *)ptr->ai_addr;
|
(const struct sockaddr_in *)ptr->ai_addr;
|
||||||
ip->type = IPV4_ADDRESS;
|
ip->family = AF_INET;
|
||||||
ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr;
|
ip->data.d4 = sin->sin_addr;
|
||||||
++ip;
|
++ip;
|
||||||
}
|
}
|
||||||
assert (ip - al->addresses == cnt);
|
assert (ip - al->addresses == cnt);
|
||||||
return al;
|
return al;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_IPV4(addr) (((const ip_address *) addr)->type == IPV4_ADDRESS)
|
#define IS_IPV4(addr) (((const ip_address *) addr)->family == AF_INET)
|
||||||
|
|
||||||
/* Compare two IP addresses by type, giving preference to the IPv4
|
/* Compare two IP addresses by family, giving preference to the IPv4
|
||||||
address (sorting it first). In other words, return -1 if ADDR1 is
|
address (sorting it first). In other words, return -1 if ADDR1 is
|
||||||
IPv4 and ADDR2 is IPv6, +1 if ADDR1 is IPv6 and ADDR2 is IPv4, and
|
IPv4 and ADDR2 is IPv6, +1 if ADDR1 is IPv6 and ADDR2 is IPv4, and
|
||||||
0 otherwise.
|
0 otherwise.
|
||||||
@ -234,7 +231,7 @@ cmp_prefer_ipv4 (const void *addr1, const void *addr2)
|
|||||||
return !IS_IPV4 (addr1) - !IS_IPV4 (addr2);
|
return !IS_IPV4 (addr1) - !IS_IPV4 (addr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_IPV6(addr) (((const ip_address *) addr)->type == IPV6_ADDRESS)
|
#define IS_IPV6(addr) (((const ip_address *) addr)->family == AF_INET6)
|
||||||
|
|
||||||
/* Like the above, but give preference to the IPv6 address. */
|
/* Like the above, but give preference to the IPv6 address. */
|
||||||
|
|
||||||
@ -267,7 +264,7 @@ address_list_from_ipv4_addresses (char **vec)
|
|||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ip_address *ip = &al->addresses[i];
|
ip_address *ip = &al->addresses[i];
|
||||||
ip->type = IPV4_ADDRESS;
|
ip->family = AF_INET;
|
||||||
memcpy (ADDRESS_IPV4_DATA (ip), vec[i], 4);
|
memcpy (ADDRESS_IPV4_DATA (ip), vec[i], 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,26 +403,18 @@ getaddrinfo_with_timeout (const char *node, const char *service,
|
|||||||
const char *
|
const char *
|
||||||
print_address (const ip_address *addr)
|
print_address (const ip_address *addr)
|
||||||
{
|
{
|
||||||
switch (addr->type)
|
|
||||||
{
|
|
||||||
case IPV4_ADDRESS:
|
|
||||||
return inet_ntoa (ADDRESS_IPV4_IN_ADDR (addr));
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
case IPV6_ADDRESS:
|
|
||||||
{
|
|
||||||
static char buf[64];
|
static char buf[64];
|
||||||
if (!inet_ntop (AF_INET6, &ADDRESS_IPV6_IN6_ADDR (addr),
|
if (!inet_ntop (addr->family, IP_INADDR_DATA (addr), buf, sizeof buf))
|
||||||
buf, sizeof (buf)))
|
|
||||||
snprintf (buf, sizeof buf, "<error: %s>", strerror (errno));
|
snprintf (buf, sizeof buf, "<error: %s>", strerror (errno));
|
||||||
buf[sizeof (buf) - 1] = '\0';
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
#else
|
||||||
|
return inet_ntoa (addr->data.d4);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
abort ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following two functions were adapted from glibc. */
|
/* The following two functions were adapted from glibc's
|
||||||
|
implementation of inet_pton, written by Paul Vixie. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_valid_ipv4_address (const char *str, const char *end)
|
is_valid_ipv4_address (const char *str, const char *end)
|
||||||
|
56
src/host.h
56
src/host.h
@ -47,48 +47,30 @@ struct address_list;
|
|||||||
/* This struct defines an IP address, tagged with family type. */
|
/* This struct defines an IP address, tagged with family type. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Address type. */
|
/* Address family, one of AF_INET or AF_INET6. */
|
||||||
enum {
|
int family;
|
||||||
IPV4_ADDRESS
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
, IPV6_ADDRESS
|
|
||||||
#endif /* ENABLE_IPV6 */
|
|
||||||
} type;
|
|
||||||
|
|
||||||
/* Address data union: ipv6 contains IPv6-related data (address and
|
/* The actual data, in the form of struct in_addr or in6_addr: */
|
||||||
scope), and ipv4 contains the IPv4 address. */
|
|
||||||
union {
|
union {
|
||||||
|
struct in_addr d4; /* IPv4 address */
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
struct {
|
struct in6_addr d6; /* IPv6 address */
|
||||||
struct in6_addr addr;
|
#endif
|
||||||
# ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
} data;
|
||||||
unsigned int scope_id;
|
|
||||||
# endif
|
/* Under IPv6 getaddrinfo also returns scope_id. Since it's
|
||||||
} ipv6;
|
IPv6-specific it strictly belongs in the above union, but we put
|
||||||
#endif /* ENABLE_IPV6 */
|
it here for simplicity. */
|
||||||
struct {
|
#if defined ENABLE_IPV6 && defined HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||||
struct in_addr addr;
|
int ipv6_scope;
|
||||||
} ipv4;
|
#endif
|
||||||
} u;
|
|
||||||
} ip_address;
|
} ip_address;
|
||||||
|
|
||||||
/* Because C doesn't support anonymous unions, access to ip_address
|
/* IP_INADDR_DATA macro returns a void pointer that can be interpreted
|
||||||
elements is unwieldy. Hence the accessors.
|
as a pointer to struct in_addr in IPv4 context or a pointer to
|
||||||
|
struct in6_addr in IPv4 context. This pointer can be passed to
|
||||||
The _ADDR accessors return the address as the struct in_addr or
|
functions that work on either, such as inet_ntop. */
|
||||||
in6_addr. The _DATA accessor returns a pointer to the address data
|
#define IP_INADDR_DATA(x) ((void *) &(x)->data)
|
||||||
-- pretty much the same as the above, but cast to void*. The
|
|
||||||
_SCOPE accessor returns the address's scope_id, and makes sense
|
|
||||||
only when IPv6 and HAVE_SOCKADDR_IN6_SCOPE_ID are both defined. */
|
|
||||||
|
|
||||||
#define ADDRESS_IPV4_IN_ADDR(x) ((x)->u.ipv4.addr)
|
|
||||||
/* Don't use &x->u.ipv4.addr.s_addr because it can be #defined to a
|
|
||||||
bitfield, which you can't take an address of. */
|
|
||||||
#define ADDRESS_IPV4_DATA(x) ((void *)&(x)->u.ipv4.addr)
|
|
||||||
|
|
||||||
#define ADDRESS_IPV6_IN6_ADDR(x) ((x)->u.ipv6.addr)
|
|
||||||
#define ADDRESS_IPV6_DATA(x) ((void *)&(x)->u.ipv6.addr)
|
|
||||||
#define ADDRESS_IPV6_SCOPE(x) ((x)->u.ipv6.scope_id)
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LH_SILENT = 1,
|
LH_SILENT = 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user