This command returns an array of all guest interfaces among with their IP and HW addresses. --- src/qemu/qemu_agent.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_agent.h | 2 + 2 files changed, 137 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 7a0381c..cab02a0 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1410,3 +1410,138 @@ qemuAgentSuspend(qemuAgentPtr mon, virJSONValueFree(reply); return ret; } + +char * +qemuAgentGetInterfaces(qemuAgentPtr mon) +{ + char *ret = NULL; + int i, j, size = -1; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr ret_array = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL); + + if (!cmd) + return NULL; + + if (qemuAgentCommand(mon, cmd, &reply) < 0 || + qemuAgentCheckError(cmd, reply) < 0) + goto cleanup; + + if (!(ret_array = virJSONValueObjectGet(reply, "return"))) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qemu agent didn't provide 'return' field")); + goto cleanup; + } + + if ((size = virJSONValueArraySize(ret_array)) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qemu agent didn't return an array of interfaces")); + goto cleanup; + } + + virBufferAddLit(&buf, "<interfaces>\n"); + virBufferAdjustIndent(&buf, 2); + + for (i = 0; i < size; i++) { + virJSONValuePtr tmp_iface = virJSONValueArrayGet(ret_array, i); + virJSONValuePtr ip_addr_arr = NULL; + const char *name, *hwaddr; + int ip_addr_arr_size; + + /* Shouldn't happen but doesn't hurt to check neither */ + if (!tmp_iface) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("something has went really wrong")); + goto cleanup; + } + + virBufferAddLit(&buf, "<interface>\n"); + virBufferAdjustIndent(&buf, 2); + + /* interface name is required to be presented */ + name = virJSONValueObjectGetString(tmp_iface, "name"); + if (!name) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qemu agent didn't provide 'name' field")); + goto cleanup; + } + virBufferAsprintf(&buf, "<name>%s</name>\n", name); + + /* hwaddr might be omitted */ + hwaddr = virJSONValueObjectGetString(tmp_iface, "hardware-address"); + if (hwaddr) + virBufferAsprintf(&buf, "<hwaddr>%s</hwaddr>\n", hwaddr); + + /* as well as IP address which - moreover - + * can be presented multiple times */ + ip_addr_arr = virJSONValueObjectGet(tmp_iface, "ip-addresses"); + if (!ip_addr_arr) + goto interface_cont; + + if ((ip_addr_arr_size = virJSONValueArraySize(ip_addr_arr)) < 0) { + /* Mmm, empty 'ip-address'? */ + goto interface_cont; + } + + virBufferAddLit(&buf, "<addresses>\n"); + virBufferAdjustIndent(&buf, 2); + for (j = 0; j < ip_addr_arr_size; j++) { + virJSONValuePtr ip_addr_obj = virJSONValueArrayGet(ip_addr_arr, j); + const char *type, *addr; + int prefix; + + /* Shouldn't happen but doesn't hurt to check neither */ + if (!ip_addr_obj) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("something has went really wrong")); + goto cleanup; + } + + type = virJSONValueObjectGetString(ip_addr_obj, "ip-address-type"); + if (!type) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("qemu agent didn't provide 'ip-address-type'" + " field for interface '%s'"), name); + goto cleanup; + } + + addr = virJSONValueObjectGetString(ip_addr_obj, "ip-address"); + if (!addr) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("qemu agent didn't provide 'ip-address'" + " field for interface '%s'"), name); + goto cleanup; + } + + if (virJSONValueObjectGetNumberInt(ip_addr_obj, "prefix", + &prefix) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed 'prefix' field")); + goto cleanup; + } + virBufferAsprintf(&buf, "<ip type='%s' prefix='%d'>%s</ip>\n", + type, prefix, addr); + } + + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</addresses>\n"); + +interface_cont: + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</interface>\n"); + } + + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</interfaces>\n"); + + ret = virBufferContentAndReset(&buf); + +cleanup: + virBufferFreeAndReset(&buf); + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 0816d90..1561652 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -80,4 +80,6 @@ int qemuAgentFSThaw(qemuAgentPtr mon); int qemuAgentSuspend(qemuAgentPtr mon, unsigned int target); + +char *qemuAgentGetInterfaces(qemuAgentPtr mon); #endif /* __QEMU_AGENT_H__ */ -- 1.7.8.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list