]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Handle ranges properly during IP comparisons
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 15 Mar 2019 00:23:58 +0000 (18:23 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 15 Mar 2019 00:23:58 +0000 (18:23 -0600)
Hadn't implemented ranges when I implemented comparisons.
Then I forgot to update the code when I added ranges.

Fixes #3.

configure.ac
src/resource/asn.c
src/resource/ip4.c
src/resource/ip6.c
src/sorted_array.c

index c959e6aebd7857400cee41b70b46aad1cbef5b6f..da71f204171ed264b91ea93de29593260959ea9c 100644 (file)
@@ -10,8 +10,6 @@ AM_INIT_AUTOMAKE([subdir-objects])
 # Checks for programs.
 AC_PROG_CC
 
-# Checks for libraries.
-
 # Checks for header files.
 AC_CHECK_HEADERS([netinet/in.h stdlib.h string.h unistd.h])
 
index b140768c6673bd1213ff9cb04c7a1540e6c4839a..d63803ac18f1352af67dbe2f994b74b0f06a4696 100644 (file)
@@ -24,11 +24,11 @@ asn_cmp(void *arg1, void *arg2)
                return SACMP_CHILD;
        if (n2min <= n1min && n1max <= n2max)
                return SACMP_PARENT;
-       if (n1max == n2min - 1)
+       if (n2min != 0 && n1max == n2min - 1)
                return SACMP_ADJACENT_RIGHT;
        if (n1max < n2min)
                return SACMP_RIGHT;
-       if (n2max == n1min - 1)
+       if (n1min != 0 && n2max == n1min - 1)
                return SACMP_ADJACENT_LEFT;
        if (n2max < n1min)
                return SACMP_LEFT;
index f1902e6791d363841b1e5517fdf1645d802d8847..ff0201bb957260ce7dac9a7395308029b3c36da8 100644 (file)
@@ -21,10 +21,15 @@ r4_cmp(void *arg1, void *arg2)
                return SACMP_CHILD;
        if (n2min <= n1min && n1max <= n2max)
                return SACMP_PARENT;
+       if (n2min != 0 && n1max == n2min - 1)
+               return SACMP_ADJACENT_RIGHT;
        if (n1max < n2min)
                return SACMP_RIGHT;
+       if (n1min != 0 && n2max == n1min - 1)
+               return SACMP_ADJACENT_LEFT;
        if (n2max < n1min)
                return SACMP_LEFT;
+
        return SACMP_INTERSECTION;
 }
 
@@ -77,7 +82,8 @@ res4_add_range(struct resources_ipv4 *ips, struct ipv4_range *range)
        return sarray_add((struct sorted_array *) ips, &n);
 }
 
-bool res4_empty(struct resources_ipv4 *ips)
+bool
+res4_empty(struct resources_ipv4 *ips)
 {
        return sarray_empty((struct sorted_array *) ips);
 }
index dccf661c2b2072af302afe8b818ab77806926a33..20acce15967abfb8c3ef9f2054ace588d050aac6 100644 (file)
@@ -31,6 +31,25 @@ addr_lt(struct in6_addr const *a, struct in6_addr const *b)
        return addr_cmp(a, b) < 0;
 }
 
+/* a + 1 == b? */
+static bool
+addr_is_successor(struct in6_addr const *a, struct in6_addr const *b)
+{
+       struct in6_addr a_plus_1;
+       unsigned int i;
+
+       memcpy(&a_plus_1, a, sizeof(a_plus_1));
+       for (i = 15; i >= 0; i--) {
+               if (a_plus_1.s6_addr[i] != UINT8_MAX) {
+                       a_plus_1.s6_addr[i]++;
+                       return memcmp(&a_plus_1, b, sizeof(a_plus_1)) == 0;
+               }
+               a_plus_1.s6_addr[i] = 0;
+       }
+
+       return false; /* b cannot be the successor of 0xFFFFF...FFF */
+}
+
 static enum sarray_comparison
 r6_cmp(void *arg1, void *arg2)
 {
@@ -45,10 +64,15 @@ r6_cmp(void *arg1, void *arg2)
                return SACMP_CHILD;
        if (addr_le(a2min, a1min) && addr_le(a1max, a2max))
                return SACMP_PARENT;
+       if (addr_is_successor(a1max, a2min))
+               return SACMP_ADJACENT_RIGHT;
        if (addr_lt(a1max, a2min))
                return SACMP_RIGHT;
+       if (addr_is_successor(a2max, a1min))
+               return SACMP_ADJACENT_LEFT;
        if (addr_lt(a2max, a1min))
                return SACMP_LEFT;
+
        return SACMP_INTERSECTION;
 }
 
index ac2fd1267f2b2e0516fd6dd87c12fc6d6a093615..42434382777736c618d94d46edd6a9a3b38cff7f 100644 (file)
@@ -161,16 +161,16 @@ sarray_contains(struct sorted_array *sarray, void *elem)
                        continue;
                case SACMP_RIGHT:
                case SACMP_ADJACENT_RIGHT:
+                       if (mid == sarray->count - 1)
+                               return false;
                        left = mid + 1;
                        continue;
                case SACMP_EQUAL:
                case SACMP_CHILD:
                        return true;
                case SACMP_PARENT:
-                       return false;
                case SACMP_INTERSECTION:
-                       /* Fall through; it's not supposed to happen here. */
-                       break;
+                       return false;
                }
 
                pr_crit("Unknown comparison value: %u", cmp);