version 1.1.1.1, 2012/02/21 23:16:02
|
version 1.1.1.2, 2012/05/29 12:55:57
|
Line 1
|
Line 1
|
/* $Id$ */ |
/* $Id$ */ |
/* MiniUPnP project |
/* MiniUPnP project |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* (c) 2006-2008 Thomas Bernard | * (c) 2006-2011 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 */ |
|
|
|
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
#include <syslog.h> |
#include <syslog.h> |
#include <unistd.h> |
#include <unistd.h> |
Line 18
|
Line 19
|
#include <sys/sockio.h> |
#include <sys/sockio.h> |
#endif |
#endif |
|
|
|
#include "config.h" |
#include "getifaddr.h" |
#include "getifaddr.h" |
|
#if defined(USE_GETIFADDRS) || defined(ENABLE_IPV6) |
|
#include <ifaddrs.h> |
|
#endif |
|
|
int |
int |
getifaddr(const char * ifname, char * buf, int len) |
getifaddr(const char * ifname, char * buf, int len) |
{ |
{ |
|
#ifndef USE_GETIFADDRS |
|
/* use ioctl SIOCGIFADDR. Works only for ip v4 */ |
/* SIOCGIFADDR struct ifreq * */ |
/* SIOCGIFADDR struct ifreq * */ |
int s; |
int s; |
struct ifreq ifr; |
struct ifreq ifr; |
int ifrlen; |
int ifrlen; |
struct sockaddr_in * addr; |
struct sockaddr_in * addr; |
ifrlen = sizeof(ifr); |
ifrlen = sizeof(ifr); |
|
|
if(!ifname || ifname[0]=='\0') |
if(!ifname || ifname[0]=='\0') |
return -1; |
return -1; |
s = socket(PF_INET, SOCK_DGRAM, 0); |
s = socket(PF_INET, SOCK_DGRAM, 0); |
Line 52 getifaddr(const char * ifname, char * buf, int len)
|
Line 60 getifaddr(const char * ifname, char * buf, int len)
|
return -1; |
return -1; |
} |
} |
close(s); |
close(s); |
|
#else /* ifndef USE_GETIFADDRS */ |
|
/* Works for all address families (both ip v4 and ip v6) */ |
|
struct ifaddrs * ifap; |
|
struct ifaddrs * ife; |
|
|
|
if(!ifname || ifname[0]=='\0') |
|
return -1; |
|
if(getifaddrs(&ifap)<0) |
|
{ |
|
syslog(LOG_ERR, "getifaddrs: %m"); |
|
return -1; |
|
} |
|
for(ife = ifap; ife; ife = ife->ifa_next) |
|
{ |
|
/* skip other interfaces */ |
|
if(0 != strcmp(ifname, ife->ifa_name)) |
|
continue; |
|
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); |
|
break; |
|
/* |
|
case AF_INET6: |
|
inet_ntop(ife->ifa_addr->sa_family, |
|
&((struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr, |
|
buf, len); |
|
*/ |
|
} |
|
} |
|
freeifaddrs(ifap); |
|
#endif |
return 0; |
return 0; |
} |
} |
|
|
|
#ifdef ENABLE_IPV6 |
|
int |
|
find_ipv6_addr(const char * ifname, |
|
char * dst, int n) |
|
{ |
|
struct ifaddrs * ifap; |
|
struct ifaddrs * ife; |
|
const struct sockaddr_in6 * addr; |
|
char buf[64]; |
|
int r = 0; |
|
|
|
if(!dst) |
|
return -1; |
|
|
|
if(getifaddrs(&ifap)<0) |
|
{ |
|
syslog(LOG_ERR, "getifaddrs: %m"); |
|
return -1; |
|
} |
|
for(ife = ifap; ife; ife = ife->ifa_next) |
|
{ |
|
/* skip other interfaces if one was specified */ |
|
if(ifname && (0 != strcmp(ifname, ife->ifa_name))) |
|
continue; |
|
if(ife->ifa_addr->sa_family == AF_INET6) |
|
{ |
|
addr = (const struct sockaddr_in6 *)ife->ifa_addr; |
|
if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr) |
|
&& !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) |
|
{ |
|
inet_ntop(ife->ifa_addr->sa_family, |
|
&addr->sin6_addr, |
|
buf, sizeof(buf)); |
|
/* add brackets */ |
|
snprintf(dst, n, "[%s]", buf); |
|
r = 1; |
|
} |
|
} |
|
} |
|
return r; |
|
} |
|
#endif |
|
|