diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc
index ba71d04..17acae3 100644
--- a/etc/inc/filter.inc
+++ b/etc/inc/filter.inc
@@ -415,7 +415,13 @@ function filter_generate_aliases() {
 			$extraalias = "";
 			$ip = find_interface_ip($alias['address']);
 			$extraalias = " " . link_ip_to_carp_interface($ip);
-			$aliases .= "{$alias['name']} = \"{ {$alias['address']}{$extralias} }\"\n";
+			if ($alias['type'] != 'urltable')
+				$aliases .= "{$alias['name']} = \"{ {$alias['address']}{$extralias} }\"\n";
+			else {
+				$urlfn = alias_expand_urltable($alias['name']);
+				if ($urlfn)
+					$aliases .= "table <{$alias['name']}> persist file \"{$urlfn}\"\n";
+			}
 		}
 	}
 
@@ -2013,7 +2019,8 @@ function generate_user_filter_rule($rule, $ngcounter) {
 		} else {
 			if ($g['debug'])
 				echo "{$src_table} NOT found in cache...adding\n";
-			$table_cache[$src_table] = $src_table_line;
+			if (strpos($src_table_line, 'http://') === false)
+				$table_cache[$src_table] = $src_table_line;
 		}
 	if (isset($dst_table))
 		if (isset($table_cache[$dst_table])) {
@@ -2022,7 +2029,8 @@ function generate_user_filter_rule($rule, $ngcounter) {
 		} else {
 			if ($g['debug'])
 				echo "{$dst_table} NOT found in cache...adding\n";
-			$table_cache[$dst_table] = $dst_table_line;
+			if (strpos($dst_table_line, 'http://') === false)
+				$table_cache[$dst_table] = $dst_table_line;
 		}
 
 	/* exception(s) to a user rules can go here. */
diff --git a/etc/inc/pfsense-utils.inc b/etc/inc/pfsense-utils.inc
index c45def5..2f0f6fb 100644
--- a/etc/inc/pfsense-utils.inc
+++ b/etc/inc/pfsense-utils.inc
@@ -3905,4 +3905,47 @@ function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb,
 
 }
 
+function process_alias_urltable($name, $url, $freq, $forceupdate=false) {
+	$aliastable_prefix = "/var/db/aliastables/";
+	$aliastable_filename = $aliastable_prefix . $name . ".txt";
+
+	// Make the aliases directory if it doesn't exist
+	if (!file_exists($aliastable_prefix)) {
+		mkdir($aliastable_prefix);
+	} elseif (!is_dir($aliastable_prefix)) {
+		unlink($aliastable_prefix);
+		mkdir($aliastable_prefix);
+	}
+
+	// If the file doesn't exist or is older than update_freq days, fetch a new copy.
+	if (!file_exists($aliastable_filename) 
+		|| ((time() - filemtime($aliastable_filename)) > ($freq * 86400))
+		|| $forceupdate) {
+
+		// Try to fetch the URL supplied
+		conf_mount_rw();
+		unlink_if_exists($aliastable_filename . ".tmp");
+		mwexec("/usr/bin/fetch -q -o " . escapeshellarg($aliastable_filename) . ".tmp " . escapeshellarg($url));
+		mwexec("/usr/bin/grep -v '^#' " . escapeshellarg($aliastable_filename) . ".tmp > " . escapeshellarg($aliastable_filename));
+		unlink_if_exists($aliastable_filename . ".tmp");
+		conf_mount_ro();
+		if (filesize($aliastable_filename)) {
+			return true;
+		} else {
+			// If it's unfetchable or an empty file, bail
+			return false;
+		}
+	} else {
+		// File exists, and it doesn't need updated.
+		return -1;
+	}
+}
+
+function is_valid_http_url($url) {
+	$parsed = parse_url($url);
+	if (($parsed['scheme'] == 'http') && (is_fqdn($parsed['host']) || is_ipaddr($parsed['host'])))
+		return true;
+	else
+		return false;
+}
 ?>
