On Tue, Nov 26, 2013 at 02:36:00AM +0530, Nehal J Wani wrote: > diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c > index 83dc931..1aedf86 100644 > --- a/src/network/bridge_driver.c > +++ b/src/network/bridge_driver.c > @@ -2991,6 +3023,220 @@ cleanup: > return ret; > } > > +/* This function parses the leases file of dnsmasq. > + * > + * An example of custom leases file content: > + * > + * 1385245780 52:54:00:2f:ba:76 * 192.168.150.153 * * > + * 1385245781 52:54:00:2f:ba:76 3127926 2001:db8:ca2:2:1::6c * 00:04:76:00:cf:ae:b3:0b:fc:cd:0e:22:2e:97:76:65:74:ec > + * 1385245964 52:54:00:44:7c:d7 * 192.168.150.219 iiit-ad885e4aa1 01:52:54:00:44:7c:d7 > + * 1385245964 52:54:00:44:7c:d7 * 192.168.150.219 * 01:52:54:00:44:7c:d7 > + * 1385246016 52:54:00:5d:99:92 * 192.168.150.212 iiit-ad885e4aa1 01:52:54:00:5d:99:92 > + * 1385246041 52:54:00:3b:16:e0 * 192.168.150.207 * * > + * 1385246081 52:54:00:db:dd:98 * 192.168.150.234 * * > + * 1385246088 52:54:00:db:dd:98 14409112 2001:db8:ca2:2:1::6d * 00:04:76:00:cf:ae:b3:0b:fc:cd:0e:22:2e:97:76:65:74:ec > + * > + */ > +static int > +networkGetDHCPLeasesHelper(virNetworkObjPtr obj, > + const char *mac, > + virNetworkDHCPLeasesPtr **leases) > +{ > + int rv = -1; > + size_t i = 0; > + size_t nleases = 0; > + char *lease_file = NULL; > + char **lease_fields = NULL; > + char *lease_entries = NULL; > + char *lease_entry = NULL; > + virNetworkDHCPLeasesPtr *leases_ret = NULL; > + virNetworkDHCPLeasesPtr lease = NULL; > + int lease_file_len = 0; > + bool ipv6 = false; > + bool need_results = !!leases; > + > + /* Retrieve custom leases file location */ > + lease_file = networkDnsmasqLeaseFileNameCustom(obj->def->bridge); > + > + if ((lease_file_len = virFileReadAll(lease_file, > + VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX, > + &lease_entries)) < 0) { Small indentation alignemnt bug. > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("No leases available for network: %s"), obj->def->name); Hmm, if we have started the network, but no VMs have yet booted, then will we find that the lease file does not exist ? Or is the lease file guaranteed to exist, even if no leases have been assigned yet. Basically we must make sure we don't return an error if no leases have been handed out yet - just return 0 lease results. > + goto cleanup; > + } > + > + lease_entry = lease_entries[0] == '\0' ? NULL : lease_entries; > + > + while (lease_entry) { > + int nfields = 0; > + ipv6 = false; > + > + char *eol = strchr(lease_entry, '\n'); > + *eol = '\0'; > + > + /* Split the lease line */ > + if (!(lease_fields = virStringSplit(lease_entry, " ", > + VIR_NETWORK_DHCP_LEASE_FIELDS))) > + goto error; > + > + nfields = virStringListLength(lease_fields); > + > + /* Forward lease_entry to the next lease */ > + lease_entry = strchr(lease_entry, '\0'); > + if (lease_entry - lease_entries + 1 < lease_file_len) > + lease_entry++; > + else > + lease_entry = NULL; > + > + if (nfields != VIR_NETWORK_DHCP_LEASE_FIELDS) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Number of lease params aren't equal to: %d"), > + VIR_NETWORK_DHCP_LEASE_FIELDS); > + goto error; > + } > + > + if (mac && virMacAddrCompare(mac, lease_fields[1])) { > + virStringFreeList(lease_fields); > + continue; > + } > + > + if (need_results) { > + if (VIR_ALLOC(lease) < 0) > + goto error; > + > + /* Convert expirytime here */ > + if (virStrToLong_ll(lease_fields[0], NULL, 10, &(lease->expirytime)) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Unable to convert lease expiry time to integer: %s"), > + lease_fields[0]); > + goto error; > + } > + > + /* Unlike IPv4, IPv6 uses ':' instead of '.' as separator */ > + ipv6 = strchr(lease_fields[3], ':') ? true : false; > + > + lease->type = ipv6 ? VIR_IP_ADDR_TYPE_IPV6 : VIR_IP_ADDR_TYPE_IPV4; > + lease->prefix = virSocketAddrGetIpPrefix(&obj->def->ips->address, > + &obj->def->ips->netmask, > + obj->def->ips->prefix); > + > + if ((VIR_STRDUP(lease->mac, lease_fields[1]) < 0) || > + (VIR_STRDUP(lease->ipaddr, lease_fields[3]) < 0) || > + (VIR_STRDUP(lease->interface, obj->def->bridge) < 0)) > + goto error; > + > + /* IAID is NULL in case of ipv4 */ > + if (STREQ(lease_fields[2], "*")) > + lease->iaid = NULL; > + else if (VIR_STRDUP(lease->iaid, lease_fields[2]) < 0) > + goto error; > + > + /* Only two fields, hostname and clientid can be NULL > + * Refer: http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2013q3/007544.html > + */ > + if (STREQ(lease_fields[4], "*")) > + lease->hostname = NULL; > + else if (VIR_STRDUP(lease->hostname, lease_fields[4]) < 0) > + goto error; > + > + if (STREQ(lease_fields[5], "*")) > + lease->clientid = NULL; > + else if (VIR_STRDUP(lease->clientid, lease_fields[5]) < 0) > + goto error; > + > + if (VIR_INSERT_ELEMENT(leases_ret, nleases, nleases, lease) < 0) > + goto error; > + } > + else > + nleases++; > + > + VIR_FREE(lease); > + virStringFreeList(lease_fields); > + } > + > + lease_fields = NULL; > + > + if (need_results && mac && !leases_ret) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("no lease with matching MAC address: %s"), mac); > + goto error; > + } > + > + if (leases_ret) { > + /* NULL terminated array */ > + ignore_value(VIR_REALLOC_N(leases_ret, nleases + 1)); > + *leases = leases_ret; > + leases_ret = NULL; > + } > + > + rv = nleases; > + > +cleanup: > + VIR_FREE(lease); > + VIR_FREE(lease_file); > + VIR_FREE(lease_entries); > + if (lease_fields) > + virStringFreeList(lease_fields); > + return rv; > + > +error: > + if (leases_ret) { > + for (i = 0; i < nleases; i++) > + virNetworkDHCPLeaseFree(leases_ret[i]); > + VIR_FREE(leases_ret); > + } > + goto cleanup; > +} > + > +static int > +networkGetDHCPLeases(virNetworkPtr network, > + virNetworkDHCPLeasesPtr **leases, > + unsigned int flags) > +{ > + int rv = -1; > + virNetworkObjPtr obj; > + > + virCheckFlags(0, -1); > + > + if (!(obj = networkObjFromNetwork(network))) > + return rv; > + > + if (virNetworkGetDHCPLeasesEnsureACL(network->conn, obj->def) < 0) > + goto cleanup; > + > + rv = networkGetDHCPLeasesHelper(obj, NULL, leases); > + > +cleanup: > + if (obj) > + virNetworkObjUnlock(obj); > + return rv; > +} > + > +static int > +networkGetDHCPLeasesForMAC(virNetworkPtr network, > + const char *mac, > + virNetworkDHCPLeasesPtr **leases, > + unsigned int flags) > +{ > + int rv = -1; > + virNetworkObjPtr obj; > + > + virCheckFlags(0, -1); > + > + if (!(obj = networkObjFromNetwork(network))) > + return rv; > + > + if (virNetworkGetDHCPLeasesForMACEnsureACL(network->conn, obj->def) < 0) > + goto cleanup; > + > + rv = networkGetDHCPLeasesHelper(obj, mac, leases); > + > +cleanup: > + if (obj) > + virNetworkObjUnlock(obj); > + return rv; > +} > > static virNetworkDriver networkDriver = { > "Network", > @@ -3015,6 +3261,8 @@ static virNetworkDriver networkDriver = { > .networkSetAutostart = networkSetAutostart, /* 0.2.1 */ > .networkIsActive = networkIsActive, /* 0.7.3 */ > .networkIsPersistent = networkIsPersistent, /* 0.7.3 */ > + .networkGetDHCPLeases = networkGetDHCPLeases, /* 1.1.4 */ > + .networkGetDHCPLeasesForMAC = networkGetDHCPLeasesForMAC, /* 1.1.4 */ s/1.1.4/1.2.1/ now Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list