public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
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;
}

      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).