summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Davis <phil.davis@inf.org>2014-10-24 20:17:04 +0545
committerPhil Davis <phil.davis@inf.org>2014-10-24 20:17:04 +0545
commitbb67ac32bc2a27321cc7c0b2d24f9adc9639584d (patch)
treeeab6220ff953ac7c79b867173e7784e8b979022f
parentfeb1953e849e634a31c73fcb262734bd03362ef3 (diff)
downloadpfsense-bb67ac32bc2a27321cc7c0b2d24f9adc9639584d.zip
pfsense-bb67ac32bc2a27321cc7c0b2d24f9adc9639584d.tar.gz
Support converting an IP range to an array of addresses
so that it can be used for expanding ranges in host alias input.
-rw-r--r--etc/inc/util.inc64
1 files changed, 52 insertions, 12 deletions
diff --git a/etc/inc/util.inc b/etc/inc/util.inc
index bf77e95..683061c 100644
--- a/etc/inc/util.inc
+++ b/etc/inc/util.inc
@@ -384,8 +384,8 @@ function ip2ulong($ip) {
/* Find out how many IPs are contained within a given IP range
* e.g. 192.168.0.0 to 192.168.0.255 returns 256
*/
-function ip_range_size($startip, $endip) {
- if (is_ipaddr($startip) && is_ipaddr($endip)) {
+function ip_range_size_v4($startip, $endip) {
+ if (is_ipaddrv4($startip) && is_ipaddrv4($endip)) {
// Operate as unsigned long because otherwise it wouldn't work
// when crossing over from 127.255.255.255 / 128.0.0.0 barrier
return abs(ip2ulong($startip) - ip2ulong($endip)) + 1;
@@ -396,7 +396,7 @@ function ip_range_size($startip, $endip) {
/* Find the smallest possible subnet mask which can contain a given number of IPs
* e.g. 512 IPs can fit in a /23, but 513 IPs need a /22
*/
-function find_smallest_cidr($number) {
+function find_smallest_cidr_v4($number) {
$smallest = 1;
for ($b=32; $b > 0; $b--) {
$smallest = ($number <= pow(2,$b)) ? $b : $smallest;
@@ -428,17 +428,52 @@ function ip_greater_than($ip1, $ip2) {
return ip2ulong($ip1) > ip2ulong($ip2);
}
-/* Convert a range of IPs to an array of subnets which can contain the range. */
+/* Convert a range of IPv4 addresses to an array of individual addresses. */
+/* Note: IPv6 ranges are not yet supported here. */
+function ip_range_to_address_array($startip, $endip, $max_size = 5000) {
+ if (!is_ipaddrv4($startip) || !is_ipaddrv4($endip)) {
+ return false;
+ }
+
+ if (ip_greater_than($startip, $endip)) {
+ // Swap start and end so we can process sensibly.
+ $temp = $startip;
+ $startip = $endip;
+ $endip = $temp;
+ }
+
+ if (ip_range_size_v4($startip, $endip) > $max_size)
+ return false;
+
+ // Container for IP addresses within this range.
+ $rangeaddresses = array();
+ $end_int = ip2ulong($endip);
+ for ($ip_int = ip2ulong($startip); $ip_int <= $end_int; $ip_int++) {
+ $rangeaddresses[] = long2ip($ip_int);
+ }
+
+ return $rangeaddresses;
+}
+
+/* Convert a range of IPv4 addresses to an array of subnets which can contain the range. */
+/* Note: IPv6 ranges are not yet supported here. */
function ip_range_to_subnet_array($startip, $endip) {
- if (!is_ipaddr($startip) || !is_ipaddr($endip)) {
+ if (!is_ipaddrv4($startip) || !is_ipaddrv4($endip)) {
return array();
}
+ if (ip_greater_than($startip, $endip)) {
+ // Swap start and end so we can process sensibly.
+ $temp = $startip;
+ $startip = $endip;
+ $endip = $temp;
+ }
+
// Container for subnets within this range.
$rangesubnets = array();
// Figure out what the smallest subnet is that holds the number of IPs in the given range.
- $cidr = find_smallest_cidr(ip_range_size($startip, $endip));
+ $cidr = find_smallest_cidr_v4(ip_range_size_v4($startip, $endip));
// Loop here to reduce subnet size and retest as needed. We need to make sure
// that the target subnet is wholly contained between $startip and $endip.
@@ -473,7 +508,7 @@ function ip_range_to_subnet_array($startip, $endip) {
}
}
- // Some logic that will recursivly search from $startip to the first IP before the start of the subnet we just found.
+ // Some logic that will recursively search from $startip to the first IP before the start of the subnet we just found.
// NOTE: This may never be hit, the way the above algo turned out, but is left for completeness.
if ($startip != $targetsub_min) {
$rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array($startip, ip_before($targetsub_min)));
@@ -489,12 +524,19 @@ function ip_range_to_subnet_array($startip, $endip) {
return $rangesubnets;
}
+/* returns true if $range is a valid pair of IPv4 or IPv6 addresses separated by a "-"
+ false - if not a valid pair
+ true (numeric 4 or 6) - if valid, gives type of addresses */
function is_iprange($range) {
if (substr_count($range, '-') != 1) {
return false;
}
list($ip1, $ip2) = explode ('-', $range);
- return (is_ipaddr($ip1) && is_ipaddr($ip2));
+ if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2))
+ return 4;
+ if (is_ipaddrv6($ip1) && is_ipaddrv6($ip2))
+ return 6;
+ return false;
}
/* returns true if $ipaddr is a valid dotted IPv4 address or a IPv6 */
@@ -644,7 +686,7 @@ function is_domain($domain) {
if (!is_string($domain))
return false;
- if (preg_match('/^(?:(?:[a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*(?:[a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$/i', $domain))
+ if (preg_match('/^(?:(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9])\.)*(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9\.])$/i', $domain))
return true;
else
return false;
@@ -1710,9 +1752,7 @@ function is_interface_mismatch() {
}
}
- if ($g['minimum_nic_count'] > $i) {
- $do_assign = true;
- } else if (file_exists("{$g['tmp_path']}/assign_complete"))
+ if (file_exists("{$g['tmp_path']}/assign_complete"))
$do_assign = false;
if (!empty($missing_interfaces) && $do_assign)
OpenPOWER on IntegriCloud