* src/conf/network_conf.h: extend the structure to store the range * src/conf/network_conf.c: before adding a range parse the IP addresses do some checking and keep the size diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 14eb543..992e02a 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -217,6 +217,90 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets, } } +static int +virNetworkDHCPCheckRange(virConnectPtr conn, + const char *start, const char *end) { + virIPv4Val ip4s, ip4e; + virIPv6Val ip6s, ip6e; + int ret; + int i; + + if (virParseIPv4(start, &ip4s) == 0) { + if (virParseIPv4(end, &ip4e) < 0) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot parse IPv4 address '%s'"), + end); + return(-1); + } + + /* + * check at least the 2 first IP match i.e on same class C subnet + */ + for (i = 0; i < 2;i++) { + if (ip4s[i] != ip4e[i]) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("start and end of DHCP range do not match '%s' and '%s'"), + start, end); + return(-1); + } + } + ret = ip4e[3] - ip4s[3] + 256 * (ip4e[2] - ip4s[2]); + + /* + * a bit of sanity checking on the range + * Should we complain for a range of more than 10,000 ? + */ + if (ret < 0) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("start and end of DHCP range swapped '%s' and '%s'"), + start, end); + return(-1); + } + + /* include the boundaries */ + ret++; + } else if (virParseIPv6(start, &ip6s) == 0) { + if (virParseIPv6(end, &ip6e) < 0) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot parse IPv6 address '%s'"), + end); + return(-1); + } + + /* + * check the prefix up to the last group are identical + */ + for (i = 0; i < 7;i++) { + if (ip6s[i] != ip6e[i]) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("start and end of DHCP range do not match '%s' and '%s'"), + start, end); + return(-1); + } + } + ret = ip6e[7] - ip6s[7]; + + /* + * a bit of sanity checking on the range + * Should we complain for a range of more than 10,000 ? + */ + if (ret < 0) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("start and end of DHCP range swapped '%s' and '%s'"), + start, end); + return(-1); + } + + /* include the boundaries */ + ret++; + } else { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot parse IP address '%s'"), + start); + return(-1); + } + return(ret); +} static int virNetworkDHCPRangeDefParseXML(virConnectPtr conn, @@ -230,6 +314,7 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn, if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "range")) { xmlChar *start, *end; + int range; if (!(start = xmlGetProp(cur, BAD_CAST "start"))) { cur = cur->next; @@ -240,6 +325,13 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn, xmlFree(start); continue; } + range = virNetworkDHCPCheckRange(conn, (const char *)start, + (const char *)end); + if (range < 0) { + xmlFree(start); + xmlFree(end); + continue; + } if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) { xmlFree(start); @@ -249,6 +341,7 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn, } def->ranges[def->nranges].start = (char *)start; def->ranges[def->nranges].end = (char *)end; + def->ranges[def->nranges].size = range; def->nranges++; } else if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "host")) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index e983a01..2960e8b 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -45,6 +45,7 @@ typedef virNetworkDHCPRangeDef *virNetworkDHCPRangeDefPtr; struct _virNetworkDHCPRangeDef { char *start; char *end; + int size; }; typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef; Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list