miniupnpd/getifaddr.c: don't use getifaddrs() in IPv4 only

should fix #62 :
Don't use getifaddrs() in IPv4 only
so we avoid problems if getifaddrs() implementation is buggy
This commit is contained in:
Thomas Bernard 2014-03-14 10:04:49 +01:00
parent acbe15c5ea
commit 7cb493919f
1 changed files with 27 additions and 8 deletions

View File

@ -1,7 +1,7 @@
/* $Id: getifaddr.c,v 1.19 2013/12/13 14:28:40 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2013 Thomas Bernard
* (c) 2006-2014 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -55,11 +55,14 @@ getifaddr(const char * ifname, char * buf, int len,
}
ifaddr = (struct sockaddr_in *)&ifr.ifr_addr;
if(addr) *addr = ifaddr->sin_addr;
if(!inet_ntop(AF_INET, &ifaddr->sin_addr, buf, len))
if(buf)
{
syslog(LOG_ERR, "inet_ntop(): %m");
close(s);
return -1;
if(!inet_ntop(AF_INET, &ifaddr->sin_addr, buf, len))
{
syslog(LOG_ERR, "inet_ntop(): %m");
close(s);
return -1;
}
}
if(mask)
{
@ -99,9 +102,12 @@ getifaddr(const char * ifname, char * buf, int len,
switch(ife->ifa_addr->sa_family)
{
case AF_INET:
inet_ntop(ife->ifa_addr->sa_family,
&((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
buf, len);
if(buf)
{
inet_ntop(ife->ifa_addr->sa_family,
&((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
buf, len);
}
if(addr) *addr = ((struct sockaddr_in *)ife->ifa_addr)->sin_addr;
if(mask) *mask = ((struct sockaddr_in *)ife->ifa_netmask)->sin_addr;
break;
@ -123,6 +129,7 @@ getifaddr(const char * ifname, char * buf, int len,
* IPv4 or IPv6 if both are enabled... */
int getifaddr_in6(const char * ifname, struct in6_addr * addr)
{
#if defined(ENABLE_IPV6) || defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
struct ifaddrs * ife;
#ifdef ENABLE_IPV6
@ -174,6 +181,18 @@ int getifaddr_in6(const char * ifname, struct in6_addr * addr)
}
freeifaddrs(ifap);
return (found ? 0 : -1);
#else /* defined(ENABLE_IPV6) || defined(USE_GETIFADDRS) */
/* IPv4 only */
struct in_addr addr4;
if(getifaddr(ifname, NULL, 0, &addr4, NULL) < 0)
return -1;
/* IPv4-mapped IPv6 address ::ffff:1.2.3.4 */
memset(addr->s6_addr, 0, 10);
addr->s6_addr[10] = 0xff;
addr->s6_addr[11] = 0xff;
memcpy(addr->s6_addr + 12, &addr4.s_addr, 4);
return 0;
#endif
}
#endif /* ENABLE_PCP */