From: Thorsten Kukuk <kukuk@suse.de>
To: Roland McGrath <roland@redhat.com>
Cc: libc-hacker@sources.redhat.com
Subject: Re: AI_V4MAPPED/AI_ALL
Date: Mon, 31 Mar 2003 21:36:00 -0000 [thread overview]
Message-ID: <20030331132935.GA6067@suse.de> (raw)
In-Reply-To: <200303310945.h2V9jwr08823@magilla.sf.frob.com>
[-- Attachment #1: Type: text/plain, Size: 620 bytes --]
On Mon, Mar 31, Roland McGrath wrote:
> > I can write a test on basis of my current test program for this.
>
> Please do.
I have appended tst-v4mapped.c. All it needs is a hostname which has
one IPv4 address and one hostname with one IPv4 and one IPv6 address.
Currently I use www.gnu.org and wwwprod.ipv6.bieringer.de.
Thorsten
--
Thorsten Kukuk http://www.suse.de/~kukuk/ kukuk@suse.de
SuSE Linux AG Deutschherrnstr. 15-19 D-90429 Nuernberg
--------------------------------------------------------------------
Key fingerprint = A368 676B 5E1B 3E46 CFCE 2D97 F8FD 4E23 56C6 FB4B
[-- Attachment #2: tst-v4mapped.c --]
[-- Type: text/plain, Size: 6381 bytes --]
/* Test case for AI_V4MAPPED/AI_ALL and getaddrinfo(). */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <err.h>
#include <alloca.h>
static int
print_getaddrinfo (struct addrinfo *res0)
{
struct addrinfo *res;
for (res = res0; res; res = res->ai_next)
{
if (res->ai_canonname)
printf ("canonname=%s\n", res->ai_canonname);
if (res->ai_family == AF_INET)
{
char buf[INET6_ADDRSTRLEN];
struct sockaddr_in *sin = (struct sockaddr_in *) res->ai_addr;
const char *ip = inet_ntop (res->ai_family, &sin->sin_addr.s_addr,
buf, sizeof (buf));
printf ("ai_family=AF_INET\n");
printf ("ai_addr=%s\n", ip);
}
else if (res->ai_family == AF_INET6)
{
char buf[INET6_ADDRSTRLEN];
struct sockaddr_in6 *sin = (struct sockaddr_in6 *) res->ai_addr;
const char *ip =
inet_ntop (res->ai_family, (void *) &sin->sin6_addr,
buf, sizeof (buf));
printf ("ai_family=AF_INET6\n");
printf ("ai_addr=%s\n", ip);
}
else
printf ("ai_family=%i\n", res->ai_family);
}
return 0;
}
static struct addrinfo *
call_getaddrinfo (const char *name, int af, int flags)
{
struct addrinfo hints, *res;
int error;
hints.ai_family = af;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = flags;
hints.ai_protocol = 0;
hints.ai_addrlen = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
error = getaddrinfo (name, NULL, &hints, &res);
if (error)
{
fprintf (stderr, "%s\n", gai_strerror (error));
return NULL;
}
return res;
}
int
main (int argc, char *argv[])
{
int errors = 0;
struct addrinfo *res;
/* hostname, which has only one IPv4 address. */
const char *ipv4only_host = "www.gnu.org";
/* hostname, which has one IPv4 and one IPv6 address. */
const char *ipv4ipv6_host = "wwwprod.ipv6.bieringer.de";
printf ("Using getaddrinfo (%s, AF_INET, AI_CANONNAME):\n", ipv4only_host);
res = call_getaddrinfo (ipv4only_host, AF_INET, AI_CANONNAME);
if (res == NULL)
{
printf ("ERROR: getaddrinfo should return an entry\n");
++errors;
}
else
{
if (res->ai_next != NULL)
{
printf ("ERROR: getaddrinfo should return only one entry\n");
++errors;
}
if (res->ai_family != AF_INET)
{
printf ("ERROR: %d is not AF_INET\n", res->ai_family);
++errors;
}
if (res->ai_canonname == NULL)
{
printf ("ERROR: ai_canonname is not set\n");
++errors;
}
print_getaddrinfo (res);
freeaddrinfo (res);
}
printf ("Using getaddrinfo (%s, AF_INET6, AI_CANONNAME):\n", ipv4ipv6_host);
res = call_getaddrinfo (ipv4ipv6_host, AF_INET6, AI_CANONNAME);
if (res == NULL)
{
printf ("ERROR: getaddrinfo should return an entry\n");
++errors;
}
else
{
if (res->ai_next != NULL)
{
printf ("ERROR: test should return only one entry\n");
++errors;
}
if (res->ai_family != AF_INET6)
{
printf ("ERROR: %d is not AF_INET6\n", res->ai_family);
++errors;
}
if (res->ai_canonname == NULL)
{
printf ("ERROR: ai_canonname is not set\n");
++errors;
}
print_getaddrinfo (res);
freeaddrinfo (res);
}
printf ("Using getaddrinfo (%s, AF_INET6, AI_CANONNAME|AI_V4MAPPED):\n",
ipv4only_host);
res =
call_getaddrinfo (ipv4only_host, AF_INET6, AI_CANONNAME | AI_V4MAPPED);
if (res == NULL)
{
printf ("ERROR: getaddrinfo should return an entry\n");
++errors;
}
else
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) res->ai_addr;
if (res->ai_next != NULL)
{
printf ("ERROR: test should return only one entry\n");
++errors;
}
if (res->ai_family != AF_INET6)
{
printf ("ERROR: %d is not AF_INET6\n", res->ai_family);
++errors;
}
if (!IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32))
{
printf ("ERROR: No IPv6 mapped IPv4 address returned\n");
++errors;
}
if (res->ai_canonname == NULL)
{
printf ("ERROR: ai_canonname is not set\n");
++errors;
}
print_getaddrinfo (res);
freeaddrinfo (res);
}
printf ("Using getaddrinfo (%s, AF_INET6, AI_CANONNAME|AI_V4MAPPED):\n",
ipv4ipv6_host);
res =
call_getaddrinfo (ipv4ipv6_host, AF_INET6, AI_CANONNAME | AI_V4MAPPED);
if (res == NULL)
{
printf ("ERROR: getaddrinfo should return an entry\n");
++errors;
}
else
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) res->ai_addr;
if (res->ai_next != NULL)
{
printf ("ERROR: test should return only one entry\n");
++errors;
}
if (res->ai_family != AF_INET6)
{
printf ("ERROR: %d is not AF_INET6\n", res->ai_family);
++errors;
}
if (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32))
{
printf ("ERROR: getaddrinfo returns a IPv6 mapped IPv4 address\n");
++errors;
}
if (res->ai_canonname == NULL)
{
printf ("ERROR: ai_canonname is not set\n");
++errors;
}
print_getaddrinfo (res);
freeaddrinfo (res);
}
printf
("Using getaddrinfo (%s, AF_INET6, AI_CANONNAME|AI_V4MAPPED|AI_ALL):\n",
ipv4ipv6_host);
res =
call_getaddrinfo (ipv4ipv6_host, AF_INET6,
AI_CANONNAME | AI_V4MAPPED | AI_ALL);
if (res == NULL)
{
printf ("ERROR: getaddrinfo should return an entry\n");
++errors;
}
else
{
struct addrinfo *res0;
int found_ipv4 = 0, found_ipv6 = 0;
if (res->ai_next == NULL || res->ai_next->ai_next != NULL)
{
printf ("ERROR: test should return exact two entries\n");
++errors;
}
for (res0 = res; res0; res0 = res0->ai_next)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) res0->ai_addr;
if (res0->ai_family != AF_INET6)
{
printf ("ERROR: %d is not AF_INET6\n", res->ai_family);
++errors;
}
if (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32))
++found_ipv4;
else
++found_ipv6;
}
if (found_ipv4 != 1)
{
printf
("ERROR: we should got one IPv6 mapped IPv4 address, but we got %d\n",
found_ipv4);
++errors;
}
if (found_ipv6 != 1)
{
printf ("ERROR: we should got one IPv6 address, but we got %d\n",
found_ipv6);
++errors;
}
print_getaddrinfo (res);
freeaddrinfo (res);
}
return errors;
}
prev parent reply other threads:[~2003-03-31 13:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-03-24 17:59 AI_V4MAPPED/AI_ALL Thorsten Kukuk
2003-03-30 20:11 ` AI_V4MAPPED/AI_ALL Ulrich Drepper
2003-03-30 22:08 ` AI_V4MAPPED/AI_ALL Thorsten Kukuk
2003-03-30 23:33 ` AI_V4MAPPED/AI_ALL Roland McGrath
2003-03-31 9:46 ` AI_V4MAPPED/AI_ALL Thorsten Kukuk
2003-03-31 13:29 ` AI_V4MAPPED/AI_ALL Roland McGrath
2003-03-31 21:36 ` Thorsten Kukuk [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030331132935.GA6067@suse.de \
--to=kukuk@suse.de \
--cc=libc-hacker@sources.redhat.com \
--cc=roland@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).