diff options
-rw-r--r-- | source3/configure.in | 54 | ||||
-rw-r--r-- | source3/include/includes.h | 4 | ||||
-rw-r--r-- | source3/include/interfaces.h | 15 | ||||
-rw-r--r-- | source3/lib/interface.c | 27 | ||||
-rw-r--r-- | source3/lib/interfaces.c | 173 | ||||
-rw-r--r-- | source3/lib/replace/replace.h | 12 | ||||
-rw-r--r-- | source3/lib/replace/system/network.h | 12 | ||||
-rw-r--r-- | source3/lib/util.c | 26 | ||||
-rw-r--r-- | source3/utils/net_dns.c | 4 |
9 files changed, 255 insertions, 72 deletions
diff --git a/source3/configure.in b/source3/configure.in index 561d4c6e0e..919cfc93dc 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -995,7 +995,7 @@ AC_CHECK_HEADERS(limits.h float.h pthread.h) AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h) AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h) AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h) -AC_CHECK_HEADERS(sys/un.h) +AC_CHECK_HEADERS(sys/un.h ifaddrs.h) AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h) AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h) AC_CHECK_HEADERS(sys/sysmacros.h) @@ -1082,6 +1082,7 @@ AC_CHECK_TYPE(loff_t,off_t) AC_CHECK_TYPE(offset_t,loff_t) AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(wchar_t, unsigned short) +AC_CHECK_TYPE(socklen_t, int) AC_CHECK_TYPE(comparison_fn_t, [AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])]) @@ -3038,6 +3039,42 @@ SMB_CHECK_SYSCONF(_SC_NPROCESSORS_ONLN) SMB_CHECK_SYSCONF(_SC_PAGESIZE) AC_CHECK_FUNCS(getpagesize) +dnl test for sa_family_t +AC_CACHE_CHECK([for sa_family_t],samba_cv_HAVE_SA_FAMILY_T,[ +AC_TRY_COMPILE([ +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +], +[ +sa_family_t foo; +], +samba_cv_HAVE_SA_FAMILY_T=yes,samba_cv_HAVE_SA_FAMILY_T=no)]) +if test x"$samba_cv_HAVE_SA_FAMILY_T" = x"yes"; then + AC_DEFINE(HAVE_SA_FAMILY_T,1,[Whether the system has sa_family_t]) +fi + +dnl test for getifaddrs and freeifaddrs +AC_CACHE_CHECK([for getifaddrs and freeifaddrs],samba_cv_HAVE_GETIFADDRS,[ +AC_TRY_COMPILE([ +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ifaddrs.h> +#include <netdb.h>], +[ +struct ifaddrs *ifp = NULL; +int ret = getifaddrs (&ifp); +freeifaddrs(ifp); +], +samba_cv_HAVE_GETIFADDRS=yes,samba_cv_HAVE_GETIFADDRS=no)]) +if test x"$samba_cv_HAVE_GETIFADDRS" = x"yes"; then + AC_DEFINE(HAVE_GETIFADDRS,1,[Whether the system has getifaddrs]) + AC_DEFINE(HAVE_FREEIFADDRS,1,[Whether the system has freeifaddrs]) +fi + ################## # look for a method of finding the list of network interfaces iface=no; @@ -3056,6 +3093,21 @@ if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then fi if test $iface = no; then +AC_CACHE_CHECK([for iface getifaddrs],samba_cv_HAVE_GETIFADDRS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" +AC_TRY_RUN([ +#define HAVE_IFACE_GETIFADDRS 1 +#define AUTOCONF_TEST 1 +#include "${srcdir-.}/lib/interfaces.c"], + samba_cv_HAVE_IFACE_GETIFADDRS=yes,samba_cv_HAVE_IFACE_GETIFADDRS=no,samba_cv_HAVE_IFACE_GETIFADDRS=cross)]) +CPPFLAGS="$SAVE_CPPFLAGS" +if test x"$samba_cv_HAVE_IFACE_GETIFADDRS" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_GETIFADDRS,1,[Whether iface ifconf is available]) +fi +fi + +if test $iface = no; then AC_CACHE_CHECK([for iface ifconf],samba_cv_HAVE_IFACE_IFCONF,[ SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" diff --git a/source3/include/includes.h b/source3/include/includes.h index 4f11e7a093..b084eed40c 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1262,4 +1262,8 @@ void exit_server_fault(void) NORETURN_ATTRIBUTE ; #include "libnscd.h" #endif +#ifndef HAVE_SA_FAMILY_T +typedef unsigned short int sa_family_t; +#endif + #endif /* _INCLUDES_H */ diff --git a/source3/include/interfaces.h b/source3/include/interfaces.h index 3b786f1ebc..371f64292f 100644 --- a/source3/include/interfaces.h +++ b/source3/include/interfaces.h @@ -7,6 +7,17 @@ struct iface_struct { char name[16]; - struct in_addr ip; - struct in_addr netmask; + sa_family_t sa_family; + union { + struct in_addr ip; +#ifdef AF_INET6 + struct in6_addr ip6; +#endif + } iface_addr; + union { + struct in_addr netmask; +#ifdef AF_INET6 + struct in6_addr netmask6; +#endif + } iface_netmask; }; diff --git a/source3/lib/interface.c b/source3/lib/interface.c index 29ed15a0c2..c187583923 100644 --- a/source3/lib/interface.c +++ b/source3/lib/interface.c @@ -103,12 +103,12 @@ static void interpret_interface(char *token) zero_ip(&ip); zero_ip(&nmask); - + /* first check if it is an interface name */ for (i=0;i<total_probed;i++) { if (gen_fnmatch(token, probed_ifaces[i].name) == 0) { - add_interface(probed_ifaces[i].ip, - probed_ifaces[i].netmask); + add_interface(probed_ifaces[i].iface_addr.ip, + probed_ifaces[i].iface_netmask.netmask); added = 1; } } @@ -119,10 +119,11 @@ static void interpret_interface(char *token) if (!p) { ip = *interpret_addr2(token); for (i=0;i<total_probed;i++) { - if (ip.s_addr == probed_ifaces[i].ip.s_addr && - !ip_equal(allones_ip, probed_ifaces[i].netmask)) { - add_interface(probed_ifaces[i].ip, - probed_ifaces[i].netmask); + if (ip.s_addr == probed_ifaces[i].iface_addr.ip.s_addr && + !ip_equal(allones_ip, + probed_ifaces[i].iface_netmask.netmask)) { + add_interface(probed_ifaces[i].iface_addr.ip, + probed_ifaces[i].iface_netmask.netmask); return; } } @@ -145,8 +146,8 @@ static void interpret_interface(char *token) if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) || ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) { for (i=0;i<total_probed;i++) { - if (same_net(ip, probed_ifaces[i].ip, nmask)) { - add_interface(probed_ifaces[i].ip, nmask); + if (same_net(ip, probed_ifaces[i].iface_addr.ip, nmask)) { + add_interface(probed_ifaces[i].iface_addr.ip, nmask); return; } } @@ -203,11 +204,11 @@ void load_interfaces(void) for (i=0;i<total_probed;i++) { if ( #if !defined(__s390__) - probed_ifaces[i].netmask.s_addr != allones_ip.s_addr && + probed_ifaces[i].iface_netmask.netmask.s_addr != allones_ip.s_addr && #endif - probed_ifaces[i].ip.s_addr != loopback_ip.s_addr) { - add_interface(probed_ifaces[i].ip, - probed_ifaces[i].netmask); + probed_ifaces[i].iface_addr.ip.s_addr != loopback_ip.s_addr) { + add_interface(probed_ifaces[i].iface_addr.ip, + probed_ifaces[i].iface_netmask.netmask); } } return; diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c index 2a232226b8..07abf4b1c6 100644 --- a/source3/lib/interfaces.c +++ b/source3/lib/interfaces.c @@ -1,18 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. return a list of network interfaces Copyright (C) Andrew Tridgell 1998 - + Copyright (C) Jeremy Allison 2007 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -45,6 +46,10 @@ #include <netinet/in.h> #include <arpa/inet.h> +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif @@ -81,6 +86,60 @@ #include "interfaces.h" +/**************************************************************************** + Try the "standard" getifaddrs/freeifaddrs interfaces. + Also gets IPv6 interfaces. +****************************************************************************/ + +#if HAVE_IFACE_GETIFADDRS +/**************************************************************************** + Get the netmask address for a local interface. +****************************************************************************/ + +static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) +{ + struct ifaddrs *iflist = NULL; + struct ifaddrs *ifptr = NULL; + int total = 0; + + if (getifaddrs(&ifp) < 0) { + return -1; + } + + /* Loop through interfaces, looking for given IP address */ + for (ifptr = iflist, total = 0; + ifptr != NULL && total < max_interfaces; + ifptr = ifptr->ifa_next) { + + /* Skip ipv6 for now. */ + if (ifptr->ifa_addr->sa_family != AF_INET) { + continue; + } + if (!(ifptr->ifa_flags & IFF_UP)) { + continue; + } + + ifaces[total].sa_family = ifptr->ifa_addr->sa_family; + + ifaces[total].iface_addr.ip = + ((struct sockaddr_in *)ifptr->ifa_addr).sin_addr; + + ifaces[total].iface_netmask.netmask = + ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr; + + strncpy(ifaces[total].name, ifptr->ifa_name, + sizeof(ifaces[total].name)-1); + ifaces[total].name[sizeof(ifaces[total].name)-1] = 0; + total++; + } + + freeifaddrs(iflist); + + return total; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_GETIFADDRS */ #if HAVE_IFACE_IFCONF /* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 @@ -89,10 +148,11 @@ It probably also works on any BSD style system. */ /**************************************************************************** - get the netmask address for a local interface + Get the netmask address for a local interface. ****************************************************************************/ + static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ +{ struct ifconf ifc; char buff[8192]; int fd, i, n; @@ -105,17 +165,17 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } - + ifc.ifc_len = sizeof(buff); ifc.ifc_buf = buff; if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { close(fd); return -1; - } + } ifr = ifc.ifc_req; - + n = ifc.ifc_len / sizeof(struct ifreq); /* Loop through interfaces, looking for given IP address */ @@ -129,7 +189,7 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) { continue; - } + } if (!(ifr[i].ifr_flags & IFF_UP)) { continue; @@ -137,21 +197,22 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) { continue; - } + } nmask = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr; strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1); ifaces[total].name[sizeof(ifaces[total].name)-1] = 0; - ifaces[total].ip = ipaddr; - ifaces[total].netmask = nmask; + ifaces[total].sa_family = AF_INET; + ifaces[total].iface_addr.ip = ipaddr; + ifaces[total].iface_netmask.netmask = nmask; total++; } close(fd); return total; -} +} #define _FOUND_IFACE_ANY #endif /* HAVE_IFACE_IFCONF */ @@ -162,9 +223,10 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) #endif /**************************************************************************** -this should cover most of the streams based systems -Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code + This should cover most of the streams based systems. + Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code. ****************************************************************************/ + static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) { struct ifreq ifreq; @@ -180,14 +242,14 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } - + strioctl.ic_cmd = SIOCGIFCONF; strioctl.ic_dp = buff; strioctl.ic_len = sizeof(buff); if (ioctl(fd, I_STR, &strioctl) < 0) { close(fd); return -1; - } + } /* we can ignore the possible sizeof(int) here as the resulting number of interface structures won't change */ @@ -197,23 +259,23 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) at the start of the buffer if the offered size is a multiple of the structure size plus an int */ if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { - ifr = (struct ifreq *)(buff + sizeof(int)); + ifr = (struct ifreq *)(buff + sizeof(int)); } else { - ifr = (struct ifreq *)buff; + ifr = (struct ifreq *)buff; } /* Loop through interfaces */ for (i = 0; i<n && total < max_interfaces; i++) { ifreq = ifr[i]; - + strioctl.ic_cmd = SIOCGIFFLAGS; strioctl.ic_dp = (char *)&ifreq; strioctl.ic_len = sizeof(struct ifreq); if (ioctl(fd, I_STR, &strioctl) != 0) { continue; } - + if (!(ifreq.ifr_flags & IFF_UP)) { continue; } @@ -239,8 +301,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1); ifaces[total].name[sizeof(ifaces[total].name)-1] = 0; - ifaces[total].ip = ipaddr; - ifaces[total].netmask = nmask; + ifaces[total].sa_family = AF_INET; + ifaces[total].iface_addr.ip = ipaddr; + ifaces[total].iface_netmask.netmask = nmask; total++; } @@ -255,8 +318,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) #ifdef HAVE_IFACE_AIX /**************************************************************************** -this one is for AIX (tested on 4.2) + This one is for AIX (tested on 4.2). ****************************************************************************/ + static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) { char buff[8192]; @@ -314,8 +378,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1); ifaces[total].name[sizeof(ifaces[total].name)-1] = 0; - ifaces[total].ip = ipaddr; - ifaces[total].netmask = nmask; + ifaces[total].sa_family = AF_INET; + ifaces[total].iface_addr.ip = ipaddr; + ifaces[total].iface_netmask.netmask = nmask; total++; @@ -334,7 +399,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) ifr = (struct ifreq*) (((char*) ifr) + inc); i -= inc; } - close(fd); return total; @@ -354,10 +418,40 @@ static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) { int r; r = strcmp(i1->name, i2->name); - if (r) return r; - r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr); - if (r) return r; - r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr); + if (r) { + return r; + } + r = i1->sa_family - i2->sa_family; + if (r) { + return r; + } + +#ifdef AF_INET6 + if (i1->sa_family == AF_INET6) { + r = memcmp(&i1->iface_addr.ip6, + &i2->iface_addr.ip6, + sizeof(struct in6_addr)); + if (r) { + return r; + } + r = memcmp(&i1->iface_netmask.netmask6, + &i1->iface_netmask.netmask6, + sizeof(struct in6_addr)); + if (r) { + return r; + } + } +#endif + + if (i1->sa_family == AF_INET) { + r = ntohl(i1->iface_addr.ip.s_addr) - + ntohl(i2->iface_addr.ip.s_addr); + if (r) { + return r; + } + r = ntohl(i1->iface_netmask.netmask.s_addr) - + ntohl(i2->iface_netmask.netmask.s_addr); + } return r; } @@ -399,12 +493,21 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces) int i; printf("got %d interfaces:\n", total); - if (total <= 0) exit(1); + if (total <= 0) { + exit(1); + } for (i=0;i<total;i++) { + char addr[INET6_ADDRSTRLEN]; printf("%-10s ", ifaces[i].name); - printf("IP=%s ", inet_ntoa(ifaces[i].ip)); - printf("NETMASK=%s\n", inet_ntoa(ifaces[i].netmask)); + printf("IP=%s ", inet_ntop(ifaces[i].sa_family, + (const void *)&ifaces[i].iface_addr.ip, + addr, + sizeof(addr))); + printf("NETMASK=%s\n", inet_ntop(ifaces[i].sa_family, + (const void *)&ifaces[i].iface_netmask.netmask, + addr, + sizeof(addr))); } return 0; } diff --git a/source3/lib/replace/replace.h b/source3/lib/replace/replace.h index 907d9b0086..27265e35c4 100644 --- a/source3/lib/replace/replace.h +++ b/source3/lib/replace/replace.h @@ -330,18 +330,18 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); #endif +#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_NTOP) +#include "system/network.h" +#endif + #ifndef HAVE_INET_PTON -#define inet_pton rep_inet_pton int rep_inet_pton(int af, const char *src, void *dst); +#define inet_pton rep_inet_pton #endif #ifndef HAVE_INET_NTOP -#define inet_ntop rep_inet_ntop const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); -#endif - -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT EINVAL +#define inet_ntop rep_inet_ntop #endif #ifdef HAVE_LIMITS_H diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index 7469040b28..70c3ec711c 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -106,4 +106,16 @@ char *rep_inet_ntoa(struct in_addr ip); #define INADDR_NONE 0xffffffff #endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT EINVAL +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + #endif diff --git a/source3/lib/util.c b/source3/lib/util.c index 67c5f8d38f..6c86376e57 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2138,7 +2138,7 @@ BOOL is_myname_or_ipaddr(const char *s) /* optimize for the common case */ - if (strequal(servername, global_myname())) + if (strequal(servername, global_myname())) return True; /* check for an alias */ @@ -2148,10 +2148,10 @@ BOOL is_myname_or_ipaddr(const char *s) /* check for loopback */ - if (strequal(servername, "127.0.0.1")) + if (strequal(servername, "127.0.0.1")) return True; - if (strequal(servername, "localhost")) + if (strequal(servername, "localhost")) return True; /* maybe it's my dns name */ @@ -2159,7 +2159,7 @@ BOOL is_myname_or_ipaddr(const char *s) if ( get_mydnsfullname( dnsname ) ) if ( strequal( servername, dnsname ) ) return True; - + /* handle possible CNAME records */ if ( !is_ipaddress( servername ) ) { @@ -2171,25 +2171,25 @@ BOOL is_myname_or_ipaddr(const char *s) putip( (char*)&return_ip, (char*)hp->h_addr ); fstrcpy( name, inet_ntoa( return_ip ) ); servername = name; - } + } } - + /* maybe its an IP address? */ if (is_ipaddress(servername)) { struct iface_struct nics[MAX_INTERFACES]; int i, n; uint32 ip; - + ip = interpret_addr(servername); if ((ip==0) || (ip==0xffffffff)) return False; - + n = get_interfaces(nics, MAX_INTERFACES); for (i=0; i<n; i++) { - if (ip == nics[i].ip.s_addr) + if (ip == nics[i].iface_addr.ip.s_addr) return True; } - } + } /* no match */ return False; @@ -2217,14 +2217,14 @@ BOOL is_myworkgroup(const char *s) WinXP => "Windows 2002 5.1" WinXP 64bit => "Windows XP 5.2" Win2k => "Windows 2000 5.0" - NT4 => "Windows NT 4.0" + NT4 => "Windows NT 4.0" Win9x => "Windows 4.0" - Windows 2003 doesn't set the native lan manager string but + Windows 2003 doesn't set the native lan manager string but they do set the domain to "Windows 2003 5.2" (probably a bug). ********************************************************************/ void ra_lanman_string( const char *native_lanman ) -{ +{ if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 ) set_remote_arch( RA_WINXP ); else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 ) diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index 6163f53c6e..e1993488f5 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -158,8 +158,8 @@ int get_my_ip_address( struct in_addr **ips ) } for ( i=0; i<n; i++ ) { - if ( nics[i].ip.s_addr != loopback_ip.s_addr ) { - memcpy( &list[count++], &nics[i].ip, sizeof( struct in_addr ) ); + if ( nics[i].iface_addr.ip.s_addr != loopback_ip.s_addr ) { + memcpy( &list[count++], &nics[i].iface_addr.ip, sizeof( struct in_addr ) ); } } *ips = list; |