diff --git a/etc/inc/util.inc b/etc/inc/util.inc
index 61d2e55..efeaf01 100644
--- a/etc/inc/util.inc
+++ b/etc/inc/util.inc
@@ -487,6 +487,21 @@ function alias_expand_net($name) {
 		return null;
 }
 
+function alias_expand_urltable($name) {
+	global $aliastable;
+	$aliastable_prefix = "/var/db/aliastables/";
+	$aliastable_filename = $aliastable_prefix . $name . ".txt";
+
+	if (isset($aliastable[$name]) 
+		&& (is_valid_http_url($aliastable[$name]))
+		&& file_exists($aliastable_filename))
+		return $aliastable_filename;
+	elseif (process_alias_urltable($name, $aliastable[$name], 0, true))
+		return $aliastable_filename;
+	else
+		return null;
+}
+
 /* find out whether two subnets overlap */
 function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
 
diff --git a/etc/rc.update_urltables b/etc/rc.update_urltables
new file mode 100755
index 0000000..506a5b0
--- /dev/null
+++ b/etc/rc.update_urltables
@@ -0,0 +1,49 @@
+#!/usr/local/bin/php -q
+<?php
+require_once("config.inc");
+require_once("util.inc");
+require_once("pfsense-utils.inc");
+
+if (!is_array($config['aliases']['alias'])) {
+	// No aliases
+	exit;
+}
+
+// Gather list of urltable aliases
+$todo = array();
+foreach ($config['aliases']['alias'] as $alias) {
+	if ($alias['type'] = 'urltable') {
+		$tmp = array();
+		$tmp['name'] = $alias['name'];
+		$tmp['url']  = $alias['address'];
+		$tmp['freq'] = $alias['address_subnet'];
+		$todo[] = $tmp;
+	}
+}
+
+if (count($todo) > 0) {
+	log_error("{$argv[0]}: Starting up.");
+
+	if ($argv[1] != "now") {
+		// Wait a little before updating.
+		$wait = mt_rand(5, 60);
+		log_error("{$argv[0]}: Sleeping for {$wait} seconds.");
+		sleep($wait);
+	}
+
+	log_error("{$argv[0]}: Starting URL table alias updates");
+
+	foreach ($todo as $t) {
+		$r = process_alias_urltable($t['name'], $t['url'], $t['freq']);
+		if ($r == 1) {
+			$result = "";
+			exec("/sbin/pfctl -t " . escapeshellarg($t['name']) . " -T replace -f /var/db/aliastables/" . escapeshellarg($t['name']) . ".txt 2>&1", $result);
+			log_error("{$argv[0]}: Updated {$t['name']} content from {$t['url']}: {$result[0]}");
+		} elseif ($r == -1) {
+			log_error("{$argv[0]}: {$t['name']} does not need updated.");
+		} else {
+			log_error("{$argv[0]}: ERROR: could not update {$t['name']} content from {$t['url']}");
+		}
+	}
+}
+?>
\ No newline at end of file
diff --git a/usr/local/www/firewall_aliases.php b/usr/local/www/firewall_aliases.php
index e453200..9be52a4 100755
--- a/usr/local/www/firewall_aliases.php
+++ b/usr/local/www/firewall_aliases.php
@@ -85,7 +85,7 @@ if ($_GET['act'] == "del") {
 						$referenced_by = $rule['descr'];
 						break;
 					}
