From owner-freebsd-net@freebsd.org Wed Dec 9 14:35:49 2015 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 647119D52D6 for ; Wed, 9 Dec 2015 14:35:49 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mail.allbsd.org (gatekeeper.allbsd.org [IPv6:2001:2f0:104:e001::32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.allbsd.org", Issuer "RapidSSL CA" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 8ED141645 for ; Wed, 9 Dec 2015 14:35:48 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from alph.d.allbsd.org (p1141-ipbf2205funabasi.chiba.ocn.ne.jp [114.148.196.141]) (authenticated bits=56) by mail.allbsd.org (8.14.9/8.14.9) with ESMTP id tB9EZP9A038307 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) (Client CN "/C=XX/ST=Some-state/L=Some-city/O=Some-org/CN=alph.allbsd.org", Issuer "/C=XX/ST=Some-state/L=Some-city/O=Some-org/CN=alph.allbsd.org"); Wed, 9 Dec 2015 23:35:35 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.d.allbsd.org (8.15.2/8.15.2) with ESMTPA id tB9EZN3K059602; Wed, 9 Dec 2015 23:35:24 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Wed, 09 Dec 2015 23:35:15 +0900 (JST) Message-Id: <20151209.233515.1592617248580059512.hrs@allbsd.org> To: ken@pcbsd.org Cc: freebsd-net@freebsd.org Subject: Re: IPv6 Address as text (C) From: Hiroki Sato In-Reply-To: <5668369F.9020309@pcbsd.org> References: <5668369F.9020309@pcbsd.org> X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.6 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart(Wed_Dec__9_23_35_15_2015_181)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.98.6 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender DNS name whitelisted, not delayed by milter-greylist-4.4.3 (mail.allbsd.org [133.31.130.32]); Wed, 09 Dec 2015 23:35:40 +0900 (JST) X-Spam-Status: No, score=-94.5 required=13.0 tests=CONTENT_TYPE_PRESENT, RCVD_IN_AHBL, RCVD_IN_AHBL_PROXY, RCVD_IN_AHBL_SPAM, RCVD_IN_PBL, RCVD_IN_RP_RNBL, USER_IN_WHITELIST autolearn=no autolearn_force=no version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on gatekeeper.allbsd.org X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Dec 2015 14:35:49 -0000 ----Security_Multipart(Wed_Dec__9_23_35_15_2015_181)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Ken Moore wrote in <5668369F.9020309@pcbsd.org>: ke> Note: Please CC me on replies - I am not subscribed to this list. ke> ke> I am having a bit of trouble getting an accurate string representation ke> of the current IPv6 address for a given device using the C system ke> libraries and was wondering of somebody with more experience than me ke> might be able to spot the error... ke> ke> Background: ke> I have been working on a couple simple C/C++/Qt functions to return ke> printable forms of the current ipv4 and ipv6 addresses assigned to a ke> particular device, and while the ipv4 function works fine the ipv6 ke> address is consistently wrong and almost always the same string - ke> making me think it is converting some internal error code to a string ke> ("::XXe2:ffff:ff7f:0" where the "X"s are the only two characters which ke> ever change). ke> ke> The two functions are nearly identical, and I think the error probably ke> comes from needing to use inet_ntop() for the ipv6 address because ke> there is no ipv6-compatible version of the inet_ntoa() function. ke> Do you have any thoughts or ideas about where the error might be ke> coming from or a better way to read off the ipv6 address as a string? ke> ke> Here are the two functions: ke> Note: "name" is the QString of the device name (wlan0, re0, other...), ke> and is an internal variable for the overall "NetDevice" class ke> [code] ke> //Fetch the IPv4 address and return it as a QString ke> QString NetDevice::ipAsString(){ ke> struct ifreq ifr; ke> memset(&ifr, 0, sizeof(struct ifreq)); ke> ke> strncpy(ifr.ifr_name, name.toLocal8Bit(), IFNAMSIZ); ke> int s = socket(PF_INET, SOCK_DGRAM, 0); ke> ke> ioctl(s, SIOCGIFADDR, &ifr); ke> struct in_addr in = ((sockaddr_in *) &ifr.ifr_addr)->sin_addr; ke> ke> return QString( inet_ntoa(in) ); ke> } ke> ke> //Fetch the IPv6 address and return it as a QString ke> QString NetDevice::ipv6AsString(){ ke> struct ifreq ifr; ke> memset(&ifr, 0, sizeof(struct ifreq)); ke> ke> strncpy(ifr.ifr_name, name.toLocal8Bit(), IFNAMSIZ); ke> int s = socket(PF_INET6, SOCK_DGRAM, 0); ke> ke> ioctl(s, SIOCGIFADDR, &ifr); Should this be SIOCGIFADDR_IN6 here? You should check the error code. Anyway, you should use getnameinfo() for IPv4 and IPv6 instead of inet_ntop() and inet_ntoa() for this purpose. It is an address family independent API which accepts struct sockaddr directly like this: ---- struct sockaddr *sa; /* input */ char hbuf[NI_MAXHOST]; int error; error = getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); if (error) { errx(1, "getnameinfo: %s", gai_strerror(error)); /* NOTREACHED */ } printf("host=%s\n", hbuf); ---- See getnameinfo(3) for more details. -- Hiroki ----Security_Multipart(Wed_Dec__9_23_35_15_2015_181)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlZoPCMACgkQTyzT2CeTzy017QCgg0p18C2ZOOd5fyAbWJ0WKzOo DwkAnAm4cZlrHuFM/V8IYm9zGtCazqrC =04D0 -----END PGP SIGNATURE----- ----Security_Multipart(Wed_Dec__9_23_35_15_2015_181)----