Subject: IPv6 with gethostbyname2 and gethostbyaddr
To: None <tech-net@netbsd.org>
From: Jeremy C. Reed <reed@reedmedia.net>
List: tech-net
Date: 07/04/2002 11:17:39
(If this is the wrong list, please let me know about a better one.)
I read that gethostbyname2 and gethostbyaddr for IPv6 is being deprecated
and that I should use getaddrinfo or getnodebyname instead. And inet_aton
manual recommends getaddrinfo and getnameinfo for IPv6.
But how can I get gethostbyname2 and gethostbyaddr to work for IPv6?
Here are some examples:
$ ./a.out -6 ::1
Hostname: ::1
Address: 0.0.0.0
$ ./a.out -6 -x ::1
Problem looking up "::1": Resolver Error 0 (no error)
$ ./a.out -6 localhost
Hostname: localhost
Address: 0.0.0.0
I wanted the above to return:
Hostname: localhost
Address: ::1
$ ./a.out -6 -x 3ffe:8050:201:1860:290:27ff:feab:19a7:
Problem looking up "3ffe:8050:201:1860:290:27ff:feab:19a7:": Resolver
Error 0 (no error)
I was hoping that would return something like:
Hostname: www.netbsd.org
Address: 3ffe:8050:201:1860:290:27ff:feab:19a7:
My /etc/hosts has:
::1 localhost
My /etc/nsswitch.conf has:
hosts: files dns
My code is below signature. Any suggestions? Or should I just use
getaddrinfo, getnameinfo or getnodebyname?
Jeremy C. Reed
http://bsd.reedmedia.net/
#include <string.h>
#include <stdio.h>
#include <netdb.h> /* gethostbyname() and related */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h> /* AF_INET manifest constant */
#include <stdlib.h>
int main(argc, argv)
int argc;
char *argv[];
{
char *hostname = NULL;
int addrtype;
int rval = 0, reverse = 0, ipv6 = 0;
struct sockaddr_in name;
if (argc == 1) {
fprintf (stderr, "gethost: neither action flags nor hostname given.\n");
exit(1);
}
while (*++argv) {
if (*argv[0] == '-') {
if (!strcmp(*argv, "-x")) {
reverse = 1;
continue;
}
if (!strcmp(*argv, "-6")) {
ipv6 = 1;
continue;
}
}
hostname = (char *)malloc(strlen(*argv) + 1);
if (hostname) {
strncpy(hostname, *argv, strlen(*argv));
}
}
if (hostname) {
struct hostent *h;
if (reverse && 0 == inet_aton(hostname, &name.sin_addr)) {
fprintf(stderr,
"Problem looking up \"%s\": %s\n", hostname, hstrerror(h_errno));
exit (1);
}
if (ipv6 || strchr(hostname, ':')) addrtype = AF_INET6;
else addrtype = AF_INET;
if (reverse) h = gethostbyaddr((char *) &name.sin_addr,
sizeof(&name.sin_addr), addrtype);
else h = gethostbyname2(hostname, addrtype);
if (h) {
int idx = 0;
printf("Hostname: %s\n", h->h_name);
while (h->h_aliases[idx])
printf("Alias: %s\n", h->h_aliases[idx++]);
switch (h->h_addrtype) {
case AF_INET:
case AF_INET6:
for (idx = 0; h->h_addr_list[idx]; ++idx)
printf("Address: %u.%u.%u.%u\n",
(0xff & h->h_addr_list[idx][0]),
(0xff & h->h_addr_list[idx][1]),
(0xff & h->h_addr_list[idx][2]),
(0xff & h->h_addr_list[idx][3]) );
break;
default:
break;
}
} else {
/* not all OSes have h_errno & hstrerror() - Solaris doesn't */
fprintf(stderr,
"Problem looking up \"%s\": %s\n", hostname, hstrerror(h_errno));
rval = 1;
}
}
free(hostname);
return(rval);
}