void isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; REQUIRE(VALID_IFITER(iter)); REQUIRE(use_GAA_determined); if (use_GAA) { REQUIRE(NULL == iter->buf4); REQUIRE(NULL == iter->buf4); if (iter->ipaa != NULL) isc_mem_put(iter->mctx, iter->ipaa, iter->ipaasize); } else { REQUIRE(NULL == iter->ipaa); if (iter->buf4 != NULL) isc_mem_put(iter->mctx, iter->buf4, iter->buf4size); if (iter->buf6 != NULL) isc_mem_put(iter->mctx, iter->buf6, iter->buf6size); } iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); *iterp = NULL; }
isc_result_t isc_interfaceiter_next(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->result == ISC_R_SUCCESS); for (;;) { result = internal_next(iter); if (result == ISC_R_NOMORE) { result = internal_next6(iter); if (result != ISC_R_SUCCESS) break; result = internal_current6(iter); if (result != ISC_R_IGNORE) break; } else if (result != ISC_R_SUCCESS) break; result = internal_current(iter); if (result != ISC_R_IGNORE) break; } iter->result = result; return (result); }
static isc_result_t internal_current6(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; int i; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->pos6 >= 0); REQUIRE(iter->buf6 != 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET6; get_addr(AF_INET6, &iter->current.address, iter->buf6->Address[iter->pos6].lpSockaddr); /* * Get interface flags. */ iter->current.flags = INTERFACE_F_UP; if (ifNamed == FALSE) sprintf(iter->current.name, "TCP/IPv6 Interface %d", iter->pos6 + 1); for (i = 0; i< 16; i++) iter->current.netmask.type.in6.s6_addr[i] = 0xff; iter->current.netmask.family = AF_INET6; return (ISC_R_SUCCESS); }
static isc_result_t internal_current(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; unsigned long flags; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->numIF >= 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET; get_addr(AF_INET, &iter->current.address, (struct sockaddr *)&(iter->IFData.iiAddress)); /* * Get interface flags. */ iter->current.flags = 0; flags = iter->IFData.iiFlags; if ((flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; if ((flags & IFF_POINTTOPOINT) != 0) { iter->current.flags |= INTERFACE_F_POINTTOPOINT; sprintf(iter->current.name, "PPP Interface %d", iter->numIF); ifNamed = TRUE; } if ((flags & IFF_LOOPBACK) != 0) { iter->current.flags |= INTERFACE_F_LOOPBACK; sprintf(iter->current.name, "Loopback Interface %d", iter->numIF); ifNamed = TRUE; } /* * If the interface is point-to-point, get the destination address. */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { get_addr(AF_INET, &iter->current.dstaddress, (struct sockaddr *)&(iter->IFData.iiBroadcastAddress)); } if (ifNamed == FALSE) sprintf(iter->current.name, "TCP/IP Interface %d", iter->numIF); /* * Get the network mask. */ get_addr(AF_INET, &iter->current.netmask, (struct sockaddr *)&(iter->IFData.iiNetmask)); return (ISC_R_SUCCESS); }
isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { REQUIRE(VALID_IFITER(iter)); if (iter->buf6 != NULL) iter->pos6 = iter->buf6->iAddressCount; iter->result = ISC_R_SUCCESS; return (isc_interfaceiter_next(iter)); }
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; INSIST(ifa != NULL); INSIST(ifa->ifa_name != NULL); 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); memset(&iter->current, 0, sizeof(iter->current)); namelen = 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; iter->current.af = family; get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name); if (ifa->ifa_netmask != NULL) get_addr(family, &iter->current.netmask, ifa->ifa_netmask, ifa->ifa_name); if (ifa->ifa_dstaddr != NULL && (iter->current.flags & IFF_POINTOPOINT) != 0) get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr, ifa->ifa_name); return (ISC_R_SUCCESS); }
void isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; REQUIRE(VALID_IFITER(iter)); isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); *iterp = NULL; }
isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); iter->numIF = 0; for (;;) { result = internal_next(iter); if (result != ISC_R_SUCCESS) break; result = internal_current(iter, AF_INET); if (result != ISC_R_IGNORE) break; } iter->result = result; return (result); }
isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { REQUIRE(VALID_IFITER(iter)); /* * SIO_ADDRESS_LIST_QUERY (used to query IPv6 addresses) * intentionally omits localhost addresses ::1 and ::fe80 in * some cases. ntpd depends on enumerating ::1 to listen on * it, and ntpq and ntpdc default to "localhost" as the target, * so they will attempt to talk to [::1]:123 and fail. This * means we need to synthesize ::1, which we will do first, * hence + 1. */ if (iter->buf6 != NULL) iter->pos6 = iter->buf6->iAddressCount + 1; iter->result = ISC_R_SUCCESS; return (isc_interfaceiter_next(iter)); }
isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { REQUIRE(VALID_IFITER(iter)); REQUIRE(use_GAA_determined); /* * SIO_ADDRESS_LIST_QUERY (used to query IPv6 addresses) * intentionally omits localhost addresses [::1] and [::fe80] in * some cases. ntpd depends on enumerating [::1] to listen on * it, and ntpq and ntpdc default to "localhost" as the target, * so they will attempt to talk to [::1]:123 and fail. This * means we need to synthesize ::1, which we will do first, * hence iAddressCount + 1. internal_next6() will decrement * it before the first use as an index, and internal_current6() * will treat pos6 == iAddressCount as a sign to synthesize * [::1] if needed. */ if (!use_GAA && iter->buf6 != NULL) iter->pos6 = iter->buf6->iAddressCount + 1; iter->result = ISC_R_SUCCESS; return (isc_interfaceiter_next(iter)); }
isc_result_t isc_interfaceiter_next(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->result == ISC_R_SUCCESS); REQUIRE(use_GAA_determined); if (use_GAA) { do { result = internal_next_GAA(iter); if (ISC_R_NOMORE == result) goto set_result; result = internal_current_GAA(iter); } while (ISC_R_IGNORE == result); goto set_result; } for (;;) { result = internal_next(iter); if (result == ISC_R_NOMORE) { result = internal_next6(iter); if (result != ISC_R_SUCCESS) break; result = internal_current6(iter); if (result != ISC_R_IGNORE) break; } else if (result != ISC_R_SUCCESS) break; result = internal_current(iter); if (result != ISC_R_IGNORE) break; } set_result: iter->result = result; return (result); }
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); } }
static isc_result_t internal_current6(isc_interfaceiter_t *iter) { struct LIFREQ *ifrp; struct LIFREQ lifreq; int family; char strbuf[ISC_STRERRORSIZE]; 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 = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); memset(&lifreq, 0, sizeof(lifreq)); memmove(&lifreq, ifrp, sizeof(lifreq)); family = lifreq.lifr_addr.ss_family; #ifdef ISC_PLATFORM_HAVEIPV6 if (family != AF_INET && family != AF_INET6) #else if (family != AF_INET) #endif 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)); memmove(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 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 (ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%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; #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 (ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETDESTADDR, "%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 /* * Get the network mask. Netmask already zeroed. */ memset(&lifreq, 0, sizeof(lifreq)); memmove(&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; } 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 (ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETNETMASK, "%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); return (ISC_R_SUCCESS); }
static isc_result_t internal_current4(isc_interfaceiter_t *iter) { struct ifreq *ifrp; struct ifreq ifreq; int family; char strbuf[ISC_STRERRORSIZE]; #if !defined(ISC_PLATFORM_HAVEIF_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 = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); memset(&ifreq, 0, sizeof(ifreq)); memmove(&ifreq, ifrp, sizeof(ifreq)); family = ifreq.ifr_addr.sa_family; #if defined(ISC_PLATFORM_HAVEIPV6) if (family != AF_INET && family != AF_INET6) #else if (family != AF_INET) #endif 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)); memmove(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 (ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%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 (family == AF_INET) goto inet; #if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR) memset(&lifreq, 0, sizeof(lifreq)); memmove(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name)); memmove(&lifreq.lifr_addr, &iter->current.address.type.in6, sizeof(iter->current.address.type.in6)); if (ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: getting interface address: %s", ifreq.ifr_name, strbuf); return (ISC_R_IGNORE); } prefixlen = lifreq.lifr_addrlen; #else isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_INFO, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "prefix length for %s is unknown " "(assume 128)"), sabuf); prefixlen = 128; #endif /* * 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; } 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 (ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETDESTADDR, "%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 /* * Get the network mask. */ memset(&ifreq, 0, sizeof(ifreq)); memmove(&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 (ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETNETMASK, "%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); return (ISC_R_SUCCESS); }
static isc_result_t internal_current6(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; struct sockaddr_in6 *psa6; BOOL localhostSeen; int i; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->pos6 >= 0); REQUIRE(iter->buf6 != 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET6; /* * synthesize localhost ::1 before returning the rest, if ::1 * is not on the list. */ if (iter->pos6 >= (unsigned)iter->buf6->iAddressCount) { localhostSeen = FALSE; for (i = 0; i < iter->buf6->iAddressCount; i++) { psa6 = (struct sockaddr_in6 *) iter->buf6->Address[i].lpSockaddr; if (!memcmp(&iter->loop__1, &psa6->sin6_addr, sizeof(iter->loop__1))) { localhostSeen = TRUE; break; } } if (localhostSeen) iter->pos6 = iter->buf6->iAddressCount - 1; } if (iter->pos6 < (unsigned)iter->buf6->iAddressCount) { isc_netaddr_fromsockaddr(&iter->current.address, (isc_sockaddr_t *)iter->buf6->Address[iter->pos6].lpSockaddr); } else { iter->current.address.family = AF_INET6; memcpy(&iter->current.address.type.in6, &iter->loop__1, sizeof(iter->current.address.type.in6)); } /* * Get interface flags. */ iter->current.flags = INTERFACE_F_UP | INTERFACE_F_MULTICAST; if (!memcmp(&iter->current.address.type.in6, &iter->loop__1, sizeof(iter->current.address.type.in6)) || !memcmp(&iter->current.address.type.in6, &iter->loopfe80__1, sizeof(iter->current.address.type.in6))) { iter->current.flags |= INTERFACE_F_LOOPBACK; snprintf(iter->current.name, sizeof(iter->current.name), "v6loop %d", iter->buf6->iAddressCount - iter->pos6); ifNamed = TRUE; } if (ifNamed == FALSE) snprintf(iter->current.name, sizeof(iter->current.name), "IPv6 %d", iter->buf6->iAddressCount - iter->pos6); memset(iter->current.netmask.type.in6.s6_addr, 0xff, sizeof(iter->current.netmask.type.in6.s6_addr)); iter->current.netmask.family = AF_INET6; return (ISC_R_SUCCESS); }
static isc_result_t internal_current(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; unsigned long flags; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->numIF >= 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET; isc_netaddr_fromsockaddr(&iter->current.address, (isc_sockaddr_t *)&(iter->IFData.iiAddress)); /* * Get interface flags. */ iter->current.flags = 0; flags = iter->IFData.iiFlags; if ((flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; if ((flags & IFF_BROADCAST) != 0) iter->current.flags |= INTERFACE_F_BROADCAST; if ((flags & IFF_MULTICAST) != 0) iter->current.flags |= INTERFACE_F_MULTICAST; if ((flags & IFF_POINTTOPOINT) != 0) { iter->current.flags |= INTERFACE_F_POINTTOPOINT; snprintf(iter->current.name, sizeof(iter->current.name), "PPP %d", iter->numIF); ifNamed = TRUE; } if ((flags & IFF_LOOPBACK) != 0) { iter->current.flags |= INTERFACE_F_LOOPBACK; snprintf(iter->current.name, sizeof(iter->current.name), "v4loop %d", iter->numIF); ifNamed = TRUE; } /* * If the interface is point-to-point, get the destination address. */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) isc_netaddr_fromsockaddr(&iter->current.dstaddress, (isc_sockaddr_t *)&(iter->IFData.iiBroadcastAddress)); /* * Get the network mask. */ isc_netaddr_fromsockaddr(&iter->current.netmask, (isc_sockaddr_t *)&(iter->IFData.iiNetmask)); /* * If the interface is broadcast, get the broadcast address, * based on the unicast address and network mask. */ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) get_broadcastaddr(&iter->current.broadcast, &iter->current.address, &iter->current.netmask); if (ifNamed == FALSE) snprintf(iter->current.name, sizeof(iter->current.name), "IPv4 %d", iter->numIF); return (ISC_R_SUCCESS); }