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:
parent
acbe15c5ea
commit
7cb493919f
|
@ -1,7 +1,7 @@
|
||||||
/* $Id: getifaddr.c,v 1.19 2013/12/13 14:28:40 nanard Exp $ */
|
/* $Id: getifaddr.c,v 1.19 2013/12/13 14:28:40 nanard Exp $ */
|
||||||
/* MiniUPnP project
|
/* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* 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
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* 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;
|
ifaddr = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||||
if(addr) *addr = ifaddr->sin_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");
|
if(!inet_ntop(AF_INET, &ifaddr->sin_addr, buf, len))
|
||||||
close(s);
|
{
|
||||||
return -1;
|
syslog(LOG_ERR, "inet_ntop(): %m");
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(mask)
|
if(mask)
|
||||||
{
|
{
|
||||||
|
@ -99,9 +102,12 @@ getifaddr(const char * ifname, char * buf, int len,
|
||||||
switch(ife->ifa_addr->sa_family)
|
switch(ife->ifa_addr->sa_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
inet_ntop(ife->ifa_addr->sa_family,
|
if(buf)
|
||||||
&((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
|
{
|
||||||
buf, len);
|
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(addr) *addr = ((struct sockaddr_in *)ife->ifa_addr)->sin_addr;
|
||||||
if(mask) *mask = ((struct sockaddr_in *)ife->ifa_netmask)->sin_addr;
|
if(mask) *mask = ((struct sockaddr_in *)ife->ifa_netmask)->sin_addr;
|
||||||
break;
|
break;
|
||||||
|
@ -123,6 +129,7 @@ getifaddr(const char * ifname, char * buf, int len,
|
||||||
* IPv4 or IPv6 if both are enabled... */
|
* IPv4 or IPv6 if both are enabled... */
|
||||||
int getifaddr_in6(const char * ifname, struct in6_addr * addr)
|
int getifaddr_in6(const char * ifname, struct in6_addr * addr)
|
||||||
{
|
{
|
||||||
|
#if defined(ENABLE_IPV6) || defined(USE_GETIFADDRS)
|
||||||
struct ifaddrs * ifap;
|
struct ifaddrs * ifap;
|
||||||
struct ifaddrs * ife;
|
struct ifaddrs * ife;
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
|
@ -174,6 +181,18 @@ int getifaddr_in6(const char * ifname, struct in6_addr * addr)
|
||||||
}
|
}
|
||||||
freeifaddrs(ifap);
|
freeifaddrs(ifap);
|
||||||
return (found ? 0 : -1);
|
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 */
|
#endif /* ENABLE_PCP */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue