From a2eca9174c7803732658a1e6f7e8ed873c4fb6fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Aug 2006 13:37:04 +0000 Subject: r17586: merge lib/netif into lib/socket and use -lnsl -lsocket on the configure check for the interfaces. should fix the build on some old sun boxes metze (This used to be commit f20e251bfd9f1eb7ce5c00739631b1625a2aa467) --- source4/lib/socket/netif.c | 403 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 source4/lib/socket/netif.c (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c new file mode 100644 index 0000000000..0344febf38 --- /dev/null +++ b/source4/lib/socket/netif.c @@ -0,0 +1,403 @@ +/* + Unix SMB/CIFS implementation. + return a list of network interfaces + Copyright (C) Andrew Tridgell 1998 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* working out the interfaces for a OS is an incredibly non-portable + thing. We have several possible implementations below, and autoconf + tries each of them to see what works + + Note that this file does _not_ include includes.h. That is so this code + can be called directly from the autoconf tests. That also means + this code cannot use any of the normal Samba debug stuff or defines. + This is standalone code. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef AUTOCONF_TEST +#include "config.h" +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifndef SIOCGIFCONF +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef __COMPAR_FN_T +#define QSORT_CAST (__compar_fn_t) +#endif + +#ifndef QSORT_CAST +#define QSORT_CAST (int (*)(const void *, const void *)) +#endif + +#include +#define BOOL int +#include "netif.h" + +#if HAVE_IFACE_IFCONF + +/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 + V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. + + It probably also works on any BSD style system. */ + +/**************************************************************************** + 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; + struct ifreq *ifr=NULL; + int total = 0; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + + 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 */ + for (i=n-1;i>=0 && total < max_interfaces;i--) { + if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { + continue; + } + + iname = ifr[i].ifr_name; + ipaddr = (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) { + continue; + } + + if (!(ifr[i].ifr_flags & IFF_UP)) { + continue; + } + + 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; + total++; + } + + close(fd); + + return total; +} + +#elif HAVE_IFACE_IFREQ + +#ifndef I_STR +#include +#endif + +/**************************************************************************** +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; + struct strioctl strioctl; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + int total = 0; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + + 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 */ + n = strioctl.ic_len / sizeof(struct ifreq); + + /* we will assume that the kernel returns the length as an int + 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)); + } else { + ifr = (struct ifreq *)buff; + } + + /* Loop through interfaces */ + + for (i = 0; isin_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; + + total++; + } + + close(fd); + + return total; +} + +#elif HAVE_IFACE_AIX + +/**************************************************************************** +this one is for AIX (tested on 4.2) +****************************************************************************/ +static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) +{ + char buff[8192]; + int fd, i; + struct ifconf ifc; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + int total = 0; + + 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; + + /* Loop through interfaces */ + i = ifc.ifc_len; + + while (i > 0 && total < max_interfaces) { + uint_t inc; + + inc = ifr->ifr_addr.sa_len; + + if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { + goto next; + } + + ipaddr = (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr; + iname = ifr->ifr_name; + + if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { + goto next; + } + + if (!(ifr->ifr_flags & IFF_UP)) { + goto next; + } + + if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { + goto next; + } + + nmask = ((struct sockaddr_in *)&ifr->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; + + total++; + + next: + /* + * Patch from Archie Cobbs (archie@whistle.com). The + * addresses in the SIOCGIFCONF interface list have a + * minimum size. Usually this doesn't matter, but if + * your machine has tunnel interfaces, etc. that have + * a zero length "link address", this does matter. */ + + if (inc < sizeof(ifr->ifr_addr)) + inc = sizeof(ifr->ifr_addr); + inc += IFNAMSIZ; + + ifr = (struct ifreq*) (((char*) ifr) + inc); + i -= inc; + } + + + close(fd); + return total; +} + +#else /* a dummy version */ +static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) +{ + return -1; +} +#endif + + +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); + return r; +} + +/* this wrapper is used to remove duplicates from the interface list generated + above */ +int get_interfaces(struct iface_struct *ifaces, int max_interfaces) +{ + int total, i, j; + + total = _get_interfaces(ifaces, max_interfaces); + if (total <= 0) return total; + + /* now we need to remove duplicates */ + qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp); + + for (i=1;i Date: Fri, 15 Sep 2006 09:30:32 +0000 Subject: r18548: don't use #elif as we don't notice when 2 HAVE_IFACE_ versions are defined try to find the problem on Tru64...where configure says the AIX method finds 1 interface but later can't compile netif.c. (revision 18486 was the last that detects ifconf with 2 interfaces) metze (This used to be commit 8fa9852160680054ddb5316c4ee03a03f8553a37) --- source4/lib/socket/netif.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index 0344febf38..7484baa681 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -152,7 +152,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } -#elif HAVE_IFACE_IFREQ +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFCONF */ +#ifdef HAVE_IFACE_IFREQ #ifndef I_STR #include @@ -247,7 +249,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } -#elif HAVE_IFACE_AIX +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFREQ */ +#ifdef HAVE_IFACE_AIX /**************************************************************************** this one is for AIX (tested on 4.2) @@ -335,7 +339,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } -#else /* a dummy version */ +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_AIX */ +#ifndef _FOUND_IFACE_ANY static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) { return -1; -- cgit From 3c76ac114da92cd7404d643ae5a0565e4333d703 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Sep 2006 20:52:57 +0000 Subject: r18589: make inclusion of net/if.h conditional. It breaks HPUX with gcc. (This used to be commit ac71f40f8ff13c422e528dd5013842aa5a5004e7) --- source4/lib/socket/netif.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index 7484baa681..f3df7631e0 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -30,6 +30,10 @@ */ +#ifndef AUTOCONF_TEST +#include "config.h" +#endif + #include #include #include @@ -42,10 +46,6 @@ #include #include -#ifndef AUTOCONF_TEST -#include "config.h" -#endif - #ifdef HAVE_SYS_TIME_H #include #endif @@ -76,7 +76,10 @@ #define QSORT_CAST (int (*)(const void *, const void *)) #endif +#ifdef HAVE_NET_IF_H #include +#endif + #define BOOL int #include "netif.h" -- cgit From 1be714b2875f6bb1a0538b3e405e21d94257bd0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 19 Sep 2006 21:33:40 +0000 Subject: r18685: we don't need this here metze (This used to be commit cc729e646c5e3cb7919d033f90bda1dce545ff6b) --- source4/lib/socket/netif.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index f3df7631e0..0fac0e7ef5 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -80,7 +80,6 @@ #include #endif -#define BOOL int #include "netif.h" #if HAVE_IFACE_IFCONF -- cgit From e1b77f87efb667069370adc6067d81ac53d3cdab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Sep 2006 00:23:26 +0000 Subject: r18704: readd BOOL define to fix the build but I think this is the wrong fix... metze (This used to be commit 018b142d93ba2d36cd68db407e4a591461137b9b) --- source4/lib/socket/netif.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index 0fac0e7ef5..f3df7631e0 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -80,6 +80,7 @@ #include #endif +#define BOOL int #include "netif.h" #if HAVE_IFACE_IFCONF -- cgit From fd511d47e9362800a840898befa06c4b6d937df2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Sep 2006 02:09:14 +0000 Subject: r18708: much nicer fix metze (This used to be commit 8999a9eb2e7f3e8e4ff8f5311b9375bde590f2a5) --- source4/lib/socket/netif.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index f3df7631e0..1595b0dfd5 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -31,7 +31,7 @@ */ #ifndef AUTOCONF_TEST -#include "config.h" +#include "includes.h" #endif #include @@ -80,7 +80,6 @@ #include #endif -#define BOOL int #include "netif.h" #if HAVE_IFACE_IFCONF -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/lib/socket/netif.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index 1595b0dfd5..c9f43e811a 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -5,7 +5,7 @@ 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 2 of the License, or + 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, @@ -14,8 +14,7 @@ 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ -- cgit From 0b8ec6de02002e013775a1ba2d012a93e0950617 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 22:23:28 +0100 Subject: r26404: Disable socket wrapper for the interface detection code to work around the fact that the ioctls for enumerating interfaces are not very reliable when used on unix domain sockets. Ideally, we should be implementing the SIOCGIFCONF and SIOCGIFADDR ioctls in socket wrapper. (This used to be commit 035c4831003d5b5310f0874e712ef66ba3e78e34) --- source4/lib/socket/netif.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index c9f43e811a..d85bf4c716 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -29,6 +29,7 @@ */ +#define SOCKET_WRAPPER_NOT_REPLACE #ifndef AUTOCONF_TEST #include "includes.h" #endif -- cgit From c64c571591170478eead416216523c21e29a19ec Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 22:23:31 +0100 Subject: r26405: Import support for getifaddrs from Samba3. (This used to be commit 5827b7460a058e8565a406f1c3533e5f589674b5) --- source4/lib/socket/netif.c | 63 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index d85bf4c716..cd9ea6c977 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -2,6 +2,8 @@ Unix SMB/CIFS implementation. return a list of network interfaces Copyright (C) Andrew Tridgell 1998 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Jelmer Vernooij 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 @@ -40,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -76,12 +77,72 @@ #define QSORT_CAST (int (*)(const void *, const void *)) #endif +#ifdef HAVE_IFADDRS_H +#include +#endif + #ifdef HAVE_NET_IF_H #include #endif #include "netif.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(&iflist) < 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) { + + memset(&ifaces[total], '\0', sizeof(ifaces[total])); + + if (!ifptr->ifa_addr || !ifptr->ifa_netmask) { + continue; + } + + /* Check the interface is up. */ + if (!(ifptr->ifa_flags & IFF_UP)) { + continue; + } + + /* We don't support IPv6 *yet* */ + if (ifptr->ifa_addr->sa_family != AF_INET) { + continue; + } + + ifaces[total].ip = ((struct sockaddr_in *)ifptr->ifa_addr)->sin_addr; + ifaces[total].netmask = ((struct sockaddr_in *)ifptr->ifa_netmask)->sin_addr; + + strlcpy(ifaces[total].name, ifptr->ifa_name, + sizeof(ifaces[total].name)); + 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 -- cgit From be4decb2b73e3431155663c2dae3a8452ecde28a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 02:39:01 +0100 Subject: r26467: Use getifaddrs() for interface enumeration and provide replacements for platforms that don't have it in lib/replace. (This used to be commit 9b4924fbd8619033c55b4c6e2589da247332e7db) --- source4/lib/socket/netif.c | 348 +-------------------------------------------- 1 file changed, 1 insertion(+), 347 deletions(-) (limited to 'source4/lib/socket/netif.c') diff --git a/source4/lib/socket/netif.c b/source4/lib/socket/netif.c index cd9ea6c977..bf410af441 100644 --- a/source4/lib/socket/netif.c +++ b/source4/lib/socket/netif.c @@ -31,60 +31,8 @@ */ -#define SOCKET_WRAPPER_NOT_REPLACE -#ifndef AUTOCONF_TEST #include "includes.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifndef SIOCGIFCONF -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef HAVE_STRING_H -#include -#endif - -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif - -#ifdef HAVE_IFADDRS_H -#include -#endif - -#ifdef HAVE_NET_IF_H -#include -#endif - +#include "system/network.h" #include "netif.h" /**************************************************************************** @@ -92,7 +40,6 @@ Also gets IPv6 interfaces. ****************************************************************************/ -#if HAVE_IFACE_GETIFADDRS /**************************************************************************** Get the netmask address for a local interface. ****************************************************************************/ @@ -141,277 +88,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) 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 - V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. - - It probably also works on any BSD style system. */ - -/**************************************************************************** - 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; - struct ifreq *ifr=NULL; - int total = 0; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - - 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 */ - for (i=n-1;i>=0 && total < max_interfaces;i--) { - if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { - continue; - } - - iname = ifr[i].ifr_name; - ipaddr = (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr; - - if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) { - continue; - } - - if (!(ifr[i].ifr_flags & IFF_UP)) { - continue; - } - - 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; - total++; - } - - close(fd); - - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFCONF */ -#ifdef HAVE_IFACE_IFREQ - -#ifndef I_STR -#include -#endif - -/**************************************************************************** -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; - struct strioctl strioctl; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - int total = 0; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - - 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 */ - n = strioctl.ic_len / sizeof(struct ifreq); - - /* we will assume that the kernel returns the length as an int - 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)); - } else { - ifr = (struct ifreq *)buff; - } - - /* Loop through interfaces */ - - for (i = 0; isin_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; - - total++; - } - - close(fd); - - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFREQ */ -#ifdef HAVE_IFACE_AIX - -/**************************************************************************** -this one is for AIX (tested on 4.2) -****************************************************************************/ -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - char buff[8192]; - int fd, i; - struct ifconf ifc; - struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - int total = 0; - - 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; - - /* Loop through interfaces */ - i = ifc.ifc_len; - - while (i > 0 && total < max_interfaces) { - uint_t inc; - - inc = ifr->ifr_addr.sa_len; - - if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { - goto next; - } - - ipaddr = (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr; - iname = ifr->ifr_name; - - if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { - goto next; - } - - if (!(ifr->ifr_flags & IFF_UP)) { - goto next; - } - - if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { - goto next; - } - - nmask = ((struct sockaddr_in *)&ifr->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; - - total++; - - next: - /* - * Patch from Archie Cobbs (archie@whistle.com). The - * addresses in the SIOCGIFCONF interface list have a - * minimum size. Usually this doesn't matter, but if - * your machine has tunnel interfaces, etc. that have - * a zero length "link address", this does matter. */ - - if (inc < sizeof(ifr->ifr_addr)) - inc = sizeof(ifr->ifr_addr); - inc += IFNAMSIZ; - - ifr = (struct ifreq*) (((char*) ifr) + inc); - i -= inc; - } - - - close(fd); - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_AIX */ -#ifndef _FOUND_IFACE_ANY -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - return -1; -} -#endif - - static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) { int r; @@ -448,25 +124,3 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } - - -#ifdef AUTOCONF_TEST -/* this is the autoconf driver to test get_interfaces() */ - - int main() -{ - struct iface_struct ifaces[MAX_INTERFACES]; - int total = get_interfaces(ifaces, MAX_INTERFACES); - int i; - - printf("got %d interfaces:\n", total); - if (total <= 0) exit(1); - - for (i=0;i