Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jul 2012 14:21:38 -0700
From:      Doug Hardie <bc979@lafn.org>
To:        Matthias Apitz <guru@unixarea.de>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: IPv6 && getaddrinfo(3C)
Message-ID:  <80BE761E-42B1-4111-ACEC-0C31E43D105D@lafn.org>
In-Reply-To: <20120712142415.GA1624@tiny.Sisis.de>
References:  <20120712142415.GA1624@tiny.Sisis.de>

next in thread | previous in thread | raw e-mail | index | archive | help

On 12 July 2012, at 07:24, Matthias Apitz wrote:

>=20
> Hello,
>=20
> I'm playing around with IPv6 code on a FreeBSD 9 system and can't get
> getaddrinfo(3C) to do what it should do as stated in its man page:
> accept an IPv6 and IPv4 IP addr, it only works with the IPv6 form:
>=20
> $ ./a.out ::1
> host: ::1
> read: SSH-2.0-OpenSSH_5.6p1 FreeBSD-20101111
> $ ./a.out 127.0.0.1
> host: 127.0.0.1
> ssh: getaddrinfo failed code 8: hostname nor servname provided, or not =
known
> $ telnet 127.0.0.1 22
> Trying 127.0.0.1...
> Connected to localhost.
> Escape character is '^]'.
> SSH-2.0-OpenSSH_5.6p1 FreeBSD-20101111
>=20
> the used C-code is attached below; what I'm doing wrong in the code?
>=20
> Thanks
>=20
> 	matthias
>=20
> /* IPv6 client code using getaddrinfo */
>=20
> #include <stdlib.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <stdio.h>
> #include <netdb.h>
> #include <string.h>
>=20
>=20
> main(argc, argv)		/* client side */
> 	int		argc;
> 	char           *argv[];
> {
>=20
> 	struct addrinfo	req, *ans;
> 	int	code, s, n;
> 	char buf[1024];
>=20
> 	memset(&req, 0, sizeof(req));
> 	req.ai_flags =3D AI_ADDRCONFIG|AI_NUMERICHOST;
> 	req.ai_family =3D AF_INET6;	/* Same as AF_INET6. */
> 	req.ai_socktype =3D SOCK_STREAM;
>=20
> 	/*                                         */
> 	/* Use default protocol (in this case tcp) */
> 	/*                                         */
>=20
> 	req.ai_protocol =3D 0;
>=20
> 	printf("host: %s\n", argv[1]);
> 	if ((code =3D getaddrinfo(argv[1], "ssh", &req, &ans)) !=3D 0) {
> 		fprintf(stderr, "ssh: getaddrinfo failed code %d: %s\n", =
code, gai_strerror(code));
> 		exit(1);
> 	}
> 	=20
> 	=20
> 	/*                                             */
> 	/* ans must contain at least one addrinfo, use */
> 	/* the first.                                  */
> 	/*                                             */=20
> =09
> 	s =3D socket(ans->ai_family, ans->ai_socktype, =
ans->ai_protocol);
> 	if (s < 0) {
> 		perror("ssh: socket");
> 		exit(3);
> 	}
>=20
> 	/* Connect does the bind for us */
> =09
> 	if (connect(s, ans->ai_addr, ans->ai_addrlen) < 0) {
> 		perror("ssh: connect");
> 		exit(5);
> 	}
>=20
> 	n =3D read(s, buf, 1024);
> 	printf ("read: %s", buf);
> =09
> 	/* */
> 	/* Free answers after use */
> 	/* */=20
> 	freeaddrinfo(ans);
>=20
> 	exit(0);
> }
>=20
> =20

I won't claim to be an expert on this, but I have used getaddrinfo =
successfully in servers.  The only thing I see that might be an issue is =
the use of zero for ai_protocol.  The comment in the man page implies =
that value is for servers and not clients.  I suspect you have to set =
the specific protocol you want.  You haven't included AI_PASSIVE so I =
suspect its expecting you to use the address to contact a server.





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?80BE761E-42B1-4111-ACEC-0C31E43D105D>