[libvirt] [PATCH] 2/3 Store the range size when adding a DHCP range

Daniel Veillard veillard at redhat.com
Tue Oct 13 14:14:00 UTC 2009


    * 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 at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list