From: Michael Tremer Date: Thu, 8 Sep 2016 17:09:34 +0000 (+0200) Subject: DHCP: Do not accept overlapping subnet ranges X-Git-Tag: 009~285 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae02c40e7ba474de4d2b49ed1e30ebff350e835e;p=network.git DHCP: Do not accept overlapping subnet ranges Signed-off-by: Michael Tremer --- diff --git a/src/functions/functions.dhcpd b/src/functions/functions.dhcpd index fbce2050..0c8f7056 100644 --- a/src/functions/functions.dhcpd +++ b/src/functions/functions.dhcpd @@ -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} diff --git a/src/functions/functions.ipv4 b/src/functions/functions.ipv4 index 87a2fdba..0f1455ca 100644 --- a/src/functions/functions.ipv4 +++ b/src/functions/functions.ipv4 @@ -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} diff --git a/src/functions/functions.ipv6 b/src/functions/functions.ipv6 index 22991353..f2a5fadd 100644 --- a/src/functions/functions.ipv6 +++ b/src/functions/functions.ipv6 @@ -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