nm4 2009/10/20 13:39:47 BST
Modified files:
exim-src/OS os.h-NetBSD
exim-src/src os.c
Log:
Improvements to local interface IP addr detection. Fixes: #802
Revision Changes Path
1.5 +1 -0 exim/exim-src/OS/os.h-NetBSD
1.7 +72 -8 exim/exim-src/src/os.c
Index: os.h-NetBSD
===================================================================
RCS file: /home/cvs/exim/exim-src/OS/os.h-NetBSD,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- os.h-NetBSD 27 Jun 2007 08:46:28 -0000 1.4
+++ os.h-NetBSD 20 Oct 2009 12:39:47 -0000 1.5
@@ -1,8 +1,9 @@
-/* $Cambridge: exim/exim-src/OS/os.h-NetBSD,v 1.4 2007/06/27 08:46:28 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/OS/os.h-NetBSD,v 1.5 2009/10/20 12:39:47 nm4 Exp $ */
/* Exim: OS-specific C header file for NetBSD */
#define HAVE_BSD_GETLOADAVG
+#define HAVE_GETIFADDRS
#define HAVE_MMAP
#define HAVE_SYS_MOUNT_H
#define SIOCGIFCONF_GIVES_ADDR
Index: os.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/os.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- os.c 8 Jan 2007 10:50:18 -0000 1.6
+++ os.c 20 Oct 2009 12:39:47 -0000 1.7
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/os.c,v 1.6 2007/01/08 10:50:18 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/os.c,v 1.7 2009/10/20 12:39:47 nm4 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -463,6 +463,75 @@
This function finds the addresses of all the running interfaces on the machine.
A chain of blocks containing the textual form of the addresses is returned.
+getifaddrs() provides a sane consistent way to query this on modern OSs,
+otherwise fall back to a maze of twisty ioctl() calls
+
+Arguments: none
+Returns: a chain of ip_address_items, each pointing to a textual
+ version of an IP address, with the port field set to zero
+*/
+
+
+#ifndef NO_FIND_INTERFACES
+
+#ifdef HAVE_GETIFADDRS
+
+#include <ifaddrs.h>
+
+ip_address_item *
+os_common_find_running_interfaces(void)
+{
+struct ifaddrs *ifalist = NULL;
+ip_address_item *yield = NULL;
+ip_address_item *last = NULL;
+ip_address_item *next;
+
+if (getifaddrs(&ifalist) != 0)
+ log_write(0, LOG_PANIC_DIE, "Unable to call getifaddrs: %d %s",
+ errno, strerror(errno));
+
+struct ifaddrs *ifa;
+for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr->sa_family != AF_INET
+#if HAVE_IPV6
+ && ifa->ifa_addr->sa_family != AF_INET6
+#endif /* HAVE_IPV6 */
+ )
+ continue;
+
+ if ( !(ifa->ifa_flags & IFF_UP) ) /* Only want 'UP' interfaces */
+ continue;
+
+ /* Create a data block for the address, fill in the data, and put it on the
+ chain. */
+
+ next = store_get(sizeof(ip_address_item));
+ next->next = NULL;
+ next->port = 0;
+ (void)host_ntoa(-1, ifa->ifa_addr, next->address, NULL);
+
+ if (yield == NULL)
+ yield = last = next;
+ else
+ {
+ last->next = next;
+ last = next;
+ }
+
+ DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n",
+ last->address, ifa->ifa_name);
+ }
+
+/* free the list of addresses, and return the chain of data blocks. */
+
+freeifaddrs (ifalist);
+return yield;
+}
+
+#else /* HAVE_GETIFADDRS */
+
+/*
Problems:
(1) Solaris 2 has the SIOGIFNUM call to get the number of interfaces, but
@@ -486,15 +555,8 @@
the former, calling the latter does no harm, but it causes grief on Linux and
BSD systems in the case of IP aliasing, so a means of cutting it out is
provided.
-
-Arguments: none
-Returns: a chain of ip_address_items, each pointing to a textual
- version of an IP address, with the port field set to zero
*/
-
-#ifndef NO_FIND_INTERFACES
-
/* If there is IPv6 support, and SIOCGLIFCONF is defined, define macros to
use these new, longer versions of the old IPv4 interfaces. Otherwise, define
the macros to use the historical versions. */
@@ -556,7 +618,7 @@
char buf[MAX_INTERFACES*sizeof(struct V_ifreq)];
struct sockaddr *addrp;
size_t len = 0;
-char addrbuf[256];
+char addrbuf[512];
/* We have to create a socket in order to do ioctls on it to find out
what we want to know. */
@@ -701,6 +763,8 @@
return yield;
}
+#endif /* HAVE_GETIFADDRS */
+
#else /* NO_FIND_INTERFACES */
/* Some experimental or developing OS (e.g. GNU/Hurd) do not have the ioctls,