I need to get the list of IPv4 and IPv6 addresses for
some given hostname.  I also need the CNAME.

I thought getaddrinfo with the AI_CANONNAME would get
that for me, but that seems to be not the case:

g...@dell6300gwr$ getent hosts 129.148.169.51
129.148.169.51  dhcp-ubur01-169-51.East.Sun.COM
g...@dell6300gwr$ ./getaddr dhcp-ubur01-169-51.East.Sun.COM
ai[0]: af=2, len=16 saf=2, IP=129.148.169.51
ai[0]: cname="dhcp-ubur01-169-51.East.Sun.COM"
g...@dell6300gwr$ ./getaddr 129.148.169.51
ai[0]: af=2, len=16 saf=2, IP=129.148.169.51
ai[0]: cname="::ffff:129.148.169.51"

Is this a bug?  Or am I being a "noob" here?
My "getaddr" test program is attached.

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * Test getaddrinfo.  Build using:
 *	make getaddr LDLIBS="-lsocket -lnsl"
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <netdb.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

void
dump_sockaddr(struct sockaddr *sa)
{
	char paddrbuf[INET6_ADDRSTRLEN];
	struct sockaddr_in *sin;
	struct sockaddr_in6 *sin6;
	int af = sa->sa_family;
	const char *ip;

	printf(" saf=%d,", af);
	switch (af) {
	case AF_INET:
		sin = (void *)sa;
		ip = inet_ntop(AF_INET, &sin->sin_addr,
		    paddrbuf, sizeof (paddrbuf));
		break;
	case AF_INET6:
		sin6 = (void *)sa;
		ip = inet_ntop(AF_INET6, &sin6->sin6_addr,
		    paddrbuf, sizeof (paddrbuf));
		break;
	default:
		ip = "?";
		break;
	}
	printf(" IP=%s\n", ip);
}

void
dump_addrinfo(struct addrinfo *ai)
{
	int i;

	if (ai == NULL) {
		printf("ai==NULL\n");
		return;
	}

	for (i = 0; ai; i++, ai = ai->ai_next) {
		printf("ai[%d]: af=%d, len=%d", i,
		    ai->ai_family, ai->ai_addrlen);
		dump_sockaddr(ai->ai_addr);
		if (ai->ai_canonname) {
			printf("ai[%d]: cname=\"%s\"\n",
			    i, ai->ai_canonname);
		}
	}
}

/*
 * SMB client name resolution - normal, and/or NetBIOS.
 * Returns an EAI_xxx error number like getaddrinfo(3)
 */
int
getaddr(char *host)
{
	struct addrinfo hints, *res;
	char *srvaddr_str;
	int gaierr, gaierr2;

	/*
	 * Try to lookup the host address using the
	 * normal name-to-IP address mechanisms.
	 */
	memset(&hints, 0, sizeof (hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	gaierr = getaddrinfo(host, NULL, &hints, &res);
	if (gaierr == 0) {
		dump_addrinfo(res);
	} else {
		fprintf(stderr, "getaddrinfo: %s: %s",
		    host, gai_strerror(gaierr));
	}

	return (gaierr);
}

int
main(int argc, char **argv)
{
	int i;

	if (argc < 2) {
		fprintf(stderr, "usage: %s HOST\n", argv[0]);
		exit(1);
	}

	for (i = 1; i < argc; i++) {
		getaddr(argv[i]);
	}
	exit (0);
}
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to