[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:09:46 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/9b662aa5/attachment.html>
More information about the vc
mailing list