aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/iprangealiases/iprangealiases.inc18
-rw-r--r--config/iprangealiases/iprangealiases.patch249
-rw-r--r--config/iprangealiases/iprangealiases.xml65
-rwxr-xr-xpkg_config.7.xml10
4 files changed, 342 insertions, 0 deletions
diff --git a/config/iprangealiases/iprangealiases.inc b/config/iprangealiases/iprangealiases.inc
new file mode 100644
index 00000000..036bc195
--- /dev/null
+++ b/config/iprangealiases/iprangealiases.inc
@@ -0,0 +1,18 @@
+<?php
+
+function iprangealiases_install() {
+ global $g, $config;
+
+ // Test to make sure the patch is not already applied.
+ $out = `patch -fslC --reverse -p1 -b .before_iprangealiases -d / -i /usr/local/pkg/iprangealiases.patch |& grep -ci reject`;
+ if ($out == 0) {
+ // If the patch has not already been applied, test to see if it will apply cleanly.
+ $out = `patch -fsNlC -p1 -b .before_iprangealiases -d / -i /usr/local/pkg/iprangealiases.patch |& grep -ci reject`;
+ if ($out == 0) {
+ // The patch should apply cleanly, let 'er rip.
+ mwexec("patch -fsNl -p1 -b .before_iprangealiases -d / -i /usr/local/pkg/iprangealiases.patch ");
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/config/iprangealiases/iprangealiases.patch b/config/iprangealiases/iprangealiases.patch
new file mode 100644
index 00000000..6e1cdabb
--- /dev/null
+++ b/config/iprangealiases/iprangealiases.patch
@@ -0,0 +1,249 @@
+--- /etc/inc/util.inc.orig 2010-03-09 13:01:37.000000000 -0500
++++ /etc/inc/util.inc 2010-03-09 13:01:40.000000000 -0500
+@@ -78,6 +78,127 @@
+ return long2ip(gen_subnet_mask_long($bits));
+ }
+
++/* Convert IP address to unsigned long int. */
++function ip2ulong($ip) {
++ return sprintf("%u", ip2long($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)) {
++ // 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;
++ }
++ return -1;
++}
++
++/* 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) {
++ $smallest = 1;
++ for ($b=32; $b > 0; $b--) {
++ $smallest = ($number <= pow(2,$b)) ? $b : $smallest;
++ }
++ return (32-$smallest);
++}
++
++/* Return the previous IP address before the given address */
++function ip_before($ip) {
++ return long2ip(ip2long($ip)-1);
++}
++
++/* Return the next IP address after the given address */
++function ip_after($ip) {
++ return long2ip(ip2long($ip)+1);
++}
++
++/* Return true if the first IP is 'before' the second */
++function ip_less_than($ip1, $ip2) {
++ // Compare as unsigned long because otherwise it wouldn't work when
++ // crossing over from 127.255.255.255 / 128.0.0.0 barrier
++ return ip2ulong($ip1) < ip2ulong($ip2);
++}
++
++/* Return true if the first IP is 'after' the second */
++function ip_greater_than($ip1, $ip2) {
++ // Compare as unsigned long because otherwise it wouldn't work
++ // when crossing over from 127.255.255.255 / 128.0.0.0 barrier
++ return ip2ulong($ip1) > ip2ulong($ip2);
++}
++
++/* Convert a range of IPs to an array of subnets which can contain the range. */
++function ip_range_to_subnet_array($startip, $endip) {
++ if (!is_ipaddr($startip) || !is_ipaddr($endip)) {
++ return array();
++ }
++
++ // 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));
++
++ // 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.
++ for ($cidr; $cidr <= 32; $cidr++) {
++ // Find the network and broadcast addresses for the subnet being tested.
++ $targetsub_min = gen_subnet($startip, $cidr);
++ $targetsub_max = gen_subnet_max($startip, $cidr);
++
++ // Check best case where the range is exactly one subnet.
++ if (($targetsub_min == $startip) && ($targetsub_max == $endip)) {
++ // Hooray, the range is exactly this subnet!
++ return array("{$startip}/{$cidr}");
++ }
++
++ // These remaining scenarios will find a subnet that uses the largest
++ // chunk possible of the range being tested, and leave the rest to be
++ // tested recursively after the loop.
++
++ // Check if the subnet begins with $startip and ends before $endip
++ if (($targetsub_min == $startip) && ip_less_than($targetsub_max, $endip)) {
++ break;
++ }
++
++ // Check if the subnet ends at $endip and starts after $startip
++ if (ip_greater_than($targetsub_min, $startip) && ($targetsub_max == $endip)) {
++ break;
++ }
++
++ // Check if the subnet is between $startip and $endip
++ if (ip_greater_than($targetsub_min, $startip) && ip_less_than($targetsub_max, $endip)) {
++ break;
++ }
++ }
++
++ // Some logic that will recursivly 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)));
++ }
++
++ // Add in the subnet we found before, to preserve ordering
++ $rangesubnets[] = "{$targetsub_min}/{$cidr}";
++
++ // And some more logic that will search after the subnet we found to fill in to the end of the range.
++ if ($endip != $targetsub_max) {
++ $rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array(ip_after($targetsub_max), $endip));
++ }
++ return $rangesubnets;
++}
++
++function is_iprange($range) {
++ if (substr_count($range, '-') != 1) {
++ return false;
++ }
++ list($ip1, $ip2) = explode ('-', $range);
++ return (is_ipaddr($ip1) && is_ipaddr($ip2));
++}
++
+ function is_numericint($arg) {
+ return (preg_match("/[^0-9]/", $arg) ? false : true);
+ }
+--- /usr/local/www/firewall_aliases_edit.php.orig 2010-03-09 13:08:12.000000000 -0500
++++ /usr/local/www/firewall_aliases_edit.php 2010-03-10 15:49:57.000000000 -0500
+@@ -96,11 +96,6 @@
+ $reqdfields = explode(" ", "name address");
+ $reqdfieldsn = explode(",", "Name,Address");
+
+- if ($_POST['type'] == "network") {
+- $reqdfields[] = "address_subnet";
+- $reqdfieldsn[] = "Subnet bit count";
+- }
+-
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if(strtolower($_POST['name']) == "lan")
+@@ -122,10 +117,13 @@
+ $input_errors[] = "A valid address must be specified.";
+ }
+ if ($_POST['type'] == "network") {
+- if (!is_ipaddr($_POST['address'])) {
++ if (!is_numeric($_POST['address_subnet']) && !is_iprange($_POST['address'])) {
++ $input_errors[] = "Subnet bit count must be specified";
++ }
++ if (!is_ipaddr($_POST['address']) && !is_iprange($_POST['address'])) {
+ $input_errors[] = "A valid address must be specified.";
+ }
+- if (!is_numeric($_POST['address_subnet'])) {
++ if (!is_numeric($_POST['address_subnet']) && !is_iprange($_POST['address'])) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+ }
+@@ -160,21 +158,28 @@
+
+ $alias = array();
+ $alias['name'] = $_POST['name'];
+- if ($_POST['type'] == "network")
+- $alias['address'] = $_POST['address'] . "/" . $_POST['address_subnet'];
+
+- else
++ $count = 1;
++ if ($_POST['type'] == "network") {
++ if (is_iprange($_POST['address'])) {
++ list($startip, $endip) = explode('-', $_POST["address"]);
++ $rangesubnets = ip_range_to_subnet_array($startip, $endip);
++ $count = count($rangesubnets);
++ $alias['address'] .= implode($rangesubnets, ' ');
++ } else {
++ $alias['address'] = $_POST['address'] . "/" . $_POST['address_subnet'];
++ }
++ } else {
+ $alias['address'] = $_POST['address'];
++ }
+
+ $address = $alias['address'];
+ $final_address_detail = mb_convert_encoding($_POST['detail'],"HTML-ENTITIES","auto");
+- if($final_address_detail <> "") {
+- $final_address_details .= $final_address_detail;
++ if($final_address_detail <> "") {
++ $final_address_details .= str_repeat($final_address_detail . "||", $count);
+ } else {
+- $final_address_details .= "Entry added" . " ";
+- $final_address_details .= date('r');
+- }
+- $final_address_details .= "||";
++ $final_address_details .= str_repeat("Entry added " . date('r') . "||", $count);
++ }
+ $isfirst = 0;
+
+ if($_POST['type'] == "url") {
+@@ -234,28 +239,38 @@
+ } else {
+ /* item is a normal alias type */
+ for($x=0; $x<299; $x++) {
++ $count = 1;
+ $comd = "\$subnet = \$_POST['address" . $x . "'];";
+ eval($comd);
+ $comd = "\$subnet_address = \$_POST['address_subnet" . $x . "'];";
+ eval($comd);
+ if($subnet <> "") {
+- $address .= " ";
+- $address .= $subnet;
+- if($subnet_address <> "") $address .= "/" . $subnet_address;
++ if ($_POST['type'] == "network" && is_iprange($subnet)) {
++ list($startip, $endip) = explode('-', $subnet);
++ $rangesubnets = ip_range_to_subnet_array($startip, $endip);
++ $count = count($rangesubnets);
++ if ($address <> "") {
++ $address .= " ";
++ }
++ $address .= implode($rangesubnets, ' ');
++ } else {
++ $address .= " " . $subnet;
++ if ($subnet_address <> "") {
++ $address .= "/" . $subnet_address;
++ }
++ }
+
+ /* Compress in details to a single key, data separated by pipes.
+ Pulling details here lets us only pull in details for valid
+ address entries, saving us from having to track which ones to
+ process later. */
+- $comd = "\$final_address_detail = mb_convert_encoding(\$_POST['detail" . $x . "'],'HTML-ENTITIES','auto');";
+- eval($comd);
+- if($final_address_detail <> "") {
+- $final_address_details .= $final_address_detail;
+- } else {
+- $final_address_details .= "Entry added" . " ";
+- $final_address_details .= date('r');
+- }
+- $final_address_details .= "||";
++ $comd = "\$final_address_detail = mb_convert_encoding(\$_POST['detail" . $x . "'],'HTML-ENTITIES','auto');";
++ eval($comd);
++ if($final_address_detail <> "") {
++ $final_address_details .= str_repeat($final_address_detail . "||", $count);
++ } else {
++ $final_address_details .= str_repeat("Entry added " . date('r') . "||", $count);
++ }
+ }
+ }
+ }
diff --git a/config/iprangealiases/iprangealiases.xml b/config/iprangealiases/iprangealiases.xml
new file mode 100644
index 00000000..a015c2dd
--- /dev/null
+++ b/config/iprangealiases/iprangealiases.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ iprangealiases.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2007 to whom it may belong
+ All rights reserved.
+
+ Based on m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Patch to add IP Range Support to Network Aliases</description>
+ <requirements>pfSense 1.2.3</requirements>
+ <faq>None</faq>
+ <name>IP Range Aliases</name>
+ <version>0.1</version>
+ <title>IP Range Aliases</title>
+ <include_file>/usr/local/pkg/iprangealiases.inc</include_file>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/iprangealiases/iprangealiases.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/iprangealiases/iprangealiases.patch</item>
+ </additional_files_needed>
+ <custom_php_install_command>
+ iprangealiases_install();
+ </custom_php_install_command>
+</packagegui>
diff --git a/pkg_config.7.xml b/pkg_config.7.xml
index 05e0af12..cf1c81ad 100755
--- a/pkg_config.7.xml
+++ b/pkg_config.7.xml
@@ -967,5 +967,15 @@
<config_file>http://www.pfsense.org/packages/config/states-summary/states-summary.xml</config_file>
<configurationfile>states-summary.xml</configurationfile>
</package>
+ <package>
+ <name>IP Range Aliases</name>
+ <descr>Patch to add IP Range support to Network Aliases. WARNING! Cannot be uninstalled.</descr>
+ <category>System</category>
+ <config_file>http://www.pfsense.com/packages/config/iprangealiases/iprangealiases.xml</config_file>
+ <version>0.1</version>
+ <status>BETA</status>
+ <required_version>1.2.3</required_version>
+ <maximum_version>1.2.3</maximum_version>
+ </package>
</packages>
</pfsensepkgs>