This command returns an array of all guest interfaces among
with their IP and HW addresses.
---
src/qemu/qemu_agent.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 2 +
2 files changed, 173 insertions(+)
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index bb421bd..409ba04 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -1474,3 +1474,174 @@ qemuAgentFSTrim(qemuAgentPtr mon,
virJSONValueFree(reply);
return ret;
}
+
+static int
+getInterfaces(virJSONValuePtr reply,
+ virDomainInterfacePtr **ifaces)
+{
+ int ret = -1;
+ int i, size = 0;
+ virJSONValuePtr replyArray = NULL;
+
+ if (!(replyArray = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent did not provide 'return'
object"));
+ goto cleanup;
+ }
+
+ if ((size = virJSONValueArraySize(replyArray)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent did not provide any interface"));
+ goto cleanup;
+ }
+
+ if (size && VIR_ALLOC_N(*ifaces, size * sizeof(virDomainInterfacePtr)) <
0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ for (i = 0; i < size; i++) {
+ virJSONValuePtr jsonIface = virJSONValueArrayGet(replyArray, i);
+ virDomainInterfacePtr tmpIface = NULL;
+ virJSONValuePtr jsonIpAddrArr = NULL;
+ int j, jsonIpAddrArrSize = 0;
+ const char *name, *hwaddr;
+
+ if (VIR_ALLOC(tmpIface) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ (*ifaces)[i] = tmpIface;
+ /* should not happen, but doesn't hurt to check */
+ if (!jsonIface) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Something went really wrong while processing "
+ "guest agent reply"));
+ goto cleanup;
+ }
+
+ name = virJSONValueObjectGetString(jsonIface, "name");
+ if (!name) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent did not provide 'name'
object"));
+ goto cleanup;
+ }
+
+ if (!(tmpIface->name = strdup(name))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* hwaddr might be omitted */
+ hwaddr = virJSONValueObjectGetString(jsonIface, "hardware-address");
+ if (hwaddr && !(tmpIface->hwaddr = strdup(hwaddr))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* as well as ip-addresses */
+ jsonIpAddrArr = virJSONValueObjectGet(jsonIface, "ip-addresses");
+ if (!jsonIpAddrArr)
+ continue;
+
+ if ((jsonIpAddrArrSize = virJSONValueArraySize(jsonIpAddrArr)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent provided malformed "
+ "ip-addresses field"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(tmpIface->ip_addrs, jsonIpAddrArrSize) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ tmpIface->ip_addrs_count = jsonIpAddrArrSize;
+
+ for (j = 0; j < jsonIpAddrArrSize; j++) {
+ virJSONValuePtr jsonIpAddr = virJSONValueArrayGet(jsonIpAddrArr, j);
+ virDomainIPAddressPtr tmpIpAddr = &(tmpIface->ip_addrs[j]);
+ const char *ipAddr, *ipAddrType;
+
+ if (!(ipAddr = virJSONValueObjectGetString(jsonIpAddr,
+ "ip-address"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu-agent didn't provided "
+ "an ip-address field"));
+ goto cleanup;
+ }
+
+ if (!(tmpIpAddr->addr = strdup(ipAddr))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (!(ipAddrType = virJSONValueObjectGetString(jsonIpAddr,
+ "ip-address-type")))
{
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu-agent didn't provided "
+ "an ip-address-type field"));
+ goto cleanup;
+ }
+
+ if (STREQ(ipAddrType, "ipv4"))
+ tmpIpAddr->type = VIR_IP_ADDR_TYPE_IPV4;
+ else if (STREQ(ipAddrType, "ipv6"))
+ tmpIpAddr->type = VIR_IP_ADDR_TYPE_IPV6;
+ else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("qemu agent provided unknown "
+ "ip-address-type '%s'"),
+ ipAddrType);
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberInt(jsonIpAddr, "prefix",
+ &(tmpIpAddr->prefix)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu agent provided "
+ "malformed prefix field"));
+ goto cleanup;
+ }
+
+ /* Nor broadcast address is reported */
+ }
+ }
+
+ ret = size;
+
+cleanup:
+ if (ret < 0) {
+ for (i = 0; i < size; i++)
+ virDomainInterfaceFree((*ifaces)[i]);
+ VIR_FREE(*ifaces);
+ }
+ return ret;
+}
+
+int
+qemuAgentGetInterfaces(qemuAgentPtr mon,
+ virDomainInterfacePtr **ifaces)
+{
+ int ret = -1;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL);
+
+ if (!cmd)
+ return ret;
+
+ ret = qemuAgentCommand(mon, cmd, &reply,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK);
+
+ if (reply && ret == 0)
+ ret = qemuAgentCheckError(cmd, reply);
+
+ if (ret == 0)
+ ret = getInterfaces(reply, ifaces);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index dad068b..0c22920 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -85,4 +85,6 @@ int qemuAgentArbitraryCommand(qemuAgentPtr mon,
int timeout);
int qemuAgentFSTrim(qemuAgentPtr mon,
unsigned long long minimum);
+int qemuAgentGetInterfaces(qemuAgentPtr mon,
+ virDomainInterfacePtr **ifaces);
#endif /* __QEMU_AGENT_H__ */
--
1.8.0.2