summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-02-17 09:56:33 -0200
committerRenato Botelho <renato@netgate.com>2016-02-17 09:56:33 -0200
commit4c62c1ff5055339478166bf4e3bd7e902acff5ef (patch)
tree7978578da7cf42e8a07f8d4eb478dd7bef546d2c
parent74db0283581e22a441bfb55d6d0d0a2a7c438c1e (diff)
downloadpfsense-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.inc52
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)) {
OpenPOWER on IntegriCloud