This API returns dynamically allocated array of IP addresses for
all domain interfaces.
---
include/libvirt/libvirt.h.in | 32 +++++++++++++
python/generator.py | 1 +
src/driver.h | 6 +++
src/libvirt.c | 101 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++
5 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index da3ce29..604e598 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1659,6 +1659,38 @@ int virDomainGetInterfaceParameters
(virDomainPtr dom,
virTypedParameterPtr params,
int *nparams, unsigned int
flags);
+typedef enum {
+ VIR_IP_ADDR_TYPE_IPV4,
+ VIR_IP_ADDR_TYPE_IPV6,
+
+#ifdef VIR_ENUM_SENTINELS
+ VIR_IP_ADDR_TYPE_LAST
+#endif
+} virIPAddrType;
+
+
+typedef struct _virDomainInterfaceIPAddress virDomainIPAddress;
+typedef virDomainIPAddress *virDomainIPAddressPtr;
+struct _virDomainInterfaceIPAddress {
+ int type; /* virIPAddrType */
+ char *addr; /* IP address */
+ int prefix; /* IP address prefix */
+};
+
+typedef struct _virDomainInterface virDomainInterface;
+typedef virDomainInterface *virDomainInterfacePtr;
+struct _virDomainInterface {
+ char *name; /* interface name */
+ char *hwaddr; /* hardware address */
+ unsigned int ip_addrs_count; /* number of items in @ip_addr */
+ virDomainIPAddressPtr ip_addrs; /* array of IP addresses */
+};
+
+int virDomainInterfacesAddresses (virDomainPtr dom,
+ virDomainInterfacePtr *ifaces,
+ unsigned int *ifaces_count,
+ unsigned int flags);
+
/* Management of domain block devices */
int virDomainBlockPeek (virDomainPtr dom,
diff --git a/python/generator.py b/python/generator.py
index 9530867..747d1a8 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -425,6 +425,7 @@ skip_impl = (
'virDomainGetInterfaceParameters',
'virDomainGetCPUStats',
'virDomainGetDiskErrors',
+ 'virDomainInterfacesAddresses',
)
qemu_skip_impl = (
diff --git a/src/driver.h b/src/driver.h
index aa7a377..336ad31 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -394,6 +394,11 @@ typedef int
const char *device,
virTypedParameterPtr params,
int *nparams, unsigned int flags);
+typedef int
+ (*virDrvDomainInterfacesAddresses) (virDomainPtr dom,
+ virDomainInterfacePtr *ifaces,
+ unsigned int *ifaces_count,
+ unsigned int flags);
typedef int
(*virDrvDomainMemoryStats)
@@ -943,6 +948,7 @@ struct _virDriver {
virDrvDomainInterfaceStats domainInterfaceStats;
virDrvDomainSetInterfaceParameters domainSetInterfaceParameters;
virDrvDomainGetInterfaceParameters domainGetInterfaceParameters;
+ virDrvDomainInterfacesAddresses domainInterfacesAddresses;
virDrvDomainMemoryStats domainMemoryStats;
virDrvDomainBlockPeek domainBlockPeek;
virDrvDomainMemoryPeek domainMemoryPeek;
diff --git a/src/libvirt.c b/src/libvirt.c
index 6386ed4..2e30a14 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7347,6 +7347,107 @@ error:
}
/**
+ * virDomainInterfacesAddresses:
+ * @dom: domain object
+ * @ifaces: array of @dom interfaces
+ * @ifaces_count: number of items in @ifaces
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Return an array of interfaces presented in given domain
+ * among with their IP and HW addresses. Note, that single
+ * interface can have multiple or even none IP address.
+ *
+ * This API dynamically allocates the virDomainInterfacePtr
+ * struct based on how much interfaces domain @dom has,
+ * usually there's 1:1 correlation. The count of elements
+ * allocated is stored in @ifaces_count.
+ *
+ * Note that for some hypervisors a configured guest agent
+ * is needed for successful return from this API.
+ * Moreover, if guest agent is used then the interface name
+ * is the one seen by guest OS. To match such interface with
+ * the one from @dom XML use HW address or IP range.
+ *
+ * @ifaces->name is never NULL, @ifaces->hwaddr might be NULL,
+ *
+ * The caller *must* free @ifaces when no longer needed.
+ * Usual use case looks like this:
+ *
+ * virDomainInterfacePtr ifaces = NULL;
+ * unsigned int ifaces_count = 0;
+ * unsigned int i, j;
+ * virDomainPtr dom = ... obtain a domain here ...;
+ *
+ * if (virDomainInterfacesAddresses(dom, &ifaces, &ifaces_count, 0) < 0)
+ * goto cleanup;
+ *
+ * ... do something with returned values, for example:
+ * for (i = 0; i < ifaces_count; i++) {
+ * printf("name: %s", ifaces[i].name);
+ * if (ifaces[i].hwaddr)
+ * printf(" hwaddr: %s", ifaces[i].hwaddr);
+ *
+ * for (j = 0; j < ifaces[i].ip_addrs_count; j++) {
+ * virDomainIPAddressPtr ip_addr = ifaces[i].ip_addrs + j;
+ * printf("[addr: %s prefix: %d type: %d]",
+ * ip_addr->addr, ip_addr->prefix, ip_addr->type);
+ * }
+ * printf("\n");
+ * }
+ *
+ * cleanup:
+ * for (i = 0; i < ifaces_count; i++) {
+ * free(ifaces[i].name);
+ * free(ifaces[i].hwaddr);
+ * for (j = 0; j < ifaces[i].ip_addrs_count; j++)
+ * free(ifaces[i].ip_addrs[j].addr);
+ * free(ifaces[i].ip_addrs);
+ * }
+ * free(ifaces);
+ *
+ * Returns 0 on success,
+ * -1 in case of error
+ */
+int
+virDomainInterfacesAddresses (virDomainPtr dom,
+ virDomainInterfacePtr *ifaces,
+ unsigned int *ifaces_count,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "ifaces=%p, ifaces_count=%p, flags=%x",
+ ifaces, ifaces_count, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ goto error;
+ }
+
+ conn = dom->conn;
+
+ virCheckNonNullArgGoto(ifaces, error);
+ virCheckNonNullArgGoto(ifaces_count, error);
+
+ if (conn->driver->domainInterfacesAddresses) {
+ int ret;
+ ret = conn->driver->domainInterfacesAddresses(dom, ifaces,
+ ifaces_count, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(dom ? dom->conn : NULL);
+ return -1;
+}
+
+/**
* virDomainMemoryStats:
* @dom: pointer to the domain object
* @stats: nr_stats-sized array of stat structures (returned)
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 46c13fb..54b094e 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -534,4 +534,9 @@ LIBVIRT_0.9.11 {
virDomainPMWakeup;
} LIBVIRT_0.9.10;
+LIBVIRT_0.9.13 {
+ global:
+ virDomainInterfacesAddresses;
+} LIBVIRT_0.9.11;
+
# .... define new API here using predicted next version number ....
--
1.7.8.5