diff options
author | Alastair Houghton <alastair@coriolis-systems.com> | 2011-11-04 17:02:54 +0000 |
---|---|---|
committer | Alastair Houghton <alastair@coriolis-systems.com> | 2011-11-04 17:02:54 +0000 |
commit | c71567fa04e1e724f5abcdddba8ca97c40b3f98d (patch) | |
tree | d747a3a6206acfea99d57744a27a026e81ebfb9d | |
parent | 3ec8a8da849d5c59e5ba6ab532fa1bddb80b804c (diff) | |
download | netifaces-c71567fa04e1e724f5abcdddba8ca97c40b3f98d.tar.gz |
commit fad362f75136e2fe22f39d97c6c0177309586fec
Author: Leonid Evdokimov <leon@darkk.net.ru>
Date: Fri Oct 14 19:08:04 2011 +0400
Workaround for FreeBSD PR kern/152036.
I heard, that MacOS has alike problem too.
FreeBSD PR:
URL: http://www.freebsd.org/cgi/query-pr.cgi?pr=152036
Title: kern/152036: [libc] getifaddrs(3) returns truncated sockaddrs
for netmasks
-rw-r--r-- | netifaces.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/netifaces.c b/netifaces.c index a0e3546..eebd78f 100644 --- a/netifaces.c +++ b/netifaces.c @@ -30,8 +30,9 @@ #endif /* For the benefit of stupid platforms (Linux), include all the sockaddr - definitions we can lay our hands on. */ -#if !HAVE_SOCKADDR_SA_LEN + definitions we can lay our hands on. It can also be useful for the benefit + of another stupid platform (FreeBSD, see PR 152036). */ +#include <netinet/in.h> # if HAVE_NETASH_ASH_H # include <netash/ash.h> # endif @@ -120,6 +121,7 @@ static int af_to_len(int af) return sizeof (struct sockaddr); } +#if !HAVE_SOCKADDR_SA_LEN #define SA_LEN(sa) af_to_len(sa->sa_family) #if HAVE_SIOCGLIFNUM #define SS_LEN(sa) af_to_len(sa->ss_family) @@ -267,13 +269,43 @@ string_from_sockaddr (struct sockaddr *addr, char *buffer, int buflen) { + struct sockaddr* bigaddr = 0; + int failure; + struct sockaddr* gniaddr; + socklen_t gnilen; + if (!addr || addr->sa_family == AF_UNSPEC) return -1; - if (getnameinfo (addr, SA_LEN(addr), + if (SA_LEN(addr) < af_to_len(addr->sa_family)) { + /* Someteims ifa_netmask can be truncated. So let's detruncate it. FreeBSD + * PR: kern/152036: getifaddrs(3) returns truncated sockaddrs for netmasks + * -- http://www.freebsd.org/cgi/query-pr.cgi?pr=152036 */ + gnilen = af_to_len(addr->sa_family); + bigaddr = calloc(1, gnilen); + if (!bigaddr) + return -1; + memcpy(bigaddr, addr, SA_LEN(addr)); +#if HAVE_SOCKADDR_SA_LEN + bigaddr->sa_len = gnilen; +#endif + gniaddr = bigaddr; + } else { + gnilen = SA_LEN(addr); + gniaddr = addr; + } + + failure = getnameinfo (gniaddr, gnilen, buffer, buflen, NULL, 0, - NI_NUMERICHOST) != 0) { + NI_NUMERICHOST); + + if (bigaddr) { + free(bigaddr); + bigaddr = 0; + } + + if (failure) { int n, len; char *ptr; const char *data; |