summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/inc/captiveportal.inc25
-rwxr-xr-xusr/local/www/services_captiveportal_hostname.php192
-rwxr-xr-xusr/local/www/services_captiveportal_hostname_edit.php218
3 files changed, 424 insertions, 11 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc
index 50ddf90..e171fe9 100644
--- a/etc/inc/captiveportal.inc
+++ b/etc/inc/captiveportal.inc
@@ -639,9 +639,13 @@ EOD;
/* generate passthru mac database */
$cprules .= captiveportal_passthrumac_configure(true);
$cprules .= "\n";
+
/* allowed ipfw rules to make allowed ip work */
$cprules .= captiveportal_allowedip_configure();
+ /* allowed ipfw rules to make allowed hostnames work */
+ $cprules .= captiveportal_allowedhostname_configure();
+
/* load rules */
if ($reinit == true)
$cprules = "table all flush\nflush\n{$cprules}";
@@ -1046,6 +1050,7 @@ function captiveportal_allowedip_configure_entry($ipent) {
A change results in reloading the ruleset.
*/
function setup_dnsfilter_entries($hostname) {
+ global $g, $config;
$cp_filterdns_filename = "{$g['varetc_path']}/filterdns-captiveportal.conf";
$fd = fopen($cp_filterdns_filename, "w");
if (is_array($config['captiveportal']['allowedhostname']))
@@ -1053,11 +1058,7 @@ function setup_dnsfilter_entries($hostname) {
fwrite($fd, $hostnameent . "\n");
fclose($fd);
killbypid("{$g['tmp_path']}/dnswatch-cpah.pid");
- mwexec("/usr/local/sbin/dnswatch {$g['tmp_path']}/dnswatch-cpah.pid 300 '/etc/rc.filter_configure_sync' {$g['varetc_path']}/dnswatch-captiveportal.conf");
-}
-
-function captiveportal_allowedhostname_configure_entry($ipent) {
-
+ mwexec("/usr/local/sbin/dnswatch {$g['tmp_path']}/dnswatch-cpah.pid 300 '/etc/rc.captiveportal_configure' {$g['varetc_path']}/dnswatch-captiveportal.conf");
}
function captiveportal_allowedhostname_configure() {
@@ -1065,10 +1066,13 @@ function captiveportal_allowedhostname_configure() {
$rules = "";
setup_dnsfilter_entries();
- if (is_array($config['captiveportal']['allowedhostname']))
- foreach ($config['captiveportal']['allowedhostname'] as $hostnameent)
- $rules .= captiveportal_allowedip_configure_entry($hostnameent);
-
+ if (is_array($config['captiveportal']['allowedhostname'])) {
+ foreach ($config['captiveportal']['allowedhostname'] as $hostnameent) {
+ $ipaddress = gethostbyname($hostnameent);
+ if(is_ipaddr($ipaddress))
+ $rules .= captiveportal_allowedip_configure_entry($ipaddress);
+ }
+ }
return $rules;
}
@@ -1077,9 +1081,8 @@ function captiveportal_allowedip_configure() {
$rules = "";
if (is_array($config['captiveportal']['allowedip'])) {
- foreach ($config['captiveportal']['allowedip'] as $ipent) {
+ foreach ($config['captiveportal']['allowedip'] as $ipent)
$rules .= captiveportal_allowedip_configure_entry($ipent);
- }
}
return $rules;
diff --git a/usr/local/www/services_captiveportal_hostname.php b/usr/local/www/services_captiveportal_hostname.php
new file mode 100755
index 0000000..2840479
--- /dev/null
+++ b/usr/local/www/services_captiveportal_hostname.php
@@ -0,0 +1,192 @@
+<?php
+/*
+ services_captiveportal_hostname.php
+ Copyright (C) 2011 Scott Ullrich <sullrich@gmail.com>
+ All rights reserved.
+
+ Originally part of m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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.
+*/
+/*
+ pfSense_BUILDER_BINARIES: /sbin/ipfw
+ pfSense_MODULE: captiveportal
+*/
+
+##|+PRIV
+##|*IDENT=page-services-captiveportal-allowedhostnames
+##|*NAME=Services: Captive portal: Allowed IPs page
+##|*DESCR=Allow access to the 'Services: Captive portal: Allowed IPs' page.
+##|*MATCH=services_captiveportal_ip.php*
+##|-PRIV
+
+$statusurl = "status_captiveportal.php";
+$logurl = "diag_logs_auth.php";
+
+require("guiconfig.inc");
+require("functions.inc");
+require("filter.inc");
+require("shaper.inc");
+require("captiveportal.inc");
+
+$pgtitle = array(gettext("Services"),gettext("Captive portal"));
+
+if (!is_array($config['captiveportal']['allowedhostname']))
+ $config['captiveportal']['allowedhostname'] = array();
+
+$a_allowedhostnames = &$config['captiveportal']['allowedhostname'] ;
+
+if ($_GET['act'] == "del") {
+ if ($a_allowedhostnames[$_GET['id']]) {
+ $ipent = $a_allowedhostnames[$_GET['id']];
+
+ if (isset($config['captiveportal']['enable'])) {
+ if (!empty($ipent['sn']))
+ $ipent['ip'] .= "/{$ipent['sn']}";
+ $ip = gethostbyname($ipent['ip']);
+ if(is_ipaddr($ip)) {
+ mwexec("/sbin/ipfw table 3 delete {$ip}");
+ mwexec("/sbin/ipfw table 4 delete {$ip}");
+ mwexec("/sbin/ipfw table 5 delete {$ip}");
+ mwexec("/sbin/ipfw table 6 delete {$ip}");
+ mwexec("/sbin/ipfw table 7 delete {$ip}");
+ mwexec("/sbin/ipfw table 8 delete {$ip}");
+ mwexec("/sbin/ipfw table 9 delete {$ip}");
+ mwexec("/sbin/ipfw table 10 delete {$ip}");
+ }
+ }
+
+ unset($a_allowedhostnames[$_GET['id']]);
+ write_config();
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+
+
+include("head.inc");
+?>
+<?php include("fbegin.inc"); ?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<form action="services_captiveportal_ip.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+<?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("Captive portal"), false, "services_captiveportal.php");
+ $tab_array[] = array(gettext("Pass-through MAC"), false, "services_captiveportal_mac.php");
+ $tab_array[] = array(gettext("Allowed IP Addresses"), true, "services_captiveportal_ip.php");
+ $tab_array[] = array(gettext("Allowed Hostnames"), true, "services_captiveportal_hostname.php");
+ $tab_array[] = array(gettext("Vouchers"), false, "services_captiveportal_vouchers.php");
+ $tab_array[] = array(gettext("File Manager"), false, "services_captiveportal_filemanager.php");
+ display_top_tabs($tab_array);
+?>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr"><?=gettext("Hostname"); ?></td>
+ <td width="60%" class="listhdr"><?=gettext("Description"); ?></td>
+ <td width="10%" class="list">
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td width="17" heigth="17"></td>
+ <td><a href="services_captiveportal_ip_edit.php"><img src="/themes/<?php echo $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add address"); ?>" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <?php $i = 0; foreach ($a_allowedhostnames as $ip): ?>
+ <tr ondblclick="document.location='services_captiveportal_ip_edit.php?id=<?=$i;?>'">
+ <td class="listlr">
+ <?php
+ if($ip['dir'] == "to") {
+ echo "any <img src=\"/themes/{$g['theme']}/images/icons/icon_in.gif\" width=\"11\" height=\"11\" align=\"absmiddle\"> ";
+ }
+ if($ip['dir'] == "both") {
+ echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_pass.gif\" width=\"11\" height=\"11\" align=\"absmiddle\"> ";
+ }
+ echo strtolower($ip['ip']);
+ if($ip['sn'] != "32" && is_numeric($ip['sn'])) {
+ $sn = $ip['sn'];
+ echo "/$sn";
+ }
+ if($ip['dir'] == "from") {
+ echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_in.gif\" width=\"11\" height=\"11\" align=\"absmiddle\"> any";
+ }
+
+ ?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($ip['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_captiveportal_ip_edit.php?id=<?=$i;?>"><img src="/themes/<?php echo $g['theme']; ?>/images/icons/icon_e.gif" title="<?=gettext("edit address"); ?>" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_captiveportal_ip.php?act=del&id=<?=$i;?>" onclick="return confirm('<?=gettext("Do you really want to delete this address?"); ?>')"><img src="/themes/<?php echo $g['theme']; ?>/images/icons/icon_x.gif" title="<?=gettext("delete address"); ?>" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2">&nbsp;</td>
+ <td class="list">
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td width="17" heigth="17"></td>
+ <td><a href="services_captiveportal_ip_edit.php"><img src="/themes/<?php echo $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add address"); ?>" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><p class="vexpl"><span class="red"><strong>
+ <?=gettext("Note:"); ?><br>
+ </strong></span>
+ <?=gettext("Adding allowed Hostnamees will allow IP access to/from these addresses through the captive portal without being taken to the portal page. This can be used for a web server serving images for the portal page or a DNS server on another network, for example. By specifying <em>from</em> addresses, it may be used to always allow pass-through access from a client behind the captive portal."); ?></p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><span class="vexpl"><?=gettext("any"); ?> <img src="/themes/<?=$g['theme'];?>/images/icons/icon_in.gif" width="11" height="11" align="absmiddle"> x.x.x.x </span></td>
+ <td><span class="vexpl"><?=gettext("All connections"); ?> <strong><?=gettext("to"); ?></strong> <?=gettext("the Hostname are allowed"); ?></span></td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td>x.x.x.x <span class="vexpl"><img src="/themes/<?=$g['theme'];?>/images/icons/icon_in.gif" width="11" height="11" align="absmiddle"></span> <?=gettext("any"); ?>&nbsp;&nbsp;&nbsp; </td>
+ <td><span class="vexpl"><?=gettext("All connections"); ?> <strong><?=gettext("from"); ?></strong> <?=gettext("the Hostname are allowed"); ?> </span></td>
+ </tr>
+ <tr>
+ <td><span class="vexpl"><img src="/themes/<?=$g['theme'];?>/images/icons/icon_pass.gif" width="11" height="11" align="right"></span>&nbsp;&nbsp;&nbsp;&nbsp; </td>
+ <td><span class="vexpl"> All connections <strong>to</strong> and <strong>from</strong> the Hostname are allowed </span></td>
+ </tr>
+ </table></td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_hostname_edit.php b/usr/local/www/services_captiveportal_hostname_edit.php
new file mode 100755
index 0000000..ca166d4
--- /dev/null
+++ b/usr/local/www/services_captiveportal_hostname_edit.php
@@ -0,0 +1,218 @@
+<?php
+/*
+ services_captiveportal_hostname_edit.php
+ Copyright (C) 2011 Scott Ullrich <sullrich@gmail.com>
+ All rights reserved.
+
+ Originally part of m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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.
+*/
+/*
+ pfSense_BUILDER_BINARIES: /sbin/ipfw
+ pfSense_MODULE: captiveportal
+*/
+
+##|+PRIV
+##|*IDENT=page-services-captiveportal-editallowedhostnames
+##|*NAME=Services: Captive portal: Edit Allowed IPs page
+##|*DESCR=Allow access to the 'Services: Captive portal: Edit Allowed IPs' page.
+##|*MATCH=services_captiveportal_ip_edit.php*
+##|-PRIV
+
+function allowedhostnamescmp($a, $b) {
+ return strcmp($a['hostname'], $b['hostname']);
+}
+
+function allowedhostnames_sort() {
+ global $g, $config;
+
+ usort($config['captiveportal']['allowedhostname'],"allowedhostnamescmp");
+}
+
+$statusurl = "status_captiveportal.php";
+$logurl = "diag_logs_auth.php";
+
+require("guiconfig.inc");
+require("functions.inc");
+require("filter.inc");
+require("shaper.inc");
+require("captiveportal.inc");
+
+$pgtitle = array(gettext("Services"),gettext("Captive portal"),gettext("Edit allowed Hostname"));
+
+if (!is_array($config['captiveportal']['allowedhostname']))
+ $config['captiveportal']['allowedhostname'] = array();
+
+$a_allowedhostnames = &$config['captiveportal']['allowedhostname'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_allowedhostnames[$id]) {
+ $pconfig['hostname'] = $a_allowedhostnames[$id]['hostname'];
+ $pconfig['sn'] = $a_allowedhostnames[$id]['sn'];
+ $pconfig['dir'] = $a_allowedhostnames[$id]['dir'];
+ $pconfig['bw_up'] = $a_allowedhostnames[$id]['bw_up'];
+ $pconfig['bw_down'] = $a_allowedhostnames[$id]['bw_down'];
+ $pconfig['descr'] = $a_allowedhostnames[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ip");
+ $reqdfieldsn = array(gettext("Allowed Hostname"));
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['hostname'] && !is_hostname($_POST['hostname']))) {
+ $input_errors[] = sprintf(gettext("A valid Hostname must be specified. [%s]"), $_POST['hostname']);
+ }
+ if ($_POST['bw_up'] && !is_numeric($_POST['bw_up']))
+ $input_errors[] = gettext("Upload speed needs to be an integer");
+ if ($_POST['bw_down'] && !is_numeric($_POST['bw_down']))
+ $input_errors[] = gettext("Download speed needs to be an integer");
+
+ foreach ($a_allowedhostnames as $ipent) {
+ if (isset($id) && ($a_allowedhostnames[$id]) && ($a_allowedhostnames[$id] === $ipent))
+ continue;
+
+ if ($ipent['hostname'] == $_POST['hostname']){
+ $input_errors[] = sprintf("[%s] %s.", $_POST['hostname'], gettext("already allowed")) ;
+ break ;
+ }
+ }
+
+ if (!$input_errors) {
+ $ip = array();
+ $ip['hostname'] = $_POST['hostname'];
+ $ip['sn'] = $_POST['sn'];
+ $ip['dir'] = $_POST['dir'];
+ $ip['descr'] = $_POST['descr'];
+ if ($_POST['bw_up'])
+ $ip['bw_up'] = $_POST['bw_up'];
+ if ($_POST['bw_down'])
+ $ip['bw_down'] = $_POST['bw_down'];
+ if (isset($id) && $a_allowedhostnames[$id]) {
+ $oldip = $a_allowedhostnames[$id]['hostname'];
+ if (!empty($a_allowedhostnames[$id]['sn']))
+ $oldip .= "/{$a_allowedhostnames[$id]['sn']}";
+ $a_allowedhostnames[$id] = $ip;
+ } else {
+ $oldip = $ip['hostname'];
+ if (!empty($$ip['sn']))
+ $oldip .= "/{$$ip['sn']}";
+ $a_allowedhostnames[] = $ip;
+ }
+ allowedhostnames_sort();
+
+ write_config();
+
+ if (isset($config['captiveportal']['enable']) && is_module_loaded("ipfw.ko")) {
+ $rules = "";
+ $hostname = gethostbyname($oldip);
+ if($hostname)
+ for ($i = 3; $i < 10; $i++)
+ $rules .= "table {$i} delete {$hostname}\n";
+ $hostname = gethostbyname($ip);
+ if(is_ipaddr($hostname))
+ $rules .= captiveportal_allowedip_configure_entry($hostname);
+ file_put_contents("{$g['tmp_path']}/allowedhostname_tmp{$id}", $rules);
+ mwexec("/sbin/ipfw -q {$g['tmp_path']}/allowedhostname_tmp{$id}");
+ @unlink("{$g['tmp_path']}/allowedhostname_tmp{$id}");
+ }
+
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+
+include("head.inc");
+
+?>
+<?php include("fbegin.inc"); ?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_captiveportal_ip_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"><?=gettext("Direction"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="dir" class="formfld">
+ <?php
+ $dirs = array(gettext("Both"),gettext("From"),gettext("To")) ;
+ foreach ($dirs as $dir): ?>
+ <option value="<?=strtolower($dir);?>" <?php if (strtolower($dir) == strtolower($pconfig['dir'])) echo "selected";?> >
+ <?=htmlspecialchars($dir);?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ <span class="vexpl"><?=gettext("Use"); ?> <em><?=gettext("From"); ?></em> <?=gettext("to always allow an Hostname through the captive portal (without authentication)"); ?>.
+ <?=gettext("Use"); ?> <em><?=gettext("To"); ?></em> <?=gettext("to allow access from all clients (even non-authenticated ones) behind the portal to this Hostname"); ?>.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"><?=gettext("Hostname"); ?></td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="ip" type="text" class="formfld unknown" id="ip" size="17" value="<?=htmlspecialchars($pconfig['hostname']);?>">
+ <br>
+ <span class="vexpl"><?=gettext("Hostname");?>.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed)"); ?>.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth up"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="bw_up" type="text" class="formfld unknown" id="bw_up" size="10" value="<?=htmlspecialchars($pconfig['bw_up']);?>">
+ <br> <span class="vexpl"><?=gettext("Enter a upload limit to be enforced on this Hostname in Kbit/s"); ?></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?=gettext("Bandwidth down"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="bw_down" type="text" class="formfld unknown" id="bw_down" size="10" value="<?=htmlspecialchars($pconfig['bw_down']);?>">
+ <br> <span class="vexpl"><?=gettext("Enter a download limit to be enforced on this Hostname in Kbit/s"); ?></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Save"); ?>">
+ <?php if (isset($id) && $a_allowedhostnames[$id]): ?>
+ <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
OpenPOWER on IntegriCloud