On 01/03/13 14:46, Michal Privoznik wrote: > 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(); size is > 0 now and *ifaces = NULL, if you jump to cleanup you'll dereference it. I'd suggest just returning -1 here and above. > + 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++) { extra space > + 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")); didn't provide > + 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")); here too > + 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]); (*ifaces)[i] might be NULL here, but virDomainInterfaceFree doesn't check for that. > + VIR_FREE(*ifaces); > + } > + return ret; > +} > + -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list