-					if($rule['source']['address'] == $alias_name) {
+					if($rule['destination']['address'] == $alias_name) {
 						$is_alias_referenced = true;
 						$referenced_by = $rule['descr'];
 						break;
@@ -177,11 +177,10 @@ include("head.inc");
   </td>
   <td class="listr" ondblclick="document.location='firewall_aliases_edit.php?id=<?=$i;?>';">
       <?php
-	$addresses = implode(", ", array_slice(explode(" ", $alias['address']), 0, 10));
+	$tmpaddr = explode(" ", $alias['address']);
+	$addresses = implode(", ", array_slice($tmpaddr, 0, 10));
 	echo $addresses;
-	if(count($addresses) < 10) {
-		echo " ";
-	} else {
+	if(count($tmpaddr) > 10) {
 		echo "...";
 	}
     ?>
diff --git a/usr/local/www/firewall_aliases_edit.php b/usr/local/www/firewall_aliases_edit.php
index 62e1272..f88b4b3 100755
--- a/usr/local/www/firewall_aliases_edit.php
+++ b/usr/local/www/firewall_aliases_edit.php
@@ -65,10 +65,14 @@ if (isset($id) && $a_aliases[$id]) {
 	if ($addresssubnettest)
 		$pconfig['type'] = "network";
 	else
-		if (is_ipaddr($address[0]))
+		if (is_ipaddr($address[0])) {
 			$pconfig['type'] = "host";
-		else
+		} elseif (is_valid_http_url($pconfig['address'])) {
+			$pconfig['type'] = $a_aliases[$id]['type'];
+			$pconfig['address_subnet'] = $a_aliases[$id]['address_subnet'];
+		} else {
 			$pconfig['type'] = "port";
+		}
 
 	if($a_aliases[$id]['aliasurl'] <> "") {
 		$pconfig['type'] = "url";
@@ -99,6 +103,9 @@ if ($_POST) {
 	if ($_POST['type'] == "network") {
 		$reqdfields[] = "address_subnet";
 		$reqdfieldsn[] = "Subnet bit count";
+	} elseif ($_POST['type'] == "urltable") {
+		$reqdfields[] = "address_subnet";
+		$reqdfieldsn[] = "Update Frequency";
 	}
 
 	do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
@@ -131,10 +138,18 @@ if ($_POST) {
 	}
 
 	if ($_POST['type'] == "url") {
-		if(stristr($_POST['address'], "http") == false)
+		if(is_valid_http_url($_POST['address']) == false)
 			$input_errors[] = "You must provide a valid URL to the resource.";
 	}
 
+	if ($_POST['type'] == "urltable") {
+		if(is_valid_http_url($_POST['address']) == false)
+			$input_errors[] = "You must provide a valid URL to the resource.";
+		if (!is_numeric($_POST['address_subnet'])) {
+			$input_errors[] = "A valid update frequency must be specified.";
+		}
+	}
+
 	if ($_POST['type'] == "port")
 		if (! is_port($_POST['address']) && ! is_portrange($_POST['address']))
 			$input_errors[] = "Please specify a valid port or portrange.";
@@ -177,7 +192,25 @@ if ($_POST) {
     	$final_address_details .= "||";
 	$isfirst = 0;
 
-	if($_POST['type'] == "url") {
+	if ($_POST['type'] == "urltable") {
+		$address = "";
+		$isfirst = 0;
+
+		/* item is a url type */
+		if ($_POST['address']) {
+			/* fetch down and add in */
+			$isfirst = 0;
+			$address = $_POST['address'];
+			$alias['address_subnet'] = $_POST['address_subnet'];
+			if (strtolower(substr($_POST['address'], 0, 4)) != "http") {
+				$input_errors[] = "You must provide a valid URL.";
+				$dont_update = true;
+			} elseif (! process_alias_urltable($_POST['name'], $_POST['address'], $_POST['address_subnet'], true)) {
+				$input_errors[] = "Unable to fetch usable data.";
+				$dont_update = true;
+			}
+		}
+	} elseif($_POST['type'] == "url") {
 		$address = "";
 		$isfirst = 0;
 		$address_count = 2;
@@ -355,13 +388,14 @@ $hosts_str = gettext("Host(s)");
 $ip_str = gettext("IP");
 $ports_str = gettext("Port(s)");
 $port_str = gettext("Port");
+$urltable_str = gettext("URL Table");
 $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.");
 $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.");
+$urltable_help = gettext("Enter a single URL and set the time that you would like the url refreshed in days.  After saving {$g['product_name']} will download the URL and save the items as a persistent table, which works like the bogons list. (cron job to update is not added automatically)");
 
 $jscriptstr .= <<<EOD
 
@@ -376,6 +410,7 @@ function update_box_type() {
 		document.getElementById ("twocolumn").firstChild.data = "{$cidr_str}";
 		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
 		document.getElementById ("itemhelp").firstChild.data = "{$networks_help}";
+		document.getElementById ("addrowbutton").style.display = 'block';
 	} else if(selected == '{$hosts_str}') {
 		document.getElementById ("addressnetworkport").firstChild.data = "{$hosts_str}";
 		document.getElementById ("address_subnet").visible = false;
@@ -384,6 +419,7 @@ function update_box_type() {
 		document.getElementById ("twocolumn").firstChild.data = "";
 		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
 		document.getElementById ("itemhelp").firstChild.data = "{$hosts_help}";
+		document.getElementById ("addrowbutton").style.display = 'block';
 	} else if(selected == '{$ports_str}') {
 		document.getElementById ("addressnetworkport").firstChild.data = "{$ports_str}";
 		document.getElementById ("address_subnet").visible = false;
@@ -392,6 +428,7 @@ function update_box_type() {
 		document.getElementById ("twocolumn").firstChild.data = "";
 		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
 		document.getElementById ("itemhelp").firstChild.data = "{$ports_help}";
+		document.getElementById ("addrowbutton").style.display = 'block';
 	} else if(selected == '{$url_str}') {
 		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
 		document.getElementById ("address_subnet").visible = true;
@@ -400,6 +437,16 @@ function update_box_type() {
 		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
 		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
 		document.getElementById ("itemhelp").firstChild.data = "{$url_help}";
+		document.getElementById ("addrowbutton").style.display = 'block';
+	} else if(selected == '{$urltable_str}') {
+		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
+		document.getElementById ("address_subnet").visible = true;
+		document.getElementById ("address_subnet").disabled = false;
+		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
+		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
+		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
+		document.getElementById ("itemhelp").firstChild.data = "{$urltable_help}";
+		document.getElementById ("addrowbutton").style.display = 'none';
 	}
 }
 </script>
@@ -480,6 +527,7 @@ EOD;
         <option value="host" <?php if ($pconfig['type'] == "host") echo "selected"; ?>>Host(s)</option>
         <option value="network" <?php if ($pconfig['type'] == "network") echo "selected"; ?>>Network(s)</option>
         <option value="port" <?php if ($pconfig['type'] == "port") echo "selected"; ?>>Port(s)</option>
+        <option value="urltable" <?php if ($pconfig['type'] == "urltable") echo "selected"; ?>>URL Table</option>
       </select>
     </td>
   </tr>
@@ -525,7 +573,7 @@ EOD;
 			        <select name="address_subnet<?php echo $tracker; ?>" class="formselect" id="address_subnet<?php echo $tracker; ?>">
 			          <option></option>
 			          <?php for ($i = 32; $i >= 1; $i--): ?>
-			          <option value="<?=$i;?>" <?php if ($i == $address_subnet) echo "selected"; ?>><?=$i;?></option>
+			          <option value="<?=$i;?>" <?php if (($i == $address_subnet) || ($i == $pconfig['address_subnet'])) echo "selected"; ?>><?=$i;?></option>
 			          <?php endfor; ?>
 			        </select>
 			      </td>
@@ -549,8 +597,8 @@ EOD;
 
         </tfoot>
 		  </table>
-			<a onclick="javascript:addRowTo('maintable'); typesel_change(); return false;" href="#">
-        <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" />
+			<div id="addrowbutton"><a onclick="javascript:addRowTo('maintable'); typesel_change(); return false;" href="#">
+        <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" /></div>
       </a>
 		</td>
   </tr>