[Git][NTPsec/ntpsec][master] 11 commits: libisc: merge libisc/ifiter_*c into libisc/interfaceiter.c

Gary E. Miller gitlab at mg.gitlab.com
Wed Jun 7 03:08:12 UTC 2017


Gary E. Miller pushed to branch master at NTPsec / ntpsec


Commits:
23d15ed8 by Gary E. Miller at 2017-06-06T18:36:12-07:00
libisc: merge libisc/ifiter_*c into libisc/interfaceiter.c

I hate when C files get included into C files.

- - - - -
5e38194c by Gary E. Miller at 2017-06-06T18:55:17-07:00
libisc: merge isc/sockaddr.h into ntp_io.c

ntp_io.c was the only user of sockaddr.h

- - - - -
b30ced26 by Gary E. Miller at 2017-06-06T19:03:24-07:00
ntp_io: simplify struct isc_sockaddr a tad.

- - - - -
9e5b0952 by Gary E. Miller at 2017-06-06T19:15:02-07:00
libisc: move struct isc_netaddr to isc/interfaceiter.h

- - - - -
8ea08035 by Gary E. Miller at 2017-06-06T19:26:20-07:00
libisc: be a bit smarter about what includes what

- - - - -
6fefa46b by Gary E. Miller at 2017-06-06T19:42:43-07:00
libisc: minor clean up isc/interfaceiter.h

- - - - -
02b4e9e3 by Gary E. Miller at 2017-06-06T19:44:52-07:00
libisc: rename isc/mem.h to isc_mem.h

Stop confusion with system copy of isc/mem.h

- - - - -
998be994 by Gary E. Miller at 2017-06-06T19:50:18-07:00
libisc: move isc/result.h to isc_result.h

- - - - -
ad330848 by Gary E. Miller at 2017-06-06T19:54:42-07:00
libisc: move isc/netaddr.h -> isc_netaddr.h

Stop confusion with system copy.

- - - - -
711495b6 by Gary E. Miller at 2017-06-06T19:57:59-07:00
libisc: move isc/error.h to isc_error.h

Stop stepping on the isc namespace.

- - - - -
c9d47e6c by Gary E. Miller at 2017-06-06T20:05:49-07:00
libisc: remove last traces of libisc/include

- - - - -


26 changed files:

- libisc/include/isc/error.h → include/isc_error.h
- libisc/include/isc/interfaceiter.h → include/isc_interfaceiter.h
- include/isc/mem.h → include/isc_mem.h
- libisc/include/isc/netaddr.h → include/isc_netaddr.h
- libisc/include/isc/result.h → include/isc_result.h
- include/ntp_io.h
- include/ntp_net.h
- libisc/error.c
- − libisc/ifiter_getifaddrs.c
- − libisc/ifiter_ioctl.c
- − libisc/ifiter_sysctl.c
- − libisc/include/isc/sockaddr.h
- libisc/interfaceiter.c
- libisc/net.c
- libisc/wscript
- libntp/assert.c
- libntp/initnetwork.c
- libntp/lib_strbuf.c
- libntp/pymodule.c
- libntp/socktoa.c
- libntp/wscript
- ntpd/ntp_config.c
- ntpd/ntp_io.c
- ntpd/ntpd.c
- wafhelpers/waf.py
- wscript


Changes:

=====================================
libisc/include/isc/error.h → include/isc_error.h
=====================================
--- a/libisc/include/isc/error.h
+++ b/include/isc_error.h
@@ -8,7 +8,7 @@
 #ifndef GUARD_ISC_ERROR_H
 #define GUARD_ISC_ERROR_H 1
 
-/*! \file isc/error.h */
+/* isc_error.h */
 
 /*
  * ISC_FORMAT_PRINTF().


=====================================
libisc/include/isc/interfaceiter.h → include/isc_interfaceiter.h
=====================================
--- a/libisc/include/isc/interfaceiter.h
+++ b/include/isc_interfaceiter.h
@@ -12,8 +12,8 @@
  ***** Module Info
  *****/
 
-/*! \file isc/interfaceiter.h
- * \brief Iterates over the list of network interfaces.
+/* isc_interfaceiter.h
+ * Iterates over the list of network interfaces.
  *
  * Interfaces whose address family is not supported are ignored and never
  * returned by the iterator.  Interfaces whose netmask, interface flags,
@@ -28,27 +28,36 @@
  *** Imports
  ***/
 
-#include "isc/netaddr.h"
-#include "isc/result.h"
+#include "isc_result.h"
 
-typedef struct isc_interface	 isc_interface_t;      /* Interface */
 typedef struct isc_interfaceiter isc_interfaceiter_t;  /* Interface Iterator */
 typedef struct isc_mem           isc_mem_t;	       /* Memory */
 
+/* Net Address */
+typedef struct isc_netaddr {
+	unsigned int family;
+	union {
+		struct in_addr in;
+		struct in6_addr in6;
+	} type;
+	uint32_t zone;
+} isc_netaddr_t;	      
+
+
 /*!
  * \brief Public structure describing a network interface.
  */
 
-struct isc_interface {
-	char name[32];			/*%< Interface name, null-terminated. */
-	unsigned int af;		/*%< Address family. */
-	isc_netaddr_t address;		/*%< Local address. */
-	isc_netaddr_t netmask;		/*%< Network mask. */
-	isc_netaddr_t broadcast;	/*&< Broadcast address. */
-	isc_netaddr_t dstaddress; 	/*%< Destination address (point-to-point only). */
-	uint32_t flags;		/*%< Flags; see INTERFACE flags. */
-	unsigned int ifindex;		/*%< Interface index for IP(V6)_MULTICAST_IF. */
-};
+typedef struct isc_interface {
+	char name[32];		   /* Interface name, null-terminated. */
+	unsigned int af;	   /* Address family. */
+	isc_netaddr_t address;	   /* Local address. */
+	isc_netaddr_t netmask;	   /* Network mask. */
+	isc_netaddr_t broadcast;   /* Broadcast address. */
+	isc_netaddr_t dstaddress;  /* Destination address (point-to-point only). */
+	uint32_t flags;		   /* Flags; see INTERFACE flags. */
+	unsigned int ifindex;	   /* Interface index for IP(V6)_MULTICAST_IF. */
+} isc_interface_t;
 
 /*@{*/
 /*! Interface flags. */


=====================================
include/isc/mem.h → include/isc_mem.h
=====================================
--- a/include/isc/mem.h
+++ b/include/isc_mem.h
@@ -17,7 +17,7 @@
 
 #include <stdio.h>
 
-#include "isc/result.h"
+#include "isc_result.h"
 
 #include "ntp_stdlib.h"
 


=====================================
libisc/include/isc/netaddr.h → include/isc_netaddr.h
=====================================
--- a/libisc/include/isc/netaddr.h
+++ b/include/isc_netaddr.h
@@ -8,14 +8,10 @@
 #ifndef GUARD_ISC_NETADDR_H
 #define GUARD_ISC_NETADDR_H 1
 
-/*! \file isc/netaddr.h */
+/* isc_netaddr.h */
 
 #include <stdbool.h>
-/* for struct sockaddr on *BSD */
-#include <sys/socket.h>                /* Contractual promise. */
-
-#include <netinet/in.h>		/* Contractual promise. */
-#include "isc/result.h"
+#include "isc_result.h"
 
 /*
  * Basic Networking Types
@@ -50,9 +46,6 @@
  *	RFC 2553
  */
 
-typedef struct isc_sockaddr	isc_sockaddr_t;		/* Socket Address */
-typedef struct isc_netaddr	isc_netaddr_t;		/* Net Address */
-
 /***
  *** Functions.
  ***/
@@ -91,13 +84,4 @@ isc_net_probeipv6(void);
 bool
 isc_net_probe_ipv6only_bool(void);
 
-struct isc_netaddr {
-	unsigned int family;
-	union {
-		struct in_addr in;
-		struct in6_addr in6;
-	} type;
-	uint32_t zone;
-};
-
 #endif /* GUARD_ISC_NETADDR_H */


=====================================
libisc/include/isc/result.h → include/isc_result.h
=====================================
--- a/libisc/include/isc/result.h
+++ b/include/isc_result.h
@@ -8,7 +8,7 @@
 #ifndef GUARD_ISC_RESULT_H
 #define GUARD_ISC_RESULT_H 1
 
-/* isc/result.h */
+/* isc_result.h */
 
 typedef unsigned int			isc_result_t;	/* Result */
 


=====================================
include/ntp_io.h
=====================================
--- a/include/ntp_io.h
+++ b/include/ntp_io.h
@@ -11,7 +11,7 @@
 #include <fcntl.h>
 #include <netinet/in.h>
 
-#include "isc/netaddr.h"
+#include "isc_netaddr.h"
 
 /*
  * NIC rule match types


=====================================
include/ntp_net.h
=====================================
--- a/include/ntp_net.h
+++ b/include/ntp_net.h
@@ -10,7 +10,7 @@
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netdb.h>
-#include "isc/netaddr.h"  /* use local copy of isc/netddr.h, not system copy */
+#include "isc_netaddr.h"
 
 #include "ntp_malloc.h"
 


=====================================
libisc/error.c
=====================================
--- a/libisc/error.c
+++ b/libisc/error.c
@@ -15,7 +15,7 @@
 #include "ntp_config.h"
 #include "ntp_syslog.h"
 
-#include "isc/error.h"
+#include "isc_error.h"
 
 
 #define MAX_UNEXPECTED_ERRORS 100


=====================================
libisc/ifiter_getifaddrs.c deleted
=====================================
--- a/libisc/ifiter_getifaddrs.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2003  Internet Software Consortium.
- * Copyright 2015 by the NTPsec project contributors
- * SPDX-License-Identifier: ISC
- */
-
-/*! \file
- * \brief
- * Obtain the list of network interfaces using the getifaddrs(3) library.
- */
-
-#include <ifaddrs.h>
-
-#include "ntp_assert.h"
-#include "isc/error.h"
-
-/*% Iterator Magic */
-#define IFITER_MAGIC		ISC_MAGIC('I', 'F', 'I', 'G')
-/*% Valid Iterator */
-#define VALID_IFITER(t)		ISC_MAGIC_VALID(t, IFITER_MAGIC)
-
-#ifdef __linux
-static bool seenv6 = false;
-#endif
-
-/*% Iterator structure */
-struct isc_interfaceiter {
-	unsigned int		magic;		/*%< Magic number. */
-	isc_mem_t		*mctx;
-	void			*buf;		/*%< (unused) */
-	unsigned int		bufsize;	/*%< (always 0) */
-	struct ifaddrs		*ifaddrs;	/*%< List of ifaddrs */
-	struct ifaddrs		*pos;		/*%< Ptr to current ifaddr */
-	isc_interface_t		current;	/*%< Current interface data. */
-	isc_result_t		result;		/*%< Last result code. */
-#ifdef  __linux
-	FILE *                  proc;
-	char                    entry[ISC_IF_INET6_SZ];
-	isc_result_t            valid;
-#endif
-};
-
-isc_result_t
-isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
-	isc_interfaceiter_t *iter;
-	isc_result_t result;
-	char strbuf[BUFSIZ];
-	int trys, ret = 0;
-
-	REQUIRE(mctx != NULL);
-	REQUIRE(iterp != NULL);
-	REQUIRE(*iterp == NULL);
-
-	iter = isc_mem_get(mctx, sizeof(*iter));
-	if (iter == NULL)
-		return (ISC_R_NOMEMORY);
-
-	iter->mctx = mctx;
-	iter->buf = NULL;
-	iter->bufsize = 0;
-	iter->ifaddrs = NULL;
-#ifdef __linux
-	/*
-	 * Only open "/proc/net/if_inet6" if we have never seen a IPv6
-	 * address returned by getifaddrs().
-	 */
-	if (!seenv6) {
-		iter->proc = fopen("/proc/net/if_inet6", "r");
-		if (iter->proc == NULL) {
-			(void)strerror_r(errno, strbuf, sizeof(strbuf));
-/*			isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-				      ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
-				      "failed to open /proc/net/if_inet6");
-*/
-		}
-	} else
-		iter->proc = NULL;
-	iter->valid = ISC_R_FAILURE;
-#endif
-
-	/* If interrupted, try again */
-	for (trys = 0; trys < 3; trys++) {
-		if ((ret = getifaddrs(&iter->ifaddrs)) >= 0)
-			break;
-		if (errno != EINTR)
-			break;
-	}
-	if (ret < 0) {
-		(void)strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("getting interface addresses: getifaddrs: %s",
-				 strbuf);
-		result = ISC_R_UNEXPECTED;
-		goto failure;
-	}
-
-	/*
-	 * A newly created iterator has an undefined position
-	 * until isc_interfaceiter_first() is called.
-	 */
-	iter->pos = NULL;
-	iter->result = ISC_R_FAILURE;
-
-	iter->magic = IFITER_MAGIC;
-	*iterp = iter;
-	return (ISC_R_SUCCESS);
-
- failure:
-#ifdef __linux
-	if (iter->proc != NULL)
-		fclose(iter->proc);
-#endif
-	if (iter->ifaddrs != NULL) /* just in case */
-		freeifaddrs(iter->ifaddrs);
-	isc_mem_put(mctx, iter, sizeof(*iter));
-	return (result);
-}
-
-/*
- * Get information about the current interface to iter->current.
- * If successful, return ISC_R_SUCCESS.
- * If the interface has an unsupported address family,
- * return ISC_R_IGNORE.
- */
-
-static isc_result_t
-internal_current(isc_interfaceiter_t *iter) {
-	struct ifaddrs *ifa;
-	int family;
-	unsigned int namelen;
-
-	REQUIRE(VALID_IFITER(iter));
-
-	ifa = iter->pos;
-
-#ifdef __linux
-	/*
-	 * [Bug 2792]
-	 * burnicki: iter->pos is usually never NULL here (anymore?),
-	 * so linux_if_inet6_current(iter) is never called here.
-	 * However, that routine would check (under Linux), if the
-	 * interface is in a tentative state, e.g. if there's no link
-	 * yet but an IPv6 address has already be assigned.
-	 */
-	if (iter->pos == NULL)
-		return (linux_if_inet6_current(iter));
-#endif
-
-	INSIST(ifa != NULL);
-	INSIST(ifa->ifa_name != NULL);
-
-
-#ifdef IFF_RUNNING
-	/*
-	 * [Bug 2792]
-	 * burnicki: if the interface is not running then
-	 * it may be in a tentative state. See above.
-	 */
-	if ((ifa->ifa_flags & IFF_RUNNING) == 0)
-		return (ISC_R_IGNORE);
-#endif
-
-	if (ifa->ifa_addr == NULL)
-		return (ISC_R_IGNORE);
-
-	family = ifa->ifa_addr->sa_family;
-	if (family != AF_INET && family != AF_INET6)
-		return (ISC_R_IGNORE);
-
-#ifdef __linux
-	if (family == AF_INET6)
-		seenv6 = true;
-#endif
-
-	memset(&iter->current, 0, sizeof(iter->current));
-
-	namelen = (unsigned int)strlen(ifa->ifa_name);
-	if (namelen > sizeof(iter->current.name) - 1)
-		namelen = sizeof(iter->current.name) - 1;
-
-	memset(iter->current.name, 0, sizeof(iter->current.name));
-	memcpy(iter->current.name, ifa->ifa_name, namelen);
-
-	iter->current.flags = 0;
-
-	if ((ifa->ifa_flags & IFF_UP) != 0)
-		iter->current.flags |= INTERFACE_F_UP;
-
-	if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0)
-		iter->current.flags |= INTERFACE_F_POINTTOPOINT;
-
-	if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
-		iter->current.flags |= INTERFACE_F_LOOPBACK;
-
-	if ((ifa->ifa_flags & IFF_BROADCAST) != 0)
-		iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-	if ((ifa->ifa_flags & IFF_MULTICAST) != 0)
-		iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
-	iter->current.af = (unsigned int)family;
-
-	get_addr((unsigned int)family, &iter->current.address,
-                  ifa->ifa_addr, ifa->ifa_name);
-
-	if (ifa->ifa_netmask != NULL)
-		get_addr((unsigned int)family, &iter->current.netmask, ifa->ifa_netmask,
-			 ifa->ifa_name);
-
-	if (ifa->ifa_dstaddr != NULL &&
-	    (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
-		get_addr((unsigned int)family, &iter->current.dstaddress,
-                         ifa->ifa_dstaddr,
-			 ifa->ifa_name);
-
-	if (ifa->ifa_broadaddr != NULL &&
-	    (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
-		get_addr((unsigned int)family, &iter->current.broadcast,
-                         ifa->ifa_broadaddr,
-			 ifa->ifa_name);
-
-	iter->current.ifindex = if_nametoindex(iter->current.name);
-	return (ISC_R_SUCCESS);
-}
-
-/*
- * Step the iterator to the next interface.  Unlike
- * isc_interfaceiter_next(), this may leave the iterator
- * positioned on an interface that will ultimately
- * be ignored.  Return ISC_R_NOMORE if there are no more
- * interfaces, otherwise ISC_R_SUCCESS.
- */
-static isc_result_t
-internal_next(isc_interfaceiter_t *iter) {
-
-	if (iter->pos != NULL)
-		iter->pos = iter->pos->ifa_next;
-	if (iter->pos == NULL) {
-#ifdef __linux
-		if (!seenv6)
-			return (linux_if_inet6_next(iter));
-#endif
-		return (ISC_R_NOMORE);
-	}
-
-	return (ISC_R_SUCCESS);
-}
-
-static void
-internal_destroy(isc_interfaceiter_t *iter) {
-
-#ifdef __linux
-	if (iter->proc != NULL)
-		fclose(iter->proc);
-	iter->proc = NULL;
-#endif
-	if (iter->ifaddrs)
-		freeifaddrs(iter->ifaddrs);
-	iter->ifaddrs = NULL;
-}
-
-static
-void internal_first(isc_interfaceiter_t *iter) {
-
-#ifdef __linux
-	linux_if_inet6_first(iter);
-#endif
-	iter->pos = iter->ifaddrs;
-}


=====================================
libisc/ifiter_ioctl.c deleted
=====================================
--- a/libisc/ifiter_ioctl.c
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003  Internet Software Consortium.
- * Copyright 2015 by the NTPsec project contributors
- * SPDX-License-Identifier: ISC
- */
-
-/*! \file
- * \brief
- * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
- * See netintro(4).
- */
-
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-#ifdef HAVE_STRUCT_IF_LADDRCONF
-#define lifc_len iflc_len
-#define lifc_buf iflc_buf
-#define lifc_req iflc_req
-#define LIFCONF if_laddrconf
-#else
-#define USE_LIFC_FAMILY 1
-#define USE_LIFC_FLAGS 1
-#define LIFCONF lifconf
-#endif
-
-#ifdef HAVE_STRUCT_IF_LADDRREQ
-#define lifr_addr iflr_addr
-#define lifr_name iflr_name
-#define lifr_dstaddr iflr_dstaddr
-#define lifr_broadaddr iflr_broadaddr
-#define lifr_flags iflr_flags
-#define lifr_index iflr_index
-#define ss_family sa_family
-#define LIFREQ if_laddrreq
-#else
-#define LIFREQ lifreq
-#endif
-#endif
-
-#define IFITER_MAGIC		ISC_MAGIC('I', 'F', 'I', 'T')
-#define VALID_IFITER(t)		ISC_MAGIC_VALID(t, IFITER_MAGIC)
-
-struct isc_interfaceiter {
-	unsigned int		magic;		/* Magic number. */
-	isc_mem_t		*mctx;
-	int			mode;
-	int			socket;
-	struct ifconf 		ifc;
-	void			*buf;		/* Buffer for sysctl data. */
-	unsigned int		bufsize;	/* Bytes allocated. */
-	unsigned int		pos;		/* Current offset in
-						   SIOCGIFCONF data */
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	int			socket6;
-	struct LIFCONF 		lifc;
-	void			*buf6;		/* Buffer for sysctl data. */
-	unsigned int		bufsize6;	/* Bytes allocated. */
-	unsigned int		pos6;		/* Current offset in
-						   SIOCGLIFCONF data */
-	isc_result_t		result6;	/* Last result code. */
-	bool		first6;
-#endif
-#ifdef	__linux
-	FILE *			proc;
-	char			entry[ISC_IF_INET6_SZ];
-	isc_result_t		valid;
-#endif
-	isc_interface_t		current;	/* Current interface data. */
-	isc_result_t		result;		/* Last result code. */
-};
-
-/*%
- * Size of buffer for SIOCGLIFCONF, in bytes.  We assume no sane system
- * will have more than a megabyte of interface configuration data.
- */
-#define IFCONF_BUFSIZE_INITIAL	4096
-#define IFCONF_BUFSIZE_MAX	1048576
-
-#ifdef __linux
-#ifndef IF_NAMESIZE
-# ifdef IFNAMSIZ
-#  define IF_NAMESIZE  IFNAMSIZ
-# else
-#  define IF_NAMESIZE 16
-# endif
-#endif
-#endif
-
-static int
-isc_ioctl(int fildes, int req, char *arg);
-
-static int
-isc_ioctl(int fildes, int req, char *arg) {
-	int trys;
-	int ret;
-
-	for (trys = 0; trys < 3; trys++) {
-		if ((ret = ioctl(fildes, req, arg)) < 0) {
-			if (errno == EINTR)
-				continue;
-		}
-		break;
-	}
-	return (ret);
-}
-
-static isc_result_t
-getbuf4(isc_interfaceiter_t *iter) {
-	char strbuf[BUFSIZ];
-
-	iter->bufsize = IFCONF_BUFSIZE_INITIAL;
-
-	for (;;) {
-		iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
-		if (iter->buf == NULL)
-			return (ISC_R_NOMEMORY);
-
-		memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len));
-		iter->ifc.ifc_len = iter->bufsize;
-		iter->ifc.ifc_buf = iter->buf;
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion".  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc)
-		    == -1) {
-			if (errno != EINVAL) {
-				strerror_r(errno, strbuf, sizeof(strbuf));
-				UNEXPECTED_ERROR("get interface "
-						 "configuration: %s",
-						 strbuf);
-				goto unexpected;
-			}
-			/*
-			 * EINVAL.  Retry with a bigger buffer.
-			 */
-		} else {
-			/*
-			 * The ioctl succeeded.
-			 * Some OS's just return what will fit rather
-			 * than set EINVAL if the buffer is too small
-			 * to fit all the interfaces in.  If
-			 * ifc.lifc_len is too near to the end of the
-			 * buffer we will grow it just in case and
-			 * retry.
-			 */
-			if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq)
-			    < iter->bufsize)
-				break;
-		}
-		if (iter->bufsize >= IFCONF_BUFSIZE_MAX) {
-			UNEXPECTED_ERROR("get interface configuration: "
-					 "maximum buffer size exceeded");
-			goto unexpected;
-		}
-		isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
-
-		iter->bufsize *= 2;
-	}
-	return (ISC_R_SUCCESS);
-
- unexpected:
-	isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
-	iter->buf = NULL;
-	return (ISC_R_UNEXPECTED);
-}
-
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-static isc_result_t
-getbuf6(isc_interfaceiter_t *iter) {
-	char strbuf[BUFSIZ];
-	isc_result_t result;
-
-	iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;
-
-	for (;;) {
-		iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);
-		if (iter->buf6 == NULL)
-			return (ISC_R_NOMEMORY);
-
-		memset(&iter->lifc, 0, sizeof(iter->lifc));
-#ifdef USE_LIFC_FAMILY
-		iter->lifc.lifc_family = AF_INET6;
-#endif
-#ifdef USE_LIFC_FLAGS
-		iter->lifc.lifc_flags = 0;
-#endif
-		iter->lifc.lifc_len = iter->bufsize6;
-		iter->lifc.lifc_buf = iter->buf6;
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion".  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)
-		    == -1) {
-#ifdef __hpux
-			/*
-			 * IPv6 interface scanning is not available on all
-			 * kernels w/ IPv6 sockets.
-			 */
-			if (errno == ENOENT) {
-				strerror_r(errno, strbuf, sizeof(strbuf));
-				isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-					      ISC_LOGMODULE_INTERFACE,
-					      ISC_LOG_DEBUG(1),
-							"get interface "
-							"configuration: %s",
-					       strbuf);
-				result = ISC_R_FAILURE;
-				goto cleanup;
-			}
-#endif
-			if (errno != EINVAL) {
-				strerror_r(errno, strbuf, sizeof(strbuf));
-				UNEXPECTED_ERROR("get interface "
-						 "configuration: %s",
-						 strbuf);
-				result = ISC_R_UNEXPECTED;
-				goto cleanup;
-			}
-			/*
-			 * EINVAL.  Retry with a bigger buffer.
-			 */
-		} else {
-			/*
-			 * The ioctl succeeded.
-			 * Some OS's just return what will fit rather
-			 * than set EINVAL if the buffer is too small
-			 * to fit all the interfaces in.  If
-			 * ifc.ifc_len is too near to the end of the
-			 * buffer we will grow it just in case and
-			 * retry.
-			 */
-			if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ)
-			    < iter->bufsize6)
-				break;
-		}
-		if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) {
-			UNEXPECTED_ERROR("get interface configuration: "
-					 "maximum buffer size exceeded");
-			result = ISC_R_UNEXPECTED;
-			goto cleanup;
-		}
-		isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
-
-		iter->bufsize6 *= 2;
-	}
-
-	if (iter->lifc.lifc_len != 0)
-		iter->mode = 6;
-	return (ISC_R_SUCCESS);
-
- cleanup:
-	isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
-	iter->buf6 = NULL;
-	return (result);
-}
-#endif
-
-isc_result_t
-isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
-	isc_interfaceiter_t *iter;
-	isc_result_t result;
-	char strbuf[BUFSIZ];
-
-	REQUIRE(mctx != NULL);
-	REQUIRE(iterp != NULL);
-	REQUIRE(*iterp == NULL);
-
-	iter = isc_mem_get(mctx, sizeof(*iter));
-	if (iter == NULL)
-		return (ISC_R_NOMEMORY);
-
-	iter->mctx = mctx;
-	iter->mode = 4;
-	iter->buf = NULL;
-	iter->pos = (unsigned int) -1;
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	iter->buf6 = NULL;
-	iter->pos6 = (unsigned int) -1;
-	iter->result6 = ISC_R_NOMORE;
-	iter->socket6 = -1;
-	iter->first6 = false;
-#endif
-
-	/*
-	 * Get the interface configuration, allocating more memory if
-	 * necessary.
-	 */
-
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	result = isc_net_probeipv6();
-	if (result == ISC_R_SUCCESS) {
-		/*
-		 * Create an unbound datagram socket to do the SIOCGLIFCONF
-		 * ioctl on.  HP/UX requires an AF_INET6 socket for
-		 * SIOCGLIFCONF to get IPv6 addresses.
-		 */
-		if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-			strerror_r(errno, strbuf, sizeof(strbuf));
-			UNEXPECTED_ERROR("making interface scan socket: %s",
-					 strbuf);
-			result = ISC_R_UNEXPECTED;
-			goto socket6_failure;
-		}
-		result = iter->result6 = getbuf6(iter);
-		if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS)
-			goto ioctl6_failure;
-	}
-#endif
-	if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("making interface scan socket: %s",
-				 strbuf);
-		result = ISC_R_UNEXPECTED;
-		goto socket_failure;
-	}
-	result = getbuf4(iter);
-	if (result != ISC_R_SUCCESS)
-		goto ioctl_failure;
-
-	/*
-	 * A newly created iterator has an undefined position
-	 * until isc_interfaceiter_first() is called.
-	 */
-#ifdef __linux
-	iter->proc = fopen("/proc/net/if_inet6", "r");
-	iter->valid = ISC_R_FAILURE;
-#endif
-	iter->result = ISC_R_FAILURE;
-
-	iter->magic = IFITER_MAGIC;
-	*iterp = iter;
-	return (ISC_R_SUCCESS);
-
- ioctl_failure:
-	if (iter->buf != NULL)
-		isc_mem_put(mctx, iter->buf, iter->bufsize);
-	(void) close(iter->socket);
-
- socket_failure:
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	if (iter->buf6 != NULL)
-		isc_mem_put(mctx, iter->buf6, iter->bufsize6);
-  ioctl6_failure:
-	if (iter->socket6 != -1)
-		(void) close(iter->socket6);
-  socket6_failure:
-#endif
-
-	isc_mem_put(mctx, iter, sizeof(*iter));
-	return (result);
-}
-
-/*
- * Get information about the current interface to iter->current.
- * If successful, return ISC_R_SUCCESS.
- * If the interface has an unsupported address family, or if
- * some operation on it fails, return ISC_R_IGNORE to make
- * the higher-level iterator code ignore it.
- */
-
-static isc_result_t
-internal_current4(isc_interfaceiter_t *iter) {
-	struct ifreq *ifrp;
-	struct ifreq ifreq;
-	int family;
-	char strbuf[BUFSIZ];
-#if !defined(HAVE_STRUCT_IF_LADDRREQ) && defined(SIOCGLIFADDR)
-	struct lifreq lifreq;
-#else
-	char sabuf[256];
-#endif
-	int i, bits, prefixlen;
-
-	REQUIRE(VALID_IFITER(iter));
-
-	if (iter->ifc.ifc_len == 0 ||
-	    iter->pos == (unsigned int)iter->ifc.ifc_len) {
-#ifdef __linux
-		return (linux_if_inet6_current(iter));
-#else
-		return (ISC_R_NOMORE);
-#endif
-	}
-
-	INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len);
-
-	ifrp = (void *)((char *) iter->ifc.ifc_req + iter->pos);
-
-	memset(&ifreq, 0, sizeof(ifreq));
-	memcpy(&ifreq, ifrp, sizeof(ifreq));
-
-	family = ifreq.ifr_addr.sa_family;
-	if (family != AF_INET && family != AF_INET6)
-		return (ISC_R_IGNORE);
-
-	memset(&iter->current, 0, sizeof(iter->current));
-	iter->current.af = family;
-
-	INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name));
-	memset(iter->current.name, 0, sizeof(iter->current.name));
-	memcpy(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
-
-	get_addr(family, &iter->current.address,
-		 (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name);
-
-	/*
-	 * If the interface does not have a address ignore it.
-	 */
-	switch (family) {
-	case AF_INET:
-		if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
-			return (ISC_R_IGNORE);
-		break;
-	case AF_INET6:
-		if (memcmp(&iter->current.address.type.in6, &in6addr_any,
-			   sizeof(in6addr_any)) == 0)
-			return (ISC_R_IGNORE);
-		break;
-	}
-
-	/*
-	 * Get interface flags.
-	 */
-
-	iter->current.flags = 0;
-
-	/*
-	 * Ignore the HP/UX warning about "integer overflow during
-	 * conversion.  It comes from its own macro definition,
-	 * and is really hard to shut up.
-	 */
-	if (isc_ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("%s: getting interface flags: %s",
-				 ifreq.ifr_name, strbuf);
-		return (ISC_R_IGNORE);
-	}
-
-	if ((ifreq.ifr_flags & IFF_UP) != 0)
-		iter->current.flags |= INTERFACE_F_UP;
-
-#ifdef IFF_POINTOPOINT
-	if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0)
-		iter->current.flags |= INTERFACE_F_POINTTOPOINT;
-#endif
-
-	if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
-		iter->current.flags |= INTERFACE_F_LOOPBACK;
-
-	if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
-		iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-	if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
-		iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
-	if (family == AF_INET)
-		goto inet;
-
-	memset(&lifreq, 0, sizeof(lifreq));
-	memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name));
-	memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6,
-	       sizeof(iter->current.address.type.in6));
-
-	if (isc_ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("%s: getting interface address: %s",
-				 ifreq.ifr_name, strbuf);
-		return (ISC_R_IGNORE);
-	}
-	prefixlen = lifreq.lifr_addrlen;
-
-	/*
-	 * Netmask already zeroed.
-	 */
-	iter->current.netmask.family = family;
-	for (i = 0; i < 16; i++) {
-		if (prefixlen > 8) {
-			bits = 0;
-			prefixlen -= 8;
-		} else {
-			bits = 8 - prefixlen;
-			prefixlen = 0;
-		}
-		iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff;
-	}
-	iter->current.ifindex = if_nametoindex(iter->current.name);
-	return (ISC_R_SUCCESS);
-
- inet:
-	if (family != AF_INET)
-		return (ISC_R_IGNORE);
-#ifdef IFF_POINTOPOINT
-	/*
-	 * If the interface is point-to-point, get the destination address.
-	 */
-	if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion.  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq)
-		    < 0) {
-			strerror_r(errno, strbuf, sizeof(strbuf));
-			UNEXPECTED_ERROR("%s: getting destination address: %s",
-					 ifreq.ifr_name, strbuf);
-			return (ISC_R_IGNORE);
-		}
-		get_addr(family, &iter->current.dstaddress,
-			 (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name);
-	}
-#endif
-
-	if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion.  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(iter->socket, SIOCGIFBRDADDR, (char *)&ifreq)
-		    < 0) {
-			strerror_r(errno, strbuf, sizeof(strbuf));
-			UNEXPECTED_ERROR("%s: getting broadcast address: %s",
-					 ifreq.ifr_name, strbuf);
-			return (ISC_R_IGNORE);
-		}
-		get_addr(family, &iter->current.broadcast,
-			 (struct sockaddr *)&ifreq.ifr_broadaddr, ifreq.ifr_name);
-	}
-
-	/*
-	 * Get the network mask.
-	 */
-	memset(&ifreq, 0, sizeof(ifreq));
-	memcpy(&ifreq, ifrp, sizeof(ifreq));
-	/*
-	 * Ignore the HP/UX warning about "integer overflow during
-	 * conversion.  It comes from its own macro definition,
-	 * and is really hard to shut up.
-	 */
-	if (isc_ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("%s: getting netmask: %s",
-				 ifreq.ifr_name, strbuf);
-		return (ISC_R_IGNORE);
-	}
-	get_addr(family, &iter->current.netmask,
-		 (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name);
-	iter->current.ifindex = if_nametoindex(iter->current.name);
-	return (ISC_R_SUCCESS);
-}
-
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-static isc_result_t
-internal_current6(isc_interfaceiter_t *iter) {
-	struct LIFREQ *ifrp;
-	struct LIFREQ lifreq;
-	int family;
-	char strbuf[BUFSIZ];
-	int fd;
-
-	REQUIRE(VALID_IFITER(iter));
-	if (iter->result6 != ISC_R_SUCCESS)
-		return (iter->result6);
-	REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
-
-	ifrp = (void *)((char *)iter->lifc.lifc_req + iter->pos6);
-
-	memset(&lifreq, 0, sizeof(lifreq));
-	memcpy(&lifreq, ifrp, sizeof(lifreq));
-
-	family = lifreq.lifr_addr.ss_family;
-	if (family != AF_INET && family != AF_INET6)
-		return (ISC_R_IGNORE);
-
-	memset(&iter->current, 0, sizeof(iter->current));
-	iter->current.af = family;
-
-	INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name));
-	memset(iter->current.name, 0, sizeof(iter->current.name));
-	memcpy(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name));
-
-	get_addr(family, &iter->current.address,
-		 (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
-
-	if (isc_netaddr_islinklocal(&iter->current.address))
-		isc_netaddr_setzone(&iter->current.address, 
-				    (uint32_t)lifreq.lifr_index);
-
-	/*
-	 * If the interface does not have a address ignore it.
-	 */
-	switch (family) {
-	case AF_INET:
-		if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
-			return (ISC_R_IGNORE);
-		break;
-	case AF_INET6:
-		if (memcmp(&iter->current.address.type.in6, &in6addr_any,
-			   sizeof(in6addr_any)) == 0)
-			return (ISC_R_IGNORE);
-		break;
-	}
-
-	/*
-	 * Get interface flags.
-	 */
-
-	iter->current.flags = 0;
-
-	if (family == AF_INET6)
-		fd = iter->socket6;
-	else
-		fd = iter->socket;
-
-	/*
-	 * Ignore the HP/UX warning about "integer overflow during
-	 * conversion.  It comes from its own macro definition,
-	 * and is really hard to shut up.
-	 */
-	if (isc_ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("%s: getting interface flags: %s",
-				 lifreq.lifr_name, strbuf);
-		return (ISC_R_IGNORE);
-	}
-
-	if ((lifreq.lifr_flags & IFF_UP) != 0)
-		iter->current.flags |= INTERFACE_F_UP;
-
-#ifdef IFF_POINTOPOINT
-	if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0)
-		iter->current.flags |= INTERFACE_F_POINTTOPOINT;
-#endif
-
-	if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
-		iter->current.flags |= INTERFACE_F_LOOPBACK;
-
-	if ((lifreq.lifr_flags & IFF_BROADCAST) != 0) {
-		iter->current.flags |= INTERFACE_F_BROADCAST;
-	}
-
-#ifdef IFF_MULTICAST
-	if ((lifreq.lifr_flags & IFF_MULTICAST) != 0) {
-		iter->current.flags |= INTERFACE_F_MULTICAST;
-	}
-#endif
-
-#ifdef IFF_POINTOPOINT
-	/*
-	 * If the interface is point-to-point, get the destination address.
-	 */
-	if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion.  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq)
-		    < 0) {
-			strerror_r(errno, strbuf, sizeof(strbuf));
-			UNEXPECTED_ERROR("%s: getting destination address: %s",
-					 lifreq.lifr_name, strbuf);
-			return (ISC_R_IGNORE);
-		}
-		get_addr(family, &iter->current.dstaddress,
-			 (struct sockaddr *)&lifreq.lifr_dstaddr,
-			 lifreq.lifr_name);
-	}
-#endif
-
-#ifdef SIOCGLIFBRDADDR
-	if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
-		/*
-		 * Ignore the HP/UX warning about "integer overflow during
-		 * conversion.  It comes from its own macro definition,
-		 * and is really hard to shut up.
-		 */
-		if (isc_ioctl(iter->socket, SIOCGLIFBRDADDR, (char *)&lifreq)
-		    < 0) {
-			strerror_r(errno, strbuf, sizeof(strbuf));
-			UNEXPECTED_ERROR("%s: getting broadcast address: %s",
-					 lifreq.lifr_name, strbuf);
-			return (ISC_R_IGNORE);
-		}
-		get_addr(family, &iter->current.broadcast,
-			 (struct sockaddr *)&lifreq.lifr_broadaddr,
-			 lifreq.lifr_name);
-	}
-#endif	/* SIOCGLIFBRDADDR */
-
-	/*
-	 * Get the network mask.  Netmask already zeroed.
-	 */
-	memset(&lifreq, 0, sizeof(lifreq));
-	memcpy(&lifreq, ifrp, sizeof(lifreq));
-
-#ifdef lifr_addrlen
-	/*
-	 * Special case: if the system provides lifr_addrlen member, the
-	 * netmask of an IPv6 address can be derived from the length, since
-	 * an IPv6 address always has a contiguous mask.
-	 */
-	if (family == AF_INET6) {
-		int i, bits;
-
-		iter->current.netmask.family = family;
-		for (i = 0; i < lifreq.lifr_addrlen; i += 8) {
-			bits = lifreq.lifr_addrlen - i;
-			bits = (bits < 8) ? (8 - bits) : 0;
-			iter->current.netmask.type.in6.s6_addr[i / 8] =
-				(~0 << bits) & 0xff;
-		}
-		iter->current.ifindex = if_nametoindex(iter->current.name);
-		return (ISC_R_SUCCESS);
-	}
-#endif
-
-	/*
-	 * Ignore the HP/UX warning about "integer overflow during
-	 * conversion.  It comes from its own macro definition,
-	 * and is really hard to shut up.
-	 */
-	if (isc_ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("%s: getting netmask: %s",
-				 lifreq.lifr_name, strbuf);
-		return (ISC_R_IGNORE);
-	}
-	get_addr(family, &iter->current.netmask,
-		 (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
-
-	iter->current.ifindex = if_nametoindex(iter->current.name);
-	return (ISC_R_SUCCESS);
-}
-#endif
-
-static isc_result_t
-internal_current(isc_interfaceiter_t *iter) {
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	if (iter->mode == 6) {
-		iter->result6 = internal_current6(iter);
-		if (iter->result6 != ISC_R_NOMORE)
-			return (iter->result6);
-	}
-#endif
-	return (internal_current4(iter));
-}
-
-/*
- * Step the iterator to the next interface.  Unlike
- * isc_interfaceiter_next(), this may leave the iterator
- * positioned on an interface that will ultimately
- * be ignored.  Return ISC_R_NOMORE if there are no more
- * interfaces, otherwise ISC_R_SUCCESS.
- */
-static isc_result_t
-internal_next4(isc_interfaceiter_t *iter) {
-#ifdef ISC_PLATFORM_HAVESALEN
-	struct ifreq *ifrp;
-#endif
-
-	if (iter->pos < (unsigned int) iter->ifc.ifc_len) {
-#ifdef ISC_PLATFORM_HAVESALEN
-		ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
-
-		if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
-			iter->pos += sizeof(ifrp->ifr_name) +
-				     ifrp->ifr_addr.sa_len;
-		else
-#endif
-			iter->pos += sizeof(struct ifreq);
-
-	} else {
-		INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len);
-#ifdef __linux
-		return (linux_if_inet6_next(iter));
-#else
-		return (ISC_R_NOMORE);
-#endif
-	}
-	return (ISC_R_SUCCESS);
-}
-
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-static isc_result_t
-internal_next6(isc_interfaceiter_t *iter) {
-#ifdef ISC_PLATFORM_HAVESALEN
-	struct LIFREQ *ifrp;
-#endif
-
-	if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE)
-		return (iter->result6);
-
-	REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
-
-#ifdef ISC_PLATFORM_HAVESALEN
-	ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
-
-	if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr))
-		iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
-	else
-#endif
-		iter->pos6 += sizeof(struct LIFREQ);
-
-	if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len)
-		return (ISC_R_NOMORE);
-
-	return (ISC_R_SUCCESS);
-}
-#endif
-
-static isc_result_t
-internal_next(isc_interfaceiter_t *iter) {
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	if (iter->mode == 6) {
-		iter->result6 = internal_next6(iter);
-		if (iter->result6 != ISC_R_NOMORE)
-			return (iter->result6);
-		if (iter->first6) {
-			iter->first6 = false;
-			return (ISC_R_SUCCESS);
-		}
-	}
-#endif
-	return (internal_next4(iter));
-}
-
-static void
-internal_destroy(isc_interfaceiter_t *iter) {
-	(void) close(iter->socket);
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	if (iter->socket6 != -1)
-		(void) close(iter->socket6);
-	if (iter->buf6 != NULL) {
-		isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
-	}
-#endif
-#ifdef __linux
-	if (iter->proc != NULL)
-		fclose(iter->proc);
-#endif
-}
-
-static
-void internal_first(isc_interfaceiter_t *iter) {
-	iter->pos = 0;
-#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
-	iter->pos6 = 0;
-	if (iter->result6 == ISC_R_NOMORE)
-		iter->result6 = ISC_R_SUCCESS;
-	iter->first6 = true;
-#endif
-#ifdef __linux
-	linux_if_inet6_first(iter);
-#endif
-}


=====================================
libisc/ifiter_sysctl.c deleted
=====================================
--- a/libisc/ifiter_sysctl.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003  Internet Software Consortium.
- * Copyright 2015 by the NTPsec project contributors
- * SPDX-License-Identifier: ISC
- */
-
-/*! \file
- * \brief
- * Obtain the list of network interfaces using sysctl.
- * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14,
- * and 19.16.
- */
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-
-#include <net/route.h>
-#include <net/if_dl.h>
-
-#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
-                    : sizeof(long))
-
-#define IFITER_MAGIC		ISC_MAGIC('I', 'F', 'I', 'S')
-#define VALID_IFITER(t)		ISC_MAGIC_VALID(t, IFITER_MAGIC)
-
-struct isc_interfaceiter {
-	unsigned int		magic;		/* Magic number. */
-	isc_mem_t		*mctx;
-	void			*buf;		/* Buffer for sysctl data. */
-	unsigned int		bufsize;	/* Bytes allocated. */
-	unsigned int		bufused;	/* Bytes used. */
-	unsigned int		pos;		/* Current offset in
-						   sysctl data. */
-	isc_interface_t		current;	/* Current interface data. */
-	isc_result_t		result;		/* Last result code. */
-};
-
-static int mib[6] = {
-	CTL_NET,
-	PF_ROUTE,
-        0,
-	0, 			/* Any address family. */
-        NET_RT_IFLIST,
-	0 			/* Flags. */
-};
-
-isc_result_t
-isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
-	isc_interfaceiter_t *iter;
-	isc_result_t result;
-	size_t bufsize;
-	size_t bufused;
-	char strbuf[BUFSIZ];
-
-	REQUIRE(mctx != NULL);
-	REQUIRE(iterp != NULL);
-	REQUIRE(*iterp == NULL);
-
-	iter = isc_mem_get(mctx, sizeof(*iter));
-	if (iter == NULL)
-		return (ISC_R_NOMEMORY);
-
-	iter->mctx = mctx;
-	iter->buf = 0;
-
-	/*
-	 * Determine the amount of memory needed.
-	 */
-	bufsize = 0;
-	if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("getting interface list size: sysctl: %s",
-				 strbuf);
-		result = ISC_R_UNEXPECTED;
-		goto failure;
-	}
-	iter->bufsize = bufsize;
-
-	iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
-	if (iter->buf == NULL) {
-		result = ISC_R_NOMEMORY;
-		goto failure;
-	}
-
-	bufused = bufsize;
-	if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) {
-		strerror_r(errno, strbuf, sizeof(strbuf));
-		UNEXPECTED_ERROR("getting interface list: sysctl: %s",
-				 strbuf);
-		result = ISC_R_UNEXPECTED;
-		goto failure;
-	}
-	iter->bufused = bufused;
-	INSIST(iter->bufused <= iter->bufsize);
-
-	/*
-	 * A newly created iterator has an undefined position
-	 * until isc_interfaceiter_first() is called.
-	 */
-	iter->pos = (unsigned int) -1;
-	iter->result = ISC_R_FAILURE;
-
-	iter->magic = IFITER_MAGIC;
-	*iterp = iter;
-	return (ISC_R_SUCCESS);
-
- failure:
-	if (iter->buf != NULL)
-		isc_mem_put(mctx, iter->buf, iter->bufsize);
-	isc_mem_put(mctx, iter, sizeof(*iter));
-	return (result);
-}
-
-/*
- * Get information about the current interface to iter->current.
- * If successful, return ISC_R_SUCCESS.
- * If the interface has an unsupported address family,
- * return ISC_R_IGNORE.  In case of other failure,
- * return ISC_R_UNEXPECTED.
- */
-
-static isc_result_t
-internal_current(isc_interfaceiter_t *iter) {
-	struct ifa_msghdr *ifam, *ifam_end;
-
-	REQUIRE(VALID_IFITER(iter));
-	REQUIRE (iter->pos < (unsigned int) iter->bufused);
-
-	ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
-	ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused);
-
-	// Skip wrong RTM version headers
-	if (ifam->ifam_version != RTM_VERSION)
-		return (ISC_R_IGNORE);
-
-	if (ifam->ifam_type == RTM_IFINFO) {
-		struct if_msghdr *ifm = (struct if_msghdr *) ifam;
-		struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1);
-		unsigned int namelen;
-
-		memset(&iter->current, 0, sizeof(iter->current));
-
-		iter->current.ifindex = sdl->sdl_index;
-		namelen = sdl->sdl_nlen;
-		if (namelen > sizeof(iter->current.name) - 1)
-			namelen = sizeof(iter->current.name) - 1;
-
-		memset(iter->current.name, 0, sizeof(iter->current.name));
-		memcpy(iter->current.name, sdl->sdl_data, namelen);
-
-		iter->current.flags = 0;
-
-		if ((ifam->ifam_flags & IFF_UP) != 0)
-			iter->current.flags |= INTERFACE_F_UP;
-
-		if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0)
-			iter->current.flags |= INTERFACE_F_POINTTOPOINT;
-
-		if ((ifam->ifam_flags & IFF_LOOPBACK) != 0)
-			iter->current.flags |= INTERFACE_F_LOOPBACK;
-
-		if ((ifam->ifam_flags & IFF_BROADCAST) != 0)
-			iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-		if ((ifam->ifam_flags & IFF_MULTICAST) != 0)
-			iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
-		/*
-		 * This is not an interface address.
-		 * Force another iteration.
-		 */
-		return (ISC_R_IGNORE);
-	} else if (ifam->ifam_type == RTM_NEWADDR) {
-		int i;
-		int family;
-		struct sockaddr *mask_sa = NULL;
-		struct sockaddr *addr_sa = NULL;
-		struct sockaddr *dst_sa = NULL;
-
-		struct sockaddr *sa = (struct sockaddr *)(ifam + 1);
-		family = sa->sa_family;
-
-		for (i = 0; i < RTAX_MAX; i++)
-		{
-			if ((ifam->ifam_addrs & (1 << i)) == 0)
-				continue;
-
-			INSIST(sa < (struct sockaddr *) ifam_end);
-
-			switch (i) {
-			case RTAX_NETMASK: /* Netmask */
-				mask_sa = sa;
-				break;
-			case RTAX_IFA: /* Interface address */
-				addr_sa = sa;
-				break;
-			case RTAX_BRD: /* Broadcast or destination address */
-				dst_sa = sa;
-				break;
-			}
-#ifdef ISC_PLATFORM_HAVESALEN
-			sa = (struct sockaddr *)((char*)(sa)
-					 + ROUNDUP(sa->sa_len));
-#else
-			/* XXX untested. */
-			sa = (struct sockaddr *)((char*)(sa)
-					 + ROUNDUP(sizeof(struct sockaddr)));
-#endif
-		}
-
-		if (addr_sa == NULL)
-			return (ISC_R_IGNORE);
-
-		family = addr_sa->sa_family;
-		if (family != AF_INET && family != AF_INET6)
-			return (ISC_R_IGNORE);
-
-		iter->current.af = family;
-
-		get_addr(family, &iter->current.address, addr_sa,
-			 iter->current.name);
-
-		if (mask_sa != NULL)
-			get_addr(family, &iter->current.netmask, mask_sa,
-				 iter->current.name);
-
-		if (dst_sa != NULL &&
-		    (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
-			get_addr(family, &iter->current.dstaddress, dst_sa,
-				 iter->current.name);
-
-		if (dst_sa != NULL &&
-		    (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
-			get_addr(family, &iter->current.broadcast, dst_sa,
-				 iter->current.name);
-
-		return (ISC_R_SUCCESS);
-	} else {
-		printf("warning: unexpected interface list message type\n");
-		return (ISC_R_IGNORE);
-	}
-}
-
-/*
- * Step the iterator to the next interface.  Unlike
- * isc_interfaceiter_next(), this may leave the iterator
- * positioned on an interface that will ultimately
- * be ignored.  Return ISC_R_NOMORE if there are no more
- * interfaces, otherwise ISC_R_SUCCESS.
- */
-static isc_result_t
-internal_next(isc_interfaceiter_t *iter) {
-	struct ifa_msghdr *ifam;
-	REQUIRE (iter->pos < (unsigned int) iter->bufused);
-
-	ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
-
-	iter->pos += ifam->ifam_msglen;
-
-	if (iter->pos >= iter->bufused)
-		return (ISC_R_NOMORE);
-
-	return (ISC_R_SUCCESS);
-}
-
-static void
-internal_destroy(isc_interfaceiter_t *iter) {
-	UNUSED_ARG(iter); /* Unused. */
-	/*
-	 * Do nothing.
-	 */
-}
-
-static
-void internal_first(isc_interfaceiter_t *iter) {
-	iter->pos = 0;
-}


=====================================
libisc/include/isc/sockaddr.h deleted
=====================================
--- a/libisc/include/isc/sockaddr.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003  Internet Software Consortium.
- * Copyright 2015 by the NTPsec project contributors
- * SPDX-License-Identifier: ISC
- */
-
-#ifndef GUARD_ISC_SOCKADDR_H
-#define GUARD_ISC_SOCKADDR_H 1
-
-/*! \file isc/sockaddr.h */
-
-#include "isc/netaddr.h"
-#include "isc/result.h"
-
-#define ISC_LINK(type) struct { type *prev, *next; }
-
-struct isc_sockaddr {
-	union {
-		struct sockaddr		sa;
-		struct sockaddr_in	sin;
-		struct sockaddr_in6	sin6;
-	}				type;
-	unsigned int			length;		/* XXXRTH beginning? */
-	ISC_LINK(struct isc_sockaddr)	link;
-};
-
-#endif /* GUARD_ISC_SOCKADDR_H */


=====================================
libisc/interfaceiter.c
=====================================
--- a/libisc/interfaceiter.c
+++ b/libisc/interfaceiter.c
@@ -5,26 +5,27 @@
  * SPDX-License-Identifier: ISC
  */
 
-/*! \file */
-
 #include "config.h"
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>		/* Required for ifiter_ioctl.c. */
+#include <sys/sockio.h>         /* Required for ifiter_ioctl.c. */
 #endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+#include <netinet/in.h>                /* Contractual promise. */
 
 #include "ntp_assert.h"
-#include "isc/interfaceiter.h"
-#include "isc/mem.h"
-#include "isc/netaddr.h"
-#include "isc/result.h"
+#include "isc_interfaceiter.h"
+#include "isc_mem.h"
+#include "isc_netaddr.h"
+#include "isc_result.h"
+#include "isc_error.h"
+
 
 /* Must follow <isc/net.h>. */
 #ifdef HAVE_NET_IF6_H
@@ -49,17 +50,17 @@ isc_netaddr_islinklocal(isc_netaddr_t *na) __attribute__((pure));
 
 static void
 isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
-	memset(netaddr, 0, sizeof(*netaddr));
-	netaddr->family = AF_INET6;
-	netaddr->type.in6 = *ina6;
+        memset(netaddr, 0, sizeof(*netaddr));
+        netaddr->family = AF_INET6;
+        netaddr->type.in6 = *ina6;
 }
 
 static void
 isc_netaddr_setzone(isc_netaddr_t *netaddr, uint32_t zone) {
-	/* we currently only support AF_INET6. */
-	REQUIRE(netaddr->family == AF_INET6);
+        /* we currently only support AF_INET6. */
+        REQUIRE(netaddr->family == AF_INET6);
 
-	netaddr->zone = zone;
+        netaddr->zone = zone;
 }
 
 /*
@@ -67,18 +68,18 @@ isc_netaddr_setzone(isc_netaddr_t *netaddr, uint32_t zone) {
  */
 static bool
 isc_netaddr_islinklocal(isc_netaddr_t *na) {
-	switch (na->family) {
-	case AF_INET:
-		return (false);
-	case AF_INET6:
-		return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
-	default:
-		return (false);
-	}
+        switch (na->family) {
+        case AF_INET:
+                return (false);
+        case AF_INET6:
+                return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
+        default:
+                return (false);
+        }
 }
 
 typedef struct {
-	unsigned int magic;
+        unsigned int magic;
 } isc__magic_t;
 
 /*
@@ -87,10 +88,10 @@ typedef struct {
  * The intent of this is to allow magic numbers to be checked even though
  * the object is otherwise opaque.
  */
-#define ISC_MAGIC_VALID(a,b)	(((a) != NULL) && \
-				 (((const isc__magic_t *)(a))->magic == (b)))
+#define ISC_MAGIC_VALID(a,b)    (((a) != NULL) && \
+                                 (((const isc__magic_t *)(a))->magic == (b)))
 
-#define ISC_MAGIC(a, b, c, d)	((a) << 24 | (b) << 16 | (c) << 8 | (d))
+#define ISC_MAGIC(a, b, c, d)   ((a) << 24 | (b) << 16 | (c) << 8 | (d))
 
 /* Common utility functions */
 
@@ -105,72 +106,72 @@ typedef struct {
 
 static void
 get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
-	 char *ifname)
+         char *ifname)
 {
-	struct sockaddr_in6 *sa6;
-
-	/* clear any remaining value for safety */
-	memset(dst, 0, sizeof(*dst));
-
-	dst->family = family;
-	switch (family) {
-	case AF_INET:
-		memcpy(&dst->type.in,
-		       &((struct sockaddr_in *)(void *)src)->sin_addr,
-		       sizeof(struct in_addr));
-		break;
-	case AF_INET6:
-		sa6 = (struct sockaddr_in6 *)(void *)src;
-		memcpy(&dst->type.in6, &sa6->sin6_addr,
-		       sizeof(struct in6_addr));
-		if (sa6->sin6_scope_id != 0)
-			isc_netaddr_setzone(dst, sa6->sin6_scope_id);
-		else {
-			/*
-			 * BSD variants embed scope zone IDs in the 128bit
-			 * address as a kernel internal form.  Unfortunately,
-			 * the embedded IDs are not hidden from applications
-			 * when getting access to them by sysctl or ioctl.
-			 * We convert the internal format to the pure address
-			 * part and the zone ID part.
-			 * Since multicast addresses should not appear here
-			 * and they cannot be distinguished from netmasks,
-			 * we only consider unicast link-local addresses.
-			 */
-			if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
-				uint16_t zone16;
-
-				memcpy(&zone16, &sa6->sin6_addr.s6_addr[2],
-				       sizeof(zone16));
-				zone16 = ntohs(zone16);
-				if (zone16 != 0) {
-					/* the zone ID is embedded */
-					isc_netaddr_setzone(dst,
-							    (uint32_t)zone16);
-					dst->type.in6.s6_addr[2] = 0;
-					dst->type.in6.s6_addr[3] = 0;
-				} else if (ifname != NULL) {
-					unsigned int zone;
-
-					/*
-					 * sin6_scope_id is still not provided,
-					 * but the corresponding interface name
-					 * is know.  Use the interface ID as
-					 * the link ID.
-					 */
-					zone = if_nametoindex(ifname);
-					if (zone != 0) {
-						isc_netaddr_setzone(dst,
-								    (uint32_t)zone);
-					}
-				}
-			}
-		}
-		break;
-	default:
-		INSIST(0);
-		break;
-	}
+        struct sockaddr_in6 *sa6;
+
+        /* clear any remaining value for safety */
+        memset(dst, 0, sizeof(*dst));
+
+        dst->family = family;
+        switch (family) {
+        case AF_INET:
+                memcpy(&dst->type.in,
+                       &((struct sockaddr_in *)(void *)src)->sin_addr,
+                       sizeof(struct in_addr));
+                break;
+        case AF_INET6:
+                sa6 = (struct sockaddr_in6 *)(void *)src;
+                memcpy(&dst->type.in6, &sa6->sin6_addr,
+                       sizeof(struct in6_addr));
+                if (sa6->sin6_scope_id != 0)
+                        isc_netaddr_setzone(dst, sa6->sin6_scope_id);
+                else {
+                        /*
+                         * BSD variants embed scope zone IDs in the 128bit
+                         * address as a kernel internal form.  Unfortunately,
+                         * the embedded IDs are not hidden from applications
+                         * when getting access to them by sysctl or ioctl.
+                         * We convert the internal format to the pure address
+                         * part and the zone ID part.
+                         * Since multicast addresses should not appear here
+                         * and they cannot be distinguished from netmasks,
+                         * we only consider unicast link-local addresses.
+                         */
+                        if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
+                                uint16_t zone16;
+
+                                memcpy(&zone16, &sa6->sin6_addr.s6_addr[2],
+                                       sizeof(zone16));
+                                zone16 = ntohs(zone16);
+                                if (zone16 != 0) {
+                                        /* the zone ID is embedded */
+                                        isc_netaddr_setzone(dst,
+                                                            (uint32_t)zone16);
+                                        dst->type.in6.s6_addr[2] = 0;
+                                        dst->type.in6.s6_addr[3] = 0;
+                                } else if (ifname != NULL) {
+                                        unsigned int zone;
+
+                                        /*
+                                         * sin6_scope_id is still not provided,
+                                         * but the corresponding interface name
+                                         * is know.  Use the interface ID as
+                                         * the link ID.
+                                         */
+                                        zone = if_nametoindex(ifname);
+                                        if (zone != 0) {
+                                                isc_netaddr_setzone(dst,
+                                                                    (uint32_t)zone);
+                                        }
+                                }
+                        }
+                }
+                break;
+        default:
+                INSIST(0);
+                break;
+        }
 }
 
 /*
@@ -208,109 +209,1509 @@ isc_interfaceiter_current_bool(isc_interfaceiter_t *iter,
 }
 
 
+/*
+ *  start of the big 3 way switch, in order, try:
+ *
+ * 1. have ifaddrs.h
+ * 2. have sys/sysctl.h
+ * 3. using the SIOCGLIFCONF ioctl.
+ *
+ * question, do we need all three??
+ */
 #if HAVE_IFADDRS_H
-#include "ifiter_getifaddrs.c"
+
+/*
+ * Obtain the list of network interfaces using the getifaddrs(3) library.
+ */
+
+#include <ifaddrs.h>
+
+/*% Iterator Magic */
+#define IFITER_MAGIC            ISC_MAGIC('I', 'F', 'I', 'G')
+/*% Valid Iterator */
+#define VALID_IFITER(t)         ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+#ifdef __linux
+static bool seenv6 = false;
+#endif
+
+/*% Iterator structure */
+struct isc_interfaceiter {
+        unsigned int            magic;          /*%< Magic number. */
+        isc_mem_t               *mctx;
+        void                    *buf;           /*%< (unused) */
+        unsigned int            bufsize;        /*%< (always 0) */
+        struct ifaddrs          *ifaddrs;       /*%< List of ifaddrs */
+        struct ifaddrs          *pos;           /*%< Ptr to current ifaddr */
+        isc_interface_t         current;        /*%< Current interface data. */
+        isc_result_t            result;         /*%< Last result code. */
+#ifdef  __linux
+        FILE *                  proc;
+        char                    entry[ISC_IF_INET6_SZ];
+        isc_result_t            valid;
+#endif
+};
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+        isc_interfaceiter_t *iter;
+        isc_result_t result;
+        char strbuf[BUFSIZ];
+        int trys, ret = 0;
+
+        REQUIRE(mctx != NULL);
+        REQUIRE(iterp != NULL);
+        REQUIRE(*iterp == NULL);
+
+        iter = isc_mem_get(mctx, sizeof(*iter));
+        if (iter == NULL)
+                return (ISC_R_NOMEMORY);
+
+        iter->mctx = mctx;
+        iter->buf = NULL;
+        iter->bufsize = 0;
+        iter->ifaddrs = NULL;
+#ifdef __linux
+        /*
+         * Only open "/proc/net/if_inet6" if we have never seen a IPv6
+         * address returned by getifaddrs().
+         */
+        if (!seenv6) {
+                iter->proc = fopen("/proc/net/if_inet6", "r");
+                if (iter->proc == NULL) {
+                        (void)strerror_r(errno, strbuf, sizeof(strbuf));
+/*                      isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                                      ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+                                      "failed to open /proc/net/if_inet6");
+*/
+                }
+        } else
+                iter->proc = NULL;
+        iter->valid = ISC_R_FAILURE;
+#endif
+
+        /* If interrupted, try again */
+        for (trys = 0; trys < 3; trys++) {
+                if ((ret = getifaddrs(&iter->ifaddrs)) >= 0)
+                        break;
+                if (errno != EINTR)
+                        break;
+        }
+        if (ret < 0) {
+                (void)strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("getting interface addresses: getifaddrs: %s",
+                                 strbuf);
+                result = ISC_R_UNEXPECTED;
+                goto failure;
+        }
+
+        /*
+         * A newly created iterator has an undefined position
+         * until isc_interfaceiter_first() is called.
+         */
+        iter->pos = NULL;
+        iter->result = ISC_R_FAILURE;
+
+        iter->magic = IFITER_MAGIC;
+        *iterp = iter;
+        return (ISC_R_SUCCESS);
+
+ failure:
+#ifdef __linux
+        if (iter->proc != NULL)
+                fclose(iter->proc);
+#endif
+        if (iter->ifaddrs != NULL) /* just in case */
+                freeifaddrs(iter->ifaddrs);
+        isc_mem_put(mctx, iter, sizeof(*iter));
+        return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family,
+ * return ISC_R_IGNORE.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+        struct ifaddrs *ifa;
+        int family;
+        unsigned int namelen;
+
+        REQUIRE(VALID_IFITER(iter));
+
+        ifa = iter->pos;
+
+#ifdef __linux
+        /*
+         * [Bug 2792]
+         * burnicki: iter->pos is usually never NULL here (anymore?),
+         * so linux_if_inet6_current(iter) is never called here.
+         * However, that routine would check (under Linux), if the
+         * interface is in a tentative state, e.g. if there's no link
+         * yet but an IPv6 address has already be assigned.
+         */
+        if (iter->pos == NULL)
+                return (linux_if_inet6_current(iter));
+#endif
+
+        INSIST(ifa != NULL);
+        INSIST(ifa->ifa_name != NULL);
+
+
+#ifdef IFF_RUNNING
+        /*
+         * [Bug 2792]
+         * burnicki: if the interface is not running then
+         * it may be in a tentative state. See above.
+         */
+        if ((ifa->ifa_flags & IFF_RUNNING) == 0)
+                return (ISC_R_IGNORE);
+#endif
+
+        if (ifa->ifa_addr == NULL)
+                return (ISC_R_IGNORE);
+
+        family = ifa->ifa_addr->sa_family;
+        if (family != AF_INET && family != AF_INET6)
+                return (ISC_R_IGNORE);
+
+#ifdef __linux
+        if (family == AF_INET6)
+                seenv6 = true;
+#endif
+
+        memset(&iter->current, 0, sizeof(iter->current));
+
+        namelen = (unsigned int)strlen(ifa->ifa_name);
+        if (namelen > sizeof(iter->current.name) - 1)
+                namelen = sizeof(iter->current.name) - 1;
+
+        memset(iter->current.name, 0, sizeof(iter->current.name));
+        memcpy(iter->current.name, ifa->ifa_name, namelen);
+
+        iter->current.flags = 0;
+
+        if ((ifa->ifa_flags & IFF_UP) != 0)
+                iter->current.flags |= INTERFACE_F_UP;
+
+        if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0)
+                iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+
+        if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
+                iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+        if ((ifa->ifa_flags & IFF_BROADCAST) != 0)
+                iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+        if ((ifa->ifa_flags & IFF_MULTICAST) != 0)
+                iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+        iter->current.af = (unsigned int)family;
+
+        get_addr((unsigned int)family, &iter->current.address,
+                  ifa->ifa_addr, ifa->ifa_name);
+
+        if (ifa->ifa_netmask != NULL)
+                get_addr((unsigned int)family, &iter->current.netmask, ifa->ifa_netmask,
+                         ifa->ifa_name);
+
+        if (ifa->ifa_dstaddr != NULL &&
+            (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+                get_addr((unsigned int)family, &iter->current.dstaddress,
+                         ifa->ifa_dstaddr,
+                         ifa->ifa_name);
+
+        if (ifa->ifa_broadaddr != NULL &&
+            (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+                get_addr((unsigned int)family, &iter->current.broadcast,
+                         ifa->ifa_broadaddr,
+                         ifa->ifa_name);
+
+        iter->current.ifindex = if_nametoindex(iter->current.name);
+        return (ISC_R_SUCCESS);
+}
+
+/*
+ * Step the iterator to the next interface.  Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored.  Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+
+        if (iter->pos != NULL)
+                iter->pos = iter->pos->ifa_next;
+        if (iter->pos == NULL) {
+#ifdef __linux
+                if (!seenv6)
+                        return (linux_if_inet6_next(iter));
+#endif
+                return (ISC_R_NOMORE);
+        }
+
+        return (ISC_R_SUCCESS);
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+        if (iter->proc != NULL)
+                fclose(iter->proc);
+        iter->proc = NULL;
+#endif
+        if (iter->ifaddrs)
+                freeifaddrs(iter->ifaddrs);
+        iter->ifaddrs = NULL;
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+        linux_if_inet6_first(iter);
+#endif
+        iter->pos = iter->ifaddrs;
+}
+/* end HAVE_IFADDRS_H */
 #elif defined(HAVE_IFLIST_SYSCTL) && HAVE_IFLIST_SYSCTL
-#include "ifiter_sysctl.c"
+
+/*
+ * Obtain the list of network interfaces using sysctl.
+ * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14,
+ * and 19.16.
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <net/route.h>
+#include <net/if_dl.h>
+
+#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
+                    : sizeof(long))
+
+#define IFITER_MAGIC            ISC_MAGIC('I', 'F', 'I', 'S')
+#define VALID_IFITER(t)         ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+struct isc_interfaceiter {
+        unsigned int            magic;          /* Magic number. */
+        isc_mem_t               *mctx;
+        void                    *buf;           /* Buffer for sysctl data. */
+        unsigned int            bufsize;        /* Bytes allocated. */
+        unsigned int            bufused;        /* Bytes used. */
+        unsigned int            pos;            /* Current offset in
+                                                   sysctl data. */
+        isc_interface_t         current;        /* Current interface data. */
+        isc_result_t            result;         /* Last result code. */
+};
+
+static int mib[6] = {
+        CTL_NET,
+        PF_ROUTE,
+        0,
+        0,                      /* Any address family. */
+        NET_RT_IFLIST,
+        0                       /* Flags. */
+};
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+        isc_interfaceiter_t *iter;
+        isc_result_t result;
+        size_t bufsize;
+        size_t bufused;
+        char strbuf[BUFSIZ];
+
+        REQUIRE(mctx != NULL);
+        REQUIRE(iterp != NULL);
+        REQUIRE(*iterp == NULL);
+
+        iter = isc_mem_get(mctx, sizeof(*iter));
+        if (iter == NULL)
+                return (ISC_R_NOMEMORY);
+
+        iter->mctx = mctx;
+        iter->buf = 0;
+
+        /*
+         * Determine the amount of memory needed.
+         */
+        bufsize = 0;
+        if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("getting interface list size: sysctl: %s",
+                                 strbuf);
+                result = ISC_R_UNEXPECTED;
+                goto failure;
+        }
+        iter->bufsize = bufsize;
+
+        iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
+        if (iter->buf == NULL) {
+                result = ISC_R_NOMEMORY;
+                goto failure;
+        }
+
+        bufused = bufsize;
+        if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("getting interface list: sysctl: %s",
+                                 strbuf);
+                result = ISC_R_UNEXPECTED;
+                goto failure;
+        }
+        iter->bufused = bufused;
+        INSIST(iter->bufused <= iter->bufsize);
+
+        /*
+         * A newly created iterator has an undefined position
+         * until isc_interfaceiter_first() is called.
+         */
+        iter->pos = (unsigned int) -1;
+        iter->result = ISC_R_FAILURE;
+
+        iter->magic = IFITER_MAGIC;
+        *iterp = iter;
+        return (ISC_R_SUCCESS);
+
+ failure:
+        if (iter->buf != NULL)
+                isc_mem_put(mctx, iter->buf, iter->bufsize);
+        isc_mem_put(mctx, iter, sizeof(*iter));
+        return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family,
+ * return ISC_R_IGNORE.  In case of other failure,
+ * return ISC_R_UNEXPECTED.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+        struct ifa_msghdr *ifam, *ifam_end;
+
+        REQUIRE(VALID_IFITER(iter));
+        REQUIRE (iter->pos < (unsigned int) iter->bufused);
+
+        ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
+        ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused);
+
+        // Skip wrong RTM version headers
+        if (ifam->ifam_version != RTM_VERSION)
+                return (ISC_R_IGNORE);
+
+        if (ifam->ifam_type == RTM_IFINFO) {
+                struct if_msghdr *ifm = (struct if_msghdr *) ifam;
+                struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1);
+                unsigned int namelen;
+
+                memset(&iter->current, 0, sizeof(iter->current));
+
+                iter->current.ifindex = sdl->sdl_index;
+                namelen = sdl->sdl_nlen;
+                if (namelen > sizeof(iter->current.name) - 1)
+                        namelen = sizeof(iter->current.name) - 1;
+
+                memset(iter->current.name, 0, sizeof(iter->current.name));
+                memcpy(iter->current.name, sdl->sdl_data, namelen);
+
+                iter->current.flags = 0;
+
+                if ((ifam->ifam_flags & IFF_UP) != 0)
+                        iter->current.flags |= INTERFACE_F_UP;
+
+                if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0)
+                        iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+
+                if ((ifam->ifam_flags & IFF_LOOPBACK) != 0)
+                        iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+                if ((ifam->ifam_flags & IFF_BROADCAST) != 0)
+                        iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+                if ((ifam->ifam_flags & IFF_MULTICAST) != 0)
+                        iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+                /*
+                 * This is not an interface address.
+                 * Force another iteration.
+                 */
+                return (ISC_R_IGNORE);
+        } else if (ifam->ifam_type == RTM_NEWADDR) {
+                int i;
+                int family;
+                struct sockaddr *mask_sa = NULL;
+                struct sockaddr *addr_sa = NULL;
+                struct sockaddr *dst_sa = NULL;
+
+                struct sockaddr *sa = (struct sockaddr *)(ifam + 1);
+                family = sa->sa_family;
+
+                for (i = 0; i < RTAX_MAX; i++)
+                {
+                        if ((ifam->ifam_addrs & (1 << i)) == 0)
+                                continue;
+
+                        INSIST(sa < (struct sockaddr *) ifam_end);
+
+                        switch (i) {
+                        case RTAX_NETMASK: /* Netmask */
+                                mask_sa = sa;
+                                break;
+                        case RTAX_IFA: /* Interface address */
+                                addr_sa = sa;
+                                break;
+                        case RTAX_BRD: /* Broadcast or destination address */
+                                dst_sa = sa;
+                                break;
+                        }
+#ifdef ISC_PLATFORM_HAVESALEN
+                        sa = (struct sockaddr *)((char*)(sa)
+                                         + ROUNDUP(sa->sa_len));
+#else
+                        /* XXX untested. */
+                        sa = (struct sockaddr *)((char*)(sa)
+                                         + ROUNDUP(sizeof(struct sockaddr)));
+#endif
+                }
+
+                if (addr_sa == NULL)
+                        return (ISC_R_IGNORE);
+
+                family = addr_sa->sa_family;
+                if (family != AF_INET && family != AF_INET6)
+                        return (ISC_R_IGNORE);
+
+                iter->current.af = family;
+
+                get_addr(family, &iter->current.address, addr_sa,
+                         iter->current.name);
+
+                if (mask_sa != NULL)
+                        get_addr(family, &iter->current.netmask, mask_sa,
+                                 iter->current.name);
+
+                if (dst_sa != NULL &&
+                    (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+                        get_addr(family, &iter->current.dstaddress, dst_sa,
+                                 iter->current.name);
+
+                if (dst_sa != NULL &&
+                    (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+                        get_addr(family, &iter->current.broadcast, dst_sa,
+                                 iter->current.name);
+
+                return (ISC_R_SUCCESS);
+        } else {
+                printf("warning: unexpected interface list message type\n");
+                return (ISC_R_IGNORE);
+        }
+}
+
+/*
+ * Step the iterator to the next interface.  Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored.  Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+        struct ifa_msghdr *ifam;
+        REQUIRE (iter->pos < (unsigned int) iter->bufused);
+
+        ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
+
+        iter->pos += ifam->ifam_msglen;
+
+        if (iter->pos >= iter->bufused)
+                return (ISC_R_NOMORE);
+
+        return (ISC_R_SUCCESS);
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+        UNUSED_ARG(iter); /* Unused. */
+        /*
+         * Do nothing.
+         */
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+        iter->pos = 0;
+}
+/* end defined(HAVE_IFLIST_SYSCTL) && HAVE_IFLIST_SYSCTL */
+#else
+
+/*
+ * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
+ * See netintro(4).
+ */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+#ifdef HAVE_STRUCT_IF_LADDRCONF
+#define lifc_len iflc_len
+#define lifc_buf iflc_buf
+#define lifc_req iflc_req
+#define LIFCONF if_laddrconf
+#else
+#define USE_LIFC_FAMILY 1
+#define USE_LIFC_FLAGS 1
+#define LIFCONF lifconf
+#endif
+
+#ifdef HAVE_STRUCT_IF_LADDRREQ
+#define lifr_addr iflr_addr
+#define lifr_name iflr_name
+#define lifr_dstaddr iflr_dstaddr
+#define lifr_broadaddr iflr_broadaddr
+#define lifr_flags iflr_flags
+#define lifr_index iflr_index
+#define ss_family sa_family
+#define LIFREQ if_laddrreq
+#else
+#define LIFREQ lifreq
+#endif
+#endif
+
+#define IFITER_MAGIC            ISC_MAGIC('I', 'F', 'I', 'T')
+#define VALID_IFITER(t)         ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+struct isc_interfaceiter {
+        unsigned int            magic;          /* Magic number. */
+        isc_mem_t               *mctx;
+        int                     mode;
+        int                     socket;
+        struct ifconf           ifc;
+        void                    *buf;           /* Buffer for sysctl data. */
+        unsigned int            bufsize;        /* Bytes allocated. */
+        unsigned int            pos;            /* Current offset in
+                                                   SIOCGIFCONF data */
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        int                     socket6;
+        struct LIFCONF          lifc;
+        void                    *buf6;          /* Buffer for sysctl data. */
+        unsigned int            bufsize6;       /* Bytes allocated. */
+        unsigned int            pos6;           /* Current offset in
+                                                   SIOCGLIFCONF data */
+        isc_result_t            result6;        /* Last result code. */
+        bool            first6;
+#endif
+#ifdef  __linux
+        FILE *                  proc;
+        char                    entry[ISC_IF_INET6_SZ];
+        isc_result_t            valid;
+#endif
+        isc_interface_t         current;        /* Current interface data. */
+        isc_result_t            result;         /* Last result code. */
+};
+
+/*%
+ * Size of buffer for SIOCGLIFCONF, in bytes.  We assume no sane system
+ * will have more than a megabyte of interface configuration data.
+ */
+#define IFCONF_BUFSIZE_INITIAL  4096
+#define IFCONF_BUFSIZE_MAX      1048576
+
+#ifdef __linux
+#ifndef IF_NAMESIZE
+# ifdef IFNAMSIZ
+#  define IF_NAMESIZE  IFNAMSIZ
+# else
+#  define IF_NAMESIZE 16
+# endif
+#endif
+#endif
+
+static int
+isc_ioctl(int fildes, int req, char *arg);
+
+static int
+isc_ioctl(int fildes, int req, char *arg) {
+        int trys;
+        int ret;
+
+        for (trys = 0; trys < 3; trys++) {
+                if ((ret = ioctl(fildes, req, arg)) < 0) {
+                        if (errno == EINTR)
+                                continue;
+                }
+                break;
+        }
+        return (ret);
+}
+
+static isc_result_t
+getbuf4(isc_interfaceiter_t *iter) {
+        char strbuf[BUFSIZ];
+
+        iter->bufsize = IFCONF_BUFSIZE_INITIAL;
+
+        for (;;) {
+                iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
+                if (iter->buf == NULL)
+                        return (ISC_R_NOMEMORY);
+
+                memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len));
+                iter->ifc.ifc_len = iter->bufsize;
+                iter->ifc.ifc_buf = iter->buf;
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion".  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc)
+                    == -1) {
+                        if (errno != EINVAL) {
+                                strerror_r(errno, strbuf, sizeof(strbuf));
+                                UNEXPECTED_ERROR("get interface "
+                                                 "configuration: %s",
+                                                 strbuf);
+                                goto unexpected;
+                        }
+                        /*
+                         * EINVAL.  Retry with a bigger buffer.
+                         */
+                } else {
+                        /*
+                         * The ioctl succeeded.
+                         * Some OS's just return what will fit rather
+                         * than set EINVAL if the buffer is too small
+                         * to fit all the interfaces in.  If
+                         * ifc.lifc_len is too near to the end of the
+                         * buffer we will grow it just in case and
+                         * retry.
+                         */
+                        if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq)
+                            < iter->bufsize)
+                                break;
+                }
+                if (iter->bufsize >= IFCONF_BUFSIZE_MAX) {
+                        UNEXPECTED_ERROR("get interface configuration: "
+                                         "maximum buffer size exceeded");
+                        goto unexpected;
+                }
+                isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+                iter->bufsize *= 2;
+        }
+        return (ISC_R_SUCCESS);
+
+ unexpected:
+        isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+        iter->buf = NULL;
+        return (ISC_R_UNEXPECTED);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+getbuf6(isc_interfaceiter_t *iter) {
+        char strbuf[BUFSIZ];
+        isc_result_t result;
+
+        iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;
+
+        for (;;) {
+                iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);
+                if (iter->buf6 == NULL)
+                        return (ISC_R_NOMEMORY);
+
+                memset(&iter->lifc, 0, sizeof(iter->lifc));
+#ifdef USE_LIFC_FAMILY
+                iter->lifc.lifc_family = AF_INET6;
+#endif
+#ifdef USE_LIFC_FLAGS
+                iter->lifc.lifc_flags = 0;
+#endif
+                iter->lifc.lifc_len = iter->bufsize6;
+                iter->lifc.lifc_buf = iter->buf6;
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion".  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)
+                    == -1) {
+#ifdef __hpux
+                        /*
+                         * IPv6 interface scanning is not available on all
+                         * kernels w/ IPv6 sockets.
+                         */
+                        if (errno == ENOENT) {
+                                strerror_r(errno, strbuf, sizeof(strbuf));
+                                isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                                              ISC_LOGMODULE_INTERFACE,
+                                              ISC_LOG_DEBUG(1),
+                                                        "get interface "
+                                                        "configuration: %s",
+                                               strbuf);
+                                result = ISC_R_FAILURE;
+                                goto cleanup;
+                        }
+#endif
+                        if (errno != EINVAL) {
+                                strerror_r(errno, strbuf, sizeof(strbuf));
+                                UNEXPECTED_ERROR("get interface "
+                                                 "configuration: %s",
+                                                 strbuf);
+                                result = ISC_R_UNEXPECTED;
+                                goto cleanup;
+                        }
+                        /*
+                         * EINVAL.  Retry with a bigger buffer.
+                         */
+                } else {
+                        /*
+                         * The ioctl succeeded.
+                         * Some OS's just return what will fit rather
+                         * than set EINVAL if the buffer is too small
+                         * to fit all the interfaces in.  If
+                         * ifc.ifc_len is too near to the end of the
+                         * buffer we will grow it just in case and
+                         * retry.
+                         */
+                        if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ)
+                            < iter->bufsize6)
+                                break;
+                }
+                if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) {
+                        UNEXPECTED_ERROR("get interface configuration: "
+                                         "maximum buffer size exceeded");
+                        result = ISC_R_UNEXPECTED;
+                        goto cleanup;
+                }
+                isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+
+                iter->bufsize6 *= 2;
+        }
+
+        if (iter->lifc.lifc_len != 0)
+                iter->mode = 6;
+        return (ISC_R_SUCCESS);
+
+ cleanup:
+        isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+        iter->buf6 = NULL;
+        return (result);
+}
+#endif
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+        isc_interfaceiter_t *iter;
+        isc_result_t result;
+        char strbuf[BUFSIZ];
+
+        REQUIRE(mctx != NULL);
+        REQUIRE(iterp != NULL);
+        REQUIRE(*iterp == NULL);
+
+        iter = isc_mem_get(mctx, sizeof(*iter));
+        if (iter == NULL)
+                return (ISC_R_NOMEMORY);
+
+        iter->mctx = mctx;
+        iter->mode = 4;
+        iter->buf = NULL;
+        iter->pos = (unsigned int) -1;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        iter->buf6 = NULL;
+        iter->pos6 = (unsigned int) -1;
+        iter->result6 = ISC_R_NOMORE;
+        iter->socket6 = -1;
+        iter->first6 = false;
+#endif
+
+        /*
+         * Get the interface configuration, allocating more memory if
+         * necessary.
+         */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        result = isc_net_probeipv6();
+        if (result == ISC_R_SUCCESS) {
+                /*
+                 * Create an unbound datagram socket to do the SIOCGLIFCONF
+                 * ioctl on.  HP/UX requires an AF_INET6 socket for
+                 * SIOCGLIFCONF to get IPv6 addresses.
+                 */
+                if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                        strerror_r(errno, strbuf, sizeof(strbuf));
+                        UNEXPECTED_ERROR("making interface scan socket: %s",
+                                         strbuf);
+                        result = ISC_R_UNEXPECTED;
+                        goto socket6_failure;
+                }
+                result = iter->result6 = getbuf6(iter);
+                if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS)
+                        goto ioctl6_failure;
+        }
+#endif
+        if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("making interface scan socket: %s",
+                                 strbuf);
+                result = ISC_R_UNEXPECTED;
+                goto socket_failure;
+        }
+        result = getbuf4(iter);
+        if (result != ISC_R_SUCCESS)
+                goto ioctl_failure;
+
+        /*
+         * A newly created iterator has an undefined position
+         * until isc_interfaceiter_first() is called.
+         */
+#ifdef __linux
+        iter->proc = fopen("/proc/net/if_inet6", "r");
+        iter->valid = ISC_R_FAILURE;
+#endif
+        iter->result = ISC_R_FAILURE;
+
+        iter->magic = IFITER_MAGIC;
+        *iterp = iter;
+        return (ISC_R_SUCCESS);
+
+ ioctl_failure:
+        if (iter->buf != NULL)
+                isc_mem_put(mctx, iter->buf, iter->bufsize);
+        (void) close(iter->socket);
+
+ socket_failure:
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        if (iter->buf6 != NULL)
+                isc_mem_put(mctx, iter->buf6, iter->bufsize6);
+  ioctl6_failure:
+        if (iter->socket6 != -1)
+                (void) close(iter->socket6);
+  socket6_failure:
+#endif
+
+        isc_mem_put(mctx, iter, sizeof(*iter));
+        return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family, or if
+ * some operation on it fails, return ISC_R_IGNORE to make
+ * the higher-level iterator code ignore it.
+ */
+
+static isc_result_t
+internal_current4(isc_interfaceiter_t *iter) {
+        struct ifreq *ifrp;
+        struct ifreq ifreq;
+        int family;
+        char strbuf[BUFSIZ];
+#if !defined(HAVE_STRUCT_IF_LADDRREQ) && defined(SIOCGLIFADDR)
+        struct lifreq lifreq;
+#else
+        char sabuf[256];
+#endif
+        int i, bits, prefixlen;
+
+        REQUIRE(VALID_IFITER(iter));
+
+        if (iter->ifc.ifc_len == 0 ||
+            iter->pos == (unsigned int)iter->ifc.ifc_len) {
+#ifdef __linux
+                return (linux_if_inet6_current(iter));
+#else
+                return (ISC_R_NOMORE);
+#endif
+        }
+
+        INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len);
+
+        ifrp = (void *)((char *) iter->ifc.ifc_req + iter->pos);
+
+        memset(&ifreq, 0, sizeof(ifreq));
+        memcpy(&ifreq, ifrp, sizeof(ifreq));
+
+        family = ifreq.ifr_addr.sa_family;
+        if (family != AF_INET && family != AF_INET6)
+                return (ISC_R_IGNORE);
+
+        memset(&iter->current, 0, sizeof(iter->current));
+        iter->current.af = family;
+
+        INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name));
+        memset(iter->current.name, 0, sizeof(iter->current.name));
+        memcpy(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
+
+        get_addr(family, &iter->current.address,
+                 (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name);
+
+        /*
+         * If the interface does not have a address ignore it.
+         */
+        switch (family) {
+        case AF_INET:
+                if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+                        return (ISC_R_IGNORE);
+                break;
+        case AF_INET6:
+                if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+                           sizeof(in6addr_any)) == 0)
+                        return (ISC_R_IGNORE);
+                break;
+        }
+
+        /*
+         * Get interface flags.
+         */
+
+        iter->current.flags = 0;
+
+        /*
+         * Ignore the HP/UX warning about "integer overflow during
+         * conversion.  It comes from its own macro definition,
+         * and is really hard to shut up.
+         */
+        if (isc_ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("%s: getting interface flags: %s",
+                                 ifreq.ifr_name, strbuf);
+                return (ISC_R_IGNORE);
+        }
+
+        if ((ifreq.ifr_flags & IFF_UP) != 0)
+                iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+        if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0)
+                iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+        if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
+                iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+        if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
+                iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+        if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
+                iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+        if (family == AF_INET)
+                goto inet;
+
+        memset(&lifreq, 0, sizeof(lifreq));
+        memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name));
+        memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6,
+               sizeof(iter->current.address.type.in6));
+
+        if (isc_ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("%s: getting interface address: %s",
+                                 ifreq.ifr_name, strbuf);
+                return (ISC_R_IGNORE);
+        }
+        prefixlen = lifreq.lifr_addrlen;
+
+        /*
+         * Netmask already zeroed.
+         */
+        iter->current.netmask.family = family;
+        for (i = 0; i < 16; i++) {
+                if (prefixlen > 8) {
+                        bits = 0;
+                        prefixlen -= 8;
+                } else {
+                        bits = 8 - prefixlen;
+                        prefixlen = 0;
+                }
+                iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff;
+        }
+        iter->current.ifindex = if_nametoindex(iter->current.name);
+        return (ISC_R_SUCCESS);
+
+ inet:
+        if (family != AF_INET)
+                return (ISC_R_IGNORE);
+#ifdef IFF_POINTOPOINT
+        /*
+         * If the interface is point-to-point, get the destination address.
+         */
+        if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion.  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq)
+                    < 0) {
+                        strerror_r(errno, strbuf, sizeof(strbuf));
+                        UNEXPECTED_ERROR("%s: getting destination address: %s",
+                                         ifreq.ifr_name, strbuf);
+                        return (ISC_R_IGNORE);
+                }
+                get_addr(family, &iter->current.dstaddress,
+                         (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name);
+        }
+#endif
+
+        if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion.  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(iter->socket, SIOCGIFBRDADDR, (char *)&ifreq)
+                    < 0) {
+                        strerror_r(errno, strbuf, sizeof(strbuf));
+                        UNEXPECTED_ERROR("%s: getting broadcast address: %s",
+                                         ifreq.ifr_name, strbuf);
+                        return (ISC_R_IGNORE);
+                }
+                get_addr(family, &iter->current.broadcast,
+                         (struct sockaddr *)&ifreq.ifr_broadaddr, ifreq.ifr_name);
+        }
+
+        /*
+         * Get the network mask.
+         */
+        memset(&ifreq, 0, sizeof(ifreq));
+        memcpy(&ifreq, ifrp, sizeof(ifreq));
+        /*
+         * Ignore the HP/UX warning about "integer overflow during
+         * conversion.  It comes from its own macro definition,
+         * and is really hard to shut up.
+         */
+        if (isc_ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("%s: getting netmask: %s",
+                                 ifreq.ifr_name, strbuf);
+                return (ISC_R_IGNORE);
+        }
+        get_addr(family, &iter->current.netmask,
+                 (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name);
+        iter->current.ifindex = if_nametoindex(iter->current.name);
+        return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+        struct LIFREQ *ifrp;
+        struct LIFREQ lifreq;
+        int family;
+        char strbuf[BUFSIZ];
+        int fd;
+
+        REQUIRE(VALID_IFITER(iter));
+        if (iter->result6 != ISC_R_SUCCESS)
+                return (iter->result6);
+        REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+        ifrp = (void *)((char *)iter->lifc.lifc_req + iter->pos6);
+
+        memset(&lifreq, 0, sizeof(lifreq));
+        memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+        family = lifreq.lifr_addr.ss_family;
+        if (family != AF_INET && family != AF_INET6)
+                return (ISC_R_IGNORE);
+
+        memset(&iter->current, 0, sizeof(iter->current));
+        iter->current.af = family;
+
+        INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name));
+        memset(iter->current.name, 0, sizeof(iter->current.name));
+        memcpy(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name));
+
+        get_addr(family, &iter->current.address,
+                 (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+        if (isc_netaddr_islinklocal(&iter->current.address))
+                isc_netaddr_setzone(&iter->current.address,
+                                    (uint32_t)lifreq.lifr_index);
+
+        /*
+         * If the interface does not have a address ignore it.
+         */
+        switch (family) {
+        case AF_INET:
+                if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+                        return (ISC_R_IGNORE);
+                break;
+        case AF_INET6:
+                if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+                           sizeof(in6addr_any)) == 0)
+                        return (ISC_R_IGNORE);
+                break;
+        }
+
+        /*
+         * Get interface flags.
+         */
+
+        iter->current.flags = 0;
+
+        if (family == AF_INET6)
+                fd = iter->socket6;
+        else
+                fd = iter->socket;
+
+        /*
+         * Ignore the HP/UX warning about "integer overflow during
+         * conversion.  It comes from its own macro definition,
+         * and is really hard to shut up.
+         */
+        if (isc_ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("%s: getting interface flags: %s",
+                                 lifreq.lifr_name, strbuf);
+                return (ISC_R_IGNORE);
+        }
+
+        if ((lifreq.lifr_flags & IFF_UP) != 0)
+                iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+        if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0)
+                iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+        if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
+                iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+        if ((lifreq.lifr_flags & IFF_BROADCAST) != 0) {
+                iter->current.flags |= INTERFACE_F_BROADCAST;
+        }
+
+#ifdef IFF_MULTICAST
+        if ((lifreq.lifr_flags & IFF_MULTICAST) != 0) {
+                iter->current.flags |= INTERFACE_F_MULTICAST;
+        }
+#endif
+
+#ifdef IFF_POINTOPOINT
+        /*
+         * If the interface is point-to-point, get the destination address.
+         */
+        if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion.  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq)
+                    < 0) {
+                        strerror_r(errno, strbuf, sizeof(strbuf));
+                        UNEXPECTED_ERROR("%s: getting destination address: %s",
+                                         lifreq.lifr_name, strbuf);
+                        return (ISC_R_IGNORE);
+                }
+                get_addr(family, &iter->current.dstaddress,
+                         (struct sockaddr *)&lifreq.lifr_dstaddr,
+                         lifreq.lifr_name);
+        }
+#endif
+
+#ifdef SIOCGLIFBRDADDR
+        if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+                /*
+                 * Ignore the HP/UX warning about "integer overflow during
+                 * conversion.  It comes from its own macro definition,
+                 * and is really hard to shut up.
+                 */
+                if (isc_ioctl(iter->socket, SIOCGLIFBRDADDR, (char *)&lifreq)
+                    < 0) {
+                        strerror_r(errno, strbuf, sizeof(strbuf));
+                        UNEXPECTED_ERROR("%s: getting broadcast address: %s",
+                                         lifreq.lifr_name, strbuf);
+                        return (ISC_R_IGNORE);
+                }
+                get_addr(family, &iter->current.broadcast,
+                         (struct sockaddr *)&lifreq.lifr_broadaddr,
+                         lifreq.lifr_name);
+        }
+#endif  /* SIOCGLIFBRDADDR */
+
+        /*
+         * Get the network mask.  Netmask already zeroed.
+         */
+        memset(&lifreq, 0, sizeof(lifreq));
+        memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+#ifdef lifr_addrlen
+        /*
+         * Special case: if the system provides lifr_addrlen member, the
+         * netmask of an IPv6 address can be derived from the length, since
+         * an IPv6 address always has a contiguous mask.
+         */
+        if (family == AF_INET6) {
+                int i, bits;
+
+                iter->current.netmask.family = family;
+                for (i = 0; i < lifreq.lifr_addrlen; i += 8) {
+                        bits = lifreq.lifr_addrlen - i;
+                        bits = (bits < 8) ? (8 - bits) : 0;
+                        iter->current.netmask.type.in6.s6_addr[i / 8] =
+                                (~0 << bits) & 0xff;
+                }
+                iter->current.ifindex = if_nametoindex(iter->current.name);
+                return (ISC_R_SUCCESS);
+        }
+#endif
+
+        /*
+         * Ignore the HP/UX warning about "integer overflow during
+         * conversion.  It comes from its own macro definition,
+         * and is really hard to shut up.
+         */
+        if (isc_ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) {
+                strerror_r(errno, strbuf, sizeof(strbuf));
+                UNEXPECTED_ERROR("%s: getting netmask: %s",
+                                 lifreq.lifr_name, strbuf);
+                return (ISC_R_IGNORE);
+        }
+        get_addr(family, &iter->current.netmask,
+                 (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+        iter->current.ifindex = if_nametoindex(iter->current.name);
+        return (ISC_R_SUCCESS);
+}
+#endif
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        if (iter->mode == 6) {
+                iter->result6 = internal_current6(iter);
+                if (iter->result6 != ISC_R_NOMORE)
+                        return (iter->result6);
+        }
+#endif
+        return (internal_current4(iter));
+}
+
+/*
+ * Step the iterator to the next interface.  Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored.  Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next4(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+        struct ifreq *ifrp;
+#endif
+
+        if (iter->pos < (unsigned int) iter->ifc.ifc_len) {
+#ifdef ISC_PLATFORM_HAVESALEN
+                ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
+
+                if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
+                        iter->pos += sizeof(ifrp->ifr_name) +
+                                     ifrp->ifr_addr.sa_len;
+                else
+#endif
+                        iter->pos += sizeof(struct ifreq);
+
+        } else {
+                INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len);
+#ifdef __linux
+                return (linux_if_inet6_next(iter));
 #else
-#include "ifiter_ioctl.c"
+                return (ISC_R_NOMORE);
+#endif
+        }
+        return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+        struct LIFREQ *ifrp;
+#endif
+
+        if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE)
+                return (iter->result6);
+
+        REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+#ifdef ISC_PLATFORM_HAVESALEN
+        ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
+
+        if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr))
+                iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
+        else
+#endif
+                iter->pos6 += sizeof(struct LIFREQ);
+
+        if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len)
+                return (ISC_R_NOMORE);
+
+        return (ISC_R_SUCCESS);
+}
 #endif
 
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        if (iter->mode == 6) {
+                iter->result6 = internal_next6(iter);
+                if (iter->result6 != ISC_R_NOMORE)
+                        return (iter->result6);
+                if (iter->first6) {
+                        iter->first6 = false;
+                        return (ISC_R_SUCCESS);
+                }
+        }
+#endif
+        return (internal_next4(iter));
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+        (void) close(iter->socket);
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        if (iter->socket6 != -1)
+                (void) close(iter->socket6);
+        if (iter->buf6 != NULL) {
+                isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+        }
+#endif
+#ifdef __linux
+        if (iter->proc != NULL)
+                fclose(iter->proc);
+#endif
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+        iter->pos = 0;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+        iter->pos6 = 0;
+        if (iter->result6 == ISC_R_NOMORE)
+                iter->result6 = ISC_R_SUCCESS;
+        iter->first6 = true;
+#endif
+#ifdef __linux
+        linux_if_inet6_first(iter);
+#endif
+}
+/* end of "ifiter_ioctl" */
+#endif
+/* end of the big 3 way switch */
+
 #ifdef __linux
 static void
 linux_if_inet6_first(isc_interfaceiter_t *iter) {
-	if (iter->proc != NULL) {
-		rewind(iter->proc);
-		(void)linux_if_inet6_next(iter);
-	} else
-		iter->valid = ISC_R_NOMORE;
+        if (iter->proc != NULL) {
+                rewind(iter->proc);
+                (void)linux_if_inet6_next(iter);
+        } else
+                iter->valid = ISC_R_NOMORE;
 }
 
 static isc_result_t
 linux_if_inet6_next(isc_interfaceiter_t *iter) {
-	if (iter->proc != NULL &&
-	    fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
-		iter->valid = ISC_R_SUCCESS;
-	else
-		iter->valid = ISC_R_NOMORE;
-	return (iter->valid);
+        if (iter->proc != NULL &&
+            fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
+                iter->valid = ISC_R_SUCCESS;
+        else
+                iter->valid = ISC_R_NOMORE;
+        return (iter->valid);
 }
 
 static isc_result_t
 linux_if_inet6_current(isc_interfaceiter_t *iter) {
-	char address[33];
-	char name[IF_NAMESIZE+1];
-	struct in6_addr addr6;
-	unsigned int ifindex;
-	int prefix, scope, flags;
-	int res;
-	unsigned int i;
-
-	if (iter->valid != ISC_R_SUCCESS)
-		return (iter->valid);
-	if (iter->proc == NULL) {
-/*		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-			      "/proc/net/if_inet6:iter->proc == NULL");
+        char address[33];
+        char name[IF_NAMESIZE+1];
+        struct in6_addr addr6;
+        unsigned int ifindex;
+        int prefix, scope, flags;
+        int res;
+        unsigned int i;
+
+        if (iter->valid != ISC_R_SUCCESS)
+                return (iter->valid);
+        if (iter->proc == NULL) {
+/*              isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                              ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                              "/proc/net/if_inet6:iter->proc == NULL");
 */
-		return (ISC_R_FAILURE);
-	}
+                return (ISC_R_FAILURE);
+        }
 
-	res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
-		     address, &ifindex, (unsigned int *)&prefix,
+        res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
+                     address, &ifindex, (unsigned int *)&prefix,
                      (unsigned int *) &scope,
                      (unsigned int *)&flags, name);
-	if (res != 6) {
-/*		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-			      "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
-			      res);
+        if (res != 6) {
+/*              isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                              ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                              "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
+                              res);
 */
-		return (ISC_R_FAILURE);
-	}
-	if (strlen(address) != 32) {
-/*		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-			      "/proc/net/if_inet6:strlen(%s) != 32", address);
+                return (ISC_R_FAILURE);
+        }
+        if (strlen(address) != 32) {
+/*              isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                              ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                              "/proc/net/if_inet6:strlen(%s) != 32", address);
 */
-		return (ISC_R_FAILURE);
-	}
-	/*
-	** Ignore DAD addresses --
-	** we can't bind to them until they are resolved
-	*/
+                return (ISC_R_FAILURE);
+        }
+        /*
+        ** Ignore DAD addresses --
+        ** we can't bind to them until they are resolved
+        */
 #ifdef IFA_F_TENTATIVE
-	if (flags & IFA_F_TENTATIVE)
-		return (ISC_R_IGNORE);
-#endif
-
-	for (i = 0; i < 16; i++) {
-		unsigned char byte;
-		static const char hex[] = "0123456789abcdef";
-		byte = ((strchr(hex, address[i * 2]) - hex) << 4) |
-		       (strchr(hex, address[i * 2 + 1]) - hex);
-		addr6.s6_addr[i] = byte;
-	}
-	iter->current.af = AF_INET6;
-	iter->current.flags = INTERFACE_F_UP;
-	isc_netaddr_fromin6(&iter->current.address, &addr6);
-	iter->current.ifindex = ifindex;
-	if (isc_netaddr_islinklocal(&iter->current.address)) {
-		isc_netaddr_setzone(&iter->current.address,
-				    (uint32_t)ifindex);
-	}
-	for (i = 0; i < 16; i++) {
-		if (prefix > 8) {
-			addr6.s6_addr[i] = 0xff;
-			prefix -= 8;
-		} else {
-			addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
-			prefix = 0;
-		}
-	}
-	isc_netaddr_fromin6(&iter->current.netmask, &addr6);
-	strlcpy(iter->current.name, name, sizeof(iter->current.name));
-	return (ISC_R_SUCCESS);
+        if (flags & IFA_F_TENTATIVE)
+                return (ISC_R_IGNORE);
+#endif
+
+        for (i = 0; i < 16; i++) {
+                unsigned char byte;
+                static const char hex[] = "0123456789abcdef";
+                byte = ((strchr(hex, address[i * 2]) - hex) << 4) |
+                       (strchr(hex, address[i * 2 + 1]) - hex);
+                addr6.s6_addr[i] = byte;
+        }
+        iter->current.af = AF_INET6;
+        iter->current.flags = INTERFACE_F_UP;
+        isc_netaddr_fromin6(&iter->current.address, &addr6);
+        iter->current.ifindex = ifindex;
+        if (isc_netaddr_islinklocal(&iter->current.address)) {
+                isc_netaddr_setzone(&iter->current.address,
+                                    (uint32_t)ifindex);
+        }
+        for (i = 0; i < 16; i++) {
+                if (prefix > 8) {
+                        addr6.s6_addr[i] = 0xff;
+                        prefix -= 8;
+                } else {
+                        addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
+                        prefix = 0;
+                }
+        }
+        isc_netaddr_fromin6(&iter->current.netmask, &addr6);
+        strlcpy(iter->current.name, name, sizeof(iter->current.name));
+        return (ISC_R_SUCCESS);
 }
 #endif
 
@@ -320,64 +1721,64 @@ linux_if_inet6_current(isc_interfaceiter_t *iter) {
 
 isc_result_t
 isc_interfaceiter_current(isc_interfaceiter_t *iter,
-			  isc_interface_t *ifdata)
+                          isc_interface_t *ifdata)
 {
-	REQUIRE(iter->result == ISC_R_SUCCESS);
-	memcpy(ifdata, &iter->current, sizeof(*ifdata));
-	return (ISC_R_SUCCESS);
+        REQUIRE(iter->result == ISC_R_SUCCESS);
+        memcpy(ifdata, &iter->current, sizeof(*ifdata));
+        return (ISC_R_SUCCESS);
 }
 
 isc_result_t
 isc_interfaceiter_first(isc_interfaceiter_t *iter) {
-	isc_result_t result;
+        isc_result_t result;
 
-	REQUIRE(VALID_IFITER(iter));
+        REQUIRE(VALID_IFITER(iter));
 
-	internal_first(iter);
-	for (;;) {
-		result = internal_current(iter);
-		if (result != ISC_R_IGNORE)
-			break;
-		result = internal_next(iter);
-		if (result != ISC_R_SUCCESS)
-			break;
-	}
-	iter->result = result;
-	return (result);
+        internal_first(iter);
+        for (;;) {
+                result = internal_current(iter);
+                if (result != ISC_R_IGNORE)
+                        break;
+                result = internal_next(iter);
+                if (result != ISC_R_SUCCESS)
+                        break;
+        }
+        iter->result = result;
+        return (result);
 }
 
 isc_result_t
 isc_interfaceiter_next(isc_interfaceiter_t *iter) {
-	isc_result_t result;
+        isc_result_t result;
 
-	REQUIRE(VALID_IFITER(iter));
-	REQUIRE(iter->result == ISC_R_SUCCESS);
+        REQUIRE(VALID_IFITER(iter));
+        REQUIRE(iter->result == ISC_R_SUCCESS);
 
-	for (;;) {
-		result = internal_next(iter);
-		if (result != ISC_R_SUCCESS)
-			break;
-		result = internal_current(iter);
-		if (result != ISC_R_IGNORE)
-			break;
-	}
-	iter->result = result;
-	return (result);
+        for (;;) {
+                result = internal_next(iter);
+                if (result != ISC_R_SUCCESS)
+                        break;
+                result = internal_current(iter);
+                if (result != ISC_R_IGNORE)
+                        break;
+        }
+        iter->result = result;
+        return (result);
 }
 
 void
 isc_interfaceiter_destroy(isc_interfaceiter_t **iterp)
 {
-	isc_interfaceiter_t *iter;
-	REQUIRE(iterp != NULL);
-	iter = *iterp;
-	REQUIRE(VALID_IFITER(iter));
-
-	internal_destroy(iter);
-	if (iter->buf != NULL)
-		isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
-
-	iter->magic = 0;
-	isc_mem_put(iter->mctx, iter, sizeof(*iter));
-	*iterp = NULL;
+        isc_interfaceiter_t *iter;
+        REQUIRE(iterp != NULL);
+        iter = *iterp;
+        REQUIRE(VALID_IFITER(iter));
+
+        internal_destroy(iter);
+        if (iter->buf != NULL)
+                isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+        iter->magic = 0;
+        isc_mem_put(iter->mctx, iter, sizeof(*iter));
+        *iterp = NULL;
 }


=====================================
libisc/net.c
=====================================
--- a/libisc/net.c
+++ b/libisc/net.c
@@ -18,9 +18,13 @@
 #include <unistd.h>
 #include <string.h>
 
-#include "isc/netaddr.h"
-#include "isc/error.h"
-#include "isc/result.h"
+/* for struct sockaddr on *BSD */
+#include <sys/socket.h>                /* Contractual promise. */
+#include <netinet/in.h>                /* Contractual promise. */
+
+#include "isc_netaddr.h"
+#include "isc_error.h"
+#include "isc_result.h"
 
 static isc_result_t	ipv4_result = ISC_R_NOTFOUND;
 static isc_result_t	ipv6_result = ISC_R_NOTFOUND;


=====================================
libisc/wscript
=====================================
--- a/libisc/wscript
+++ b/libisc/wscript
@@ -9,9 +9,6 @@ def build(ctx):
 
     ctx(
         features="c bld_include src_include",
-        includes=[
-            "%s/libisc/include/" % ctx.srcnode.abspath(),
-        ],
         source=libisc_source,
         target="libisc_obj",
     )


=====================================
libntp/assert.c
=====================================
--- a/libntp/assert.c
+++ b/libntp/assert.c
@@ -16,7 +16,7 @@
 #include "ntp_debug.h"
 #include "ntp_syslog.h"
 #include "ntp_assert.h"
-#include "isc/result.h"
+#include "isc_result.h"
 
 #ifdef USEBACKTRACE
 


=====================================
libntp/initnetwork.c
=====================================
--- a/libntp/initnetwork.c
+++ b/libntp/initnetwork.c
@@ -3,7 +3,7 @@
  */
 #include "config.h"
 
-#include "isc/netaddr.h"
+#include "isc_netaddr.h"
 #include "ntp_stdlib.h"
 
 /*


=====================================
libntp/lib_strbuf.c
=====================================
--- a/libntp/lib_strbuf.c
+++ b/libntp/lib_strbuf.c
@@ -3,7 +3,7 @@
  */
 #include "config.h"
 
-#include "isc/netaddr.h"
+#include "isc_netaddr.h"
 
 #include "ntp_fp.h"
 #include "ntp_stdlib.h"


=====================================
libntp/pymodule.c
=====================================
--- a/libntp/pymodule.c
+++ b/libntp/pymodule.c
@@ -18,7 +18,7 @@
 
 #include "ntp_config.h"
 #include "ntp_assert.h"
-#include "isc/error.h"
+#include "isc_error.h"
 
 #include "ntp_control.h"
 


=====================================
libntp/socktoa.c
=====================================
--- a/libntp/socktoa.c
+++ b/libntp/socktoa.c
@@ -10,8 +10,7 @@
 
 #include <stdio.h>
 #include <arpa/inet.h>
-#include "isc/netaddr.h"
-#include "isc/sockaddr.h"
+#include "isc_netaddr.h"
 
 #include "ntp_fp.h"
 #include "lib_strbuf.h"


=====================================
libntp/wscript
=====================================
--- a/libntp/wscript
+++ b/libntp/wscript
@@ -42,9 +42,7 @@ def build(ctx):
     if not ctx.env.HAVE_STRLCAT or not ctx.env.HAVE_STRLCPY:
         libntp_source_sharable += ["strl_obsd.c"]
 
-    includes = [
-        "%s/libisc/include/" % srcnode,
-        ] + ctx.env.PLATFORM_INCLUDES
+    includes = ctx.env.PLATFORM_INCLUDES
 
     # C library
     ctx(


=====================================
ntpd/ntp_config.c
=====================================
--- a/ntpd/ntp_config.c
+++ b/ntpd/ntp_config.c
@@ -22,7 +22,7 @@
 #include <signal.h>
 #include <sys/wait.h>
 
-#include "isc/netaddr.h"
+#include "isc_netaddr.h"
 
 #include "ntp.h"
 #include "ntpd.h"


=====================================
ntpd/ntp_io.c
=====================================
--- a/ntpd/ntp_io.c
+++ b/ntpd/ntp_io.c
@@ -22,10 +22,9 @@
 #include "ntp_dns.h"
 #include "timespecops.h"
 
-#include "isc/mem.h"
-#include "isc/interfaceiter.h"
-#include "isc/netaddr.h"
-#include "isc/sockaddr.h"
+#include "isc_mem.h"
+#include "isc_interfaceiter.h"
+#include "isc_netaddr.h"
 
 #ifdef HAVE_NET_ROUTE_H
 # define USE_ROUTING_SOCKET
@@ -125,6 +124,17 @@ static bool
 netaddr_eqprefix(const isc_netaddr_t *, const isc_netaddr_t *,
                     unsigned int) __attribute__((pure));
 
+/* Socket Address */
+typedef struct isc_sockaddr {
+	union {
+		struct sockaddr		sa;
+		struct sockaddr_in	sin;
+		struct sockaddr_in6	sin6;
+	}				type;
+	unsigned int			length;		/* XXXRTH beginning? */
+        struct { struct isc_sockaddr *prev, *next; } link;
+} isc_sockaddr_t;
+
 static void
 netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source);
 


=====================================
ntpd/ntpd.c
=====================================
--- a/ntpd/ntpd.c
+++ b/ntpd/ntpd.c
@@ -15,7 +15,7 @@
 #ifdef ENABLE_DNS_LOOKUP
 #include "ntp_dns.h"
 #endif
-#include "isc/error.h"
+#include "isc_error.h"
 
 #include <unistd.h>
 #include <sys/stat.h>


=====================================
wafhelpers/waf.py
=====================================
--- a/wafhelpers/waf.py
+++ b/wafhelpers/waf.py
@@ -20,14 +20,12 @@ def insert_srcdir(self):
 @feature('libisc_include')
 def insert_libiscdir(self):
         srcnode = self.bld.srcnode.abspath()
-        self.includes += ["%s/libisc/include/" % srcnode]
 
 
 @before_method('apply_incpaths')
 @feature('libisc_pthread_include')
 def insert_libiscpthreaddir(self):
         srcnode = self.bld.srcnode.abspath()
-        self.includes += ["%s/libisc/pthreads/include/" % srcnode]
 
 
 def manpage_subst_fun(task, text):


=====================================
wscript
=====================================
--- a/wscript
+++ b/wscript
@@ -148,7 +148,6 @@ def configure(ctx):
             "-P", "%s/devel/trace/" % srcnode,
             "-f", "-I%s" % bldnode,
             "-f", "-I%s/include/" % srcnode,
-            "-f", "-I%s/libisc/include/" % srcnode,
         ]
 
     # Not needed to build.  Used by utility scripts.



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/3ce5a5f0766e20b61378a75f851feffc7b9fd7b6...c9d47e6ca7616c896e2d16b102ccf224c90ad11a

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/3ce5a5f0766e20b61378a75f851feffc7b9fd7b6...c9d47e6ca7616c896e2d16b102ccf224c90ad11a
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170607/beacb9ad/attachment.html>


More information about the vc mailing list