ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1999-2005, 2007, 2014-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater/* $Id: ifiter_sysctl.c,v 1.25 2007/06/19 23:47:18 tbox Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * \brief
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * Obtain the list of network interfaces using sysctl.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14,
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * and 19.16.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#include <sys/param.h>
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#include <sys/sysctl.h>
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#include <net/route.h>
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#include <net/if_dl.h>
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
3759f10fc543747668b1ca4b4671f35b0dea8445Francis Dupont#include <isc/print.h>
3759f10fc543747668b1ca4b4671f35b0dea8445Francis Dupont
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson/* XXX what about Alpha? */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#ifdef sgi
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#define ROUNDUP(a) ((a) > 0 ? \
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) : \
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson sizeof(__uint64_t))
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#else
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
431a83fb29482c5170b3e4026e59bb14849a6707Tinderbox User : sizeof(long))
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#endif
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'S')
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonstruct isc_interfaceiter {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson unsigned int magic; /* Magic number. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_mem_t *mctx;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson void *buf; /* Buffer for sysctl data. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson unsigned int bufsize; /* Bytes allocated. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson unsigned int bufused; /* Bytes used. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson unsigned int pos; /* Current offset in
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson sysctl data. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_interface_t current; /* Current interface data. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_result_t result; /* Last result code. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson};
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonstatic int mib[6] = {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson CTL_NET,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence PF_ROUTE,
431a83fb29482c5170b3e4026e59bb14849a6707Tinderbox User 0,
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson 0, /* Any address family. */
431a83fb29482c5170b3e4026e59bb14849a6707Tinderbox User NET_RT_IFLIST,
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson 0 /* Flags. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson};
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceisc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_interfaceiter_t *iter;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_result_t result;
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson size_t bufsize;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence size_t bufused;
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews char strbuf[ISC_STRERRORSIZE];
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE(mctx != NULL);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE(iterp != NULL);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE(*iterp == NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter = isc_mem_get(mctx, sizeof(*iter));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (iter == NULL)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (ISC_R_NOMEMORY);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->mctx = mctx;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->buf = 0;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Determine the amount of memory needed.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson bufsize = 0;
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence UNEXPECTED_ERROR(__FILE__, __LINE__,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence isc_msgcat_get(isc_msgcat,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSGSET_IFITERSYSCTL,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSG_GETIFLISTSIZE,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "getting interface "
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "list size: sysctl: %s"),
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews strbuf);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson result = ISC_R_UNEXPECTED;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson goto failure;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson iter->bufsize = bufsize;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (iter->buf == NULL) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson result = ISC_R_NOMEMORY;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson goto failure;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson bufused = bufsize;
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence UNEXPECTED_ERROR(__FILE__, __LINE__,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence isc_msgcat_get(isc_msgcat,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSGSET_IFITERSYSCTL,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSG_GETIFLIST,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "getting interface list: "
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "sysctl: %s"),
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews strbuf);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson result = ISC_R_UNEXPECTED;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson goto failure;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
79c08618e9f27da052ad6bbc0b232f23ff2e568eAndreas Gustafsson iter->bufused = bufused;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson INSIST(iter->bufused <= iter->bufsize);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson /*
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * A newly created iterator has an undefined position
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * until isc_interfaceiter_first() is called.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->pos = (unsigned int) -1;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->result = ISC_R_FAILURE;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->magic = IFITER_MAGIC;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson *iterp = iter;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (ISC_R_SUCCESS);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson failure:
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (iter->buf != NULL)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson isc_mem_put(mctx, iter->buf, iter->bufsize);
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson isc_mem_put(mctx, iter, sizeof(*iter));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (result);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson}
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson/*
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * Get information about the current interface to iter->current.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * If successful, return ISC_R_SUCCESS.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * If the interface has an unsupported address family,
461a00bbdee50a46ba7fcfb3f9f2847d3bda5ad3Andreas Gustafsson * return ISC_R_IGNORE. In case of other failure,
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * return ISC_R_UNEXPECTED.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonstatic isc_result_t
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssoninternal_current(isc_interfaceiter_t *iter) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct ifa_msghdr *ifam, *ifam_end;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE(VALID_IFITER(iter));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE (iter->pos < (unsigned int) iter->bufused);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (ifam->ifam_type == RTM_IFINFO) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct if_msghdr *ifm = (struct if_msghdr *) ifam;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson unsigned int namelen;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson memset(&iter->current, 0, sizeof(iter->current));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson namelen = sdl->sdl_nlen;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (namelen > sizeof(iter->current.name) - 1)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson namelen = sizeof(iter->current.name) - 1;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
2305225a1c70bf80dd544f801f3259d35d4220ceBrian Wellington memset(iter->current.name, 0, sizeof(iter->current.name));
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(iter->current.name, sdl->sdl_data, namelen);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->current.flags = 0;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if ((ifam->ifam_flags & IFF_UP) != 0)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->current.flags |= INTERFACE_F_UP;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->current.flags |= INTERFACE_F_POINTTOPOINT;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if ((ifam->ifam_flags & IFF_LOOPBACK) != 0)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->current.flags |= INTERFACE_F_LOOPBACK;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson /*
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * This is not an interface address.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * Force another iteration.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson */
461a00bbdee50a46ba7fcfb3f9f2847d3bda5ad3Andreas Gustafsson return (ISC_R_IGNORE);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson } else if (ifam->ifam_type == RTM_NEWADDR) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson int i;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson int family;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct sockaddr *mask_sa = NULL;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct sockaddr *addr_sa = NULL;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct sockaddr *dst_sa = NULL;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct sockaddr *sa = (struct sockaddr *)(ifam + 1);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson family = sa->sa_family;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson for (i = 0; i < RTAX_MAX; i++)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if ((ifam->ifam_addrs & (1 << i)) == 0)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson continue;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson INSIST(sa < (struct sockaddr *) ifam_end);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson switch (i) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson case RTAX_NETMASK: /* Netmask */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson mask_sa = sa;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson break;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson case RTAX_IFA: /* Interface address */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson addr_sa = sa;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson break;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson case RTAX_BRD: /* Broadcast or destination address */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson dst_sa = sa;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson break;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
91c49d591c79159a965adb9d78c03cc2f334991eAndreas Gustafsson#ifdef ISC_PLATFORM_HAVESALEN
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson sa = (struct sockaddr *)((char*)(sa)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson + ROUNDUP(sa->sa_len));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#else
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#ifdef sgi
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Do as the contributed SGI code does.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson sa = (struct sockaddr *)((char*)(sa)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson + ROUNDUP(_FAKE_SA_LEN_DST(sa)));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#else
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson /* XXX untested. */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson sa = (struct sockaddr *)((char*)(sa)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson + ROUNDUP(sizeof(struct sockaddr)));
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#endif
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson#endif
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (addr_sa == NULL)
461a00bbdee50a46ba7fcfb3f9f2847d3bda5ad3Andreas Gustafsson return (ISC_R_IGNORE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson family = addr_sa->sa_family;
c549b3a4d5fedba2ae960df667864e824acb1ef9Mark Andrews if (family != AF_INET && family != AF_INET6)
461a00bbdee50a46ba7fcfb3f9f2847d3bda5ad3Andreas Gustafsson return (ISC_R_IGNORE);
757a38d502c1d921c2318c00f6cb72251d8f15edMark Andrews
757a38d502c1d921c2318c00f6cb72251d8f15edMark Andrews iter->current.af = family;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
846f974d5737710588eb676b64ba138da27c45ddMark Andrews get_addr(family, &iter->current.address, addr_sa,
846f974d5737710588eb676b64ba138da27c45ddMark Andrews iter->current.name);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (mask_sa != NULL)
846f974d5737710588eb676b64ba138da27c45ddMark Andrews get_addr(family, &iter->current.netmask, mask_sa,
846f974d5737710588eb676b64ba138da27c45ddMark Andrews iter->current.name);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (dst_sa != NULL &&
5a4854e226ce5eca99bcfb5557b36ea210bb25bcMark Andrews (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
846f974d5737710588eb676b64ba138da27c45ddMark Andrews get_addr(family, &iter->current.dstaddress, dst_sa,
846f974d5737710588eb676b64ba138da27c45ddMark Andrews iter->current.name);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (ISC_R_SUCCESS);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson } else {
5456bddd393aafd9fa5ac4cc905d3ac1b9854635Mukund Sivaraman printf("%s",
5456bddd393aafd9fa5ac4cc905d3ac1b9854635Mukund Sivaraman isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence ISC_MSG_UNEXPECTEDTYPE,
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "warning: unexpected interface list "
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence "message type\n"));
461a00bbdee50a46ba7fcfb3f9f2847d3bda5ad3Andreas Gustafsson return (ISC_R_IGNORE);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson }
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson}
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson/*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Step the iterator to the next interface. Unlike
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * isc_interfaceiter_next(), this may leave the iterator
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * positioned on an interface that will ultimately
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * be ignored. Return ISC_R_NOMORE if there are no more
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson * interfaces, otherwise ISC_R_SUCCESS.
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonstatic isc_result_t
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssoninternal_next(isc_interfaceiter_t *iter) {
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson struct ifa_msghdr *ifam;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson REQUIRE (iter->pos < (unsigned int) iter->bufused);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson iter->pos += ifam->ifam_msglen;
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson if (iter->pos >= iter->bufused)
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (ISC_R_NOMORE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson return (ISC_R_SUCCESS);
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson}
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssonstatic void
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafssoninternal_destroy(isc_interfaceiter_t *iter) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence UNUSED(iter); /* Unused. */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Do nothing.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson}
ca485ab26fffa241a3eac1899b2d2012dd1fdb73Andreas Gustafsson
21ba6c18e4ccc73933af5cf28701a5cc3b7963ecMark Andrewsstatic
21ba6c18e4ccc73933af5cf28701a5cc3b7963ecMark Andrewsvoid internal_first(isc_interfaceiter_t *iter) {
21ba6c18e4ccc73933af5cf28701a5cc3b7963ecMark Andrews iter->pos = 0;
21ba6c18e4ccc73933af5cf28701a5cc3b7963ecMark Andrews}