From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/8866 Path: news.gmane.org!not-for-mail From: Jo-Philipp Wich Newsgroups: gmane.linux.lib.musl.general Subject: Fix handling of peer-to-peer interfaces in getifaddrs() Date: Tue, 17 Nov 2015 11:33:48 +0100 Message-ID: <1447756429-2304-1-git-send-email-jow@openwrt.org> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1447756642 15151 80.91.229.3 (17 Nov 2015 10:37:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 17 Nov 2015 10:37:22 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-8879-gllmg-musl=m.gmane.org@lists.openwall.com Tue Nov 17 11:37:08 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1ZyddE-0001gp-Jx for gllmg-musl@m.gmane.org; Tue, 17 Nov 2015 11:37:00 +0100 Original-Received: (qmail 3829 invoked by uid 550); 17 Nov 2015 10:36:57 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 3763 invoked from network); 17 Nov 2015 10:36:51 -0000 X-Mailer: git-send-email 2.1.4 Xref: news.gmane.org gmane.linux.lib.musl.general:8866 Archived-At: properly handle point-to-point interfaces in getifaddrs() With point-to-point interfaces, the IFA_ADDRESS netlink attribute contains the peer address while an extra attribute IFA_LOCAL carries the actual local interface address. Currently musl lacks any treatment of IFA_LOCAL leading to bogus results when using getifaddrs() to obtain the local and remote IP addresses of point-to-point interfaces like ppp ones. The following test case illustrates the problem: -- 8< -- #include #include #include #include #include #include int main(int argc, char **argv) { struct ifaddrs *ifa, *ifap; char local[32]; char remote[32]; if (!getifaddrs(&ifa)) { for (ifap = ifa; ifap; ifap = ifap->ifa_next) { if (!ifap->ifa_name || strcmp(ifap->ifa_name, argv[1]) || !ifap->ifa_addr || ifap->ifa_addr->sa_family != AF_INET) continue; inet_ntop(AF_INET, &((struct sockaddr_in *)ifap->ifa_addr)->sin_addr, local, sizeof(local)); if (ifap->ifa_dstaddr) inet_ntop(AF_INET, &((struct sockaddr_in *)ifap->ifa_dstaddr)->sin_addr, remote, sizeof(remote)); else strcpy(remote, "(null)"); printf("local addr = %s / remote addr = %s\n", local, remote); break; } freeifaddrs(ifa); } return 0; } -- >8 -- I used the following command sequence to assert the results: $ gcc -o /tmp/ifa /tmp/ifa.c $ ip link add name dummy0 type dummy $ ip addr add 1.1.1.1 peer 2.2.2.2 dev dummy0 $ /tmp/ifa dummy0 That led to the following result on musl: local addr = 2.2.2.2 / remote addr = (null) Note that the local address is unexpectedly 2.2.2.2 while it should be 1.1.1.1 and the remote address is not set at all. Running the same test on an ordinary glibc system (Debian) and on an uclibc based OpenWrt gives the correct result: local addr = 1.1.1.1 / remote addr = 2.2.2.2 The proposed change adds special treatment of IFA_LOCAL to getifaddrs(), following the logic used in uclibc and glibc implementations. Reagrds, Jo-Philipp