]> git.ipfire.org Git - network.git/commitdiff
DHCP: Do not accept overlapping subnet ranges
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 8 Sep 2016 17:09:34 +0000 (19:09 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 8 Sep 2016 17:09:34 +0000 (19:09 +0200)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/functions/functions.dhcpd
src/functions/functions.ipv4
src/functions/functions.ipv6

index fbce20502e31df8c3297100679d10d17a1097cc1..0c8f7056372deee08fbf347335221c2fc854cce3 100644 (file)
@@ -761,6 +761,13 @@ dhcpd_subnet_range_new() {
                return ${EXIT_ERROR}
        fi
 
+       # Search for any overlaps
+       local overlaps=$(dhcpd_subnet_range_overlaps ${proto} ${subnet} ${range})
+       if isset overlaps; then
+               error "DHCP subnet range ${range} overlaps with ${overlaps}"
+               return ${EXIT_ERROR}
+       fi
+
        # Write the configuration to file.
        local file=$(dhcpd_subnet_range_path ${proto} ${subnet} ${range})
        assert isset file
@@ -851,6 +858,57 @@ dhcpd_subnet_range_exists() {
        return ${EXIT_FALSE}
 }
 
+dhcpd_subnet_range_overlaps() {
+       assert [ $# -eq 3 ]
+
+       local proto=${1}
+       local subnet=${2}
+       local range=${3}
+
+       local start=${range%-*}
+       local end=${range#*-}
+
+       assert isset start
+       assert isset end
+
+       local settings=$(dhcpd_subnet_range_settings ${proto})
+
+       local r ${settings}
+       for r in $(dhcpd_subnet_range_list ${proto} ${subnet}); do
+               dhcpd_subnet_range_read ${proto} ${subnet} ${r}
+
+               # Check if the new range is a sub-range of any existing range
+
+               # Check if the start address is somewhere in this range
+               if ${proto}_addr_ge ${START} ${start} && ${proto}_addr_le ${START} ${end}; then
+                       print "${r}"
+                       return ${EXIT_TRUE}
+               fi
+
+               # Check if the end address is somewhere in this range
+               if ${proto}_addr_ge ${END} ${start} && ${proto}_addr_le ${END} ${end}; then
+                       print "${r}"
+                       return ${EXIT_TRUE}
+               fi
+
+               # Check if any existing range is a sub-range of the new range
+
+               # Check if the start address is somewhere in this range
+               if ${proto}_addr_ge ${start} ${START} && ${proto}_addr_le ${start} ${END}; then
+                       print "${r}"
+                       return ${EXIT_TRUE}
+               fi
+
+               # Check if the end address is somewhere in this range
+               if ${proto}_addr_ge ${end} ${START} && ${proto}_addr_le ${end} ${END}; then
+                       print "${r}"
+                       return ${EXIT_TRUE}
+               fi
+       done
+
+       return ${EXIT_FALSE}
+}
+
 dhcpd_subnet_settings() {
        local proto=${1}
 
index 87a2fdba0abf5c08e59b4c9b960d53b6c4b8d0bf..0f1455cae78076943dff030370659cdd2398fa31 100644 (file)
@@ -290,6 +290,18 @@ ipv4_addr_gt() {
                && return ${EXIT_TRUE} || return ${EXIT_FALSE}
 }
 
+ipv4_addr_ge() {
+       ipv4_addr_eq $@ || ipv4_addr_gt $@
+}
+
+ipv4_addr_lt() {
+       ! ipv4_addr_eq $@ && ! ipv4_addr_gt $@
+}
+
+ipv4_addr_le() {
+       ipv4_addr_eq $@ || ! ipv4_addr_gt $@
+}
+
 ipv4_range() {
        local range=${1}
 
index 229913535e688b25935065488930d23f992d6caa..f2a5fadd36b7a90da49aeb87fa0290e83a222716 100644 (file)
@@ -418,6 +418,18 @@ ipv6_addr_gt() {
                && return ${EXIT_TRUE} || return ${EXIT_FALSE}
 }
 
+ipv6_addr_ge() {
+       ipv6_addr_eq $@ || ipv6_addr_gt $@
+}
+
+ipv6_addr_lt() {
+       ! ipv6_addr_eq $@ && ! ipv6_addr_gt $@
+}
+
+ipv6_addr_le() {
+       ipv6_addr_eq $@ || ! ipv6_addr_gt $@
+}
+
 ipv6_hash() {
        local address="${1}"
        assert isset address