From: Alberto Leiva Popper Date: Fri, 15 Mar 2019 00:23:58 +0000 (-0600) Subject: Handle ranges properly during IP comparisons X-Git-Tag: v0.0.2~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=088b07422ad73e9eff06178f6f2bc47589f8ad72;p=thirdparty%2FFORT-validator.git Handle ranges properly during IP comparisons Hadn't implemented ranges when I implemented comparisons. Then I forgot to update the code when I added ranges. Fixes #3. --- diff --git a/configure.ac b/configure.ac index c959e6ae..da71f204 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/resource/asn.c b/src/resource/asn.c index b140768c..d63803ac 100644 --- a/src/resource/asn.c +++ b/src/resource/asn.c @@ -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; diff --git a/src/resource/ip4.c b/src/resource/ip4.c index f1902e67..ff0201bb 100644 --- a/src/resource/ip4.c +++ b/src/resource/ip4.c @@ -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); } diff --git a/src/resource/ip6.c b/src/resource/ip6.c index dccf661c..20acce15 100644 --- a/src/resource/ip6.c +++ b/src/resource/ip6.c @@ -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; } diff --git a/src/sorted_array.c b/src/sorted_array.c index ac2fd126..42434382 100644 --- a/src/sorted_array.c +++ b/src/sorted_array.c @@ -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);