return false;
}
#endif /* HAVE_NETDB */
+
+#ifdef HAVE_NETDB
+const char *nvme_iface_matching_addr(const struct ifaddrs *iface_list, const char *addr)
+{
+ const struct ifaddrs *iface_it;
+ struct addrinfo *info = NULL, hint = { .ai_flags = AI_NUMERICHOST, .ai_family = AF_UNSPEC };
+ const char *iface_name = NULL;
+
+ if (!iface_list || !addr || getaddrinfo(addr, 0, &hint, &info) || !info)
+ return NULL;
+
+ /* Walk through the linked list */
+ for (iface_it = iface_list; iface_it != NULL; iface_it = iface_it->ifa_next) {
+ struct sockaddr *ifaddr = iface_it->ifa_addr;
+
+ if (ifaddr && (ifaddr->sa_family == AF_INET || ifaddr->sa_family == AF_INET6) &&
+ _nvme_ipaddrs_eq(info->ai_addr, ifaddr)) {
+ iface_name = iface_it->ifa_name;
+ break;
+ }
+ }
+
+ freeaddrinfo(info);
+
+ return iface_name;
+}
+
+bool nvme_iface_primary_addr_matches(const struct ifaddrs *iface_list, const char *iface, const char *addr)
+{
+ const struct ifaddrs *iface_it;
+ struct addrinfo *info = NULL, hint = { .ai_flags = AI_NUMERICHOST, .ai_family = AF_UNSPEC };
+ bool match_found = false;
+
+ if (!iface_list || !addr || getaddrinfo(addr, 0, &hint, &info) || !info)
+ return false;
+
+ /* Walk through the linked list */
+ for (iface_it = iface_list; iface_it != NULL; iface_it = iface_it->ifa_next) {
+ if (strcmp(iface, iface_it->ifa_name))
+ continue; /* Not the interface we're looking for*/
+
+ /* The interface list is ordered in a way that the primary
+ * address is listed first. As soon as the parsed address
+ * matches the family of the address we're looking for, we
+ * have found the primary address for that family.
+ */
+ if (iface_it->ifa_addr && (iface_it->ifa_addr->sa_family == info->ai_addr->sa_family)) {
+ match_found = _nvme_ipaddrs_eq(info->ai_addr, iface_it->ifa_addr);
+ break;
+ }
+ }
+
+ freeaddrinfo(info);
+
+ return match_found;
+}
+
+#else /* HAVE_NETDB */
+
+const char *nvme_iface_matching_addr(const struct ifaddrs *iface_list, const char *addr)
+{
+ nvme_msg(NULL, LOG_ERR, "no support for interface lookup; "
+ "recompile with libnss support.\n");
+
+ return NULL;
+}
+
+bool nvme_iface_primary_addr_matches(const struct ifaddrs *iface_list, const char *iface, const char *addr)
+{
+ nvme_msg(NULL, LOG_ERR, "no support for interface lookup; "
+ "recompile with libnss support.\n");
+
+ return false;
+}
+
+#endif /* HAVE_NETDB */
#ifndef _LIBNVME_UTIL_H
#define _LIBNVME_UTIL_H
+#include <ifaddrs.h>
+
#include "types.h"
/**
*/
bool nvme_ipaddrs_eq(const char *addr1, const char *addr2);
+/**
+ * nvme_iface_matching_addr - Get interface matching @addr
+ * @iface_list: Interface list returned by getifaddrs()
+ * @addr: Address to match
+ *
+ * Parse the interface list pointed to by @iface_list looking
+ * for the interface that has @addr as one of its assigned
+ * addresses.
+ *
+ * Return: The name of the interface that owns @addr or NULL.
+ */
+const char *nvme_iface_matching_addr(const struct ifaddrs *iface_list, const char *addr);
+
+/**
+ * nvme_iface_primary_addr_matches - Check that interface's primary address matches
+ * @iface_list: Interface list returned by getifaddrs()
+ * @iface: Interface to match
+ * @addr: Address to match
+ *
+ * Parse the interface list pointed to by @iface_list and looking for
+ * interface @iface. The get its primary address and check if it matches
+ * @addr.
+ *
+ * Return: true if a match is found, false otherwise.
+ */
+bool nvme_iface_primary_addr_matches(const struct ifaddrs *iface_list, const char *iface, const char *addr);
+
#endif /* _LIBNVME_UTIL_H */