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>