diff options
Diffstat (limited to 'config/iprangealiases')
-rw-r--r-- | config/iprangealiases/iprangealiases.inc | 18 | ||||
-rw-r--r-- | config/iprangealiases/iprangealiases.patch | 265 | ||||
-rw-r--r-- | config/iprangealiases/iprangealiases.xml | 65 |
3 files changed, 348 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..5a80e111 --- /dev/null +++ b/config/iprangealiases/iprangealiases.patch @@ -0,0 +1,265 @@ +--- /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 18:54:36.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); ++ } + } + } + } +@@ -358,7 +373,7 @@ + $url_str = gettext("URL"); + $update_freq_str = gettext("Update Freq."); + +-$networks_help = gettext("Networks can be expressed like 10.0.0.0 format. Select the CIDR (network mask) that pertains to each entry."); ++$networks_help = gettext("Networks can be expressed like 10.0.0.0 format. Select the CIDR (network mask) that pertains to each entry. You may also enter an IP Range such as 192.168.1.1-192.168.1.254."); + $hosts_help = gettext("Enter as many hosts as you would like. Hosts should be expressed in their ip address format."); + $ports_help = gettext("Enter as many ports as you wish. Port ranges can be expressed by seperating with a colon."); + $url_help = gettext("Enter as many urls as you wish. Also set the time that you would like the url refreshed in days. After saving {$g['product_name']} will download the URL and import the items into the alias."); +@@ -595,4 +610,4 @@ + } + fclose($fd); + } +-?> +\ No newline at end of file ++?> diff --git a/config/iprangealiases/iprangealiases.xml b/config/iprangealiases/iprangealiases.xml new file mode 100644 index 00000000..0464ec6a --- /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.2</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> |