diff options
author | Renato Botelho <renato@netgate.com> | 2016-02-17 09:56:33 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2016-02-17 09:56:33 -0200 |
commit | 4c62c1ff5055339478166bf4e3bd7e902acff5ef (patch) | |
tree | 7978578da7cf42e8a07f8d4eb478dd7bef546d2c | |
parent | 74db0283581e22a441bfb55d6d0d0a2a7c438c1e (diff) | |
download | pfsense-4c62c1ff5055339478166bf4e3bd7e902acff5ef.zip pfsense-4c62c1ff5055339478166bf4e3bd7e902acff5ef.tar.gz |
Implement get_v6_ptr_zones()
This function takes an IPv6 subnet and return an array containing all
DNS PTR zones
-rw-r--r-- | src/etc/inc/util.inc | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 31d929c..8005283 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -931,6 +931,58 @@ function check_subnetsv6_overlap($subnet1, $bits1, $subnet2, $bits2) { return ($subnetv6_start1 == $subnetv6_start2); } +/* return all PTR zones for a IPv6 network */ +function get_v6_ptr_zones($subnet, $bits) { + $result = array(); + + if (!is_ipaddrv6($subnet)) { + return $result; + } + + if (!is_numericint($bits) || $bits > 128) { + return $result; + } + + /* + * Find a small nibble boundary subnet mask + * e.g. a /29 will create 8 /32 PTR zones + */ + $small_sn = $bits; + while ($small_sn % 4 != 0) { + $small_sn++; + } + + /* Get network prefix */ + $small_subnet = Net_IPv6::getNetmask($subnet, $bits); + + /* + * While small network is part of bigger one, increase 4-bit in last + * digit to get next small network + */ + while (Net_IPv6::isInNetmask($small_subnet, $subnet, $bits)) { + /* Get a pure hex value */ + $unpacked = unpack('H*hex', inet_pton($small_subnet)); + /* Create PTR record using $small_sn / 4 chars */ + $result[] = implode('.', array_reverse(str_split(substr( + $unpacked['hex'], 0, $small_sn / 4)))).'.ip6.arpa'; + + /* Detect what part of IP should be increased */ + $change_part = (int) ($small_sn / 16); + if ($small_sn % 16 == 0) { + $change_part--; + } + + /* Convert desired part to decimal and increase 1 */ + $parts = explode(":", Net_IPv6::uncompress($small_subnet)); + $dec = base_convert($parts[$change_part], 16, 10) + 1; + /* Move back to hex and rebuild IP address */ + $parts[$change_part] = base_convert($dec, 10, 16); + $small_subnet = implode(":", $parts); + } + + return $result; +} + /* return true if $addr is in $subnet, false if not */ function ip_in_subnet($addr, $subnet) { if (is_ipaddrv6($addr) && is_subnetv6($subnet)) { |