summaryrefslogtreecommitdiffstats
path: root/usr
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2004-11-07 03:06:49 +0000
committerScott Ullrich <sullrich@pfsense.org>2004-11-07 03:06:49 +0000
commit5b237745003431d487de361ca0980a467ee2f5d5 (patch)
tree0a29f0237f9e8e536112f9fc816e7a52bbc19691 /usr
downloadpfsense-5b237745003431d487de361ca0980a467ee2f5d5.zip
pfsense-5b237745003431d487de361ca0980a467ee2f5d5.tar.gz
Initial revision
Diffstat (limited to 'usr')
-rwxr-xr-xusr/local/bin/runmsntp.sh12
-rwxr-xr-xusr/local/captiveportal/index.php407
-rw-r--r--usr/local/captiveportal/radius_accounting.inc241
-rw-r--r--usr/local/captiveportal/radius_authentication.inc128
-rw-r--r--usr/local/etc/php.ini10
-rw-r--r--usr/local/lib/php.ini10
-rwxr-xr-xusr/local/sbin/ppp-linkup21
-rwxr-xr-xusr/local/sbin/vpn-linkdown7
-rwxr-xr-xusr/local/sbin/vpn-linkup7
-rwxr-xr-xusr/local/www/diag_backup.php126
-rwxr-xr-xusr/local/www/diag_defaults.php73
-rwxr-xr-xusr/local/www/diag_dhcp_leases.php189
-rwxr-xr-xusr/local/www/diag_ipsec_sad.php139
-rwxr-xr-xusr/local/www/diag_ipsec_spd.php155
-rwxr-xr-xusr/local/www/diag_logs.php102
-rwxr-xr-xusr/local/www/diag_logs_dhcp.php103
-rwxr-xr-xusr/local/www/diag_logs_filter.php190
-rwxr-xr-xusr/local/www/diag_logs_settings.php202
-rwxr-xr-xusr/local/www/diag_logs_vpn.php111
-rwxr-xr-xusr/local/www/diag_ping.php113
-rwxr-xr-xusr/local/www/diag_resetstate.php97
-rwxr-xr-xusr/local/www/edit.php128
-rwxr-xr-xusr/local/www/exec.php240
-rwxr-xr-xusr/local/www/exec_raw.php38
-rwxr-xr-xusr/local/www/fbegin.inc131
-rwxr-xr-xusr/local/www/fend.inc8
-rwxr-xr-xusr/local/www/firewall_aliases.php127
-rwxr-xr-xusr/local/www/firewall_aliases_edit.php195
-rwxr-xr-xusr/local/www/firewall_nat.php171
-rwxr-xr-xusr/local/www/firewall_nat_1to1.php145
-rwxr-xr-xusr/local/www/firewall_nat_1to1_edit.php216
-rwxr-xr-xusr/local/www/firewall_nat_edit.php365
-rwxr-xr-xusr/local/www/firewall_nat_out.php184
-rwxr-xr-xusr/local/www/firewall_nat_out_edit.php311
-rwxr-xr-xusr/local/www/firewall_nat_server.php143
-rwxr-xr-xusr/local/www/firewall_nat_server_edit.php153
-rwxr-xr-xusr/local/www/firewall_rules.php268
-rwxr-xr-xusr/local/www/firewall_rules_edit.php773
-rwxr-xr-xusr/local/www/firewall_shaper.php269
-rwxr-xr-xusr/local/www/firewall_shaper_edit.php776
-rwxr-xr-xusr/local/www/firewall_shaper_queues.php141
-rwxr-xr-xusr/local/www/firewall_shaper_queues_edit.php187
-rwxr-xr-xusr/local/www/graph.php325
-rwxr-xr-xusr/local/www/gui.css271
-rwxr-xr-xusr/local/www/guiconfig.inc442
-rwxr-xr-xusr/local/www/ifstats.cgibin0 -> 4136 bytes
-rwxr-xr-xusr/local/www/index.php180
-rwxr-xr-xusr/local/www/interfaces.php630
-rwxr-xr-xusr/local/www/interfaces_assign.php265
-rwxr-xr-xusr/local/www/interfaces_lan.php173
-rwxr-xr-xusr/local/www/interfaces_opt.php276
-rwxr-xr-xusr/local/www/interfaces_vlan.php149
-rwxr-xr-xusr/local/www/interfaces_vlan_edit.php146
-rwxr-xr-xusr/local/www/interfaces_wan.php630
-rwxr-xr-xusr/local/www/interfaces_wlan.inc182
-rwxr-xr-xusr/local/www/license.php187
-rwxr-xr-xusr/local/www/logobig.jpgbin0 -> 7911 bytes
-rwxr-xr-xusr/local/www/reboot.php66
-rwxr-xr-xusr/local/www/services_captiveportal.php396
-rwxr-xr-xusr/local/www/services_captiveportal_ip.php152
-rwxr-xr-xusr/local/www/services_captiveportal_ip_edit.php152
-rwxr-xr-xusr/local/www/services_captiveportal_mac.php133
-rwxr-xr-xusr/local/www/services_captiveportal_mac_edit.php134
-rwxr-xr-xusr/local/www/services_dhcp.php337
-rwxr-xr-xusr/local/www/services_dhcp_edit.php176
-rwxr-xr-xusr/local/www/services_dhcp_relay.php229
-rwxr-xr-xusr/local/www/services_dnsmasq.php168
-rwxr-xr-xusr/local/www/services_dnsmasq_edit.php160
-rwxr-xr-xusr/local/www/services_dyndns.php197
-rwxr-xr-xusr/local/www/services_proxyarp.php124
-rwxr-xr-xusr/local/www/services_proxyarp_edit.php231
-rwxr-xr-xusr/local/www/services_snmp.php145
-rwxr-xr-xusr/local/www/services_wol.php162
-rwxr-xr-xusr/local/www/services_wol_edit.php143
-rwxr-xr-xusr/local/www/status.php150
-rwxr-xr-xusr/local/www/status_captiveportal.php128
-rwxr-xr-xusr/local/www/status_graph.php80
-rwxr-xr-xusr/local/www/status_interfaces.php283
-rwxr-xr-xusr/local/www/status_wireless.php189
-rwxr-xr-xusr/local/www/system.php260
-rwxr-xr-xusr/local/www/system_advanced.php289
-rwxr-xr-xusr/local/www/system_firmware.php206
-rwxr-xr-xusr/local/www/system_routes.php126
-rwxr-xr-xusr/local/www/system_routes_edit.php176
-rwxr-xr-xusr/local/www/vpn_ipsec.php192
-rwxr-xr-xusr/local/www/vpn_ipsec_edit.php527
-rwxr-xr-xusr/local/www/vpn_ipsec_keys.php107
-rwxr-xr-xusr/local/www/vpn_ipsec_keys_edit.php135
-rwxr-xr-xusr/local/www/vpn_ipsec_mobile.php330
-rwxr-xr-xusr/local/www/vpn_openvpn.php366
-rwxr-xr-xusr/local/www/vpn_openvpn_cli.php148
-rwxr-xr-xusr/local/www/vpn_openvpn_cli_edit.php353
-rwxr-xr-xusr/local/www/vpn_pptp.php309
-rwxr-xr-xusr/local/www/vpn_pptp_users.php126
-rwxr-xr-xusr/local/www/vpn_pptp_users_edit.php159
-rwxr-xr-xusr/sbin/config_lock.sh9
-rwxr-xr-xusr/sbin/config_unlock.sh9
97 files changed, 19030 insertions, 0 deletions
diff --git a/usr/local/bin/runmsntp.sh b/usr/local/bin/runmsntp.sh
new file mode 100755
index 0000000..f7100b9
--- /dev/null
+++ b/usr/local/bin/runmsntp.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# write our PID to file
+echo $$ > $1
+
+# execute msntp in endless loop; restart if it
+# exits (wait 1 second to avoid restarting too fast in case
+# the network is not yet setup)
+while true; do
+ /usr/local/bin/msntp -r -P no -l $2 -x $3 $4
+ sleep 1
+done
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php
new file mode 100755
index 0000000..c264625
--- /dev/null
+++ b/usr/local/captiveportal/index.php
@@ -0,0 +1,407 @@
+#!/usr/local/bin/php
+<?php
+/*
+ index.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("globals.inc");
+require("util.inc");
+require("config.inc");
+require("radius_authentication.inc") ;
+require("radius_accounting.inc") ;
+
+header("Expires: 0");
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+$orig_host = $_ENV['HTTP_HOST'];
+$orig_request = $_ENV['CAPTIVE_REQPATH'];
+$lockfile = "{$g['varrun_path']}/captiveportal.lock";
+$clientip = $_ENV['REMOTE_ADDR'];
+
+if (!$clientip) {
+ /* not good - bail out */
+ exit;
+}
+
+/* find MAC address for client */
+$clientmac = arp_get_mac_by_ip($clientip);
+if (!$clientmac && !isset($config['captiveportal']['nomacfilter'])) {
+ /* unable to find MAC address - shouldn't happen! - bail out */
+ exit;
+}
+
+if ($clientmac && portal_mac_fixed($clientmac)) {
+ /* punch hole in ipfw for pass thru mac addresses */
+ portal_allow($clientip, $clientmac, "unauthenticated");
+
+} else if ($_POST['accept'] && file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+
+ /* authenticate against radius server */
+ $radiusservers = captiveportal_get_radius_servers();
+
+ if ($_POST['auth_user'] && $_POST['auth_pass']) {
+ $auth_val = RADIUS_AUTHENTICATION($_POST['auth_user'],
+ $_POST['auth_pass'],
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['port'],
+ $radiusservers[0]['key']);
+ if ($auth_val == 2) {
+ $sessionid = portal_allow($clientip, $clientmac, $_POST['auth_user']);
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ $auth_val = RADIUS_ACCOUNTING_START($_POST['auth_user'],
+ $sessionid,
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ } else {
+ readfile("{$g['varetc_path']}/captiveportal-error.html");
+ }
+ } else {
+ readfile("{$g['varetc_path']}/captiveportal-error.html");
+ }
+
+} else if ($_POST['accept'] && $clientip) {
+ portal_allow($clientip, $clientmac, "unauthenticated");
+} else if ($_POST['logout_id']) {
+ disconnect_client($_POST['logout_id']);
+ echo <<<EOD
+<HTML>
+<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
+<BODY BGCOLOR="#435370">
+<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
+<B>You've been disconnected.</B>
+</SPAN>
+<SCRIPT LANGUAGE="JavaScript">
+<!--
+setTimeout('window.close();',5000) ;
+-->
+</SCRIPT>
+</BODY>
+</HTML>
+
+EOD;
+} else if (($_ENV['SERVER_PORT'] != 8001) && isset($config['captiveportal']['httpslogin'])) {
+ /* redirect to HTTPS login page */
+ header("Location: https://{$config['captiveportal']['httpsname']}:8001/?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+} else {
+ /* display captive portal page */
+ $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
+
+ /* substitute variables */
+ if (isset($config['captiveportal']['httpslogin']))
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
+ else
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "", $htmltext);
+
+ if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
+ $redirurl = urldecode($matches[1]);
+ else
+ $redirurl = "http://{$orig_host}{$orig_request}";
+ $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
+
+ echo $htmltext;
+}
+
+exit;
+
+function portal_mac_fixed($clientmac) {
+ global $g ;
+
+ /* open captive portal mac db */
+ if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db","r") ;
+ if (!$fd) {
+ return FALSE;
+ }
+ while (!feof($fd)) {
+ $mac = trim(fgets($fd)) ;
+ if(strcasecmp($clientmac, $mac) == 0) {
+ fclose($fd) ;
+ return TRUE ;
+ }
+ }
+ fclose($fd) ;
+ }
+ return FALSE ;
+}
+
+function portal_allow($clientip,$clientmac,$clientuser) {
+
+ global $orig_host, $orig_request, $g, $config;
+
+ /* user has accepted AUP - let him in */
+ portal_lock();
+
+ /* get next ipfw rule number */
+ if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
+ $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
+ if (!$ruleno)
+ $ruleno = 10000; /* first rule number */
+
+ $saved_ruleno = $ruleno;
+
+ /* generate unique session ID */
+ $tod = gettimeofday();
+ $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
+
+ /* add ipfw rules for layer 3 */
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from $clientip to any in");
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to $clientip out");
+
+ /* add ipfw rules for layer 2 */
+ if (!isset($config['captiveportal']['nomacfilter'])) {
+ $l2ruleno = $ruleno + 10000;
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
+ }
+
+ /* read in client database */
+ $cpdb = array();
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd)) ;
+ if($line) {
+ $cpdb[] = explode(",",$line);
+ }
+ }
+ fclose($fd);
+ }
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find an existing entry and delete it */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if(!strcasecmp($cpdb[$i][2],$clientip)) {
+ if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* rewrite information to database */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+ if ($fd) {
+ foreach ($cpdb as $cpent) {
+ fwrite($fd, join(",", $cpent) . "\n");
+ }
+ /* write in this new entry */
+ fwrite($fd, time().",{$ruleno},{$clientip},{$clientmac},{$clientuser},{$sessionid}\n") ;
+ fclose($fd);
+ }
+
+ /* write next rule number */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
+ if ($fd) {
+ $ruleno++;
+ if ($ruleno > 19899)
+ $ruleno = 10000; /* wrap around */
+ fwrite($fd, $ruleno);
+ fclose($fd);
+ }
+
+ portal_unlock();
+
+ /* redirect user to desired destination */
+ if ($config['captiveportal']['redirurl'])
+ $redirurl = $config['captiveportal']['redirurl'];
+ else if ($_POST['redirurl'])
+ $redirurl = $_POST['redirurl'];
+ else
+ $redirurl = "http://{$orig_host}{$orig_request}";
+
+ if(isset($config['captiveportal']['logoutwin_enable'])) {
+
+ if (isset($config['captiveportal']['httpslogin']))
+ $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
+ else
+ $logouturl = "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/";
+
+ echo <<<EOD
+<HTML>
+<HEAD><TITLE>Redirecting...</TITLE></HEAD>
+<BODY>
+<SPAN STYLE="font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
+<B>Redirecting to <A HREF="{$redirurl}">{$redirurl}</A>...</B>
+</SPAN>
+<SCRIPT LANGUAGE="JavaScript">
+<!--
+LogoutWin = window.open('', 'Logout', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=256,height=64');
+if (LogoutWin) {
+ LogoutWin.document.write('<HTML>');
+ LogoutWin.document.write('<HEAD><TITLE>Logout</TITLE></HEAD>') ;
+ LogoutWin.document.write('<BODY BGCOLOR="#435370">');
+ LogoutWin.document.write('<DIV ALIGN="center" STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">') ;
+ LogoutWin.document.write('<B>Click the button below to disconnect</B><P>');
+ LogoutWin.document.write('<FORM METHOD="POST" ACTION="{$logouturl}">');
+ LogoutWin.document.write('<INPUT NAME="logout_id" TYPE="hidden" VALUE="{$sessionid}">');
+ LogoutWin.document.write('<INPUT NAME="logout" TYPE="submit" VALUE="Logout">');
+ LogoutWin.document.write('</FORM>');
+ LogoutWin.document.write('</DIV></BODY>');
+ LogoutWin.document.write('</HTML>');
+ LogoutWin.document.close();
+}
+
+document.location.href="{$redirurl}";
+-->
+</SCRIPT>
+</BODY>
+</HTML>
+
+EOD;
+ } else {
+ header("Location: " . $redirurl);
+ }
+
+ return $sessionid;
+}
+
+/* read RADIUS servers into array */
+function captiveportal_get_radius_servers() {
+
+ global $g;
+
+ if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
+ if ($fd) {
+ $radiusservers = array();
+ while (!feof($fd)) {
+ $line = trim(fgets($fd));
+ if ($line) {
+ $radsrv = array();
+ list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
+ $radiusservers[] = $radsrv;
+ }
+ }
+ fclose($fd);
+
+ return $radiusservers;
+ }
+ }
+
+ return false;
+}
+
+/* lock captive portal information, decide that the lock file is stale after
+ 10 seconds */
+function portal_lock() {
+
+ global $lockfile;
+
+ $n = 0;
+ while ($n < 10) {
+ /* open the lock file in append mode to avoid race condition */
+ if ($fd = @fopen($lockfile, "x")) {
+ /* succeeded */
+ fclose($fd);
+ return;
+ } else {
+ /* file locked, wait and try again */
+ sleep(1);
+ $n++;
+ }
+ }
+}
+
+/* unlock captive portal information file */
+function portal_unlock() {
+
+ global $lockfile;
+
+ if (file_exists($lockfile))
+ unlink($lockfile);
+}
+
+/* remove a single client by session ID
+ by Dinesh Nair
+ */
+function disconnect_client($sessionid) {
+
+ global $g, $config;
+
+ portal_lock();
+
+ /* read database */
+ $cpdb = array() ;
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd)) ;
+ if($line) {
+ $cpdb[] = explode(",",$line);
+ }
+ }
+ fclose($fd);
+ }
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find entry */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if ($cpdb[$i][5] == $sessionid) {
+ /* this client needs to be deleted - remove ipfw rules */
+ if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* rewrite information to database */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+ if ($fd) {
+ foreach ($cpdb as $cpent) {
+ fwrite($fd, join(",", $cpent) . "\n");
+ }
+ fclose($fd);
+ }
+
+ portal_unlock();
+}
+?>
diff --git a/usr/local/captiveportal/radius_accounting.inc b/usr/local/captiveportal/radius_accounting.inc
new file mode 100644
index 0000000..7004971
--- /dev/null
+++ b/usr/local/captiveportal/radius_accounting.inc
@@ -0,0 +1,241 @@
+<?php
+/*
+ radius_accounting.inc
+ 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.
+*/
+
+
+function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "m0n0wall" ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $thisidentifier=rand()%256;
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6+ // nasPortType
+ 6+ // Acct Status Type
+ 6+ // Acct RADIUS Authenticated
+ 2+strlen($sessionid); // Acct SessionID
+
+ // v v v v v v v v v 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 E
+ $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ 0,0,0,0, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,1, // Acct Status Type = Start
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid // Acct Session ID
+ );
+
+ /* Generate Accounting Request Authenticator */
+ $RA = md5($data.$radiuskey) ;
+
+ // v v v v v v v v v 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 E
+ $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,1, // Acct Status Type = Start
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid // Acct Session ID
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 5 -> Accounting-Response
+ // See RFC2866 for this.
+}
+
+function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "quewall" ;
+
+ $input_pkts = $input_bytes = $output_pkts = $output_bytes = 0 ;
+
+ exec("/sbin/ipfw show {$ruleno}", $ipfw) ;
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[0], $matches) ;
+ $output_pkts = $matches[2] ;
+ $output_bytes = $matches[3] ;
+
+ unset($matches) ;
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[1], $matches) ;
+ $input_pkts = $matches[2] ;
+ $input_bytes = $matches[3] ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $thisidentifier=rand()%256;
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6+ // nasPortType
+ 6+ // Acct Status Type
+ 6+ // Acct RADIUS Authenticated
+ 2+strlen($sessionid)+ // Acct SessionID
+ 6+ // Acct terminate
+ 6+ // Session time
+ 6+ // input bytes
+ 6+ // input packets
+ 6+ // output bytes
+ 6; // output packets
+
+ // v v v v v v v v v 1 1 1 1 1 1 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 E
+ $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCNCCNCCNCCNCCNCCN",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ 0,0,0,0, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,2, // Acct Status Type = Stop
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid, // Acct Session ID
+ 49,6,1, // Acct Terminate = User Request
+ 46,6,time() - $start_time, // Session Time
+ 42,6,$input_bytes, // Input Octets
+ 47,6,$input_pkts, // Input Packets
+ 43,6,$output_bytes, // Output Octets
+ 48,6,$output_pkts // Output Packets
+ );
+
+ /* Generate Accounting Request Authenticator */
+ $RA = md5($data.$radiuskey) ;
+
+ // v v v v v v v v v 1 1 1 1 1 1 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 E
+ $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCNCCNCCNCCNCCNCCN",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,2, // Acct Status Type = Stop
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid, // Acct Session ID
+ 49,6,1, // Acct Terminate = User Request
+ 46,6,time() - $start_time, // Session Time
+ 42,6,$input_bytes, // Input Octets
+ 47,6,$input_pkts, // Input Packets
+ 43,6,$output_bytes, // Output Octets
+ 48,6,$output_pkts // Output Packets
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 5 -> Accounting-Response
+ // See RFC2866 for this.
+}
+?>
diff --git a/usr/local/captiveportal/radius_authentication.inc b/usr/local/captiveportal/radius_authentication.inc
new file mode 100644
index 0000000..c106da3
--- /dev/null
+++ b/usr/local/captiveportal/radius_authentication.inc
@@ -0,0 +1,128 @@
+<?php
+ //
+ // $Id$
+ //
+ // radius authentication v1.0 by Edwin Groothuis (edwin@mavetju.org)
+ //
+ // If you didn't get this file via http://www.mavetju.org, please
+ // check for the availability of newer versions.
+ //
+ // See LICENSE for distribution issues. If this file isn't in
+ // the distribution, please inform me about it.
+ //
+ // If you want to use this script, fill in the configuration in
+ // radius_authentication.conf and call the function
+ // RADIUS_AUTHENTICATION() with the username and password
+ // provided by the user. If it returns a 2, the authentication
+ // was successfull!
+
+ // If you want to use this, make sure that you have raw sockets
+ // enabled during compile-time: "./configure --enable-sockets".
+
+ // This version has been modified by Dinesh Nair <dinesh@alphaque.com>
+ // for use in the m0n0wall distribution http://m0n0.ch/wall/
+ //
+ // Changes include moving from raw sockets to fsockopen
+ // and the removal of dependency on external conf file
+ // An existing bug which resulted in a malformed RADIUS packet
+ // was also fixed and patches submitted to Edwin. This bug would
+ // have caused authentication to fail on every access.
+
+function RADIUS_AUTHENTICATION($username,$password,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "m0n0wall" ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $RA=pack("CCCCCCCCCCCCCCCC", // auth code
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255);
+
+ $encryptedpassword=Encrypt($password,$sharedsecret,$RA);
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($encryptedpassword)+ // userpassword
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6; // nasPortType
+
+ $thisidentifier=rand()%256;
+ // v v v v v v v v v
+ // Line # 1 2 3 4 5 6 7 8 E
+ $data=pack("CCCCa*CCCCCCCCa*CCa*CCa*CCCCCCCCCCCC",
+ 1,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 2,2+strlen($encryptedpassword),$encryptedpassword, // userpassword
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15 // nasPortType = Ethernet
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "encryptedpassword is $encryptedpassword with len " . strlen($encryptedpassword) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 2 -> Access-Accept
+ // 3 -> Access-Reject
+ // See RFC2865 for this.
+}
+
+function Encrypt($password,$key,$RA) {
+ global $debug;
+
+ $keyRA=$key.$RA;
+
+ if ($debug)
+ echo "<br>key: $key<br>password: $password<hr>\n";
+
+ $md5checksum=md5($keyRA);
+ $output="";
+
+ for ($i=0;$i<=15;$i++) {
+ if (2*$i>strlen($md5checksum)) $m=0; else $m=hexdec(substr($md5checksum,2*$i,2));
+ if ($i>strlen($keyRA)) $k=0; else $k=ord(substr($keyRA,$i,1));
+ if ($i>strlen($password)) $p=0; else $p=ord(substr($password,$i,1));
+ $c=$m^$p;
+ $output.=chr($c);
+ }
+ return $output;
+}
+?>
diff --git a/usr/local/etc/php.ini b/usr/local/etc/php.ini
new file mode 100644
index 0000000..3145b15
--- /dev/null
+++ b/usr/local/etc/php.ini
@@ -0,0 +1,10 @@
+magic_quotes_gpc = Off
+max_execution_time = 0
+max_input_time = 180
+register_argc_argv = Off
+file_uploads = On
+upload_tmp_dir = /ftmp
+upload_max_filesize = 6M
+post_max_size = 7M
+html_errors = Off
+include_path = ".:/etc/inc:/usr/local/www:/usr/local/captiveportal"
diff --git a/usr/local/lib/php.ini b/usr/local/lib/php.ini
new file mode 100644
index 0000000..3145b15
--- /dev/null
+++ b/usr/local/lib/php.ini
@@ -0,0 +1,10 @@
+magic_quotes_gpc = Off
+max_execution_time = 0
+max_input_time = 180
+register_argc_argv = Off
+file_uploads = On
+upload_tmp_dir = /ftmp
+upload_max_filesize = 6M
+post_max_size = 7M
+html_errors = Off
+include_path = ".:/etc/inc:/usr/local/www:/usr/local/captiveportal"
diff --git a/usr/local/sbin/ppp-linkup b/usr/local/sbin/ppp-linkup
new file mode 100755
index 0000000..01bca8e
--- /dev/null
+++ b/usr/local/sbin/ppp-linkup
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+rm -f /var/etc/nameservers.conf
+
+# unset CGI environment variables so as not to confuse PHP
+unset CONTENT_TYPE GATEWAY_INTERFACE REMOTE_USER REMOTE_ADDR AUTH_TYPE
+unset HTTP_USER_AGENT CONTENT_LENGTH SCRIPT_FILENAME HTTP_HOST
+unset SERVER_SOFTWARE HTTP_REFERER SERVER_PROTOCOL REQUEST_METHOD
+unset SERVER_PORT SCRIPT_NAME SERVER_NAME
+
+# write nameservers to file
+if [ "$6" = "dns1" ]; then
+ echo $7 >> /var/etc/nameservers.conf
+fi
+if [ "$8" = "dns2" ]; then
+ echo $9 >> /var/etc/nameservers.conf
+fi
+
+# let the configuration system know that the
+# WAN IP address has changed
+/etc/rc.newwanip
diff --git a/usr/local/sbin/vpn-linkdown b/usr/local/sbin/vpn-linkdown
new file mode 100755
index 0000000..1147119
--- /dev/null
+++ b/usr/local/sbin/vpn-linkdown
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# record logout
+/usr/bin/logger -p local3.info "logout,$1,,$3"
+
+# resync ipfilter
+/sbin/ipf -y
diff --git a/usr/local/sbin/vpn-linkup b/usr/local/sbin/vpn-linkup
new file mode 100755
index 0000000..c56cb95
--- /dev/null
+++ b/usr/local/sbin/vpn-linkup
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# record login
+/usr/bin/logger -p local3.info "login,$1,$4,$5"
+
+# resync ipfilter
+/sbin/ipf -y
diff --git a/usr/local/www/diag_backup.php b/usr/local/www/diag_backup.php
new file mode 100755
index 0000000..888651c
--- /dev/null
+++ b/usr/local/www/diag_backup.php
@@ -0,0 +1,126 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_backup.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+/* omit no-cache headers because it confuses IE with file downloads */
+$omit_nocacheheaders = true;
+require("guiconfig.inc");
+
+if ($_POST) {
+
+ unset($input_errors);
+
+ if (stristr($_POST['Submit'], "Restore"))
+ $mode = "restore";
+ else if (stristr($_POST['Submit'], "Download"))
+ $mode = "download";
+
+ if ($mode) {
+ if ($mode == "download") {
+ config_lock();
+
+ $fn = "config-" . $config['system']['hostname'] . "." .
+ $config['system']['domain'] . "-" . date("YmdHis") . ".xml";
+
+ $fs = filesize($g['conf_path'] . "/config.xml");
+ header("Content-Type: application/octet-stream");
+ header("Content-Disposition: attachment; filename=$fn");
+ header("Content-Length: $fs");
+ readfile($g['conf_path'] . "/config.xml");
+ config_unlock();
+ exit;
+ } else if ($mode == "restore") {
+ if (is_uploaded_file($_FILES['conffile']['tmp_name'])) {
+ if (config_install($_FILES['conffile']['tmp_name']) == 0) {
+ system_reboot();
+ $savemsg = "The configuration has been restored. The firewall is now rebooting.";
+ } else {
+ $input_errors[] = "The configuration could not be restored.";
+ }
+ } else {
+ $input_errors[] = "The configuration could not be restored (file upload error).";
+ }
+ }
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: Backup/restore");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">Diagnostics: Backup/restore</p>
+ <form action="diag_backup.php" method="post" enctype="multipart/form-data">
+ <?php if ($input_errors) print_input_errors($input_errors); ?>
+ <?php if ($savemsg) print_info_box($savemsg); ?>
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="listtopic">Backup configuration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="baseline">&nbsp;</td>
+ <td width="78%" class="listn">
+ <p> Click this button to download the system configuration
+ in XML format.<br>
+ <br>
+ <input name="Submit" type="submit" class="formbtn" id="download" value="Download configuration">
+ <br>
+ &nbsp; <br>
+ &nbsp; </p></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic">Restore configuration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="baseline">&nbsp;</td>
+ <td width="78%" class="listn">
+ <p> Open a m0n0wall configuration XML file and click the button
+ below to restore the configuration.<br>
+ <br>
+ <strong><span class="red">Note:</span></strong><br>
+ The firewall will reboot after restoring the configuration.<br>
+ <br>
+ <input name="conffile" type="file" class="formfld" id="conffile" size="40">
+ <br>
+ <br>
+ <input name="Submit" type="submit" class="formbtn" id="restore" value="Restore configuration">
+ </p>
+ </td>
+ </tr>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_defaults.php b/usr/local/www/diag_defaults.php
new file mode 100755
index 0000000..3ba3ea0
--- /dev/null
+++ b/usr/local/www/diag_defaults.php
@@ -0,0 +1,73 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_defaults.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+ if ($_POST['Submit'] != " No ") {
+ reset_factory_defaults();
+ system_reboot();
+ $rebootmsg = "The system has been reset to factory defaults and is now rebooting. This may take one minute.";
+ } else {
+ header("Location: index.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: Factory defaults");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: Factory defaults</p>
+<?php if ($rebootmsg): echo print_info_box($rebootmsg); else: ?>
+<form action="diag_defaults.php" method="post">
+ <p><strong>If you click &quot;Yes&quot;, the firewall will be reset
+ to factory defaults and will reboot immediately. The entire system
+ configuration will be overwritten. The LAN IP address will be
+ reset to 192.168.1.1, the system will be configured as a DHCP
+ server, and the password will be set to 'mono'.<br>
+ <br>
+ Are you sure you want to proceed?</strong></p>
+ <p>
+ <input name="Submit" type="submit" class="formbtn" value=" Yes ">
+ <input name="Submit" type="submit" class="formbtn" value=" No ">
+ </p>
+ </form>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_dhcp_leases.php b/usr/local/www/diag_dhcp_leases.php
new file mode 100755
index 0000000..4b730fa
--- /dev/null
+++ b/usr/local/www/diag_dhcp_leases.php
@@ -0,0 +1,189 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_dhcp_leases.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Björn Pålsson <bjorn@networksab.com> and 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.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: DHCP leases");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: DHCP leases</p>
+<?php
+
+flush();
+
+function leasecmp($a, $b) {
+ return strcmp($a[$_GET['order']], $b[$_GET['order']]);
+}
+
+$fp = @fopen("{$g['vardb_path']}/dhcpd.leases","r");
+
+if ($fp):
+
+$return = array();
+
+while ($line = fgets($fp)) {
+ $matches = "";
+
+ // Sort out comments
+ // C-style comments not supported!
+ if (preg_match("/^\s*[\r|\n]/", $line, $matches[0]) ||
+ preg_match("/^([^\"#]*)#.*$/", $line, $matches[1]) ||
+ preg_match("/^([^\"]*)\/\/.*$/", $line, $matches[2]) ||
+ preg_match("/\s*#(.*)/", $line, $matches[3]) ||
+ preg_match("/\\\"\176/", $line, $matches[4])
+ ) {
+ $line = "";
+ continue;
+ }
+
+ if (preg_match("/(.*)#(.*)/", $line, $matches))
+ $line = $matches[0];
+
+ // Tokenize lines
+ do {
+ if (preg_match("/^\s*\"([^\"]*)\"(.*)$/", $line, $matches)) {
+ $line = $matches[2];
+ $return[] = array($matches[1], 0);
+ } else if (preg_match("/^\s*([{};])(.*)$/", $line, $matches)) {
+ $line = $matches[2];
+ $return[] = array($matches[0], 1);
+ } else if (preg_match("/^\s*([^{}; \t]+)(.*)$/", $line, $matches)) {
+ $line = $matches[2];
+ $return[] = array($matches[1], 0);
+ } else
+ break;
+
+ } while($line);
+
+ $lines++;
+}
+
+fclose($fp);
+
+$leases = array();
+$i = 0;
+
+// Put everything together again
+while ($data = array_shift($return)) {
+ if ($data[0] == "next") {
+ $d = array_shift($return);
+ }
+ if ($data[0] == "lease") {
+ $d = array_shift($return);
+ $leases[$i]['ip'] = $d[0];
+ }
+ if ($data[0] == "client-hostname") {
+ $d = array_shift($return);
+ $leases[$i]['hostname'] = $d[0];
+ }
+ if ($data[0] == "hardware") {
+ $d = array_shift($return);
+ if ($d[0] == "ethernet") {
+ $d = array_shift($return);
+ $leases[$i]['mac'] = $d[0];
+ }
+ } else if ($data[0] == "starts") {
+ $d = array_shift($return);
+ $d = array_shift($return);
+ $leases[$i]['start'] = $d[0];
+ $d = array_shift($return);
+ $leases[$i]['start'] .= " " . $d[0];
+ } else if ($data[0] == "ends") {
+ $d = array_shift($return);
+ $d = array_shift($return);
+ $leases[$i]['end'] = $d[0];
+ $d = array_shift($return);
+ $leases[$i]['end'] .= " " . $d[0];
+ } else if ($data[0] == "binding") {
+ $d = array_shift($return);
+ if ($d[0] == "state") {
+ $d = array_shift($return);
+ $leases[$i]['act'] = $d[0];
+ }
+ } else if (($data[0] == "}") && ($data[1] == 1)) // End of group
+ $i++;
+}
+
+if ($_GET['order'])
+ usort($leases, "leasecmp");
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
+ <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
+ <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
+ <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
+ <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
+ </tr>
+<?php
+foreach ($leases as $data) {
+ if (($data['act'] == "active") || ($_GET['all'] == 1)) {
+ if ($data['act'] != "active") {
+ $fspans = "<span class=\"gray\">";
+ $fspane = "</span>";
+ } else {
+ $fspans = $fspane = "";
+ }
+ echo "<tr>\n";
+ echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
+ echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
+ echo "<td class=\"listr\">{$fspans}{$data['hostname']}{$fspane}&nbsp;</td>\n";
+ echo "<td class=\"listr\">{$fspans}{$data['start']}{$fspane}&nbsp;</td>\n";
+ echo "<td class=\"listr\">{$fspans}{$data['end']}{$fspane}&nbsp;</td>\n";
+ echo "</tr>\n";
+ }
+}
+?>
+</table>
+<p>
+<form action="diag_dhcp_leases.php" method="GET">
+<input type="hidden" name="order" value="<?=$_GET['order'];?>">
+<?php if ($_GET['all']): ?>
+<input type="hidden" name="all" value="0">
+<input type="submit" class="formbtn" value="Show active leases only">
+<?php else: ?>
+<input type="hidden" name="all" value="1">
+<input type="submit" class="formbtn" value="Show active and expired leases">
+<?php endif; ?>
+</form>
+<?php else: ?>
+<p><strong>No leases file found. Is the DHCP server active?</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_ipsec_sad.php b/usr/local/www/diag_ipsec_sad.php
new file mode 100755
index 0000000..caba9d1
--- /dev/null
+++ b/usr/local/www/diag_ipsec_sad.php
@@ -0,0 +1,139 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_ipsec_sad.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: IPsec");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: IPsec</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">SAD</li>
+ <li class="tabinact"><a href="diag_ipsec_spd.php">SPD</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<?php
+
+/* delete any SA? */
+if ($_GET['act'] == "del") {
+ $fd = @popen("/usr/sbin/setkey -c > /dev/null 2>&1", "w");
+ if ($fd) {
+ fwrite($fd, "delete {$_GET['src']} {$_GET['dst']} {$_GET['proto']} {$_GET['spi']} ;\n");
+ pclose($fd);
+ sleep(1);
+ }
+}
+
+/* query SAD */
+$fd = @popen("/usr/sbin/setkey -D", "r");
+$sad = array();
+if ($fd) {
+ while (!feof($fd)) {
+ $line = chop(fgets($fd));
+ if (!$line)
+ continue;
+ if ($line == "No SAD entries.")
+ break;
+ if ($line[0] != "\t") {
+ if (is_array($cursa))
+ $sad[] = $cursa;
+ $cursa = array();
+ list($cursa['src'],$cursa['dst']) = explode(" ", $line);
+ $i = 0;
+ } else {
+ $linea = explode(" ", trim($line));
+ if ($i == 1) {
+ $cursa['proto'] = $linea[0];
+ $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1);
+ } else if ($i == 2) {
+ $cursa['ealgo'] = $linea[1];
+ } else if ($i == 3) {
+ $cursa['aalgo'] = $linea[1];
+ }
+ }
+ $i++;
+ }
+ if (is_array($cursa) && count($cursa))
+ $sad[] = $cursa;
+ pclose($fd);
+}
+if (count($sad)):
+?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td nowrap class="listhdrr">Source</td>
+ <td nowrap class="listhdrr">Destination</a></td>
+ <td nowrap class="listhdrr">Protocol</td>
+ <td nowrap class="listhdrr">SPI</td>
+ <td nowrap class="listhdrr">Enc. alg.</td>
+ <td nowrap class="listhdr">Auth. alg.</td>
+ <td nowrap class="list"></td>
+ </tr>
+<?php
+foreach ($sad as $sa): ?>
+ <tr>
+ <td class="listlr"><?=htmlspecialchars($sa['src']);?></td>
+ <td class="listr"><?=htmlspecialchars($sa['dst']);?></td>
+ <td class="listr"><?=htmlspecialchars(strtoupper($sa['proto']));?></td>
+ <td class="listr"><?=htmlspecialchars($sa['spi']);?></td>
+ <td class="listr"><?=htmlspecialchars($sa['ealgo']);?></td>
+ <td class="listr"><?=htmlspecialchars($sa['aalgo']);?></td>
+ <td class="list" nowrap>
+ <?php
+ $args = "src=" . rawurlencode($sa['src']);
+ $args .= "&dst=" . rawurlencode($sa['dst']);
+ $args .= "&proto=" . rawurlencode($sa['proto']);
+ $args .= "&spi=" . rawurlencode("0x" . $sa['spi']);
+ ?>
+ <a href="diag_ipsec_sad.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security association?')"><img src="x.gif" width="17" height="17" border="0"></a>
+ </td>
+
+ </tr>
+<?php endforeach; ?>
+</table>
+<?php else: ?>
+<p><strong>No IPsec security associations.</strong></p>
+<?php endif; ?>
+</td></tr></table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_ipsec_spd.php b/usr/local/www/diag_ipsec_spd.php
new file mode 100755
index 0000000..80cd066
--- /dev/null
+++ b/usr/local/www/diag_ipsec_spd.php
@@ -0,0 +1,155 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_ipsec_spd.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: IPsec");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: IPsec</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_ipsec_sad.php">SAD</a></li>
+ <li class="tabact">SPD</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<?php
+
+/* delete any SP? */
+if ($_GET['act'] == "del") {
+ $fd = @popen("/usr/sbin/setkey -c > /dev/null 2>&1", "w");
+ if ($fd) {
+ fwrite($fd, "spddelete {$_GET['src']} {$_GET['dst']} any -P {$_GET['dir']} ;\n");
+ pclose($fd);
+ sleep(1);
+ }
+}
+
+/* query SAD */
+$fd = @popen("/usr/sbin/setkey -DP", "r");
+$spd = array();
+if ($fd) {
+ while (!feof($fd)) {
+ $line = chop(fgets($fd));
+ if (!$line)
+ continue;
+ if ($line == "No SPD entries.")
+ break;
+ if ($line[0] != "\t") {
+ if (is_array($cursp))
+ $spd[] = $cursp;
+ $cursp = array();
+ $linea = explode(" ", $line);
+ $cursp['src'] = substr($linea[0], 0, strpos($linea[0], "["));
+ $cursp['dst'] = substr($linea[1], 0, strpos($linea[1], "["));
+ $i = 0;
+ } else if (is_array($cursp)) {
+ $linea = explode(" ", trim($line));
+ if ($i == 1) {
+ if ($linea[1] == "none") /* don't show default anti-lockout rule */
+ unset($cursp);
+ else
+ $cursp['dir'] = $linea[0];
+ } else if ($i == 2) {
+ $upperspec = explode("/", $linea[0]);
+ $cursp['proto'] = $upperspec[0];
+ list($cursp['ep_src'], $cursp['ep_dst']) = explode("-", $upperspec[2]);
+ }
+ }
+ $i++;
+ }
+ if (is_array($cursp) && count($cursp))
+ $spd[] = $cursp;
+ pclose($fd);
+}
+if (count($spd)):
+?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td nowrap class="listhdrr">Source</td>
+ <td nowrap class="listhdrr">Destination</a></td>
+ <td nowrap class="listhdrr">Direction</td>
+ <td nowrap class="listhdrr">Protocol</td>
+ <td nowrap class="listhdrr">Tunnel endpoints</td>
+ <td nowrap class="list"></td>
+ </tr>
+<?php
+foreach ($spd as $sp): ?>
+ <tr>
+ <td class="listlr" valign="top"><?=htmlspecialchars($sp['src']);?></td>
+ <td class="listr" valign="top"><?=htmlspecialchars($sp['dst']);?></td>
+ <td class="listr" valign="top"><img src="<?=$sp['dir'];?>.gif" width="11" height="11" style="margin-top: 2px"></td>
+ <td class="listr" valign="top"><?=htmlspecialchars(strtoupper($sp['proto']));?></td>
+ <td class="listr" valign="top"><?=htmlspecialchars($sp['ep_src']);?> - <br>
+ <?=htmlspecialchars($sp['ep_dst']);?></td>
+ <td class="list" nowrap>
+ <?php
+ $args = "src=" . rawurlencode($sp['src']);
+ $args .= "&dst=" . rawurlencode($sp['dst']);
+ $args .= "&dir=" . rawurlencode($sp['dir']);
+ ?>
+ <a href="diag_ipsec_spd.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security policy?')"><img src="x.gif" width="17" height="17" border="0"></a>
+ </td>
+
+ </tr>
+<?php endforeach; ?>
+</table>
+<br>
+<table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td width="16"><img src="in.gif" width="11" height="11"></td>
+ <td>incoming (as seen by firewall)</td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td><img src="out.gif" width="11" height="11"></td>
+ <td>outgoing (as seen by firewall)</td>
+ </tr>
+</table>
+<?php else: ?>
+<p><strong>No IPsec security policies.</strong></p>
+<?php endif; ?>
+</td></tr></table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_logs.php b/usr/local/www/diag_logs.php
new file mode 100755
index 0000000..fe4d41a
--- /dev/null
+++ b/usr/local/www/diag_logs.php
@@ -0,0 +1,102 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear']) {
+ exec("/usr/sbin/clog -i -s 262144 /var/log/system.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+ global $g, $config;
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ echo "<tr valign=\"top\">\n";
+
+ if ($withorig) {
+ echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+ echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+ } else {
+ echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+ }
+ echo "</tr>\n";
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: System logs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">System</li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="listtopic">
+ Last <?=$nentries;?> system log entries</td>
+ </tr>
+ <?php dump_clog("/var/log/system.log", $nentries); ?>
+ </table>
+ <br><form action="diag_logs.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_logs_dhcp.php b/usr/local/www/diag_logs_dhcp.php
new file mode 100755
index 0000000..ba13ee3
--- /dev/null
+++ b/usr/local/www/diag_logs_dhcp.php
@@ -0,0 +1,103 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs_dhcp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear']) {
+ exec("/usr/sbin/clog -i -s 32768 /var/log/dhcpd.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+ global $g, $config;
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ echo "<tr valign=\"top\">\n";
+
+ if ($withorig) {
+ echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+ echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+ } else {
+ echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+ }
+ echo "</tr>\n";
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: System logs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabact">DHCP</li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="listtopic">
+ Last <?=$nentries;?> DHCP service log entries</td>
+ </tr>
+ <?php dump_clog("/var/log/dhcpd.log", $nentries); ?>
+ </table>
+ <br><form action="diag_logs_dhcp.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
+
diff --git a/usr/local/www/diag_logs_filter.php b/usr/local/www/diag_logs_filter.php
new file mode 100755
index 0000000..fece0ac
--- /dev/null
+++ b/usr/local/www/diag_logs_filter.php
@@ -0,0 +1,190 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs_filter.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear']) {
+ exec("/usr/sbin/clog -i -s 262144 /var/log/filter.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+ global $g, $config;
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ echo "<tr valign=\"top\">\n";
+
+ if ($withorig) {
+ echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+ echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+ } else {
+ echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+ }
+ echo "</tr>\n";
+ }
+}
+
+function conv_clog($logfile, $tail) {
+ global $g, $config;
+
+ /* make interface/port table */
+ $iftable = array();
+ $iftable[$config['interfaces']['lan']['if']] = "LAN";
+ $iftable[get_real_wan_interface()] = "WAN";
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+ $iftable[$config['interfaces']['opt' . $i]['if']] = $config['interfaces']['opt' . $i]['descr'];
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ $filterlog = array();
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ $ipfa = explode(" ", $logent[5]);
+
+ $flent = array();
+ $i = 0;
+ $flent['time'] = $ipfa[$i];
+ $i++;
+ if (substr($ipfa[$i], -1) == "x") {
+ $flent['count'] = substr($ipfa[$i], 0, -1);
+ $i++;
+ }
+ if ($iftable[$ipfa[$i]])
+ $flent['interface'] = $iftable[$ipfa[$i]];
+ else
+ $flent['interface'] = $ipfa[$i];
+ $i += 2;
+ $flent['act'] = $ipfa[$i];
+ $i++;
+ $flent['src'] = format_ipf_ip($ipfa[$i]);
+ $i += 2;
+ $flent['dst'] = format_ipf_ip($ipfa[$i]);
+ $i += 2;
+ $flent['proto'] = strtoupper($ipfa[$i]);
+
+ $filterlog[] = $flent;
+ }
+
+ return $filterlog;
+}
+
+function format_ipf_ip($ipfip) {
+ list($ip,$port) = explode(",", $ipfip);
+ if (!$port)
+ return $ip;
+
+ return $ip . ", port " . $port;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: System logs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabact">Firewall</li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<?php if (!isset($config['syslog']['rawfilter'])):
+ $filterlog = conv_clog("/var/log/filter.log", $nentries);
+?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
+ <td colspan="6" class="listtopic">
+ Last <?=$nentries;?> firewall log entries</td>
+ </tr>
+ <tr>
+ <td width="10%" class="listhdrr">Act</td>
+ <td width="20%" class="listhdrr">Time</td>
+ <td width="10%" class="listhdrr">If</td>
+ <td width="20%" class="listhdrr">Source</td>
+ <td width="20%" class="listhdrr">Destination</td>
+ <td width="10%" class="listhdrr">Proto</td>
+ </tr><?php foreach ($filterlog as $filterent): ?>
+ <tr>
+ <td class="listlr" nowrap>
+ <?php if (strstr(strtolower($filterent['act']), "p"))
+ $img = "pass.gif";
+ else
+ $img = "block.gif";
+ ?>
+ <img src="<?=$img;?>" width="11" height="11" align="absmiddle">
+ <?php if ($filterent['count']) echo $filterent['count'];?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['time']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['interface']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['src']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['dst']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['proto']);?></td>
+ </tr><?php endforeach; ?>
+ </table>
+<?php else: ?>
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="listtopic">
+ Last <?=$nentries;?> firewall log entries</td>
+ </tr>
+ <?php dump_clog("/var/log/filter.log", $nentries, false); ?>
+ </table>
+<?php endif; ?>
+ <br><form action="diag_logs_filter.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_logs_settings.php b/usr/local/www/diag_logs_settings.php
new file mode 100755
index 0000000..7868c56
--- /dev/null
+++ b/usr/local/www/diag_logs_settings.php
@@ -0,0 +1,202 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs_settings.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['reverse'] = isset($config['syslog']['reverse']);
+$pconfig['nentries'] = $config['syslog']['nentries'];
+$pconfig['remoteserver'] = $config['syslog']['remoteserver'];
+$pconfig['filter'] = isset($config['syslog']['filter']);
+$pconfig['dhcp'] = isset($config['syslog']['dhcp']);
+$pconfig['vpn'] = isset($config['syslog']['vpn']);
+$pconfig['system'] = isset($config['syslog']['system']);
+$pconfig['enable'] = isset($config['syslog']['enable']);
+$pconfig['logdefaultblock'] = !isset($config['syslog']['nologdefaultblock']);
+$pconfig['rawfilter'] = isset($config['syslog']['rawfilter']);
+
+if (!$pconfig['nentries'])
+ $pconfig['nentries'] = 50;
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable'] && !is_ipaddr($_POST['remoteserver'])) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['nentries'] < 5) || ($_POST['nentries'] > 1000)) {
+ $input_errors[] = "Number of log entries to show must be between 5 and 1000.";
+ }
+
+ if (!$input_errors) {
+ $config['syslog']['reverse'] = $_POST['reverse'] ? true : false;
+ $config['syslog']['nentries'] = (int)$_POST['nentries'];
+ $config['syslog']['remoteserver'] = $_POST['remoteserver'];
+ $config['syslog']['filter'] = $_POST['filter'] ? true : false;
+ $config['syslog']['dhcp'] = $_POST['dhcp'] ? true : false;
+ $config['syslog']['vpn'] = $_POST['vpn'] ? true : false;
+ $config['syslog']['system'] = $_POST['system'] ? true : false;
+ $config['syslog']['enable'] = $_POST['enable'] ? true : false;
+ $oldnologdefaultblock = isset($config['syslog']['nologdefaultblock']);
+ $config['syslog']['nologdefaultblock'] = $_POST['logdefaultblock'] ? false : true;
+ $config['syslog']['rawfilter'] = $_POST['rawfilter'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = system_syslogd_start();
+ if ($oldnologdefaultblock !== isset($config['syslog']['nologdefaultblock']))
+ $retval |= filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: System logs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+ if (document.iform.enable.checked || enable_over) {
+ document.iform.remoteserver.disabled = 0;
+ document.iform.filter.disabled = 0;
+ document.iform.dhcp.disabled = 0;
+ document.iform.vpn.disabled = 0;
+ document.iform.system.disabled = 0;
+ } else {
+ document.iform.remoteserver.disabled = 1;
+ document.iform.filter.disabled = 1;
+ document.iform.dhcp.disabled = 1;
+ document.iform.vpn.disabled = 1;
+ document.iform.system.disabled = 1;
+ }
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<form action="diag_logs_settings.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabact">Settings</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable"> <input name="reverse" type="checkbox" id="reverse" value="yes" <?php if ($pconfig['reverse']) echo "checked"; ?>>
+ <strong>Show log entries in reverse order (newest entries
+ on top)</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">Number of log entries to
+ show:
+ <input name="nentries" id="nentries" type="text" class="formfld" size="4" value="<?=htmlspecialchars($pconfig['nentries']);?>"></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vtable">&nbsp;</td>
+ <td class="vtable"> <input name="logdefaultblock" type="checkbox" id="logdefaultblock" value="yes" <?php if ($pconfig['logdefaultblock']) echo "checked"; ?>>
+ <strong>Log packets blocked by the default rule</strong><br>
+ Hint: packets that are blocked by the
+ implicit default block rule will not be logged anymore
+ if you uncheck this option. Per-rule logging options are not affected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vtable">&nbsp;</td>
+ <td class="vtable"> <input name="rawfilter" type="checkbox" id="rawfilter" value="yes" <?php if ($pconfig['rawfilter']) echo "checked"; ?>>
+ <strong>Show raw filter logs</strong><br>
+ Hint: If this is checked, filter logs are shown as generated by the packet filter, without any formatting. This will reveal more detailed information. </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable"> <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable syslog'ing to remote syslog server</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Remote syslog
+ server</td>
+ <td width="78%" class="vtable"> <input name="remoteserver" id="remoteserver" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['remoteserver']);?>">
+ <br>
+ IP address of remote syslog server<br> <br> <input name="system" id="system" type="checkbox" value="yes" onclick="enable_change(false)" <?php if ($pconfig['system']) echo "checked"; ?>>
+ system events <br> <input name="filter" id="filter" type="checkbox" value="yes" <?php if ($pconfig['filter']) echo "checked"; ?>>
+ firewall events<br> <input name="dhcp" id="dhcp" type="checkbox" value="yes" <?php if ($pconfig['dhcp']) echo "checked"; ?>>
+ DHCP service events<br> <input name="vpn" id="vpn" type="checkbox" value="yes" <?php if ($pconfig['vpn']) echo "checked"; ?>>
+ PPTP VPN events</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" height="53" valign="top">&nbsp;</td>
+ <td width="78%"><strong><span class="red">Note:</span></strong><br>
+ syslog sends UDP datagrams to port 514 on the specified
+ remote syslog server. Be sure to set syslogd on the
+ remote server to accept syslog messages from m0n0wall.
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_logs_vpn.php b/usr/local/www/diag_logs_vpn.php
new file mode 100755
index 0000000..3ed561c
--- /dev/null
+++ b/usr/local/www/diag_logs_vpn.php
@@ -0,0 +1,111 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs_vpn.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear']) {
+ exec("/usr/sbin/clog -i -s 65536 /var/log/vpn.log");
+}
+
+function dump_clog($logfile, $tail) {
+ global $g, $config;
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ $llent = explode(",", $logent[5]);
+
+ echo "<tr>\n";
+ echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+
+ if ($llent[0] == "login")
+ echo "<td class=\"listr\"><img src=\"in.gif\" width=\"11\" height=\"11\" title=\"login\"></td>\n";
+ else
+ echo "<td class=\"listr\"><img src=\"out.gif\" width=\"11\" height=\"11\" title=\"logout\"></td>\n";
+
+ echo "<td class=\"listr\">" . htmlspecialchars($llent[3]) . "</td>\n";
+ echo "<td class=\"listr\">" . htmlspecialchars($llent[2]) . "&nbsp;</td>\n";
+ echo "</tr>\n";
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: System logs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabact">PPTP VPN</li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
+ <td colspan="4" class="listtopic">
+ Last <?=$nentries;?> firewall log entries</td>
+ </tr>
+ <tr>
+ <td class="listhdrr">Time</td>
+ <td class="listhdrr">Action</td>
+ <td class="listhdrr">User</td>
+ <td class="listhdrr">IP address</td>
+ </tr>
+ <?php dump_clog("/var/log/vpn.log", $nentries); ?>
+ </table>
+ <br><form action="diag_logs_vpn.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_ping.php b/usr/local/www/diag_ping.php
new file mode 100755
index 0000000..33ad4ac
--- /dev/null
+++ b/usr/local/www/diag_ping.php
@@ -0,0 +1,113 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_ping.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Bob Zoller (bob@kludgebox.com) and 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.
+*/
+
+require("guiconfig.inc");
+
+define('MAX_COUNT', 10);
+define('DEFAULT_COUNT', 3);
+
+if ($_POST) {
+ unset($input_errors);
+ unset($do_ping);
+
+ /* input validation */
+ $reqdfields = explode(" ", "host count");
+ $reqdfieldsn = explode(",", "Host,Count");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['count'] < 1) || ($_POST['count'] > MAX_COUNT)) {
+ $input_errors[] = "Count must be between 1 and {MAX_COUNT}";
+ }
+
+ if (!$input_errors) {
+ $do_ping = true;
+ $host = preg_replace ("/[^A-Za-z0-9.]/","",$_POST['host']);
+ $count = $_POST['count'];
+
+ }
+}
+if (!isset($do_ping)) {
+ $do_ping = false;
+ $host = '';
+ $count = DEFAULT_COUNT;
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: Ping");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: Ping</font></p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="diag_ping.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Host</td>
+ <td width="78%" class="vtable">
+ <input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>"></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Count</td>
+ <td width="78%" class="vtable">
+<select name="count" class="formfld" id="count">
+ <?php for ($i = 1; $i <= MAX_COUNT; $i++): ?>
+ <option value="<?=$i;?>" <?php if ($i == $count) echo "selected"; ?>><?=$i;?></option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Ping">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" colspan="2">
+ <? if ($do_ping) {
+ echo("<strong>Ping output:</strong><br>");
+ echo('<pre>');
+ ob_end_flush();
+ system("/sbin/ping -c$count " . escapeshellarg($host));
+ echo('</pre>');
+ }
+ ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_resetstate.php b/usr/local/www/diag_resetstate.php
new file mode 100755
index 0000000..3a7f028
--- /dev/null
+++ b/usr/local/www/diag_resetstate.php
@@ -0,0 +1,97 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_resetstate.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+
+ $savemsg = "";
+ if ($_POST['nattable']) {
+ filter_flush_nat_table();
+ $savemsg = "The NAT table has been flushed successfully.";
+ }
+ if ($_POST['statetable']) {
+ filter_flush_state_table();
+ if ($savemsg)
+ $savemsg .= " ";
+ $savemsg .= "The state table has been flushed successfully.";
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Diagnostics: Reset state");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">Diagnostics: Reset state</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="diag_resetstate.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable"> <p>
+ <input name="nattable" type="checkbox" id="nattable" value="yes" checked>
+ <strong>NAT table</strong><br>
+ <input name="statetable" type="checkbox" id="statetable" value="yes" checked>
+ <strong>Firewall state table</strong><br>
+ <span class="vexpl"><br>
+ Resetting the state tables will remove all entries from
+ the corresponding tables. This means that all open connections
+ will be broken and will have to be re-established. This
+ may be necessary after making substantial changes to the
+ firewall and/or NAT rules, especially if there are IP protocol
+ mappings (e.g. for PPTP or IPv6) with open connections.<br>
+ <br>
+ </span><span class="vexpl">The firewall will normally leave
+ the state tables intact when changing rules.<br>
+ <br>
+ NOTE: If you reset the firewall state table, the browser
+ session may appear to be hung after clicking &quot;Reset&quot;.
+ Simply refresh the page to continue.</span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Reset">
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/edit.php b/usr/local/www/edit.php
new file mode 100755
index 0000000..694f40b
--- /dev/null
+++ b/usr/local/www/edit.php
@@ -0,0 +1,128 @@
+#!/usr/local/bin/php
+<?php
+if (($_POST['submit'] == "Load") && file_exists($_POST['savetopath'])) {
+ $fd = fopen($_POST['savetopath'], "r");
+ $content = fread($fd, filesize($_POST['savetopath']));
+ fclose($fd);
+ $edit_area="";
+ $ulmsg = "Loaded text from " . $_POST['savetopath'];
+} else if (($_POST['submit'] == "Save")) {
+ $content = ereg_replace("\r","",$_POST['content']) ;
+ $fd = fopen($_POST['savetopath'], "w");
+ fwrite($fd, $content);
+ fclose($fd);
+ $edit_area="";
+ $ulmsg = "Saved text to " . $_POST['savetopath'];
+} else if (($_POST['submit'] == "Load") && !file_exists($_POST['savetopath'])) {
+ $ulmsg = "File not found " . $_POST['savetopath'];
+ $content = "";
+ $_POST['savetopath'] = "";
+}
+
+if($_POST['rows'] <> "")
+ $rows = $_POST['rows'];
+else
+ $rows = 40;
+
+if($_POST['cols'] <> "")
+ $cols = $_POST['cols'];
+else
+ $cols = 80;
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<?php
+
+/*
+ Exec+ v1.02-000 - Copyright 2001-2003, All rights reserved
+ Created by technologEase (http://www.technologEase.com).
+ (modified for m0n0wall by Manuel Kasper <mk@neon1.net>)
+ (modified for pfSense Edit/Save file by Scott Ullrich, Copyright 2004)
+*/
+
+// Function: is Blank
+// Returns true or false depending on blankness of argument.
+
+function isBlank( $arg ) { return ereg( "^\s*$", $arg ); }
+
+// Function: Puts
+// Put string, Ruby-style.
+
+function puts( $arg ) { echo "$arg\n"; }
+
+// "Constants".
+
+$Version = '';
+$ScriptName = $HTTP_SERVER_VARS['SCRIPT_NAME'];
+$Title = 'pfSense: edit file';
+
+// Get year.
+
+$arrDT = localtime();
+$intYear = $arrDT[5] + 1900;
+
+?>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title><?=$Title ?></title>
+<link href="gui.css" rel="stylesheet" type="text/css">
+<style>
+<!--
+
+input {
+ font-family: courier new, courier;
+ font-weight: normal;
+ font-size: 9pt;
+}
+
+pre {
+ border: 2px solid #435370;
+ background: #F0F0F0;
+ padding: 1em;
+ font-family: courier new, courier;
+ white-space: pre;
+ line-height: 10pt;
+ font-size: 10pt;
+}
+
+.label {
+ font-family: tahoma, verdana, arial, helvetica;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+.button {
+ font-family: tahoma, verdana, arial, helvetica;
+ font-weight: bold;
+ font-size: 11px;
+}
+
+-->
+</style>
+</head>
+<body>
+<p><span class="pgtitle"><?=$Title ?></span>
+<?php if ($ulmsg) echo "<p><strong>" . $ulmsg . "</strong></p>\n"; ?>
+
+<form action="<?=$ScriptName ?>" method="POST">
+ <table>
+ <tr>
+ <td>
+ Save/Load from path: <input name="savetopath" value="<?php echo $_POST['savetopath']; ?>">
+ Rows: <input size="3" name="rows" value="<? echo $rows; ?>">
+ Cols: <input size="3" name="cols" value="<? echo $cols; ?>">
+ <input name="submit" type="submit" class="button" id="Load" value="Load">
+ <br><hr noshade width=100%>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="label">
+ <textarea rows="<?php echo $rows; ?>" cols="<?php echo $cols; ?>" name="content"><?php echo $content; ?></textarea><br>
+ <p>
+ <center><input name="submit" type="submit" class="button" id="Save" value="Save"></center></td>
+ </tr>
+ </table>
+</form>
+</body>
+</html>
+
diff --git a/usr/local/www/exec.php b/usr/local/www/exec.php
new file mode 100755
index 0000000..8f47fc5
--- /dev/null
+++ b/usr/local/www/exec.php
@@ -0,0 +1,240 @@
+#!/usr/local/bin/php
+<?php
+if (($_POST['submit'] == "Download") && file_exists($_POST['dlPath'])) {
+ session_cache_limiter('public');
+ $fd = fopen($_POST['dlPath'], "rb");
+ header("Content-Type: application/octet-stream");
+ header("Content-Length: " . filesize($_POST['dlPath']));
+ header("Content-Disposition: attachment; filename=\"" .
+ trim(htmlentities(basename($_POST['dlPath']))) . "\"");
+
+ fpassthru($fd);
+ exit;
+} else if (($_POST['submit'] == "Upload") && is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
+ move_uploaded_file($_FILES['ulfile']['tmp_name'], "/tmp/" . $_FILES['ulfile']['name']);
+ $ulmsg = "Uploaded file to /tmp/" . htmlentities($_FILES['ulfile']['name']);
+ unset($_POST['txtCommand']);
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<?php
+
+/*
+ Exec+ v1.02-000 - Copyright 2001-2003, All rights reserved
+ Created by technologEase (http://www.technologEase.com).
+
+ (modified for m0n0wall by Manuel Kasper <mk@neon1.net>)
+*/
+
+// Function: is Blank
+// Returns true or false depending on blankness of argument.
+
+function isBlank( $arg ) { return ereg( "^\s*$", $arg ); }
+
+
+// Function: Puts
+// Put string, Ruby-style.
+
+function puts( $arg ) { echo "$arg\n"; }
+
+
+// "Constants".
+
+$Version = '';
+$ScriptName = $HTTP_SERVER_VARS['SCRIPT_NAME'];
+$Title = 'm0n0wall: execute command';
+
+// Get year.
+
+$arrDT = localtime();
+$intYear = $arrDT[5] + 1900;
+
+?>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title><?=$Title ?></title>
+<script language="javascript">
+<!--
+
+ // Create recall buffer array (of encoded strings).
+
+<?php
+
+if (isBlank( $_POST['txtRecallBuffer'] )) {
+ puts( " var arrRecallBuffer = new Array;" );
+} else {
+ puts( " var arrRecallBuffer = new Array(" );
+ $arrBuffer = explode( "&", $_POST['txtRecallBuffer'] );
+ for ($i=0; $i < (count( $arrBuffer ) - 1); $i++) puts( " '" . $arrBuffer[$i] . "'," );
+ puts( " '" . $arrBuffer[count( $arrBuffer ) - 1] . "'" );
+ puts( " );" );
+}
+
+?>
+
+ // Set pointer to end of recall buffer.
+ var intRecallPtr = arrRecallBuffer.length-1;
+
+ // Functions to extend String class.
+ function str_encode() { return escape( this ) }
+ function str_decode() { return unescape( this ) }
+
+ // Extend string class to include encode() and decode() functions.
+ String.prototype.encode = str_encode
+ String.prototype.decode = str_decode
+
+ // Function: is Blank
+ // Returns boolean true or false if argument is blank.
+ function isBlank( strArg ) { return strArg.match( /^\s*$/ ) }
+
+ // Function: frmExecPlus onSubmit (event handler)
+ // Builds the recall buffer from the command string on submit.
+ function frmExecPlus_onSubmit( form ) {
+
+ if (!isBlank(form.txtCommand.value)) {
+ // If this command is repeat of last command, then do not store command.
+ if (form.txtCommand.value.encode() == arrRecallBuffer[arrRecallBuffer.length-1]) { return true }
+
+ // Stuff encoded command string into the recall buffer.
+ if (isBlank(form.txtRecallBuffer.value))
+ form.txtRecallBuffer.value = form.txtCommand.value.encode();
+ else
+ form.txtRecallBuffer.value += '&' + form.txtCommand.value.encode();
+ }
+
+ return true;
+ }
+
+ // Function: btnRecall onClick (event handler)
+ // Recalls command buffer going either up or down.
+ function btnRecall_onClick( form, n ) {
+
+ // If nothing in recall buffer, then error.
+ if (!arrRecallBuffer.length) {
+ alert( 'Nothing to recall!' );
+ form.txtCommand.focus();
+ return;
+ }
+
+ // Increment recall buffer pointer in positive or negative direction
+ // according to <n>.
+ intRecallPtr += n;
+
+ // Make sure the buffer stays circular.
+ if (intRecallPtr < 0) { intRecallPtr = arrRecallBuffer.length - 1 }
+ if (intRecallPtr > (arrRecallBuffer.length - 1)) { intRecallPtr = 0 }
+
+ // Recall the command.
+ form.txtCommand.value = arrRecallBuffer[intRecallPtr].decode();
+ }
+
+ // Function: Reset onClick (event handler)
+ // Resets form on reset button click event.
+ function Reset_onClick( form ) {
+
+ // Reset recall buffer pointer.
+ intRecallPtr = arrRecallBuffer.length;
+
+ // Clear form (could have spaces in it) and return focus ready for cmd.
+ form.txtCommand.value = '';
+ form.txtCommand.focus();
+
+ return true;
+ }
+//-->
+</script>
+<link href="gui.css" rel="stylesheet" type="text/css">
+<style>
+<!--
+
+input {
+ font-family: courier new, courier;
+ font-weight: normal;
+ font-size: 9pt;
+}
+
+pre {
+ border: 2px solid #435370;
+ background: #F0F0F0;
+ padding: 1em;
+ font-family: courier new, courier;
+ white-space: pre;
+ line-height: 10pt;
+ font-size: 10pt;
+}
+
+.label {
+ font-family: tahoma, verdana, arial, helvetica;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+.button {
+ font-family: tahoma, verdana, arial, helvetica;
+ font-weight: bold;
+ font-size: 11px;
+}
+
+-->
+</style>
+</head>
+<body>
+<p><span class="pgtitle"><?=$Title ?></span>
+<?php if (isBlank($_POST['txtCommand'])): ?>
+<p class="red"><strong>Note: this function is unsupported. Use it
+on your own risk!</strong></p>
+<?php endif; ?>
+<?php if ($ulmsg) echo "<p><strong>" . $ulmsg . "</strong></p>\n"; ?>
+<?php
+
+if (!isBlank($_POST['txtCommand'])) {
+ puts("<pre>");
+ puts("\$ " . htmlspecialchars($_POST['txtCommand']));
+ putenv("PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
+ putenv("SCRIPT_FILENAME=" . strtok($_POST['txtCommand'], " ")); /* PHP scripts */
+ $ph = popen($_POST['txtCommand'], "r" );
+ while ($line = fgets($ph)) echo htmlspecialchars($line);
+ pclose($ph);
+ puts("</pre>");
+}
+
+?>
+
+<form action="<?=$ScriptName ?>" method="POST" enctype="multipart/form-data" name="frmExecPlus" onSubmit="return frmExecPlus_onSubmit( this );">
+ <table>
+ <tr>
+ <td class="label" align="right">Command:</td>
+ <td class="type"><input name="txtCommand" type="text" size="80" value="<?=htmlspecialchars($_POST['txtCommand']);?>"></td>
+ </tr>
+ <tr>
+ <td valign="top">&nbsp;&nbsp;&nbsp;</td>
+ <td valign="top" class="label">
+ <input type="hidden" name="txtRecallBuffer" value="<?=$_POST['txtRecallBuffer'] ?>">
+ <input type="button" class="button" name="btnRecallPrev" value="<" onClick="btnRecall_onClick( this.form, -1 );">
+ <input type="submit" class="button" value="Execute">
+ <input type="button" class="button" name="btnRecallNext" value=">" onClick="btnRecall_onClick( this.form, 1 );">
+ <input type="button" class="button" value="Clear" onClick="return Reset_onClick( this.form );">
+ </td>
+ </tr>
+ <tr>
+ <td height="8"></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td align="right">Download:</td>
+ <td>
+ <input name="dlPath" type="text" id="dlPath" size="50">
+ <input name="submit" type="submit" class="button" id="download" value="Download">
+ </td>
+ </tr>
+ <tr>
+ <td align="right">Upload:</td>
+ <td valign="top" class="label">
+<input name="ulfile" type="file" class="button" id="ulfile">
+ <input name="submit" type="submit" class="button" id="upload" value="Upload"></td>
+ </tr>
+ </table>
+</form>
+</body>
+</html>
diff --git a/usr/local/www/exec_raw.php b/usr/local/www/exec_raw.php
new file mode 100755
index 0000000..6d1ca34
--- /dev/null
+++ b/usr/local/www/exec_raw.php
@@ -0,0 +1,38 @@
+#!/usr/local/bin/php
+<?php
+/*
+ exec_raw.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+header("Content-Type: text/plain");
+
+putenv("PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
+passthru($_GET['cmd']);
+
+exit(0);
+?> \ No newline at end of file
diff --git a/usr/local/www/fbegin.inc b/usr/local/www/fbegin.inc
new file mode 100755
index 0000000..1aae7f1
--- /dev/null
+++ b/usr/local/www/fbegin.inc
@@ -0,0 +1,131 @@
+<script language="javascript">
+<!--
+var tri_open = "";
+var tri_closed = "";
+
+window.onload = preload;
+
+function preload() {
+ if (document.images) {
+ tri_open = new Image(14,10);
+ tri_closed = new Image(14,10);
+ tri_open.src = "/tri_o.gif";
+ tri_closed.src = "/tri_c.gif";
+ }
+}
+
+function showhide(tspan, tri) {
+ tspanel = document.getElementById(tspan);
+ triel = document.getElementById(tri);
+ if (tspanel.style.display == 'none') {
+ tspanel.style.display = '';
+ triel.src = "/tri_o.gif";
+ } else {
+ tspanel.style.display = 'none';
+ triel.src = "/tri_c.gif";
+ }
+}
+-->
+</script>
+<table width="750" border="0" cellspacing="0" cellpadding="2">
+ <tr valign="bottom">
+ <td width="150" height="65" align="center" valign="middle"> <strong><a href="http://m0n0.ch/wall" target="_blank"><img src="/logo.gif" width="150" height="47" border="0"></a></strong></td>
+ <td height="65" bgcolor="#435370">
+ <table border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tr><td align="left" valign="bottom"><span class="tfrtitle">&nbsp;webGUI
+ Configuration</span></td>
+ <td align="right" valign="bottom">
+ <span class="hostname"><?=$config['system']['hostname'] . "." . $config['system']['domain'];?>&nbsp;</span>
+ </td></tr></table>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td width="150" bgcolor="#9D9D9D">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td><span class="navlnk"><font color="#FFFFFF"> <strong>System</strong>
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/system.php" class="navlnk">General
+ setup</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/system_routes.php" class="navlnk">Static
+ routes</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/system_firmware.php" class="navlnk">Firmware</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/system_advanced.php" class="navlnk">Advanced</a><br>
+ <strong>Interfaces</strong>
+ <?php if (!isset($config['system']['webgui']['noassigninterfaces'])): ?>
+ <a href="/interfaces_assign.php" class="navlnks">(assign)</a>
+ <?php endif; ?>
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_lan.php" class="navlnk">LAN</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_wan.php" class="navlnk">WAN</a><br>
+ <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): if (!isset($config['interfaces']['opt' . $i]['ovpn'])): ?>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_opt.php?index=<?=$i;?>" class="navlnk"><?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?></a><br>
+ <?php endif; endfor; ?>
+ <strong>Firewall</strong><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/firewall_rules.php" class="navlnk">Rules</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/firewall_nat.php" class="navlnk">NAT</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/firewall_aliases.php" class="navlnk">Aliases</a><br>
+ <strong>Services</strong><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_dnsmasq.php" class="navlnk">DNS forwarder</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_dyndns.php" class="navlnk">Dynamic
+ DNS</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_dhcp.php" class="navlnk">DHCP server</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_dhcp_relay.php" class="navlnk">DHCP relay</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_snmp.php" class="navlnk">SNMP</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_proxyarp.php" class="navlnk">Proxy ARP</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_captiveportal.php" class="navlnk">Captive portal</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_wol.php" class="navlnk">Wake on LAN</a><br>
+ <strong>VPN</strong><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_ipsec.php" class="navlnk">IPsec</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_pptp.php" class="navlnk">PPTP</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_openvpn.php" class="navlnk">OpenVPN</a><br>
+ <strong>Status</strong><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/index.php" class="navlnk">System</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_interfaces.php" class="navlnk">Interfaces</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_graph.php" class="navlnk">Traffic graph</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_wireless.php" class="navlnk">Wireless</a><br>
+ <?php if (isset($config['captiveportal']['enable'])): ?>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_captiveportal.php" class="navlnk">Captive portal</a><br>
+ <?php endif; ?>
+<?php
+/* extensions section */
+if (is_dir("{$g['www_path']}/ext")):
+?>
+ <strong>Extensions</strong><br>
+<?php
+$dh = @opendir("{$g['www_path']}/ext");
+if ($dh) {
+ while (($extd = readdir($dh)) !== false) {
+ if (($extd === ".") || ($extd === ".."))
+ continue;
+ @include("{$g['www_path']}/ext/" . $extd . "/menu.inc");
+ }
+ closedir($dh);
+}
+endif;
+?>
+ <?php if (isset($config['system']['webgui']['expanddiags']) || strstr($_SERVER['SCRIPT_FILENAME'], "diag_") || strstr($_SERVER['SCRIPT_FILENAME'], "reboot")): ?>
+ <a href="javascript:showhide('diag','tri_diag')"><img src="/tri_o.gif" id="tri_diag" width="14" height="10" border="0"></a><strong><a href="javascript:showhide('diag','tri_diag')" class="navlnk">Diagnostics</a></strong><br>
+ <span id="diag">
+ <?php else: ?>
+ <a href="javascript:showhide('diag','tri_diag')"><img src="/tri_c.gif" id="tri_diag" width="14" height="10" border="0"></a><strong><a href="javascript:showhide('diag','tri_diag')" class="navlnk">Diagnostics</a></strong><br>
+ <span id="diag" style="display: none">
+ <?php endif; ?>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_logs.php" class="navlnk">System
+ logs</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_dhcp_leases.php" class="navlnk">DHCP leases</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_ipsec_sad.php" class="navlnk">IPsec</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_ping.php" class="navlnk">Ping</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_resetstate.php" class="navlnk">Reset
+ state</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_backup.php" class="navlnk">Backup/Restore</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_defaults.php" class="navlnk">Factory
+ defaults </a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/reboot.php" class="navlnk">Reboot
+ system</a>
+ </span>
+ </font></span>
+ </td>
+ </tr></table></td>
+ <td width="600"><table width="100%" border="0" cellpadding="10" cellspacing="0">
+ <tr><td>
diff --git a/usr/local/www/fend.inc b/usr/local/www/fend.inc
new file mode 100755
index 0000000..871ec68
--- /dev/null
+++ b/usr/local/www/fend.inc
@@ -0,0 +1,8 @@
+</td></tr></table></td>
+ </tr>
+ <tr align="center" valign="top" bgcolor="#435370">
+ <td colspan="2" class="cpline">pfSense is &copy; 2004 by Scott Ullrich. All Rights Reserved.
+<br>pfSense is originally based on m0n0wall which is &copy; 2002-2004 by Manuel Kasper.
+ All rights reserved.&nbsp; [<a href="/license.php" class="tblnk">view license</a>]</td>
+ </tr>
+</table>
diff --git a/usr/local/www/firewall_aliases.php b/usr/local/www/firewall_aliases.php
new file mode 100755
index 0000000..cb94725
--- /dev/null
+++ b/usr/local/www/firewall_aliases.php
@@ -0,0 +1,127 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_aliases.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['aliases']['alias']))
+ $config['aliases']['alias'] = array();
+
+aliases_sort();
+$a_aliases = &$config['aliases']['alias'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ /* reload all components that use aliases */
+ $retval = filter_configure();
+ $retval |= shaper_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_aliasesdirty_path))
+ unlink($d_aliasesdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_aliases[$_GET['id']]) {
+ unset($a_aliases[$_GET['id']]);
+ write_config();
+ touch($d_aliasesdirty_path);
+ header("Location: firewall_aliases.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Aliases");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Aliases</p>
+<form action="firewall_aliases.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_aliasesdirty_path)): ?><p>
+<?php print_info_box_np("The alias list has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="25%" class="listhdrr">Name</td>
+ <td width="30%" class="listhdrr">Address</td>
+ <td width="35%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_aliases as $alias): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($alias['name']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($alias['address']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($alias['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="firewall_aliases_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_aliases.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this alias? All elements that still use it will become invalid (e.g. filter rules)!')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3"></td>
+ <td class="list"> <a href="firewall_aliases_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </form>
+<p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>Aliases act as placeholders for real IP addresses
+ and can be used to minimize the number of changes that have to
+ be made if a host or network address changes. You can enter the
+ name of an alias instead of an IP address in all address fields
+ that have a blue background. The alias will be resolved to its
+ current address according to the list below. If an alias cannot
+ be resolved (e.g. because you deleted it), the corresponding element
+ (e.g. filter/NAT/shaper rule) will be considered invalid and skipped.</span></p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_aliases_edit.php b/usr/local/www/firewall_aliases_edit.php
new file mode 100755
index 0000000..8955197
--- /dev/null
+++ b/usr/local/www/firewall_aliases_edit.php
@@ -0,0 +1,195 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_aliases_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['aliases']['alias']))
+ $config['aliases']['alias'] = array();
+
+aliases_sort();
+$a_aliases = &$config['aliases']['alias'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_aliases[$id]) {
+ $pconfig['name'] = $a_aliases[$id]['name'];
+ list($pconfig['address'],$pconfig['address_subnet']) =
+ explode('/', $a_aliases[$id]['address']);
+ if ($pconfig['address_subnet'])
+ $pconfig['type'] = "network";
+ else
+ $pconfig['type'] = "host";
+ $pconfig['descr'] = $a_aliases[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $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 (($_POST['name'] && !is_validaliasname($_POST['name']))) {
+ $input_errors[] = "The alias name may only consist of the characters a-z, A-Z, 0-9.";
+ }
+ if (($_POST['address'] && !is_ipaddr($_POST['address']))) {
+ $input_errors[] = "A valid address must be specified.";
+ }
+ if (($_POST['address_subnet'] && !is_numeric($_POST['address_subnet']))) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+
+ /* check for name conflicts */
+ foreach ($a_aliases as $alias) {
+ if (isset($id) && ($a_aliases[$id]) && ($a_aliases[$id] === $alias))
+ continue;
+
+ if ($alias['name'] == $_POST['name']) {
+ $input_errors[] = "An alias with this name already exists.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $alias = array();
+ $alias['name'] = $_POST['name'];
+ if ($_POST['type'] == "network")
+ $alias['address'] = $_POST['address'] . "/" . $_POST['address_subnet'];
+ else
+ $alias['address'] = $_POST['address'];
+ $alias['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_aliases[$id])
+ $a_aliases[$id] = $alias;
+ else
+ $a_aliases[] = $alias;
+
+ touch($d_aliasesdirty_path);
+
+ write_config();
+
+ header("Location: firewall_aliases.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: Firewall: Aliases: Edit alias");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+ switch (document.iform.type.selectedIndex) {
+ case 0: /* host */
+ document.iform.address_subnet.disabled = 1;
+ document.iform.address_subnet.value = "";
+ break;
+ case 1: /* network */
+ document.iform.address_subnet.disabled = 0;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Aliases: Edit alias</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_aliases_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="top" class="vncellreq">Name</td>
+ <td class="vtable"> <input name="name" type="text" class="formfld" id="name" size="40" value="<?=htmlspecialchars($pconfig['name']);?>">
+ <br> <span class="vexpl">The name of the alias may only consist
+ of the characters a-z, A-Z and 0-9.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Type</td>
+ <td class="vtable">
+ <select name="type" class="formfld" id="type" onChange="typesel_change()">
+ <option value="host" <?php if ($pconfig['type'] == "host") echo "selected"; ?>>Host</option>
+ <option value="network" <?php if ($pconfig['type'] == "network") echo "selected"; ?>>Network</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Address</td>
+ <td width="78%" class="vtable"> <input name="address" type="text" class="formfld" id="address" size="20" value="<?=htmlspecialchars($pconfig['address']);?>">
+ /
+ <select name="address_subnet" class="formfld" id="address_subnet">
+ <?php for ($i = 32; $i >= 1; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['address_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select> <br> <span class="vexpl">The address that this alias
+ represents.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_aliases[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat.php b/usr/local/www/firewall_nat.php
new file mode 100755
index 0000000..1708ef8
--- /dev/null
+++ b/usr/local/www/firewall_nat.php
@@ -0,0 +1,171 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['rule'])) {
+ $config['nat']['rule'] = array();
+}
+nat_rules_sort();
+$a_nat = &$config['nat']['rule'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval |= filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_natconfdirty_path))
+ unlink($d_natconfdirty_path);
+ if (file_exists($d_filterconfdirty_path))
+ unlink($d_filterconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_nat[$_GET['id']]) {
+ unset($a_nat[$_GET['id']]);
+ write_config();
+ touch($d_natconfdirty_path);
+ header("Location: firewall_nat.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</font></p>
+<form action="firewall_nat.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Inbound</li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="5%" class="listhdrr">If</td>
+ <td width="5%" class="listhdrr">Proto</td>
+ <td width="20%" class="listhdrr">Ext. port range</td>
+ <td width="20%" class="listhdrr">NAT IP</td>
+ <td width="20%" class="listhdrr">Int. port range</td>
+ <td width="20%" class="listhdr">Description</td>
+ <td width="5%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_nat as $natent): ?>
+ <tr valign="top">
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?=strtoupper($natent['protocol']);?>
+ </td>
+ <td class="listr">
+ <?php
+ list($beginport, $endport) = split("-", $natent['external-port']);
+ if ((!$endport) || ($beginport == $endport)) {
+ echo $beginport;
+ if ($wkports[$beginport])
+ echo " (" . $wkports[$beginport] . ")";
+ } else
+ echo $beginport . " - " . $endport;
+ ?>
+ </td>
+ <td class="listr">
+ <?=$natent['target'];?>
+ <?php if ($natent['external-address'])
+ echo "<br>(ext.: " . $natent['external-address'] . ")";
+ ?>
+ </td>
+ <td class="listr">
+ <?php if ((!$endport) || ($beginport == $endport)) {
+ echo $natent['local-port'];
+ if ($wkports[$natent['local-port']])
+ echo " (" . $wkports[$natent['local-port']] . ")";
+ } else
+ echo $natent['local-port'] . " - " .
+ ($natent['local-port']+$endport-$beginport);
+ ?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($natent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" class="list" nowrap> <a href="firewall_nat_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_nat.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="6"></td>
+ <td class="list"> <a href="firewall_nat_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>It is not possible to access NATed services
+ using the WAN IP address from within LAN (or an optional
+ network).</span></p></td>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_1to1.php b/usr/local/www/firewall_nat_1to1.php
new file mode 100755
index 0000000..f4d2e20
--- /dev/null
+++ b/usr/local/www/firewall_nat_1to1.php
@@ -0,0 +1,145 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_1to1.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['onetoone'])) {
+ $config['nat']['onetoone'] = array();
+}
+$a_1to1 = &$config['nat']['onetoone'];
+nat_1to1_rules_sort();
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval |= filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_natconfdirty_path))
+ unlink($d_natconfdirty_path);
+ if (file_exists($d_filterconfdirty_path))
+ unlink($d_filterconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_1to1[$_GET['id']]) {
+ unset($a_1to1[$_GET['id']]);
+ write_config();
+ touch($d_natconfdirty_path);
+ header("Location: firewall_nat_1to1.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_1to1.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabact">1:1</li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">External IP</td>
+ <td width="20%" class="listhdrr">Internal IP</td>
+ <td width="40%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_1to1 as $natent): ?>
+ <tr>
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?php echo $natent['external'];
+ if ($natent['subnet']) echo "/" . $natent['subnet']; ?>
+ </td>
+ <td class="listr">
+ <?php echo $natent['internal'];
+ if ($natent['subnet']) echo "/" . $natent['subnet']; ?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($natent['descr']);?>&nbsp;
+ </td>
+ <td class="list" nowrap> <a href="firewall_nat_1to1_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_nat_1to1.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4"></td>
+ <td class="list"> <a href="firewall_nat_1to1_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>Depending on the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span></p>
+</td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_1to1_edit.php b/usr/local/www/firewall_nat_1to1_edit.php
new file mode 100755
index 0000000..7361c92
--- /dev/null
+++ b/usr/local/www/firewall_nat_1to1_edit.php
@@ -0,0 +1,216 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_1to1_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['onetoone'])) {
+ $config['nat']['onetoone'] = array();
+}
+nat_1to1_rules_sort();
+$a_1to1 = &$config['nat']['onetoone'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_1to1[$id]) {
+ $pconfig['external'] = $a_1to1[$id]['external'];
+ $pconfig['internal'] = $a_1to1[$id]['internal'];
+ $pconfig['interface'] = $a_1to1[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+ if (!$a_1to1[$id]['subnet'])
+ $pconfig['subnet'] = 32;
+ else
+ $pconfig['subnet'] = $a_1to1[$id]['subnet'];
+ $pconfig['descr'] = $a_1to1[$id]['descr'];
+} else {
+ $pconfig['subnet'] = 32;
+ $pconfig['interface'] = "wan";
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface external internal");
+ $reqdfieldsn = explode(",", "Interface,External subnet,Internal subnet");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['external'] && !is_ipaddr($_POST['external']))) {
+ $input_errors[] = "A valid external subnet must be specified.";
+ }
+ if (($_POST['internal'] && !is_ipaddr($_POST['internal']))) {
+ $input_errors[] = "A valid internal subnet must be specified.";
+ }
+
+ if (is_ipaddr($config['interfaces']['wan']['ipaddr'])) {
+ if (check_subnets_overlap($_POST['external'], $_POST['subnet'],
+ $config['interfaces']['wan']['ipaddr'], 32))
+ $input_errors[] = "The WAN IP address may not be used in a 1:1 rule.";
+ }
+
+ /* check for overlaps with other 1:1 */
+ foreach ($a_1to1 as $natent) {
+ if (isset($id) && ($a_1to1[$id]) && ($a_1to1[$id] === $natent))
+ continue;
+
+ if (check_subnets_overlap($_POST['external'], $_POST['subnet'], $natent['external'], $natent['subnet'])) {
+ $input_errors[] = "Another 1:1 rule overlaps with the specified external subnet.";
+ break;
+ } else if (check_subnets_overlap($_POST['internal'], $_POST['subnet'], $natent['internal'], $natent['subnet'])) {
+ $input_errors[] = "Another 1:1 rule overlaps with the specified internal subnet.";
+ break;
+ }
+ }
+
+ /* check for overlaps with server NAT */
+ if (is_array($config['nat']['servernat'])) {
+ foreach ($config['nat']['servernat'] as $natent) {
+ if (check_subnets_overlap($_POST['external'], $_POST['subnet'],
+ $natent['ipaddr'], 32)) {
+ $input_errors[] = "A server NAT entry overlaps with the specified external subnet.";
+ break;
+ }
+ }
+ }
+
+ /* check for overlaps with advanced outbound NAT */
+ if (is_array($config['nat']['advancedoutbound']['rule'])) {
+ foreach ($config['nat']['advancedoutbound']['rule'] as $natent) {
+ if ($natent['target'] &&
+ check_subnets_overlap($_POST['external'], $_POST['subnet'], $natent['target'], 32)) {
+ $input_errors[] = "An advanced outbound NAT entry overlaps with the specified external subnet.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ $natent = array();
+ $natent['external'] = $_POST['external'];
+ $natent['internal'] = $_POST['internal'];
+ $natent['subnet'] = $_POST['subnet'];
+ $natent['descr'] = $_POST['descr'];
+ $natent['interface'] = $_POST['interface'];
+
+ if (isset($id) && $a_1to1[$id])
+ $a_1to1[$id] = $natent;
+ else
+ $a_1to1[] = $natent;
+
+ touch($d_natconfdirty_path);
+
+ write_config();
+
+ header("Location: firewall_nat_1to1.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT: Edit 1:1");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit 1:1</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_nat_1to1_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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select><br>
+ <span class="vexpl">Choose which interface this rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">External subnet</td>
+ <td width="78%" class="vtable">
+ <input name="external" type="text" class="formfld" id="external" size="20" value="<?=htmlspecialchars($pconfig['external']);?>">
+ /
+ <select name="subnet" class="formfld" id="subnet">
+ <?php for ($i = 32; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br>
+ <span class="vexpl">Enter the external (WAN) subnet for the 1:1 mapping. You may map single IP addresses by specifying a /32 subnet.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Internal subnet</td>
+ <td width="78%" class="vtable">
+ <input name="internal" type="text" class="formfld" id="internal" size="20" value="<?=htmlspecialchars($pconfig['internal']);?>">
+ <br>
+ <span class="vexpl">Enter the internal (LAN) subnet for the 1:1 mapping. The subnet size specified for the external subnet also applies to the internal subnet (they have to be the same).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_1to1[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_edit.php b/usr/local/www/firewall_nat_edit.php
new file mode 100755
index 0000000..d80865f
--- /dev/null
+++ b/usr/local/www/firewall_nat_edit.php
@@ -0,0 +1,365 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['rule'])) {
+ $config['nat']['rule'] = array();
+}
+nat_rules_sort();
+$a_nat = &$config['nat']['rule'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_nat[$id]) {
+ $pconfig['extaddr'] = $a_nat[$id]['external-address'];
+ $pconfig['proto'] = $a_nat[$id]['protocol'];
+ list($pconfig['beginport'],$pconfig['endport']) = explode("-", $a_nat[$id]['external-port']);
+ $pconfig['localip'] = $a_nat[$id]['target'];
+ $pconfig['localbeginport'] = $a_nat[$id]['local-port'];
+ $pconfig['descr'] = $a_nat[$id]['descr'];
+ $pconfig['interface'] = $a_nat[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+} else {
+ $pconfig['interface'] = "wan";
+}
+
+if ($_POST) {
+
+ if ($_POST['beginport_cust'] && !$_POST['beginport'])
+ $_POST['beginport'] = $_POST['beginport_cust'];
+ if ($_POST['endport_cust'] && !$_POST['endport'])
+ $_POST['endport'] = $_POST['endport_cust'];
+ if ($_POST['localbeginport_cust'] && !$_POST['localbeginport'])
+ $_POST['localbeginport'] = $_POST['localbeginport_cust'];
+
+ if (!$_POST['endport'])
+ $_POST['endport'] = $_POST['beginport'];
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface proto beginport localip localbeginport");
+ $reqdfieldsn = explode(",", "Interface,Protocol,Start port,NAT IP,Local port");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['beginport'] && !is_port($_POST['beginport']))) {
+ $input_errors[] = "The start port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['endport'] && !is_port($_POST['endport']))) {
+ $input_errors[] = "The end port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['localbeginport'] && !is_port($_POST['localbeginport']))) {
+ $input_errors[] = "The local port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['localip'] && !is_ipaddroralias($_POST['localip']))) {
+ $input_errors[] = "A valid NAT IP address or host alias must be specified.";
+ }
+
+ if ($_POST['beginport'] > $_POST['endport']) {
+ /* swap */
+ $tmp = $_POST['endport'];
+ $_POST['endport'] = $_POST['beginport'];
+ $_POST['beginport'] = $tmp;
+ }
+
+ if (!$input_errors) {
+ if (($_POST['endport'] - $_POST['beginport'] + $_POST['localbeginport']) > 65535)
+ $input_errors[] = "The target port range must lie between 1 and 65535.";
+ }
+
+ /* check for overlaps */
+ foreach ($a_nat as $natent) {
+ if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
+ continue;
+ if ($natent['interface'] != $_POST['interface'])
+ continue;
+ if ($natent['external-address'] != $_POST['extaddr'])
+ continue;
+
+ list($begp,$endp) = explode("-", $natent['external-port']);
+ if (!$endp)
+ $endp = $begp;
+
+ if (!( (($_POST['beginport'] < $begp) && ($_POST['endport'] < $begp))
+ || (($_POST['beginport'] > $endp) && ($_POST['endport'] > $endp)))) {
+
+ $input_errors[] = "The external port range overlaps with an existing entry.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $natent = array();
+ if ($_POST['extaddr'])
+ $natent['external-address'] = $_POST['extaddr'];
+ $natent['protocol'] = $_POST['proto'];
+
+ if ($_POST['beginport'] == $_POST['endport'])
+ $natent['external-port'] = $_POST['beginport'];
+ else
+ $natent['external-port'] = $_POST['beginport'] . "-" . $_POST['endport'];
+
+ $natent['target'] = $_POST['localip'];
+ $natent['local-port'] = $_POST['localbeginport'];
+ $natent['interface'] = $_POST['interface'];
+ $natent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_nat[$id])
+ $a_nat[$id] = $natent;
+ else
+ $a_nat[] = $natent;
+
+ touch($d_natconfdirty_path);
+
+ if ($_POST['autoadd']) {
+ /* auto-generate a matching firewall rule */
+ $filterent = array();
+ $filterent['interface'] = $_POST['interface'];
+ $filterent['protocol'] = $_POST['proto'];
+ $filterent['source']['any'] = "";
+ $filterent['destination']['address'] = $_POST['localip'];
+
+ $dstpfrom = $_POST['localbeginport'];
+ $dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
+
+ if ($dstpfrom == $dstpto)
+ $filterent['destination']['port'] = $dstpfrom;
+ else
+ $filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
+
+ $filterent['descr'] = "NAT " . $_POST['descr'];
+
+ $config['filter']['rule'][] = $filterent;
+
+ touch($d_filterconfdirty_path);
+ }
+
+ write_config();
+
+ header("Location: firewall_nat.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT: Edit");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function ext_change() {
+ if (document.iform.beginport.selectedIndex == 0) {
+ document.iform.beginport_cust.disabled = 0;
+ } else {
+ document.iform.beginport_cust.value = "";
+ document.iform.beginport_cust.disabled = 1;
+ }
+ if (document.iform.endport.selectedIndex == 0) {
+ document.iform.endport_cust.disabled = 0;
+ } else {
+ document.iform.endport_cust.value = "";
+ document.iform.endport_cust.disabled = 1;
+ }
+ if (document.iform.localbeginport.selectedIndex == 0) {
+ document.iform.localbeginport_cust.disabled = 0;
+ } else {
+ document.iform.localbeginport_cust.value = "";
+ document.iform.localbeginport_cust.disabled = 1;
+ }
+}
+function ext_rep_change() {
+ document.iform.endport.selectedIndex = document.iform.beginport.selectedIndex;
+ document.iform.localbeginport.selectedIndex = document.iform.beginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_nat_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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select><br>
+ <span class="vexpl">Choose which interface this rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">External address</td>
+ <td width="78%" class="vtable">
+ <select name="extaddr" class="formfld">
+ <option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option>
+ <?php
+ if (is_array($config['nat']['servernat'])):
+ foreach ($config['nat']['servernat'] as $sn): ?>
+ <option value="<?=$sn['ipaddr'];?>" <?php if ($sn['ipaddr'] == $pconfig['extaddr']) echo "selected"; ?>><?=htmlspecialchars("{$sn['ipaddr']} ({$sn['descr']})");?></option>
+ <?php endforeach; endif; ?>
+ </select><br>
+ <span class="vexpl">
+ If you want this rule to apply to another IP address than the IP address of the interface chosen above,
+ select it here (you need to define IP addresses on the
+ <a href="firewall_nat_server.php">Server NAT</a> page first).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Protocol</td>
+ <td width="78%" class="vtable">
+ <select name="proto" class="formfld">
+ <?php $protocols = explode(" ", "TCP UDP TCP/UDP"); foreach ($protocols as $proto): ?>
+ <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Choose which IP protocol
+ this rule should match.<br>
+ Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">External port
+ range </td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>from:&nbsp;&nbsp;</td>
+ <td><select name="beginport" class="formfld" onChange="ext_rep_change();ext_change()">
+ <option value="">(other)</option>
+ <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['beginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="beginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['beginport']; ?>"></td>
+ </tr>
+ <tr>
+ <td>to:</td>
+ <td><select name="endport" class="formfld" onChange="ext_change()">
+ <option value="">(other)</option>
+ <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['endport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="endport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['endport']; ?>"></td>
+ </tr>
+ </table>
+ <br> <span class="vexpl">Specify the port or port range on
+ the firewall's external address for this mapping.<br>
+ Hint: you can leave the <em>'to'</em> field empty if you only
+ want to map a single port</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">NAT IP</td>
+ <td width="78%" class="vtable">
+ <input name="localip" type="text" class="formfldalias" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>">
+ <br> <span class="vexpl">Enter the internal IP address of
+ the server on which you want to map the ports.<br>
+ e.g. <em>192.168.1.12</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Local port</td>
+ <td width="78%" class="vtable">
+ <select name="localbeginport" class="formfld" onChange="ext_change()">
+ <option value="">(other)</option>
+ <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['localbeginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="localbeginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['localbeginport']; ?>">
+ <br>
+ <span class="vexpl">Specify the port on the machine with the
+ IP address entered above. In case of a port range, specify
+ the beginning port of the range (the end port will be calculated
+ automatically).<br>
+ Hint: this is usually identical to the 'from' port above</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr><?php if (!(isset($id) && $a_nat[$id])): ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="autoadd" type="checkbox" id="autoadd" value="yes">
+ <strong>Auto-add a firewall rule to permit traffic through
+ this NAT rule</strong></td>
+ </tr><?php endif; ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_nat[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_out.php b/usr/local/www/firewall_nat_out.php
new file mode 100755
index 0000000..978f3b3
--- /dev/null
+++ b/usr/local/www/firewall_nat_out.php
@@ -0,0 +1,184 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_out.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['advancedoutbound']['rule']))
+ $config['nat']['advancedoutbound']['rule'] = array();
+
+$a_out = &$config['nat']['advancedoutbound']['rule'];
+nat_out_rules_sort();
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ $config['nat']['advancedoutbound']['enable'] = ($_POST['enable']) ? true : false;
+ write_config();
+
+ $retval = 0;
+
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval |= filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_natconfdirty_path))
+ unlink($d_natconfdirty_path);
+ if (file_exists($d_filterconfdirty_path))
+ unlink($d_filterconfdirty_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_out[$_GET['id']]) {
+ unset($a_out[$_GET['id']]);
+ write_config();
+ touch($d_natconfdirty_path);
+ header("Location: firewall_nat_out.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_out.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabact">Outbound</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td class="vtable"><p>
+ <input name="enable" type="checkbox" id="enable" value="yes" <?php if (isset($config['nat']['advancedoutbound']['enable'])) echo "checked";?>>
+ <strong>Enable advanced outbound NAT<br>
+ </strong></p></td>
+ </tr>
+ <tr>
+ <td> <input name="submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ <tr>
+ <td><p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>If advanced outbound NAT is enabled, no outbound NAT
+ rules will be automatically generated anymore. Instead, only the mappings
+ you specify below will be used. With advanced outbound NAT disabled,
+ a mapping is automatically created for each interface's subnet
+ (except WAN).</span> If you use target addresses other than the WAN interface's IP address, then depending on<span class="vexpl"> the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span><br>
+ <br>
+ You may enter your own mappings below.</p>
+ </td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">Source</td>
+ <td width="20%" class="listhdrr">Destination</td>
+ <td width="20%" class="listhdrr">Target</td>
+ <td width="25%" class="listhdr">Description</td>
+ <td width="5%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_out as $natent): ?>
+ <tr>
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?=$natent['source']['network'];?>
+ </td>
+ <td class="listr">
+ <?php
+ if (isset($natent['destination']['any']))
+ echo "*";
+ else {
+ if (isset($natent['destination']['not']))
+ echo "!&nbsp;";
+ echo $natent['destination']['network'];
+ }
+ ?>
+ </td>
+ <td class="listr">
+ <?php
+ if (!$natent['target'])
+ echo "*";
+ else
+ echo $natent['target'];
+ ?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($natent['descr']);?>&nbsp;
+ </td>
+ <td class="list" nowrap> <a href="firewall_nat_out_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_nat_out.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="5"></td>
+ <td class="list"> <a href="firewall_nat_out_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+</td>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_out_edit.php b/usr/local/www/firewall_nat_out_edit.php
new file mode 100755
index 0000000..723de78
--- /dev/null
+++ b/usr/local/www/firewall_nat_out_edit.php
@@ -0,0 +1,311 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_out_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['advancedoutbound']['rule']))
+ $config['nat']['advancedoutbound']['rule'] = array();
+
+$a_out = &$config['nat']['advancedoutbound']['rule'];
+nat_out_rules_sort();
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+function network_to_pconfig($adr, &$padr, &$pmask, &$pnot) {
+
+ if (isset($adr['any']))
+ $padr = "any";
+ else if ($adr['network']) {
+ list($padr, $pmask) = explode("/", $adr['network']);
+ if (!$pmask)
+ $pmask = 32;
+ }
+
+ if (isset($adr['not']))
+ $pnot = 1;
+ else
+ $pnot = 0;
+}
+
+if (isset($id) && $a_out[$id]) {
+ list($pconfig['source'],$pconfig['source_subnet']) = explode('/', $a_out[$id]['source']['network']);
+ network_to_pconfig($a_out[$id]['destination'], $pconfig['destination'],
+ $pconfig['destination_subnet'], $pconfig['destination_not']);
+ $pconfig['target'] = $a_out[$id]['target'];
+ $pconfig['interface'] = $a_out[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+ $pconfig['descr'] = $a_out[$id]['descr'];
+} else {
+ $pconfig['source_subnet'] = 24;
+ $pconfig['destination'] = "any";
+ $pconfig['destination_subnet'] = 24;
+ $pconfig['interface'] = "wan";
+}
+
+if ($_POST) {
+
+ if ($_POST['destination_type'] == "any") {
+ $_POST['destination'] = "any";
+ $_POST['destination_subnet'] = 24;
+ }
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface source source_subnet destination destination_subnet");
+ $reqdfieldsn = explode(",", "Interface,Source,Source bit count,Destination,Destination bit count");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['source'] && !is_ipaddr($_POST['source'])) {
+ $input_errors[] = "A valid source must be specified.";
+ }
+ if ($_POST['source_subnet'] && !is_numericint($_POST['source_subnet'])) {
+ $input_errors[] = "A valid source bit count must be specified.";
+ }
+ if ($_POST['destination_type'] != "any") {
+ if ($_POST['destination'] && !is_ipaddr($_POST['destination'])) {
+ $input_errors[] = "A valid destination must be specified.";
+ }
+ if ($_POST['destination_subnet'] && !is_numericint($_POST['destination_subnet'])) {
+ $input_errors[] = "A valid destination bit count must be specified.";
+ }
+ }
+ if ($_POST['target'] && !is_ipaddr($_POST['target'])) {
+ $input_errors[] = "A valid target IP address must be specified.";
+ }
+
+ /* check for existing entries */
+ $osn = gen_subnet($_POST['source'], $_POST['source_subnet']) . "/" . $_POST['source_subnet'];
+ if ($_POST['destination_type'] == "any")
+ $ext = "any";
+ else
+ $ext = gen_subnet($_POST['destination'], $_POST['destination_subnet']) . "/"
+ . $_POST['destination_subnet'];
+
+ if ($_POST['target']) {
+ /* check for clashes with 1:1 NAT (Server NAT is OK) */
+ if (is_array($config['nat']['onetoone'])) {
+ foreach ($config['nat']['onetoone'] as $natent) {
+ if (check_subnets_overlap($_POST['target'], 32, $natent['external'], $natent['subnet'])) {
+ $input_errors[] = "A 1:1 NAT mapping overlaps with the specified target IP address.";
+ break;
+ }
+ }
+ }
+ }
+
+ foreach ($a_out as $natent) {
+ if (isset($id) && ($a_out[$id]) && ($a_out[$id] === $natent))
+ continue;
+
+ if (!$natent['interface'])
+ $natent['interface'] == "wan";
+
+ if (($natent['interface'] == $_POST['interface']) && ($natent['source']['network'] == $osn)) {
+ if (isset($natent['destination']['not']) == isset($_POST['destination_not'])) {
+ if ((isset($natent['destination']['any']) && ($ext == "any")) ||
+ ($natent['destination']['network'] == $ext)) {
+ $input_errors[] = "There is already an outbound NAT rule with the specified settings.";
+ break;
+ }
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ $natent = array();
+ $natent['source']['network'] = $osn;
+ $natent['descr'] = $_POST['descr'];
+ $natent['target'] = $_POST['target'];
+ $natent['interface'] = $_POST['interface'];
+
+ if ($ext == "any")
+ $natent['destination']['any'] = true;
+ else
+ $natent['destination']['network'] = $ext;
+
+ if (isset($_POST['destination_not']) && $ext != "any")
+ $natent['destination']['not'] = true;
+
+ if (isset($id) && $a_out[$id])
+ $a_out[$id] = $natent;
+ else
+ $a_out[] = $natent;
+
+ touch($d_natconfdirty_path);
+
+ write_config();
+
+ header("Location: firewall_nat_out.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT: Edit outbound mapping");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+ switch (document.iform.destination_type.selectedIndex) {
+ case 1: // network
+ document.iform.destination.disabled = 0;
+ document.iform.destination_subnet.disabled = 0;
+ break;
+ default:
+ document.iform.destination.value = "";
+ document.iform.destination.disabled = 1;
+ document.iform.destination_subnet.value = "24";
+ document.iform.destination_subnet.disabled = 1;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit outbound mapping</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_nat_out_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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select><br>
+ <span class="vexpl">Choose which interface this rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Source</td>
+ <td width="78%" class="vtable">
+<input name="source" type="text" class="formfld" id="source" size="20" value="<?=htmlspecialchars($pconfig['source']);?>">
+
+ /
+ <select name="source_subnet" class="formfld" id="source_subnet">
+ <?php for ($i = 32; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['source_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br>
+ <span class="vexpl">Enter the source network for the outbound NAT mapping.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination</td>
+ <td width="78%" class="vtable">
+<input name="destination_not" type="checkbox" id="destination_not" value="yes" <?php if ($pconfig['destination_not']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br>
+ <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="destination_type" class="formfld" onChange="typesel_change()">
+ <option value="any" <?php if ($pconfig['destination'] == "any") echo "selected"; ?>>
+ any</option>
+ <option value="network" <?php if ($pconfig['destination'] != "any") echo "selected"; ?>>
+ Network</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="destination" type="text" class="formfld" id="destination" size="20" value="<?=htmlspecialchars($pconfig['destination']);?>">
+ /
+ <select name="destination_subnet" class="formfld" id="destination_subnet">
+ <?php for ($i = 32; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['destination_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select> </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td><span class="vexpl">Enter the destination network for
+ the outbound NAT mapping.</span></td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Target</td>
+ <td class="vtable">
+<input name="target" type="text" class="formfld" id="target" size="20" value="<?=htmlspecialchars($pconfig['target']);?>">
+ <br>
+ <span class="vexpl">Packets matching this rule will be mapped to the IP address given here. Leave blank to use the selected interface's IP address.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_out[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_server.php b/usr/local/www/firewall_nat_server.php
new file mode 100755
index 0000000..11f44b6
--- /dev/null
+++ b/usr/local/www/firewall_nat_server.php
@@ -0,0 +1,143 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_server.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['servernat'])) {
+ $config['nat']['servernat'] = array();
+}
+$a_snat = &$config['nat']['servernat'];
+nat_server_rules_sort();
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval |= filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_natconfdirty_path))
+ unlink($d_natconfdirty_path);
+ if (file_exists($d_filterconfdirty_path))
+ unlink($d_filterconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_snat[$_GET['id']]) {
+ /* make sure no inbound NAT mappings reference this entry */
+ if (is_array($config['nat']['rule'])) {
+ foreach ($config['nat']['rule'] as $rule) {
+ if ($rule['external-address'] == $a_snat[$_GET['id']]['ipaddr']) {
+ $input_errors[] = "This entry cannot be deleted because it is still referenced by at least one inbound NAT mapping.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ unset($a_snat[$_GET['id']]);
+ write_config();
+ touch($d_natconfdirty_path);
+ header("Location: firewall_nat_server.php");
+ exit;
+ }
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_server.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabact">Server NAT</li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="80%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="40%" class="listhdrr">External IP address</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_snat as $natent): ?>
+ <tr>
+ <td class="listlr">
+ <?=$natent['ipaddr'];?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($natent['descr']);?>&nbsp;
+ </td>
+ <td class="list" nowrap> <a href="firewall_nat_server_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_nat_server.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list"> <a href="firewall_nat_server_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>The external IP addresses defined on this page may be used in <a href="firewall_nat.php">inbound NAT</a> mappings. Depending on the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span></p>
+</td>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_nat_server_edit.php b/usr/local/www/firewall_nat_server_edit.php
new file mode 100755
index 0000000..4ed1f2d
--- /dev/null
+++ b/usr/local/www/firewall_nat_server_edit.php
@@ -0,0 +1,153 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_nat_server_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['servernat'])) {
+ $config['nat']['servernat'] = array();
+}
+nat_server_rules_sort();
+$a_snat = &$config['nat']['servernat'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_snat[$id]) {
+ $pconfig['ipaddr'] = $a_snat[$id]['ipaddr'];
+ $pconfig['descr'] = $a_snat[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ipaddr");
+ $reqdfieldsn = explode(",", "External IP address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid external IP address must be specified.";
+ }
+
+ if ($_POST['ipaddr'] == $config['interfaces']['wan']['ipaddr'])
+ $input_errors[] = "The WAN IP address may not be used in a Server NAT entry.";
+
+ /* check for overlaps with other server NAT */
+ foreach ($a_snat as $natent) {
+ if (isset($id) && ($a_snat[$id]) && ($a_snat[$id] === $natent))
+ continue;
+
+ if ($_POST['ipaddr'] == $natent['ipaddr']) {
+ $input_errors[] = "There is already a server NAT entry for the specified external IP address.";
+ break;
+ }
+ }
+
+ /* check for overlaps with 1:1 NAT */
+ if (is_array($config['nat']['onetoone'])) {
+ foreach ($config['nat']['onetoone'] as $natent) {
+ if (check_subnets_overlap($_POST['ipaddr'], 32, $natent['external'], $natent['subnet'])) {
+ $input_errors[] = "A 1:1 NAT mapping overlaps with the specified external IP address.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ $natent = array();
+ $natent['ipaddr'] = $_POST['ipaddr'];
+ $natent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_snat[$id]) {
+ /* modify all inbound NAT rules with this address */
+ for ($i = 0; isset($config['nat']['rule'][$i]); $i++) {
+ if ($config['nat']['rule'][$i]['external-address'] == $a_snat[$id]['ipaddr'])
+ $config['nat']['rule'][$i]['external-address'] = $natent['ipaddr'];
+ }
+ $a_snat[$id] = $natent;
+ } else
+ $a_snat[] = $natent;
+
+ touch($d_natconfdirty_path);
+
+ write_config();
+
+ header("Location: firewall_nat_server.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: NAT: Edit Server NAT");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit Server NAT</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_nat_server_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">External IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_snat[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_rules.php b/usr/local/www/firewall_rules.php
new file mode 100755
index 0000000..cd3424c
--- /dev/null
+++ b/usr/local/www/firewall_rules.php
@@ -0,0 +1,268 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_rules.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['filter']['rule'])) {
+ $config['filter']['rule'] = array();
+}
+filter_rules_sort();
+$a_filter = &$config['filter']['rule'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = filter_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_natconfdirty_path))
+ unlink($d_natconfdirty_path);
+ if (file_exists($d_filterconfdirty_path))
+ unlink($d_filterconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_filter[$_GET['id']]) {
+ unset($a_filter[$_GET['id']]);
+ write_config();
+ touch($d_filterconfdirty_path);
+ header("Location: firewall_rules.php");
+ exit;
+ }
+} else if ($_GET['act'] == "down") {
+ if ($a_filter[$_GET['id']] && $a_filter[$_GET['id']+1]) {
+ $tmp = $a_filter[$_GET['id']+1];
+ $a_filter[$_GET['id']+1] = $a_filter[$_GET['id']];
+ $a_filter[$_GET['id']] = $tmp;
+ write_config();
+ touch($d_filterconfdirty_path);
+ header("Location: firewall_rules.php");
+ exit;
+ }
+} else if ($_GET['act'] == "up") {
+ if (($_GET['id'] > 0) && $a_filter[$_GET['id']]) {
+ $tmp = $a_filter[$_GET['id']-1];
+ $a_filter[$_GET['id']-1] = $a_filter[$_GET['id']];
+ $a_filter[$_GET['id']] = $tmp;
+ write_config();
+ touch($d_filterconfdirty_path);
+ header("Location: firewall_rules.php");
+ exit;
+ }
+} else if ($_GET['act'] == "toggle") {
+ if ($a_filter[$_GET['id']]) {
+ $a_filter[$_GET['id']]['disabled'] = !isset($a_filter[$_GET['id']]['disabled']);
+ write_config();
+ touch($d_filterconfdirty_path);
+ header("Location: firewall_rules.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Rules");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Rules</p>
+<form action="firewall_rules.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_filterconfdirty_path)): ?><p>
+<?php print_info_box_np("The firewall rule configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+
+ <tr><td colspan="9">
+ <ul id="tabnav">
+ <li class="tabact">Rules</li>
+ <li class="tabinact"><a href="firewall_shaper_queues.php">Queues</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+
+ <?php $lastif = ""; for ($i = 0; isset($a_filter[$i]); $i++):
+ $filterent = $a_filter[$i];
+ if ($filterent['interface'] != $lastif):
+ if ($i):
+ ?>
+
+ <tr>
+ <td colspan="8" class="list" height="12"></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <td colspan="7" class="listtopic"><?php
+ $iflabels = array('lan' => 'LAN interface', 'wan' => 'WAN interface', 'pptp' => 'PPTP clients');
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+ $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['name'] . " interface";
+ echo htmlspecialchars($iflabels[$filterent['interface']]); ?></td>
+ <td class="list"></td>
+ </tr>
+ <tr>
+ <td width="5%" class="list">&nbsp;</td>
+ <td width="10%" class="listhdrr">Proto</td>
+ <td width="15%" class="listhdrr">Source</td>
+ <td width="10%" class="listhdrr">Port</td>
+ <td width="15%" class="listhdrr">Destination</td>
+ <td width="10%" class="listhdrr">Port</td>
+ <td width="25%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $lastif = $filterent['interface']; endif; ?>
+ <tr valign="top">
+ <td class="listt">
+ <?php if ($filterent['type'] == "block")
+ $iconfn = "block";
+ else if ($filterent['type'] == "reject") {
+ if ($filterent['protocol'] == "tcp" || $filterent['protocol'] == "udp")
+ $iconfn = "reject";
+ else
+ $iconfn = "block";
+ } else
+ $iconfn = "pass";
+ if (isset($filterent['disabled'])) {
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ $iconfn .= "_d";
+ } else {
+ $textss = $textse = "";
+ }
+ ?>
+ <a href="?act=toggle&id=<?=$i;?>"><img src="<?=$iconfn;?>.gif" width="11" height="11" border="0" title="click to toggle enabled/disabled status"></a>
+ <?php if (isset($filterent['log'])):
+ $iconfn = "log_s";
+ if (isset($filterent['disabled']))
+ $iconfn .= "_d";
+ ?>
+ <br><img src="<?=$iconfn;?>.gif" width="11" height="15" border="0">
+ <?php endif; ?>
+ </td>
+ <td class="listlr">
+ <?=$textss;?><?php if (isset($filterent['protocol'])) echo strtoupper($filterent['protocol']); else echo "*"; ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_address($filterent['source'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_port($filterent['source']['port'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_address($filterent['destination'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_port($filterent['destination']['port'])); ?><?=$textse;?>
+ </td>
+ <td class="listbg">
+ <?=$textss;?><?=htmlspecialchars($filterent['name']);?>&nbsp;<?=$textse;?>
+ </td>
+ <td valign="middle" nowrap class="list">
+ <a href="firewall_rules_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit rule" width="17" height="17" border="0"></a>
+ <?php if (($i > 0) && ($a_filter[$i-1]['interface'] == $filterent['interface'])): ?>
+ <a href="firewall_rules.php?act=up&id=<?=$i;?>"><img src="up.gif" title="move up" width="17" height="17" border="0"></a>
+ <?php else: ?>
+ <img src="up_d.gif" width="17" height="17" border="0">
+ <?php endif; ?><br>
+ <a href="firewall_rules.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" title="delete rule" width="17" height="17" border="0"></a>
+ <?php if ($a_filter[$i+1]['interface'] == $filterent['interface']): ?>
+ <a href="firewall_rules.php?act=down&id=<?=$i;?>"><img src="down.gif" title="move down" width="17" height="17" border="0"></a>
+ <?php else: ?>
+ <img src="down_d.gif" width="17" height="17" border="0">
+ <?php endif; ?>
+ <a href="firewall_rules_edit.php?dup=<?=$i;?>"><img src="plus.gif" title="add a new rule based on this one" width="17" height="17" border="0"></a>
+ </td>
+ </tr>
+ <?php endfor; ?>
+ <tr>
+ <td class="list" colspan="7"></td>
+ <td class="list"> <a href="firewall_rules_edit.php"><img src="plus.gif" title="add new rule" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td width="16"><img src="pass.gif" width="11" height="11"></td>
+ <td>pass</td>
+ <td width="14"></td>
+ <td width="16"><img src="block.gif" width="11" height="11"></td>
+ <td>block</td>
+ <td width="14"></td>
+ <td width="16"><img src="reject.gif" width="11" height="11"></td>
+ <td>reject</td>
+ <td width="14"></td>
+ <td width="16"><img src="log.gif" width="11" height="11"></td>
+ <td>log</td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td><img src="pass_d.gif" width="11" height="11"></td>
+ <td>pass (disabled)</td>
+ <td></td>
+ <td><img src="block_d.gif" width="11" height="11"></td>
+ <td>block (disabled)</td>
+ <td></td>
+ <td><img src="reject_d.gif" width="11" height="11"></td>
+ <td>reject (disabled)</td>
+ <td></td>
+ <td width="16"><img src="log_d.gif" width="11" height="11"></td>
+ <td>log (disabled)</td>
+ </tr>
+ </table>
+ </tr></table>
+ <p>
+ <strong><span class="red">Hint:<br>
+ </span></strong>rules are evaluated on a first-match basis (i.e.
+ the action of the first rule to match a packet will be executed).
+ This means that if you use block rules, you'll have to pay attention
+ to the rule order. Everything that isn't explicitly passed is blocked
+ by default.</p>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_rules_edit.php b/usr/local/www/firewall_rules_edit.php
new file mode 100755
index 0000000..620ea6e
--- /dev/null
+++ b/usr/local/www/firewall_rules_edit.php
@@ -0,0 +1,773 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_rules_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$specialsrcdst = explode(" ", "any lan pptp");
+
+if (!is_array($config['filter']['rule'])) {
+ $config['filter']['rule'] = array();
+}
+filter_rules_sort();
+$a_filter = &$config['filter']['rule'];
+
+$id = $_GET['id'];
+if (is_numeric($_POST['id']))
+ $id = $_POST['id'];
+
+$after = $_GET['after'];
+
+if (isset($_POST['after']))
+ $after = $_POST['after'];
+
+if (isset($_GET['dup'])) {
+ $id = $_GET['dup'];
+ $after = $_GET['dup'];
+}
+
+function is_specialnet($net) {
+ global $specialsrcdst;
+
+ if (in_array($net, $specialsrcdst) || strstr($net, "opt"))
+ return true;
+ else
+ return false;
+}
+
+function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
+
+ if (isset($adr['any']))
+ $padr = "any";
+ else if ($adr['network'])
+ $padr = $adr['network'];
+ else if ($adr['address']) {
+ list($padr, $pmask) = explode("/", $adr['address']);
+ if (!$pmask)
+ $pmask = 32;
+ }
+
+ if (isset($adr['not']))
+ $pnot = 1;
+ else
+ $pnot = 0;
+
+ if ($adr['port']) {
+ list($pbeginport, $pendport) = explode("-", $adr['port']);
+ if (!$pendport)
+ $pendport = $pbeginport;
+ } else {
+ $pbeginport = "any";
+ $pendport = "any";
+ }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask, $pnot, $pbeginport, $pendport) {
+
+ $adr = array();
+
+ if ($padr == "any")
+ $adr['any'] = true;
+ else if (is_specialnet($padr))
+ $adr['network'] = $padr;
+ else {
+ $adr['address'] = $padr;
+ if ($pmask != 32)
+ $adr['address'] .= "/" . $pmask;
+ }
+
+ $adr['not'] = $pnot ? true : false;
+
+ if (($pbeginport != 0) && ($pbeginport != "any")) {
+ if ($pbeginport != $pendport)
+ $adr['port'] = $pbeginport . "-" . $pendport;
+ else
+ $adr['port'] = $pbeginport;
+ }
+}
+
+if (isset($id) && $a_filter[$id]) {
+ $pconfig['interface'] = $a_filter[$id]['interface'];
+
+ if (!isset($a_filter[$id]['type']))
+ $pconfig['type'] = "pass";
+ else
+ $pconfig['type'] = $a_filter[$id]['type'];
+
+ if (isset($a_filter[$id]['protocol']))
+ $pconfig['proto'] = $a_filter[$id]['protocol'];
+ else
+ $pconfig['proto'] = "any";
+
+ if ($a_filter[$id]['protocol'] == "icmp")
+ $pconfig['icmptype'] = $a_filter[$id]['icmptype'];
+
+ address_to_pconfig($a_filter[$id]['source'], $pconfig['src'],
+ $pconfig['srcmask'], $pconfig['srcnot'],
+ $pconfig['srcbeginport'], $pconfig['srcendport']);
+
+ address_to_pconfig($a_filter[$id]['destination'], $pconfig['dst'],
+ $pconfig['dstmask'], $pconfig['dstnot'],
+ $pconfig['dstbeginport'], $pconfig['dstendport']);
+
+ $pconfig['disabled'] = isset($a_filter[$id]['disabled']);
+ $pconfig['log'] = isset($a_filter[$id]['log']);
+ $pconfig['frags'] = isset($a_filter[$id]['frags']);
+ $pconfig['descr'] = $a_filter[$id]['descr'];
+
+} else {
+ /* defaults */
+ $pconfig['type'] = "pass";
+ $pconfig['src'] = "any";
+ $pconfig['dst'] = "any";
+}
+
+if (isset($_GET['dup']))
+ unset($id);
+
+if ($_POST) {
+
+ if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "tcp/udp")) {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ } else {
+
+ if ($_POST['srcbeginport_cust'] && !$_POST['srcbeginport'])
+ $_POST['srcbeginport'] = $_POST['srcbeginport_cust'];
+ if ($_POST['srcendport_cust'] && !$_POST['srcendport'])
+ $_POST['srcendport'] = $_POST['srcendport_cust'];
+
+ if ($_POST['srcbeginport'] == "any") {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ } else {
+ if (!$_POST['srcendport'])
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+ }
+ if ($_POST['srcendport'] == "any")
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+
+ if ($_POST['dstbeginport_cust'] && !$_POST['dstbeginport'])
+ $_POST['dstbeginport'] = $_POST['dstbeginport_cust'];
+ if ($_POST['dstendport_cust'] && !$_POST['dstendport'])
+ $_POST['dstendport'] = $_POST['dstendport_cust'];
+
+ if ($_POST['dstbeginport'] == "any") {
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ } else {
+ if (!$_POST['dstendport'])
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ }
+ if ($_POST['dstendport'] == "any")
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ }
+
+ if (is_specialnet($_POST['srctype'])) {
+ $_POST['src'] = $_POST['srctype'];
+ $_POST['srcmask'] = 0;
+ } else if ($_POST['srctype'] == "single") {
+ $_POST['srcmask'] = 32;
+ }
+ if (is_specialnet($_POST['dsttype'])) {
+ $_POST['dst'] = $_POST['dsttype'];
+ $_POST['dstmask'] = 0;
+ } else if ($_POST['dsttype'] == "single") {
+ $_POST['dstmask'] = 32;
+ }
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "type interface proto src dst");
+ $reqdfieldsn = explode(",", "Type,Interface,Protocol,Source,Destination");
+
+ if (!(is_specialnet($_POST['srctype']) || ($_POST['srctype'] == "single"))) {
+ $reqdfields[] = "srcmask";
+ $reqdfieldsn[] = "Source bit count";
+ }
+ if (!(is_specialnet($_POST['dsttype']) || ($_POST['dsttype'] == "single"))) {
+ $reqdfields[] = "dstmask";
+ $reqdfieldsn[] = "Destination bit count";
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (!$_POST['srcbeginport']) {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ }
+ if (!$_POST['dstbeginport']) {
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ }
+
+ if (($_POST['srcbeginport'] && !is_port($_POST['srcbeginport']))) {
+ $input_errors[] = "The start source port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['srcendport'] && !is_port($_POST['srcendport']))) {
+ $input_errors[] = "The end source port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['dstbeginport'] && !is_port($_POST['dstbeginport']))) {
+ $input_errors[] = "The start destination port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['dstendport'] && !is_port($_POST['dstendport']))) {
+ $input_errors[] = "The end destination port must be an integer between 1 and 65535.";
+ }
+
+ if (!is_specialnet($_POST['srctype'])) {
+ if (($_POST['src'] && !is_ipaddroranyalias($_POST['src']))) {
+ $input_errors[] = "A valid source IP address or alias must be specified.";
+ }
+ if (($_POST['srcmask'] && !is_numericint($_POST['srcmask']))) {
+ $input_errors[] = "A valid source bit count must be specified.";
+ }
+ }
+ if (!is_specialnet($_POST['dsttype'])) {
+ if (($_POST['dst'] && !is_ipaddroranyalias($_POST['dst']))) {
+ $input_errors[] = "A valid destination IP address or alias must be specified.";
+ }
+ if (($_POST['dstmask'] && !is_numericint($_POST['dstmask']))) {
+ $input_errors[] = "A valid destination bit count must be specified.";
+ }
+ }
+
+ if ($_POST['srcbeginport'] > $_POST['srcendport']) {
+ /* swap */
+ $tmp = $_POST['srcendport'];
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+ $_POST['srcbeginport'] = $tmp;
+ }
+ if ($_POST['dstbeginport'] > $_POST['dstendport']) {
+ /* swap */
+ $tmp = $_POST['dstendport'];
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ $_POST['dstbeginport'] = $tmp;
+ }
+
+ if (!$input_errors) {
+ $filterent = array();
+ $filterent['type'] = $_POST['type'];
+ $filterent['interface'] = $_POST['interface'];
+
+ if ($_POST['proto'] != "any")
+ $filterent['protocol'] = $_POST['proto'];
+ else
+ unset($filterent['protocol']);
+
+ if ($_POST['proto'] == "icmp" && $_POST['icmptype'])
+ $filterent['icmptype'] = $_POST['icmptype'];
+ else
+ unset($filterent['icmptype']);
+
+ pconfig_to_address($filterent['source'], $_POST['src'],
+ $_POST['srcmask'], $_POST['srcnot'],
+ $_POST['srcbeginport'], $_POST['srcendport']);
+
+ pconfig_to_address($filterent['destination'], $_POST['dst'],
+ $_POST['dstmask'], $_POST['dstnot'],
+ $_POST['dstbeginport'], $_POST['dstendport']);
+
+ $filterent['disabled'] = $_POST['disabled'] ? true : false;
+ $filterent['log'] = $_POST['log'] ? true : false;
+ $filterent['frags'] = $_POST['frags'] ? true : false;
+ $filterent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_filter[$id])
+ $a_filter[$id] = $filterent;
+ else {
+ if (is_numeric($after))
+ array_splice($a_filter, $after+1, 0, array($filterent));
+ else
+ $a_filter[] = $filterent;
+ }
+
+ /* ALTQ */
+ $filterent['direction'] = $_POST['direction'];
+ $filterent['queue'] = $_POST['queue'];
+
+ write_config();
+ touch($d_filterconfdirty_path);
+
+ header("Location: firewall_rules.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Rules: Edit");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+var portsenabled = 1;
+
+function ext_change() {
+ if ((document.iform.srcbeginport.selectedIndex == 0) && portsenabled) {
+ document.iform.srcbeginport_cust.disabled = 0;
+ } else {
+ document.iform.srcbeginport_cust.value = "";
+ document.iform.srcbeginport_cust.disabled = 1;
+ }
+ if ((document.iform.srcendport.selectedIndex == 0) && portsenabled) {
+ document.iform.srcendport_cust.disabled = 0;
+ } else {
+ document.iform.srcendport_cust.value = "";
+ document.iform.srcendport_cust.disabled = 1;
+ }
+ if ((document.iform.dstbeginport.selectedIndex == 0) && portsenabled) {
+ document.iform.dstbeginport_cust.disabled = 0;
+ } else {
+ document.iform.dstbeginport_cust.value = "";
+ document.iform.dstbeginport_cust.disabled = 1;
+ }
+ if ((document.iform.dstendport.selectedIndex == 0) && portsenabled) {
+ document.iform.dstendport_cust.disabled = 0;
+ } else {
+ document.iform.dstendport_cust.value = "";
+ document.iform.dstendport_cust.disabled = 1;
+ }
+
+ if (!portsenabled) {
+ document.iform.srcbeginport.disabled = 1;
+ document.iform.srcendport.disabled = 1;
+ document.iform.dstbeginport.disabled = 1;
+ document.iform.dstendport.disabled = 1;
+ } else {
+ document.iform.srcbeginport.disabled = 0;
+ document.iform.srcendport.disabled = 0;
+ document.iform.dstbeginport.disabled = 0;
+ document.iform.dstendport.disabled = 0;
+ }
+}
+
+function typesel_change() {
+ switch (document.iform.srctype.selectedIndex) {
+ case 1: /* single */
+ document.iform.src.disabled = 0;
+ document.iform.srcmask.value = "";
+ document.iform.srcmask.disabled = 1;
+ break;
+ case 2: /* network */
+ document.iform.src.disabled = 0;
+ document.iform.srcmask.disabled = 0;
+ break;
+ default:
+ document.iform.src.value = "";
+ document.iform.src.disabled = 1;
+ document.iform.srcmask.value = "";
+ document.iform.srcmask.disabled = 1;
+ break;
+ }
+ switch (document.iform.dsttype.selectedIndex) {
+ case 1: /* single */
+ document.iform.dst.disabled = 0;
+ document.iform.dstmask.value = "";
+ document.iform.dstmask.disabled = 1;
+ break;
+ case 2: /* network */
+ document.iform.dst.disabled = 0;
+ document.iform.dstmask.disabled = 0;
+ break;
+ default:
+ document.iform.dst.value = "";
+ document.iform.dst.disabled = 1;
+ document.iform.dstmask.value = "";
+ document.iform.dstmask.disabled = 1;
+ break;
+ }
+}
+
+function proto_change() {
+ if (document.iform.proto.selectedIndex < 3) {
+ portsenabled = 1;
+ } else {
+ portsenabled = 0;
+ }
+
+ if (document.iform.proto.selectedIndex == 3) {
+ document.iform.icmptype.disabled = 0;
+ } else {
+ document.iform.icmptype.disabled = 1;
+ }
+
+ ext_change();
+}
+
+function src_rep_change() {
+ document.iform.srcendport.selectedIndex = document.iform.srcbeginport.selectedIndex;
+}
+function dst_rep_change() {
+ document.iform.dstendport.selectedIndex = document.iform.dstbeginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Rules: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_rules_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">Action</td>
+ <td width="78%" class="vtable">
+<select name="type" class="formfld">
+ <?php $types = explode(" ", "Pass Block Reject"); foreach ($types as $type): ?>
+ <option value="<?=strtolower($type);?>" <?php if (strtolower($type) == strtolower($pconfig['type'])) echo "selected"; ?>>
+ <?=htmlspecialchars($type);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose what to do with packets that match
+ the criteria specified below.<br>
+Hint: the difference between block and reject is that with reject, a packet (TCP RST or ICMP port unreachable for UDP) is returned to the sender, whereas with block the packet is dropped silently. In either case, the original packet is discarded. Reject only works when the protocol is set to either TCP or UDP (but not &quot;TCP/UDP&quot;) below.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
+ <strong>Disable this rule</strong><br>
+ <span class="vexpl">Set this option to disable this rule without
+ removing it from the list.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+ <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN', 'pptp' => 'PPTP');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose on which interface packets must
+ come in to match this rule.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Protocol</td>
+ <td width="78%" class="vtable">
+<select name="proto" class="formfld" onchange="proto_change()">
+ <?php $protocols = explode(" ", "TCP UDP TCP/UDP ICMP ESP AH GRE IPv6 IGMP any"); foreach ($protocols as $proto): ?>
+ <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>>
+ <?=htmlspecialchars($proto);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which IP protocol this rule should
+ match.<br>
+ Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">ICMP type</td>
+ <td class="vtable">
+ <select name="icmptype" class="formfld">
+ <?php
+
+ $icmptypes = array(
+ "" => "any",
+ "unreach" => "Destination unreachable",
+ "echo" => "Echo",
+ "echorep" => "Echo reply",
+ "squench" => "Source quench",
+ "redir" => "Redirect",
+ "timex" => "Time exceeded",
+ "paramprob" => "Parameter problem",
+ "timest" => "Timestamp",
+ "timestrep" => "Timestamp reply",
+ "inforeq" => "Information request",
+ "inforep" => "Information reply",
+ "maskreq" => "Address mask request",
+ "maskrep" => "Address mask reply"
+ );
+
+ foreach ($icmptypes as $icmptype => $descr): ?>
+ <option value="<?=$icmptype;?>" <?php if ($icmptype == $pconfig['icmptype']) echo "selected"; ?>>
+ <?=htmlspecialchars($descr);?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ <span class="vexpl">If you selected ICMP for the protocol above, you may specify an ICMP type here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Source</td>
+ <td width="78%" class="vtable">
+<input name="srcnot" type="checkbox" id="srcnot" value="yes" <?php if ($pconfig['srcnot']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br>
+ <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="srctype" class="formfld" onChange="typesel_change()">
+ <?php $sel = is_specialnet($pconfig['src']); ?>
+ <option value="any" <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>>
+ any</option>
+ <option value="single" <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+ Single host or alias</option>
+ <option value="network" <?php if (!$sel) echo "selected"; ?>>
+ Network</option>
+ <option value="lan" <?php if ($pconfig['src'] == "lan") { echo "selected"; } ?>>
+ LAN subnet</option>
+ <option value="pptp" <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>>
+ PPTP clients</option>
+ <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+ <option value="opt<?=$i;?>" <?php if ($pconfig['src'] == "opt" . $i) { echo "selected"; } ?>>
+ <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?> subnet</option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="src" type="text" class="formfldalias" id="src" size="20" value="<?php if (!is_specialnet($pconfig['src'])) echo htmlspecialchars($pconfig['src']);?>">
+ /
+ <select name="srcmask" class="formfld" id="srcmask">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['srcmask']) echo "selected"; ?>><?=$i;?></option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Source port range
+ </td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>from:&nbsp;&nbsp;</td>
+ <td><select name="srcbeginport" class="formfld" onchange="src_rep_change();ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['srcbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcbeginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="srcbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcbeginport']) echo $pconfig['srcbeginport']; ?>"></td>
+ </tr>
+ <tr>
+ <td>to:</td>
+ <td><select name="srcendport" class="formfld" onchange="ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['srcendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcendport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="srcendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcendport']) echo $pconfig['srcendport']; ?>"></td>
+ </tr>
+ </table>
+ <br> <span class="vexpl">Specify the port or port range for
+ the source of the packet for this rule.<br>
+ Hint: you can leave the <em>'to'</em> field empty if you only
+ want to filter a single port</span></td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination</td>
+ <td width="78%" class="vtable">
+ <input name="dstnot" type="checkbox" id="dstnot" value="yes" <?php if ($pconfig['dstnot']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br>
+ <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="dsttype" class="formfld" onChange="typesel_change()">
+ <?php $sel = is_specialnet($pconfig['dst']); ?>
+ <option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>>
+ any</option>
+ <option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+ Single host or alias</option>
+ <option value="network" <?php if (!$sel) echo "selected"; ?>>
+ Network</option>
+ <option value="lan" <?php if ($pconfig['dst'] == "lan") { echo "selected"; } ?>>
+ LAN subnet</option>
+ <option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>>
+ PPTP clients</option>
+ <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+ <option value="opt<?=$i;?>" <?php if ($pconfig['dst'] == "opt" . $i) { echo "selected"; } ?>>
+ <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?> subnet</option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="dst" type="text" class="formfldalias" id="dst" size="20" value="<?php if (!is_specialnet($pconfig['dst'])) echo htmlspecialchars($pconfig['dst']);?>">
+ /
+ <select name="dstmask" class="formfld" id="dstmask">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['dstmask']) echo "selected"; ?>><?=$i;?></option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination port
+ range </td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>from:&nbsp;&nbsp;</td>
+ <td><select name="dstbeginport" class="formfld" onchange="dst_rep_change();ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['dstbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstbeginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="dstbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstbeginport']) echo $pconfig['dstbeginport']; ?>"></td>
+ </tr>
+ <tr>
+ <td>to:</td>
+ <td><select name="dstendport" class="formfld" onchange="ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['dstendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstendport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="dstendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstendport']) echo $pconfig['dstendport']; ?>"></td>
+ </tr>
+ </table>
+ <br> <span class="vexpl">Specify the port or port range for
+ the destination of the packet for this rule.<br>
+ Hint: you can leave the <em>'to'</em> field empty if you only
+ want to filter a single port</span></td>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Fragments</td>
+ <td width="78%" class="vtable">
+ <input name="frags" type="checkbox" id="frags" value="yes" <?php if ($pconfig['frags']) echo "checked"; ?>>
+ <strong>Allow fragmented packets</strong><br>
+ <span class="vexpl">Hint: this option puts additional load
+ on the firewall and may make it vulnerable to DoS attacks.
+ In most cases, it is not needed. Try enabling it if you have
+ troubles connecting to certain sites.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Log</td>
+ <td width="78%" class="vtable">
+ <input name="log" type="checkbox" id="log" value="yes" <?php if ($pconfig['log']) echo "checked"; ?>>
+ <strong>Log packets that are handled by this rule</strong><br>
+ <span class="vexpl">Hint: the firewall has limited local log
+ space. Don't turn on logging for everything. If you want to
+ do a lot of logging, consider using a remote syslog server
+ (see the <a href="diag_logs_settings.php">Diagnostics: System
+ logs: Settings</a> page).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Traffic Queuing / Shaping</td>
+ <td width="78%" class="vtable">
+ Direction: <select name="direction">
+ <?php if($pconfig['direction'] <> "")
+ echo "<option value=\"" . htmlspecialchars($pconfig['direction']) . "\">" . htmlspecialchars($pconfig['direction']) . "</option>";
+ ?>
+ <option value="">DONT CARE</option>
+ <option value="in">IN</option>
+ <option value="out">OUT</option>
+ </select>
+ <br> <span class="vexpl">If you need fine grained control on direction, select an option here.
+ <p> Queue: <select name="queue">
+ <?php
+ if($pconfig['queue'] <> "") echo "<option value=\"" . $pconfig['queue'] . "\">" . $pconfig['queue'] . "</option>";
+ echo "<option value=\"\"></option>";
+ if (is_array($config['pfqueueing']['queue'])) {
+ foreach ($config['pfqueueing']['queue'] as $queue) {
+ if(is_subqueue($queue['name']) == 0) {
+ echo "<option value=\"" . $queue['name'] . "\">" . $queue['name'] . "</option>";
+ }
+ }
+ }
+ ?>
+ </select><br><span class="vexpl">To enable traffic shaping on this rule, select a queue above.</span>
+ <br><span class="vexpl"><input type="checkbox" name="autocreatequeue"> Automatically create a new queue for this rule.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_filter[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ <input name="after" type="hidden" value="<?=$after;?>">
+ </td>
+ </tr>
+
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+typesel_change();
+proto_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_shaper.php b/usr/local/www/firewall_shaper.php
new file mode 100755
index 0000000..242c3ed
--- /dev/null
+++ b/usr/local/www/firewall_shaper.php
@@ -0,0 +1,269 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_shaper.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pfqueueing']['rule'])) {
+ $config['pfqueueing']['rule'] = array();
+}
+if (!is_array($config['pfqueueing']['pipe'])) {
+ $config['pfqueueing']['pipe'] = array();
+}
+if (!is_array($config['pfqueueing']['queue'])) {
+ $config['pfqueueing']['queue'] = array();
+}
+$a_shaper = &$config['pfqueueing']['rule'];
+$a_pipe = &$config['pfqueueing']['pipe'];
+$a_queue = &$config['pfqueueing']['queue'];
+
+$pconfig['enable'] = isset($config['pfqueueing']['enable']);
+
+if ($_POST) {
+
+ if ($_POST['submit']) {
+ $pconfig = $_POST;
+ $config['pfqueueing']['enable'] = $_POST['enable'] ? true : false;
+ write_config();
+ }
+
+ if ($_POST['apply'] || $_POST['submit']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = shaper_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_shaperconfdirty_path))
+ unlink($d_shaperconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_shaper[$_GET['id']]) {
+ unset($a_shaper[$_GET['id']]);
+ write_config();
+ touch($d_shaperconfdirty_path);
+ header("Location: firewall_shaper.php");
+ exit;
+ }
+} else if ($_GET['act'] == "down") {
+ if ($a_shaper[$_GET['id']] && $a_shaper[$_GET['id']+1]) {
+ $tmp = $a_shaper[$_GET['id']+1];
+ $a_shaper[$_GET['id']+1] = $a_shaper[$_GET['id']];
+ $a_shaper[$_GET['id']] = $tmp;
+ write_config();
+ touch($d_shaperconfdirty_path);
+ header("Location: firewall_shaper.php");
+ exit;
+ }
+} else if ($_GET['act'] == "up") {
+ if (($_GET['id'] > 0) && $a_shaper[$_GET['id']]) {
+ $tmp = $a_shaper[$_GET['id']-1];
+ $a_shaper[$_GET['id']-1] = $a_shaper[$_GET['id']];
+ $a_shaper[$_GET['id']] = $tmp;
+ write_config();
+ touch($d_shaperconfdirty_path);
+ header("Location: firewall_shaper.php");
+ exit;
+ }
+} else if ($_GET['act'] == "toggle") {
+ if ($a_shaper[$_GET['id']]) {
+ $a_shaper[$_GET['id']]['disabled'] = !isset($a_shaper[$_GET['id']]['disabled']);
+ write_config();
+ touch($d_shaperconfdirty_path);
+ header("Location: firewall_shaper.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Traffic shaper");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Rules</li>
+ <li class="tabinact"><a href="firewall_shaper_pipes.php">Pipes</a></li>
+ <li class="tabinact"><a href="firewall_shaper_queues.php">Queues</a></li>
+ <li class="tabinact"><a href="firewall_shaper_magic.php">Magic shaper wizard</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td class="vtable"><p>
+ <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+ <strong>Enable traffic shaper<br>
+ </strong></p></td>
+ </tr>
+ <tr>
+ <td> <input name="submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="5%" class="listhdrrns">If</td>
+ <td width="5%" class="listhdrrns">Proto</td>
+ <td width="20%" class="listhdrr">Source</td>
+ <td width="20%" class="listhdrr">Destination</td>
+ <td width="15%" class="listhdrrns">Target</td>
+ <td width="25%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_shaper as $shaperent): ?>
+ <tr valign="top">
+ <td class="listlr">
+ <?php
+ $dis = "";
+ if (isset($shaperent['disabled'])) {
+ $dis = "_d";
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ } else {
+ $textss = $textse = "";
+ }
+ $iflabels = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+ $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+ echo $textss . htmlspecialchars($iflabels[$shaperent['interface']]);
+ echo "<br>";
+ echo "<a href=\"?act=toggle&id={$i}\">";
+ if ($shaperent['direction'] != "in")
+ echo "<img src=\"out{$dis}.gif\" width=\"11\" height=\"11\" border=\"0\" style=\"margin-top: 5px\" title=\"click to toggle enabled/disabled status\">";
+ if ($shaperent['direction'] != "out")
+ echo "<img src=\"in{$dis}.gif\" width=\"11\" height=\"11\" border=\"0\" style=\"margin-top: 5px\" title=\"click to toggle enabled/disabled status\">";
+ echo "</a>" . $textse;;
+ ?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php if (isset($shaperent['protocol'])) echo strtoupper($shaperent['protocol']); else echo "*"; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?><?php echo htmlspecialchars(pprint_address($shaperent['source'])); ?>
+ <?php if ($shaperent['source']['port']): ?><br>
+ Port: <?=htmlspecialchars(pprint_port($shaperent['source']['port'])); ?>
+ <?php endif; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?><?php echo htmlspecialchars(pprint_address($shaperent['destination'])); ?>
+ <?php if ($shaperent['destination']['port']): ?><br>
+ Port: <?=htmlspecialchars(pprint_port($shaperent['destination']['port'])); ?>
+ <?php endif; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?>
+ <?php
+ if (isset($shaperent['targetpipe'])) {
+ if ($a_pipe[$shaperent['targetpipe']]['descr'])
+ $desc = htmlspecialchars($a_pipe[$shaperent['targetpipe']]['descr']);
+ else
+ $desc = "Pipe " . ($shaperent['targetpipe']+1);
+ echo "<a href=\"firewall_shaper_pipes_edit.php?id={$shaperent['targetpipe']}\">{$desc}</a>";
+ } else if (isset($shaperent['targetqueue'])) {
+ if ($a_queue[$shaperent['targetqueue']]['descr'])
+ $desc = htmlspecialchars($a_queue[$shaperent['targetqueue']]['descr']);
+ else
+ $desc = "Queue " . ($shaperent['targetqueue']+1);
+ echo "<a href=\"firewall_shaper_queues_edit.php?id={$shaperent['targetqueue']}\">{$desc}</a>";
+ }
+ ?><?=$textse;?>
+ </td>
+ <td class="listbg">
+ <?=$textss;?><?=htmlspecialchars($shaperent['descr']);?><?=$textse;?>
+ &nbsp; </td>
+ <td valign="middle" nowrap class="list"> <a href="firewall_shaper_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit rule" width="17" height="17" border="0"></a>
+ <?php if ($i > 0): ?>
+ <a href="firewall_shaper.php?act=up&id=<?=$i;?>"><img src="up.gif" title="move up" width="17" height="17" border="0"></a>
+ <?php else: ?>
+ <img src="up_d.gif" width="17" height="17" border="0">
+ <?php endif; ?><br>
+ <a href="firewall_shaper.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" title="delete rule" width="17" height="17" border="0"></a>
+ <?php if (isset($a_shaper[$i+1])): ?>
+ <a href="firewall_shaper.php?act=down&id=<?=$i;?>"><img src="down.gif" title="move down" width="17" height="17" border="0"></a>
+ <?php else: ?>
+ <img src="down_d.gif" width="17" height="17" border="0">
+ <?php endif; ?>
+ <a href="firewall_shaper_edit.php?dup=<?=$i;?>"><img src="plus.gif" title="add a new rule based on this one" width="17" height="17" border="0"></a>
+ </td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="6"></td>
+ <td class="list"> <a href="firewall_shaper_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td width="16"><img src="in.gif" width="11" height="11"></td>
+ <td>incoming (as seen by firewall)</td>
+ <td width="14"></td>
+ <td width="16"><img src="out.gif" width="11" height="11"></td>
+ <td>outgoing (as seen by firewall)</td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td><img src="in_d.gif" width="11" height="11"></td>
+ <td>incoming (disabled)</td>
+ <td width="14"></td>
+ <td><img src="out_d.gif" width="11" height="11"></td>
+ <td>outgoing (disabled)</td>
+ </tr>
+ </table>
+ <p><span class="red"><strong>Note:</strong></span><strong><br>
+ </strong>the first rule that matches a packet will be executed.<br>
+ The following match patterns are not shown in the list above:
+ IP packet length, TCP flags.</td>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_shaper_edit.php b/usr/local/www/firewall_shaper_edit.php
new file mode 100755
index 0000000..5b0e249
--- /dev/null
+++ b/usr/local/www/firewall_shaper_edit.php
@@ -0,0 +1,776 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_shaper_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['shaper']['rule'])) {
+ $config['shaper']['rule'] = array();
+}
+$a_shaper = &$config['shaper']['rule'];
+
+$specialsrcdst = explode(" ", "any lan pptp");
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+$after = $_GET['after'];
+if (isset($_POST['after']))
+ $after = $_POST['after'];
+
+if (isset($_GET['dup'])) {
+ $id = $_GET['dup'];
+ $after = $_GET['dup'];
+}
+
+function is_specialnet($net) {
+ global $specialsrcdst;
+
+ if (in_array($net, $specialsrcdst) || strstr($net, "opt"))
+ return true;
+ else
+ return false;
+}
+
+function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
+
+ if (isset($adr['any']))
+ $padr = "any";
+ else if ($adr['network'])
+ $padr = $adr['network'];
+ else if ($adr['address']) {
+ list($padr, $pmask) = explode("/", $adr['address']);
+ if (!$pmask)
+ $pmask = 32;
+ }
+
+ if (isset($adr['not']))
+ $pnot = 1;
+ else
+ $pnot = 0;
+
+ if ($adr['port']) {
+ list($pbeginport, $pendport) = explode("-", $adr['port']);
+ if (!$pendport)
+ $pendport = $pbeginport;
+ } else {
+ $pbeginport = "any";
+ $pendport = "any";
+ }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask, $pnot, $pbeginport, $pendport) {
+
+ $adr = array();
+
+ if ($padr == "any")
+ $adr['any'] = true;
+ else if (is_specialnet($padr))
+ $adr['network'] = $padr;
+ else {
+ $adr['address'] = $padr;
+ if ($pmask != 32)
+ $adr['address'] .= "/" . $pmask;
+ }
+
+ $adr['not'] = $pnot ? true : false;
+
+ if (($pbeginport != 0) && ($pbeginport != "any")) {
+ if ($pbeginport != $pendport)
+ $adr['port'] = $pbeginport . "-" . $pendport;
+ else
+ $adr['port'] = $pbeginport;
+ }
+}
+
+if (isset($id) && $a_shaper[$id]) {
+ $pconfig['interface'] = $a_shaper[$id]['interface'];
+
+ if (isset($a_shaper[$id]['protocol']))
+ $pconfig['proto'] = $a_shaper[$id]['protocol'];
+ else
+ $pconfig['proto'] = "any";
+
+ address_to_pconfig($a_shaper[$id]['source'], $pconfig['src'],
+ $pconfig['srcmask'], $pconfig['srcnot'],
+ $pconfig['srcbeginport'], $pconfig['srcendport']);
+
+ address_to_pconfig($a_shaper[$id]['destination'], $pconfig['dst'],
+ $pconfig['dstmask'], $pconfig['dstnot'],
+ $pconfig['dstbeginport'], $pconfig['dstendport']);
+
+ if (isset($a_shaper[$id]['targetpipe'])) {
+ $pconfig['target'] = "targetpipe:" . $a_shaper[$id]['targetpipe'];
+ } else if (isset($a_shaper[$id]['targetqueue'])) {
+ $pconfig['target'] = "targetqueue:" . $a_shaper[$id]['targetqueue'];
+ }
+
+ $pconfig['direction'] = $a_shaper[$id]['direction'];
+ $pconfig['iptos'] = $a_shaper[$id]['iptos'];
+ $pconfig['iplen'] = $a_shaper[$id]['iplen'];
+ $pconfig['tcpflags'] = $a_shaper[$id]['tcpflags'];
+ $pconfig['descr'] = $a_shaper[$id]['descr'];
+ $pconfig['disabled'] = isset($a_shaper[$id]['disabled']);
+
+ if ($pconfig['srcbeginport'] == 0) {
+ $pconfig['srcbeginport'] = "any";
+ $pconfig['srcendport'] = "any";
+ }
+ if ($pconfig['dstbeginport'] == 0) {
+ $pconfig['dstbeginport'] = "any";
+ $pconfig['dstendport'] = "any";
+ }
+
+} else {
+ /* defaults */
+ $pconfig['src'] = "any";
+ $pconfig['dst'] = "any";
+}
+
+if (isset($_GET['dup']))
+ unset($id);
+
+if ($_POST) {
+
+ if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "any")) {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ } else {
+
+ if ($_POST['srcbeginport_cust'] && !$_POST['srcbeginport'])
+ $_POST['srcbeginport'] = $_POST['srcbeginport_cust'];
+ if ($_POST['srcendport_cust'] && !$_POST['srcendport'])
+ $_POST['srcendport'] = $_POST['srcendport_cust'];
+
+ if ($_POST['srcbeginport'] == "any") {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ } else {
+ if (!$_POST['srcendport'])
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+ }
+ if ($_POST['srcendport'] == "any")
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+
+ if ($_POST['dstbeginport_cust'] && !$_POST['dstbeginport'])
+ $_POST['dstbeginport'] = $_POST['dstbeginport_cust'];
+ if ($_POST['dstendport_cust'] && !$_POST['dstendport'])
+ $_POST['dstendport'] = $_POST['dstendport_cust'];
+
+ if ($_POST['dstbeginport'] == "any") {
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ } else {
+ if (!$_POST['dstendport'])
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ }
+ if ($_POST['dstendport'] == "any")
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ }
+
+ if (is_specialnet($_POST['srctype'])) {
+ $_POST['src'] = $_POST['srctype'];
+ $_POST['srcmask'] = 0;
+ } else if ($_POST['srctype'] == "single") {
+ $_POST['srcmask'] = 32;
+ }
+ if (is_specialnet($_POST['dsttype'])) {
+ $_POST['dst'] = $_POST['dsttype'];
+ $_POST['dstmask'] = 0;
+ } else if ($_POST['dsttype'] == "single") {
+ $_POST['dstmask'] = 32;
+ }
+
+ $intos = array();
+ foreach ($iptos as $tos) {
+ if ($_POST['iptos_' . $tos] == "on")
+ $intos[] = $tos;
+ else if ($_POST['iptos_' . $tos] == "off")
+ $intos[] = "!" . $tos;
+ }
+ $_POST['iptos'] = join(",", $intos);
+
+ $intcpflags = array();
+ foreach ($tcpflags as $tcpflag) {
+ if ($_POST['tcpflags_' . $tcpflag] == "on")
+ $intcpflags[] = $tcpflag;
+ else if ($_POST['tcpflags_' . $tcpflag] == "off")
+ $intcpflags[] = "!" . $tcpflag;
+ }
+ $_POST['tcpflags'] = join(",", $intcpflags);
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "target proto src dst");
+ $reqdfieldsn = explode(",", "Target,Protocol,Source,Destination");
+
+ if (!(is_specialnet($_POST['srctype']) || ($_POST['srctype'] == "single"))) {
+ $reqdfields[] = "srcmask";
+ $reqdfieldsn[] = "Source bit count";
+ }
+ if (!(is_specialnet($_POST['dsttype']) || ($_POST['dsttype'] == "single"))) {
+ $reqdfields[] = "dstmask";
+ $reqdfieldsn[] = "Destination bit count";
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (!$_POST['srcbeginport']) {
+ $_POST['srcbeginport'] = 0;
+ $_POST['srcendport'] = 0;
+ }
+ if (!$_POST['dstbeginport']) {
+ $_POST['dstbeginport'] = 0;
+ $_POST['dstendport'] = 0;
+ }
+
+ if (($_POST['srcbeginport'] && !is_port($_POST['srcbeginport']))) {
+ $input_errors[] = "The start source port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['srcendport'] && !is_port($_POST['srcendport']))) {
+ $input_errors[] = "The end source port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['dstbeginport'] && !is_port($_POST['dstbeginport']))) {
+ $input_errors[] = "The start destination port must be an integer between 1 and 65535.";
+ }
+ if (($_POST['dstendport'] && !is_port($_POST['dstendport']))) {
+ $input_errors[] = "The end destination port must be an integer between 1 and 65535.";
+ }
+
+ if (!is_specialnet($_POST['srctype'])) {
+ if (($_POST['src'] && !is_ipaddroranyalias($_POST['src']))) {
+ $input_errors[] = "A valid source IP address or alias must be specified.";
+ }
+ if (($_POST['srcmask'] && !is_numericint($_POST['srcmask']))) {
+ $input_errors[] = "A valid source bit count must be specified.";
+ }
+ }
+ if (!is_specialnet($_POST['dsttype'])) {
+ if (($_POST['dst'] && !is_ipaddroranyalias($_POST['dst']))) {
+ $input_errors[] = "A valid destination IP address or alias must be specified.";
+ }
+ if (($_POST['dstmask'] && !is_numericint($_POST['dstmask']))) {
+ $input_errors[] = "A valid destination bit count must be specified.";
+ }
+ }
+
+ if ($_POST['srcbeginport'] > $_POST['srcendport']) {
+ /* swap */
+ $tmp = $_POST['srcendport'];
+ $_POST['srcendport'] = $_POST['srcbeginport'];
+ $_POST['srcbeginport'] = $tmp;
+ }
+ if ($_POST['dstbeginport'] > $_POST['dstendport']) {
+ /* swap */
+ $tmp = $_POST['dstendport'];
+ $_POST['dstendport'] = $_POST['dstbeginport'];
+ $_POST['dstbeginport'] = $tmp;
+ }
+
+ if (($_POST['iplen'] && !preg_match("/^(\d+)(-(\d+))?$/", $_POST['iplen']))) {
+ $input_errors[] = "The IP packet length must be an integer or a range (from-to).";
+ }
+
+ if (!$input_errors) {
+ $shaperent = array();
+ $shaperent['interface'] = $_POST['interface'];
+
+ if ($_POST['proto'] != "any")
+ $shaperent['protocol'] = $_POST['proto'];
+ else
+ unset($shaperent['protocol']);
+
+ pconfig_to_address($shaperent['source'], $_POST['src'],
+ $_POST['srcmask'], $_POST['srcnot'],
+ $_POST['srcbeginport'], $_POST['srcendport']);
+
+ pconfig_to_address($shaperent['destination'], $_POST['dst'],
+ $_POST['dstmask'], $_POST['dstnot'],
+ $_POST['dstbeginport'], $_POST['dstendport']);
+
+ $shaperent['direction'] = $_POST['direction'];
+ $shaperent['iplen'] = $_POST['iplen'];
+ $shaperent['iptos'] = $_POST['iptos'];
+ $shaperent['tcpflags'] = $_POST['tcpflags'];
+ $shaperent['descr'] = $_POST['descr'];
+ $shaperent['disabled'] = $_POST['disabled'] ? true : false;
+
+ list($targettype,$target) = explode(":", $_POST['target']);
+ $shaperent[$targettype] = $target;
+
+ if (isset($id) && $a_shaper[$id])
+ $a_shaper[$id] = $shaperent;
+ else {
+ if (is_numeric($after))
+ array_splice($a_shaper, $after+1, 0, array($shaperent));
+ else
+ $a_shaper[] = $shaperent;
+ }
+
+ write_config();
+ touch($d_shaperconfdirty_path);
+
+ header("Location: firewall_shaper.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Traffic shaper: Edit rule");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+var portsenabled = 1;
+
+function ext_change() {
+ if ((document.iform.srcbeginport.selectedIndex == 0) && portsenabled) {
+ document.iform.srcbeginport_cust.disabled = 0;
+ } else {
+ document.iform.srcbeginport_cust.value = "";
+ document.iform.srcbeginport_cust.disabled = 1;
+ }
+ if ((document.iform.srcendport.selectedIndex == 0) && portsenabled) {
+ document.iform.srcendport_cust.disabled = 0;
+ } else {
+ document.iform.srcendport_cust.value = "";
+ document.iform.srcendport_cust.disabled = 1;
+ }
+ if ((document.iform.dstbeginport.selectedIndex == 0) && portsenabled) {
+ document.iform.dstbeginport_cust.disabled = 0;
+ } else {
+ document.iform.dstbeginport_cust.value = "";
+ document.iform.dstbeginport_cust.disabled = 1;
+ }
+ if ((document.iform.dstendport.selectedIndex == 0) && portsenabled) {
+ document.iform.dstendport_cust.disabled = 0;
+ } else {
+ document.iform.dstendport_cust.value = "";
+ document.iform.dstendport_cust.disabled = 1;
+ }
+
+ if (!portsenabled) {
+ document.iform.srcbeginport.disabled = 1;
+ document.iform.srcendport.disabled = 1;
+ document.iform.dstbeginport.disabled = 1;
+ document.iform.dstendport.disabled = 1;
+ } else {
+ document.iform.srcbeginport.disabled = 0;
+ document.iform.srcendport.disabled = 0;
+ document.iform.dstbeginport.disabled = 0;
+ document.iform.dstendport.disabled = 0;
+ }
+}
+
+function typesel_change() {
+ switch (document.iform.srctype.selectedIndex) {
+ case 1: /* single */
+ document.iform.src.disabled = 0;
+ document.iform.srcmask.value = "";
+ document.iform.srcmask.disabled = 1;
+ break;
+ case 2: /* network */
+ document.iform.src.disabled = 0;
+ document.iform.srcmask.disabled = 0;
+ break;
+ default:
+ document.iform.src.value = "";
+ document.iform.src.disabled = 1;
+ document.iform.srcmask.value = "";
+ document.iform.srcmask.disabled = 1;
+ break;
+ }
+ switch (document.iform.dsttype.selectedIndex) {
+ case 1: /* single */
+ document.iform.dst.disabled = 0;
+ document.iform.dstmask.value = "";
+ document.iform.dstmask.disabled = 1;
+ break;
+ case 2: /* network */
+ document.iform.dst.disabled = 0;
+ document.iform.dstmask.disabled = 0;
+ break;
+ default:
+ document.iform.dst.value = "";
+ document.iform.dst.disabled = 1;
+ document.iform.dstmask.value = "";
+ document.iform.dstmask.disabled = 1;
+ break;
+ }
+}
+
+function proto_change() {
+ if (document.iform.proto.selectedIndex < 2 || document.iform.proto.selectedIndex == 8) {
+ portsenabled = 1;
+ } else {
+ portsenabled = 0;
+ }
+
+ ext_change();
+}
+
+function src_rep_change() {
+ document.iform.srcendport.selectedIndex = document.iform.srcbeginport.selectedIndex;
+}
+function dst_rep_change() {
+ document.iform.dstendport.selectedIndex = document.iform.dstbeginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper: Edit rule</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (is_array($config['shaper']['pipe']) && (count($config['shaper']['pipe']) > 0)): ?>
+ <form action="firewall_shaper_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="top" class="vncellreq">Target</td>
+ <td class="vtable"> <select name="target" class="formfld">
+ <?php
+ foreach ($config['shaper']['pipe'] as $pipei => $pipe): ?>
+ <option value="<?="targetpipe:$pipei";?>" <?php if ("targetpipe:$pipei" == $pconfig['target']) echo "selected"; ?>>
+ <?php
+ echo htmlspecialchars("Pipe " . ($pipei + 1));
+ if ($pipe['descr'])
+ echo htmlspecialchars(" (" . $pipe['descr'] . ")");
+ ?>
+ </option>
+ <?php endforeach;
+ foreach ($config['shaper']['queue'] as $queuei => $queue): ?>
+ <option value="<?="targetqueue:$queuei";?>" <?php if ("targetqueue:$queuei" == $pconfig['target']) echo "selected"; ?>>
+ <?php
+ echo htmlspecialchars("Queue " . ($queuei + 1));
+ if ($queue['descr'])
+ echo htmlspecialchars(" (" . $queue['descr'] . ")");
+ ?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose a pipe or queue where packets that
+ match this rule should be sent.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Disabled</td>
+ <td class="vtable">
+ <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
+ <strong>Disable this rule</strong><br>
+ <span class="vexpl">Set this option to disable this rule without removing it from the list.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable"> <select name="interface" class="formfld">
+ <?php $interfaces = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface packets must pass
+ through to match this rule.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Protocol</td>
+ <td width="78%" class="vtable"> <select name="proto" class="formfld" onchange="proto_change()">
+ <?php $protocols = explode(" ", "TCP UDP ICMP ESP AH GRE IPv6 IGMP any"); foreach ($protocols as $proto): ?>
+ <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>>
+ <?=htmlspecialchars($proto);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Choose which IP protocol
+ this rule should match.<br>
+ Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Source</td>
+ <td width="78%" class="vtable"> <input name="srcnot" type="checkbox" id="srcnot" value="yes" <?php if ($pconfig['srcnot']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br> <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="srctype" class="formfld" onChange="typesel_change()">
+ <?php $sel = is_specialnet($pconfig['src']); ?>
+ <option value="any" <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>>
+ any</option>
+ <option value="single" <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+ Single host or alias</option>
+ <option value="network" <?php if (!$sel) echo "selected"; ?>>
+ Network</option>
+ <option value="lan" <?php if ($pconfig['src'] == "lan") { echo "selected"; } ?>>
+ LAN subnet</option>
+ <option value="pptp" <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>>
+ PPTP clients</option>
+ <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+ <option value="opt<?=$i;?>" <?php if ($pconfig['src'] == "opt" . $i) { echo "selected"; } ?>>
+ <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?>
+ subnet</option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="src" type="text" class="formfldalias" id="src" size="20" value="<?php if (!is_specialnet($pconfig['src'])) echo htmlspecialchars($pconfig['src']);?>">
+ /
+ <select name="srcmask" class="formfld" id="srcmask">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['srcmask']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Source port range
+ </td>
+ <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>from:&nbsp;&nbsp;</td>
+ <td><select name="srcbeginport" class="formfld" onchange="src_rep_change();ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['srcbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcbeginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="srcbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcbeginport']) echo $pconfig['srcbeginport']; ?>"></td>
+ </tr>
+ <tr>
+ <td>to:</td>
+ <td><select name="srcendport" class="formfld" onchange="ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['srcendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcendport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="srcendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcendport']) echo $pconfig['srcendport']; ?>"></td>
+ </tr>
+ </table>
+ <br> <span class="vexpl">Specify the port or port range for
+ the source of the packet for this rule.<br>
+ Hint: you can leave the <em>'to'</em> field empty if you only
+ want to filter a single port</span></td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination</td>
+ <td width="78%" class="vtable"> <input name="dstnot" type="checkbox" id="dstnot" value="yes" <?php if ($pconfig['dstnot']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br> <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="dsttype" class="formfld" onChange="typesel_change()">
+ <?php $sel = is_specialnet($pconfig['dst']); ?>
+ <option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>>
+ any</option>
+ <option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+ Single host or alias</option>
+ <option value="network" <?php if (!$sel) echo "selected"; ?>>
+ Network</option>
+ <option value="lan" <?php if ($pconfig['dst'] == "lan") { echo "selected"; } ?>>
+ LAN subnet</option>
+ <option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>>
+ PPTP clients</option>
+ <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+ <option value="opt<?=$i;?>" <?php if ($pconfig['dst'] == "opt" . $i) { echo "selected"; } ?>>
+ <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?>
+ subnet</option>
+ <?php endfor; ?>
+ </select> </td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="dst" type="text" class="formfldalias" id="dst" size="20" value="<?php if (!is_specialnet($pconfig['dst'])) echo htmlspecialchars($pconfig['dst']);?>">
+ /
+ <select name="dstmask" class="formfld" id="dstmask">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['dstmask']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination port
+ range </td>
+ <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>from:&nbsp;&nbsp;</td>
+ <td><select name="dstbeginport" class="formfld" onchange="dst_rep_change();ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['dstbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstbeginport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="dstbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstbeginport']) echo $pconfig['dstbeginport']; ?>"></td>
+ </tr>
+ <tr>
+ <td>to:</td>
+ <td><select name="dstendport" class="formfld" onchange="ext_change()">
+ <option value="">(other)</option>
+ <option value="any" <?php $bfound = 0; if ($pconfig['dstendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+ <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+ <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstendport']) {
+ echo "selected";
+ $bfound = 1;
+ }?>>
+ <?=htmlspecialchars($wkportdesc);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="dstendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstendport']) echo $pconfig['dstendport']; ?>"></td>
+ </tr>
+ </table>
+ <br> <span class="vexpl">Specify the port or port range for
+ the destination of the packet for this rule.<br>
+ Hint: you can leave the <em>'to'</em> field empty if you only
+ want to filter a single port</span></td>
+ <tr>
+ <td valign="top" class="vncell">Direction</td>
+ <td class="vtable"> <select name="direction" class="formfld">
+ <option value="" <?php if (!$pconfig['direction']) echo "selected"; ?>>any</option>
+ <option value="in" <?php if ($pconfig['direction'] == "in") echo "selected"; ?>>in</option>
+ <option value="out" <?php if ($pconfig['direction'] == "out") echo "selected"; ?>>out</option>
+ </select> <br>
+ Use this to match only packets travelling in a given direction
+ on the interface specified above (as seen from the firewall's
+ perspective). </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">IP Type of Service (TOS)</td>
+ <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+ <?php
+ $iniptos = explode(",", $pconfig['iptos']);
+ foreach ($iptos as $tos): $dontcare = true; ?>
+ <tr>
+ <td width="80" nowrap><strong>
+ <?echo $tos;?>
+ </strong></td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="on" <?php if (array_search($tos, $iniptos) !== false) { echo "checked"; $dontcare = false; }?>>
+ yes&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="off" <?php if (array_search("!" . $tos, $iniptos) !== false) { echo "checked"; $dontcare = false; }?>>
+ no&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="" <?php if ($dontcare) echo "checked";?>>
+ don't care</td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ <span class="vexpl">Use this to match packets according to their IP TOS values.
+ </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">IP packet length</td>
+ <td width="78%" class="vtable"><input name="iplen" type="text" id="iplen" size="10" value="<?=htmlspecialchars($pconfig['iplen']);?>">
+ <br>
+ Setting this makes the rule match packets of a given length
+ (either a single value or a range in the syntax <em>from-to</em>,
+ e.g. 0-80). </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">TCP flags</td>
+ <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+ <?php
+ $inflags = explode(",", $pconfig['tcpflags']);
+ foreach ($tcpflags as $tcpflag): $dontcare = true; ?>
+ <tr>
+ <td width="40" nowrap><strong>
+ <?=strtoupper($tcpflag);?>
+ </strong></td>
+ <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="on" <?php if (array_search($tcpflag, $inflags) !== false) { echo "checked"; $dontcare = false; }?>>
+ set&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="off" <?php if (array_search("!" . $tcpflag, $inflags) !== false) { echo "checked"; $dontcare = false; }?>>
+ cleared&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="" <?php if ($dontcare) echo "checked";?>>
+ don't care</td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ <span class="vexpl">Use this to choose TCP flags that must
+ be set or cleared for this rule to match.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_shaper[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ <input name="after" type="hidden" value="<?=$after;?>">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+typesel_change();
+proto_change();
+//-->
+</script>
+<?php else: ?>
+<p><strong>You need to create a pipe or queue before you can add a new rule.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_shaper_queues.php b/usr/local/www/firewall_shaper_queues.php
new file mode 100755
index 0000000..fa60240
--- /dev/null
+++ b/usr/local/www/firewall_shaper_queues.php
@@ -0,0 +1,141 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_shaper_queues.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pfqueueing']['pipe'])) {
+ $config['pfqueueing']['pipe'] = array();
+}
+if (!is_array($config['pfqueueing']['queue'])) {
+ $config['pfqueueing']['queue'] = array();
+}
+$a_queues = &$config['pfqueueing']['queue'];
+$a_pipe = &$config['pfqueueing']['pipe'];
+
+if ($_GET['act'] == "del") {
+ if ($a_queues[$_GET['id']]) {
+ /* check that no rule references this queue */
+ if (is_array($config['pfqueueing']['rule'])) {
+ foreach ($config['pfqueueing']['rule'] as $rule) {
+ if (isset($rule['targetqueue']) && ($rule['targetqueue'] == $_GET['id'])) {
+ $input_errors[] = "This queue cannot be deleted because it is still referenced by a rule.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ unset($a_queues[$_GET['id']]);
+
+ /* renumber all rules */
+ if (is_array($config['pfqueueing']['rule'])) {
+ for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
+ $currule = &$config['pfqueueing']['rule'][$i];
+ if (isset($currule['targetqueue']) && ($currule['targetqueue'] > $_GET['id']))
+ $currule['targetqueue']--;
+ }
+ }
+
+ write_config();
+ touch($d_shaperconfdirty_path);
+ header("Location: firewall_shaper_queues.php");
+ exit;
+ }
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Traffic shaper");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper Queues</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_rules.php">Rules</a></li>
+ <li class="tabact">Queues</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">No.</td>
+ <td width="5%" class="listhdrr">Priority</td>
+ <td width="20%" class="listhdrr">Options</td>
+ <td width="30%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_queues as $queue): ?>
+ <tr valign="top">
+ <td class="listlr">
+ <?=($i+1);?></td>
+ <td class="listr">
+ <?=$queue['priority'];?></td>
+ <td class="listr">
+ <?php if ($queue['options']): ?>
+ <?=$queue['options'];?>
+ <?php endif; ?>
+ &nbsp; </td>
+ <td class="listbg">
+ <?=htmlspecialchars($queue['name']);?>
+ &nbsp; </td>
+ <td valign="middle" nowrap class="list"> <a href="firewall_shaper_queues_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="firewall_shaper_queues.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this queue?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="5"></td>
+ <td class="list"> <a href="firewall_shaper_queues_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <p>
+ <strong><span class="red">Note:</span></strong> a queue can
+ only be deleted if it is not referenced by any rules.</td></p>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_shaper_queues_edit.php b/usr/local/www/firewall_shaper_queues_edit.php
new file mode 100755
index 0000000..15e0920
--- /dev/null
+++ b/usr/local/www/firewall_shaper_queues_edit.php
@@ -0,0 +1,187 @@
+#!/usr/local/bin/php
+<?php
+/*
+ firewall_shaper_queues_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$a_queues = &$config['pfqueueing']['queue'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_queues[$id]) {
+ $pconfig['bandwidth'] = $a_queues[$id]['bandwidth'] . $a_queues[$id]['bandwidthtype'];
+ $pconfig['priority'] = $a_queues[$id]['priority'];
+ $pconfig['mask'] = $a_queues[$id]['mask'];
+ $pconfig['name'] = $a_queues[$id]['name'];
+ $pconfig['options'] = $a_queues[$id]['options'];
+ $pconfig['bandwidth'] = $a_queues[$id]['bandwidth'];
+ $pconfig['bandwidthtype'] = $a_queues[$id]['bandwidthtype'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "priority");
+ $reqdfieldsn = explode(",", "Priority");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['priority'] && (!is_numericint($_POST['priority'])
+ || ($_POST['priority'] < 1) || ($_POST['priority'] > 100))) {
+ $input_errors[] = "The priority must be an integer between 1 and 100.";
+ }
+
+ if (!$input_errors) {
+ $queue = array();
+
+ $queue['schedulertype'] = $_POST['scheduler'];
+ $queue['bandwidth'] = $_POST['bandwidth'];
+ $queue['priority'] = $_POST['priority'];
+ $queue['name'] = $_POST['name'];
+
+ $scheduleroptions="";
+ if($_POST['red'] == "on")
+ $scheduleroptions .= "red ";
+
+ if($_POST['ecn'] == "on")
+ $scheduleroptions .= "ecn ";
+
+ if($_POST['default'] == "on")
+ $scheduleroptions .= "default";
+
+ $queue['options'] = $scheduleroptions;
+
+ if (isset($id) && $a_queues[$id])
+ $a_queues[$id] = $queue;
+ else
+ $a_queues[] = $queue;
+
+ write_config();
+ touch($d_shaperconfdirty_path);
+
+ header("Location: firewall_shaper_queues.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Firewall: Traffic shaper: Edit queue");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper: Edit queue</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="firewall_shaper_queues_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="top" class="vncellreq">Bandwidth</td>
+ <td class="vtable"> <input name="bandwidth" class="formfld" value="<?=htmlspecialchars($pconfig['bandwidth']);?>">
+ <select name="bandwidthtype">
+ <option value="<?=htmlspecialchars($pconfig['bandwidthtype']);?>"><?=htmlspecialchars($pconfig['bandwidthtype']);?></option>
+ <option value="b">bit/s</option>
+ <option value="Kb">Kilobit/s</option>
+ <option value="Mb">Megabit/s</option>
+ <option value="Gb">Gigabit/s</option>
+ </select>
+ <br>
+ <span class="vexpl">Choose the amount of bandwidth for this queue
+ </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Priority</td>
+ <td width="78%" class="vtable"> <input name="priority" type="text" id="priority" size="5" value="<?=htmlspecialchars($pconfig['priority']);?>">
+ <br> <span class="vexpl">Valid range: 1..100.<br>
+ All backlogged (i.e., with packets queued) queues linked to
+ the same pipe share the pipe's bandwidth proportionally to
+ their prioritys (higher priority = higher share of bandwidth).
+ Note that prioritys are not priorities; a queue with a lower
+ priority is still guaranteed to get its fraction of the bandwidth
+ even if a queue with a higher priority is permanently backlogged.
+ </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Name</td>
+ <td width="78%" class="vtable"> <input name="name" type="text" class="formfld" id="name" size="40" value="<?=htmlspecialchars($pconfig['name']);?>">
+ <br> <span class="vexpl">Enter the name of the queue here. Do not use spaces!
+ </span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Scheduler </td>
+ <td width="78%" class="vtable">
+ <select name="scheduler">
+ <option value="priq">Priority based queueing</option>
+ <option value="cbq">Class based queueing</option>
+ <option value="hfsc">Hierarchical Fair Service Curve queueing</option>
+ </select>
+ <br> <span class="vexpl">Select which type of queueing you would like to use
+ </span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Scheduler options</td>
+ <td width="78%" class="vtable">
+ <?php
+ $red = strpos($pconfig['options'], "red");
+ $ecn = strpos($pconfig['options'], "ecn");
+ $default = strpos($pconfig['options'], "default");
+ ?>
+ <input type=checkbox name="red" <?php if($red) echo " CHECKED";?> > Random Early Detection<br>
+ <input type=checkbox name="ecn" <?php if($ecn) echo " CHECKED";?> > Explicit Congestion Notification<br>
+ <input type=checkbox name="default" <?php if($default) echo " CHECKED";?> > Default (Clasee based queueing only)<br>
+ <br> <span class="vexpl">Select options for this queue
+ </span></td>
+ </tr>
+
+ <!-- XXX: add javascript to show/hide queueing options such as low bandwidth (hfsc, cbq) -->
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_queues[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/graph.php b/usr/local/www/graph.php
new file mode 100755
index 0000000..7fac8f3
--- /dev/null
+++ b/usr/local/www/graph.php
@@ -0,0 +1,325 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+ graph.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 T. Lechat <dev@lechat.org> and 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.
+*/
+
+// VERSION 1.0.4
+
+/********** HTTP GET Based Conf ***********/
+$ifnum=@$_GET["ifnum"]; //BSD / SNMP interface name / number
+$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum"; //Interface name that will be showed on top right of graph
+
+/********* Other conf *******/
+$scale_type="up"; //Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
+$nb_plot=120; //NB plot in graph
+$time_interval=1; //Refresh time Interval
+$first_stage_time_interval=2; //First stage time Intervall
+
+$urldata=@$_SERVER["SCRIPT_NAME"];
+$fetch_link = "ifstats.cgi?$ifnum";
+
+//Style
+$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
+$style['axis']="fill:black;stroke:black;stroke-width:1;";
+$style['in']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
+$style['out']="fill:#8092B3; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
+$style['graph_in']="fill:none;stroke:#435370;stroke-width:1;opacity:0.8;";
+$style['graph_out']="fill:none;stroke:#8092B3;stroke-width:1;opacity:0.8;";
+$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+$style['graphname']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
+$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
+$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
+$style['switch_unit']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
+$style['switch_scale']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
+$style['error']="fill:blue; font-family:Arial; font-size:4;";
+$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+
+//Error text if we cannot fetch data : depends on which method is used
+$error_text = "Cannot get data about interface $ifnum";
+
+$height=100; //SVG internal height : do not modify
+$width=200; //SVG internal width : do not modify
+
+/********* Graph DATA **************/
+header("Content-type: image/svg+xml");
+print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?><svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
+<g id="graph" style="visibility:visible">
+ <rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
+ <line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
+ <line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
+ <path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_out']?>"/>
+ <path id="graph_in" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_in']?>"/>
+ <path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" style="<?=$style[grid]?>"/>
+ <text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="graph_in_lbl" x="5" y="8" style="<?=$style['in']?>">In</text>
+ <text id="graph_out_lbl" x="5" y="16" style="<?=$style['out']?> ">Out</text>
+ <text id="graph_in_txt" x="20" y="8" style="<?=$style['in']?>"> </text>
+ <text id="graph_out_txt" x="20" y="16" style="<?=$style['out']?> "> </text>
+ <text id="ifname" x="<?=$width?>" y="8" style="<?=$style['graphname']?> text-anchor:end"><?=$ifname?></text>
+ <text id="switch_unit" x="<?=$width*0.55?>" y="5" style="<?=$style['switch_unit']?>">Switch to bytes/s</text>
+ <text id="switch_scale" x="<?=$width*0.55?>" y="11" style="<?=$style['switch_scale']?>">AutoScale (<?=$scale_type?>)</text>
+ <text id="datetime" x="<?=$width*0.33?>" y="5" style="<?=$style['legend']?>"> </text>
+ <text id="graphlast" x="<?=$width*0.55?>" y="17" style="<?=$style['legend']?>">Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
+ <polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
+ <text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>" style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
+ <text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>" style="visibility:hidden;<?=$style['collect_initial']?> text-anchor:middle">Collecting initial data, please wait...</text>
+</g>
+
+<script type="text/ecmascript"><![CDATA[
+var SVGDoc;
+var last_ifin=0;
+var last_ifout=0;
+var last_ugmt=0;
+var diff_ugmt=0;
+var diff_ifin=0;
+var diff_ifout=0;
+var max = 0;
+plot_in=new Array();
+plot_out=new Array();
+
+var isfirst=1;
+var index_plot=0;
+var step = <?=$width?> / <?=$nb_plot?> ;
+var unit = 'bits';
+var scale_type = '<?=$scale_type?>';
+
+function init(evt) {
+ SVGDoc = evt.getTarget().getOwnerDocument();
+ SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
+ SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
+
+ go();
+}
+
+function switch_unit(event)
+{
+ SVGDoc.getElementById('switch_unit').getFirstChild().setData('Switch to ' + unit + '/s');
+ if(unit=='bits') unit='bytes';else unit='bits';
+}
+
+function switch_scale(event)
+{
+ if(scale_type=='up') scale_type='follow';else scale_type='up';
+ SVGDoc.getElementById('switch_scale').getFirstChild().setData('AutoScale (' + scale_type + ')');
+}
+
+function go() {
+ getURL('<?=$fetch_link?>',urlcallback);
+}
+
+function urlcallback(obj) {
+ var error = 0;
+ now = new Date();
+
+ //Show datetimelegend
+ var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' +
+ LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
+ SVGDoc.getElementById('datetime').getFirstChild().setData(datetime);
+
+ //shift plot to left if nb_plot is already completed
+ var i=0;
+ if(index_plot > <?=$nb_plot?>)
+ {
+ while (i <= <?=$nb_plot?>)
+ {
+ var a=i+1;
+ plot_in[i]=plot_in[a];
+ plot_out[i]=plot_out[a];
+ i=i+1;
+ }
+ index_plot = <?=$nb_plot?>;
+ plot_in[index_plot]=0;
+ plot_out[index_plot]=0;
+ }
+
+ //if Geturl returns something
+ if (obj.success){
+ var t=obj.content.split("|");
+ var ugmt = parseFloat(t[0]);//ugmt is an unixtimestamp style
+ var ifin = parseInt(t[1]);//ifin must be in bytes
+ var ifout = parseInt(t[2]);//ifout must be in bytes
+ var scale;
+
+ if(!isNumber(ifin) || !isNumber(ifout)) {
+ goerror();
+ return;
+ } else {
+ SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
+ }
+
+ diff_ugmt = ugmt - last_ugmt;
+ diff_ifin = ifin - last_ifin;
+ diff_ifout = ifout - last_ifout;
+
+ if (diff_ugmt == 0)
+ diff_ugmt = 1; /* avoid division by zero */
+
+ last_ugmt = ugmt;
+ last_ifin = ifin;
+ last_ifout = ifout;
+
+ if(isfirst) {
+ SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
+ setTimeout('go()',<?=1000*$first_stage_time_interval?>);
+ isfirst=0;
+ return;
+ } else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
+
+ plot_in[index_plot] = diff_ifin / diff_ugmt;
+ plot_out[index_plot]= diff_ifout / diff_ugmt;
+
+ SVGDoc.getElementById('graph_in_txt').getFirstChild().setData(formatSpeed(plot_in[index_plot],unit));
+ SVGDoc.getElementById('graph_out_txt').getFirstChild().setData(formatSpeed(plot_out[index_plot],unit));
+
+ /* determine peak for sensible scaling */
+ if (scale_type == 'up') {
+ if (plot_in[index_plot] > max)
+ max = plot_in[index_plot];
+ if (plot_out[index_plot] > max)
+ max = plot_out[index_plot];
+ } else if (scale_type == 'follow') {
+ i = 0;
+ max = 0;
+ while (i <= <?=$nb_plot?>) {
+ if (plot_in[i] > max)
+ max = plot_in[i];
+ if (plot_out[i] > max)
+ max = plot_out[i];
+ i++;
+ }
+ }
+
+ var rmax;
+
+ if (unit == 'bits') {
+ /* round up max, such that
+ 100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
+ rmax = 12500;
+ i = 0;
+ while (max > rmax) {
+ i++;
+ if (i && (i % 4 == 0))
+ rmax *= 1.25;
+ else
+ rmax *= 2;
+ }
+ } else {
+ /* round up max, such that
+ 10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */
+ rmax = 10240;
+ i = 0;
+ while (max > rmax) {
+ i++;
+ if (i && (i % 4 == 0))
+ rmax *= 1.25;
+ else
+ rmax *= 2;
+
+ if (i == 8)
+ rmax *= 1.024;
+ }
+ }
+
+ scale = <?=$height?> / rmax;
+
+ /* change labels accordingly */
+ SVGDoc.getElementById('grid_txt1').getFirstChild().setData(formatSpeed(3*rmax/4,unit));
+ SVGDoc.getElementById('grid_txt2').getFirstChild().setData(formatSpeed(2*rmax/4,unit));
+ SVGDoc.getElementById('grid_txt3').getFirstChild().setData(formatSpeed(rmax/4,unit));
+
+ i = 0;
+
+ while (i <= index_plot)
+ {
+ var x = step * i;
+ var y_in= <?=$height?> - (plot_in[i] * scale);
+ var y_out= <?=$height?> - (plot_out[i] * scale);
+ if(i==0) {
+ var path_in = "M" + x + " " + y_in;
+ var path_out = "M" + x + " " + y_out;
+ }
+ else
+ {
+ var path_in = path_in + " L" + x + " " + y_in;
+ var path_out = path_out + " L" + x + " " + y_out;
+ }
+ i = i + 1;
+ }
+
+ index_plot = index_plot+1;
+ SVGDoc.getElementById('graph_in').setAttribute("d", path_in);
+ SVGDoc.getElementById('graph_out').setAttribute("d", path_out);
+
+ setTimeout('go()',<?=1000*$time_interval?>);
+ }
+ else
+ { //In case of Geturl fails
+ goerror();
+ }
+}
+
+function goerror() {
+ SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
+ setTimeout('go()',<?=1000*$time_interval?>);
+}
+
+function isNumber(a) {
+ return typeof a == 'number' && isFinite(a);
+}
+
+function formatSpeed(speed,unit){
+ if(unit=='bits') return formatSpeedBits(speed);
+ else if(unit=='bytes') return formatSpeedBytes(speed);
+}
+
+function formatSpeedBits(speed) {
+ // format speed in bits/sec, input: bytes/sec
+ if (speed < 125000)
+ return Math.round(speed / 125) + " Kbps";
+ else if (speed < 125000000)
+ return Math.round(speed / 1250)/100 + " Mbps";
+ else
+ return Math.round(speed / 1250000)/100 + " Gbps"; /* wow! */
+}
+function formatSpeedBytes(speed) {
+ // format speed in bytes/sec, input: bytes/sec
+ if (speed < 1048576)
+ return Math.round(speed / 10.24)/100 + " KB/s";
+ else if (speed < 1073741824)
+ return Math.round(speed / 10485.76)/100 + " MB/s";
+ else
+ return Math.round(speed / 10737418.24)/100 + " GB/s"; /* wow! */
+}
+function LZ(x) {
+ return (x < 0 || x > 9 ? "" : "0") + x
+}
+]]></script>
+</svg> \ No newline at end of file
diff --git a/usr/local/www/gui.css b/usr/local/www/gui.css
new file mode 100755
index 0000000..3a31c09
--- /dev/null
+++ b/usr/local/www/gui.css
@@ -0,0 +1,271 @@
+body,td,th,input,select {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 11px;
+}
+form {
+ margin: 0px;
+}
+.pgtitle {
+ font-size: 18px;
+ color: #777777;
+ font-weight: bold;
+}
+.tfrtitle {
+ font-size: 18px;
+ color: #ffffff;
+ font-weight: bold;
+}
+.vncell {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ border-bottom: 1px solid #999999;
+}
+.formfld {
+
+}
+.formfldalias {
+ background-color: #e7edf9;
+}
+.formpre {
+ font-family: Courier New, Courier, monospaced;
+ font-size: 10px;
+}
+.formbtn {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+.vvcell {
+ background-color: #FFFFC6;
+}
+.errmsg {
+ font-weight: bold;
+ color: #CC0000;
+}
+.red {
+ color: #CC0000;
+}
+.gray {
+ color: #A0A0A0;
+}
+.vexpl {
+ font-size: 11px;
+}
+a {
+ text-decoration: none;
+}
+.navlnk {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 13px;
+}
+.navlnks {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 11px;
+}
+.tblnk {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+.vncellreq {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vncellt {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vtable {
+ border-bottom: 1px solid #999999;
+}
+.vnsepcell {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.cpline {
+ font-size: 11px;
+ color: #FFFFFF;
+}
+.hostname {
+ font-size: 11px;
+ color: #FFFFFF;
+}
+.vnsepcellr {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listrpad {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+.listn {
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbg {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #D9DEE8;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listhdr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdrr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listlr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listlrns {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.list {
+ font-size: 11px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.listt {
+ font-size: 11px;
+ padding-top: 5px;
+ padding-left: 4px;
+}
+.listhdrrns {
+ background-color: #BBBBBB;
+ padding-left: 6px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-right: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listbgns {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #D9DEE8;
+ padding-left: 6px;
+ padding-right: 4px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listtopic {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #435370;
+ padding-right: 16px;
+ padding-left: 6px;
+ color: #FFFFFF;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+ul#tabnav {
+ font-size: 11px;
+ font-weight: bold;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+ul#tabnav li.tabinact {
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabcont {
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
diff --git a/usr/local/www/guiconfig.inc b/usr/local/www/guiconfig.inc
new file mode 100755
index 0000000..8efccfb
--- /dev/null
+++ b/usr/local/www/guiconfig.inc
@@ -0,0 +1,442 @@
+<?php
+/*
+ guiconfig.inc
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+/* make sure nothing is cached */
+if (!$omit_nocacheheaders) {
+ header("Expires: 0");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+}
+
+/* parse the configuration and include all configuration functions */
+require_once("config.inc");
+require_once("functions.inc");
+
+$d_natconfdirty_path = $g['varrun_path'] . "/nat.conf.dirty";
+$d_filterconfdirty_path = $g['varrun_path'] . "/filter.conf.dirty";
+$d_ipsecconfdirty_path = $g['varrun_path'] . "/ipsec.conf.dirty";
+$d_shaperconfdirty_path = $g['varrun_path'] . "/shaper.conf.dirty";
+$d_pptpuserdirty_path = $g['varrun_path'] . "/pptpd.user.dirty";
+$d_hostsdirty_path = $g['varrun_path'] . "/hosts.dirty";
+$d_staticmapsdirty_path = $g['varrun_path'] . "/staticmaps.dirty";
+$d_staticroutesdirty_path = $g['varrun_path'] . "/staticroutes.dirty";
+$d_aliasesdirty_path = $g['varrun_path'] . "/aliases.dirty";
+$d_proxyarpdirty_path = $g['varrun_path'] . "/proxyarp.dirty";
+$d_fwupenabled_path = $g['varrun_path'] . "/fwup.enabled";
+$d_firmwarelock_path = $g['varrun_path'] . "/firmware.lock";
+$d_sysrebootreqd_path = $g['varrun_path'] . "/sysreboot.reqd";
+$d_passthrumacsdirty_path = $g['varrun_path'] . "/passthrumacs.dirty";
+$d_allowedipsdirty_path = $g['varrun_path'] . "/allowedips.dirty";
+$d_ovpnclidirty_path = $g['varrun_path'] . "/ovpnclient.dirty";
+
+if (file_exists($d_firmwarelock_path)) {
+ if (!$d_isfwfile) {
+ header("Location: system_firmware.php");
+ exit;
+ } else {
+ return;
+ }
+}
+
+/* some well knows ports */
+$wkports = array(21 => "FTP", 22 => "SSH", 23 => "Telnet", 25 => "SMTP", 53 => "DNS", 80 => "HTTP",
+ 110 => "POP3", 143 => "IMAP", 443 => "HTTPS");
+
+$iptos = array("lowdelay", "throughput", "reliability", "mincost", "congestion");
+/* TCP flags */
+$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg");
+
+$specialnets = array("lan" => "LAN net", "pptp" => "PPTP clients");
+
+for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $specialnets['opt' . $i] = $config['interfaces']['opt' . $i]['descr'] . " net";
+}
+
+$medias = array("auto" => "autoselect", "100full" => "100BASE-TX full-duplex",
+ "100half" => "100BASE-TX half-duplex", "10full" => "10BASE-T full-duplex",
+ "10half" => "10BASE-T half-duplex");
+
+/* platforms that support firmware updating */
+$fwupplatforms = array('net45xx', 'net48xx', 'generic-pc', 'wrap');
+
+/* IPsec defines */
+$my_identifier_list = array('myaddress' => 'My IP address',
+ 'address' => 'IP address',
+ 'fqdn' => 'Domain name',
+ 'user_fqdn' => 'User FQDN');
+
+$p1_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish',
+ 'cast128' => 'CAST128');
+$p2_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish',
+ 'cast128' => 'CAST128', 'rijndael' => 'Rijndael (AES)');
+$p1_halgos = array('sha1' => 'SHA1', 'md5' => 'MD5');
+$p2_halgos = array('hmac_sha1' => 'SHA1', 'hmac_md5' => 'MD5');
+$p2_protos = array('esp' => 'ESP', 'ah' => 'AH');
+$p2_pfskeygroups = array('0' => 'off', '1' => '1', '2' => '2', '5' => '5');
+
+function do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
+
+ /* check for bad control characters */
+ foreach ($postdata as $pn => $pd) {
+ if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
+ $input_errors[] = "The field '" . $pn . "' contains invalid characters.";
+ }
+ }
+
+ for ($i = 0; $i < count($reqdfields); $i++) {
+ if (!$_POST[$reqdfields[$i]]) {
+ $input_errors[] = "The field '" . $reqdfieldsn[$i] . "' is required.";
+ }
+ }
+}
+
+function print_input_errors($input_errors) {
+ echo "<p><table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\">\n";
+ echo "<tr><td bgcolor=\"#A12A2A\" width=\"36\" align=\"center\" valign=\"top\"><img src=\"/err.gif\" width=\"28\" height=\"32\"></td>\n";
+ echo "<td bgcolor=\"#FFD9D1\" style=\"padding-left: 8px; padding-top: 6px\">";
+
+ echo "<span class=\"errmsg\"><p>The following input errors were detected:<ul>\n";
+ foreach ($input_errors as $ierr) {
+ echo "<li>" . htmlspecialchars($ierr) . "</li>\n";
+ }
+ echo "</ul></span>";
+
+ echo "</td></tr></table></p>";
+}
+
+function exec_rc_script($scriptname) {
+
+ global $d_sysrebootreqd_path;
+
+ if (file_exists($d_sysrebootreqd_path))
+ return 0;
+
+ exec($scriptname . " >/dev/null 2>&1", $execoutput, $retval);
+ return $retval;
+}
+
+function exec_rc_script_async($scriptname) {
+
+ global $d_sysrebootreqd_path;
+
+ if (file_exists($d_sysrebootreqd_path))
+ return 0;
+
+ exec("nohup " . $scriptname . " >/dev/null 2>&1 &", $execoutput, $retval);
+ return $retval;
+}
+
+function verify_gzip_file($fname) {
+
+ $returnvar = mwexec("/usr/bin/gunzip -S \"\" -t " . escapeshellarg($fname));
+ if ($returnvar != 0)
+ return 0;
+ else
+ return 1;
+}
+
+function print_info_box_np($msg) {
+ echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\">\n";
+ echo "<tr><td bgcolor=\"#687BA4\" align=\"center\" valign=\"top\" width=\"36\"><img src=\"/exclam.gif\" width=\"28\" height=\"32\"></td>\n";
+ echo "<td bgcolor=\"#D9DEE8\" style=\"padding-left: 8px\">";
+ echo $msg;
+ echo "</td></tr></table>";
+}
+
+function print_info_box($msg) {
+ echo "<p>";
+ print_info_box_np($msg);
+ echo "</p>";
+}
+
+function format_bytes($bytes) {
+ if ($bytes >= 1073741824) {
+ return sprintf("%.2f GB", $bytes/1073741824);
+ } else if ($bytes >= 1048576) {
+ return sprintf("%.2f MB", $bytes/1048576);
+ } else if ($bytes >= 1024) {
+ return sprintf("%.0f KB", $bytes/1024);
+ } else {
+ return sprintf("%d bytes", $bytes);
+ }
+}
+
+function get_std_save_message($ok) {
+ global $d_sysrebootreqd_path;
+
+ if ($ok == 0) {
+ if (file_exists($d_sysrebootreqd_path))
+ return "The changes have been saved. You must <a href=\"/reboot.php\">reboot</a> your firewall for changes to take effect.";
+ else
+ return "The changes have been applied successfully.";
+ } else {
+ return "ERROR: the changes could not be applied (error code $ok).";
+ }
+}
+
+function pprint_address($adr) {
+ global $specialnets;
+
+ if (isset($adr['any'])) {
+ $padr = "*";
+ } else if ($adr['network']) {
+ $padr = $specialnets[$adr['network']];
+ } else {
+ $padr = $adr['address'];
+ }
+
+ if (isset($adr['not']))
+ $padr = "! " . $padr;
+
+ return $padr;
+}
+
+function pprint_port($port) {
+ global $wkports;
+
+ $pport = "";
+
+ if (!$port)
+ echo "*";
+ else {
+ $srcport = explode("-", $port);
+ if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
+ $pport = $srcport[0];
+ if ($wkports[$srcport[0]]) {
+ $pport .= " (" . $wkports[$srcport[0]] . ")";
+ }
+ } else
+ $pport .= $srcport[0] . " - " . $srcport[1];
+ }
+
+ return $pport;
+}
+
+/* sort by interface only, retain the original order of rules that apply to
+ the same interface */
+function filter_rules_sort() {
+ global $g, $config;
+
+ /* mark each rule with the sequence number (to retain the order while sorting) */
+ for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+ $config['filter']['rule'][$i]['seq'] = $i;
+
+ function filtercmp($a, $b) {
+ if ($a['interface'] == $b['interface'])
+ return $a['seq'] - $b['seq'];
+ else
+ return -strcmp($a['interface'], $b['interface']);
+ }
+
+ usort($config['filter']['rule'], "filtercmp");
+
+ /* strip the sequence numbers again */
+ for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+ unset($config['filter']['rule'][$i]['seq']);
+}
+
+function nat_rules_sort() {
+ global $g, $config;
+
+ function natcmp($a, $b) {
+ if ($a['external-address'] == $b['external-address']) {
+ if ($a['protocol'] == $b['protocol']) {
+ if ($a['external-port'] == $b['external-port']) {
+ return 0;
+ } else {
+ return ($a['external-port'] - $b['external-port']);
+ }
+ } else {
+ return strcmp($a['protocol'], $b['protocol']);
+ }
+ } else if (!$a['external-address'])
+ return 1;
+ else if (!$b['external-address'])
+ return -1;
+ else
+ return ipcmp($a['external-address'], $b['external-address']);
+ }
+
+ usort($config['nat']['rule'], "natcmp");
+}
+
+function nat_1to1_rules_sort() {
+ global $g, $config;
+
+ function nat1to1cmp($a, $b) {
+ return ipcmp($a['external'], $b['external']);
+ }
+
+ usort($config['nat']['onetoone'], "nat1to1cmp");
+}
+
+function nat_server_rules_sort() {
+ global $g, $config;
+
+ function natservercmp($a, $b) {
+ return ipcmp($a['ipaddr'], $b['ipaddr']);
+ }
+
+ usort($config['nat']['servernat'], "natservercmp");
+}
+
+function nat_out_rules_sort() {
+ global $g, $config;
+
+ function natoutcmp($a, $b) {
+ return strcmp($a['source']['network'], $b['source']['network']);
+ }
+
+ usort($config['nat']['advancedoutbound']['rule'], "natoutcmp");
+}
+
+function pptpd_users_sort() {
+ global $g, $config;
+
+ function usercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+ }
+
+ usort($config['pptpd']['user'], "usercmp");
+}
+
+function staticroutes_sort() {
+ global $g, $config;
+
+ function staticroutecmp($a, $b) {
+ return strcmp($a['network'], $b['network']);
+ }
+
+ usort($config['staticroutes']['route'], "staticroutecmp");
+}
+
+function hosts_sort() {
+ global $g, $config;
+
+ function hostcmp($a, $b) {
+ return strcasecmp($a['host'], $b['host']);
+ }
+
+ usort($config['dnsmasq']['hosts'], "hostcmp");
+}
+
+function staticmaps_sort($if) {
+ global $g, $config;
+
+ function staticmapcmp($a, $b) {
+ return ipcmp($a['ipaddr'], $b['ipaddr']);
+ }
+
+ usort($config['dhcpd'][$if]['staticmap'], "staticmapcmp");
+}
+
+function aliases_sort() {
+ global $g, $config;
+
+ function aliascmp($a, $b) {
+ return strcmp($a['name'], $b['name']);
+ }
+
+ usort($config['aliases']['alias'], "aliascmp");
+}
+
+function ipsec_mobilekey_sort() {
+ global $g, $config;
+
+ function mobilekeycmp($a, $b) {
+ return strcmp($a['ident'][0], $b['ident'][0]);
+ }
+
+ usort($config['ipsec']['mobilekey'], "mobilekeycmp");
+}
+
+function proxyarp_sort() {
+ global $g, $config;
+
+ function proxyarpcmp($a, $b) {
+ if (isset($a['network']))
+ list($ast,$asn) = explode("/", $a['network']);
+ else if (isset($a['range'])) {
+ $ast = $a['range']['from'];
+ $asn = 32;
+ }
+ if (isset($b['network']))
+ list($bst,$bsn) = explode("/", $b['network']);
+ else if (isset($b['range'])) {
+ $bst = $b['range']['from'];
+ $bsn = 32;
+ }
+ if (ipcmp($ast, $bst) == 0)
+ return ($asn - $bsn);
+ else
+ return ipcmp($ast, $bst);
+ }
+
+ usort($config['proxyarp']['proxyarpnet'], "proxyarpcmp");
+}
+
+function passthrumacs_sort() {
+ global $g, $config;
+
+ function passthrumacscmp($a, $b) {
+ return strcmp($a['mac'], $b['mac']);
+ }
+
+ usort($config['captiveportal']['passthrumac'],"passthrumacscmp");
+}
+
+function allowedips_sort() {
+ global $g, $config;
+
+ function allowedipscmp($a, $b) {
+ return strcmp($a['ip'], $b['ip']);
+ }
+
+ usort($config['captiveportal']['allowedip'],"allowedipscmp");
+}
+
+function wol_sort() {
+ global $g, $config;
+
+ function wolcmp($a, $b) {
+ return strcmp($a['descr'], $b['descr']);
+ }
+
+ usort($config['wol']['wolentry'], "wolcmp");
+}
+
+function gentitle($pgname) {
+ global $config;
+ return $config['system']['hostname'] . "." . $config['system']['domain'] . " - " . $pgname;
+}
+
+?>
diff --git a/usr/local/www/ifstats.cgi b/usr/local/www/ifstats.cgi
new file mode 100755
index 0000000..944e95e
--- /dev/null
+++ b/usr/local/www/ifstats.cgi
Binary files differ
diff --git a/usr/local/www/index.php b/usr/local/www/index.php
new file mode 100755
index 0000000..ecaef0c
--- /dev/null
+++ b/usr/local/www/index.php
@@ -0,0 +1,180 @@
+#!/usr/local/bin/php
+<?php
+/*
+ index.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+/* find out whether there's hardware encryption (hifn) */
+unset($hwcrypto);
+$fd = @fopen("{$g['varlog_path']}/dmesg.boot", "r");
+if ($fd) {
+ while (!feof($fd)) {
+ $dmesgl = fgets($fd);
+ if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches)) {
+ $hwcrypto = $matches[1];
+ break;
+ }
+ }
+ fclose($fd);
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("m0n0wall webGUI");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr align="center" valign="top">
+ <td height="10" colspan="2">&nbsp;</td>
+ </tr>
+ <tr align="center" valign="top">
+ <td height="170" colspan="2"><img src="logobig.gif" width="520" height="149"></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic">System information</td>
+ </tr>
+ <tr>
+ <td width="25%" class="vncellt">Name</td>
+ <td width="75%" class="listr">
+ <?php echo $config['system']['hostname'] . "." . $config['system']['domain']; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="25%" valign="top" class="vncellt">Version</td>
+ <td width="75%" class="listr"> <strong>
+ <?php readfile("/etc/version"); ?>
+ </strong><br>
+ built on
+ <?php readfile("/etc/version.buildtime"); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="25%" class="vncellt">Platform</td>
+ <td width="75%" class="listr">
+ <?=htmlspecialchars($g['platform']);?>
+ </td>
+ </tr><?php if ($hwcrypto): ?>
+ <tr>
+ <td width="25%" class="vncellt">Hardware crypto</td>
+ <td width="75%" class="listr">
+ <?=htmlspecialchars($hwcrypto);?>
+ </td>
+ </tr><?php endif; ?>
+ <tr>
+ <td width="25%" class="vncellt">Uptime</td>
+ <td width="75%" class="listr">
+ <?php
+ exec("/sbin/sysctl -n kern.boottime", $boottime);
+ preg_match("/sec = (\d+)/", $boottime[0], $matches);
+ $boottime = $matches[1];
+ $uptime = time() - $boottime;
+
+ if ($uptime > 60)
+ $uptime += 30;
+ $updays = (int)($uptime / 86400);
+ $uptime %= 86400;
+ $uphours = (int)($uptime / 3600);
+ $uptime %= 3600;
+ $upmins = (int)($uptime / 60);
+
+ $uptimestr = "";
+ if ($updays > 1)
+ $uptimestr .= "$updays days, ";
+ else if ($updays > 0)
+ $uptimestr .= "1 day, ";
+ $uptimestr .= sprintf("%02d:%02d", $uphours, $upmins);
+ echo htmlspecialchars($uptimestr);
+ ?>
+ </td>
+ </tr><?php if ($config['lastchange']): ?>
+ <tr>
+ <td width="25%" class="vncellt">Last config change</td>
+ <td width="75%" class="listr">
+ <?=htmlspecialchars(date("D M j G:i:s T Y", $config['lastchange']));?>
+ </td>
+ </tr><?php endif; ?>
+ <tr>
+ <td width="25%" class="vncellt">CPU usage</td>
+ <td width="75%" class="listr">
+<?php
+$cpuTicks = explode(" ", `/sbin/sysctl -n kern.cp_time`);
+sleep(1);
+$cpuTicks2 = explode(" ", `/sbin/sysctl -n kern.cp_time`);
+
+$diff = array();
+$diff['user'] = $cpuTicks2[0] - $cpuTicks[0];
+$diff['nice'] = $cpuTicks2[1] - $cpuTicks[1];
+$diff['sys'] = $cpuTicks2[2] - $cpuTicks[2];
+$diff['intr'] = $cpuTicks2[3] - $cpuTicks[3];
+$diff['idle'] = $cpuTicks2[4] - $cpuTicks[4];
+
+$totalDiff = $diff['user'] + $diff['nice'] + $diff['sys'] + $diff['intr'] + $diff['idle'];
+
+$cpuUsage = round(100 * (1 - $diff['idle'] / $totalDiff), 0);
+
+echo "<img src='bar_left.gif' height='15' width='4' border='0' align='absmiddle'>";
+echo "<img src='bar_blue.gif' height='15' width='" . $cpuUsage . "' border='0' align='absmiddle'>";
+echo "<img src='bar_gray.gif' height='15' width='" . (100 - $cpuUsage) . "' border='0' align='absmiddle'>";
+echo "<img src='bar_right.gif' height='15' width='5' border='0' align='absmiddle'> ";
+echo $cpuUsage . "%";
+?>
+ </td>
+ </tr>
+ <tr>
+ <td width="25%" class="vncellt">Memory usage</td>
+ <td width="75%" class="listr">
+<?php
+
+exec("/sbin/sysctl -n vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count " .
+ "vm.stats.vm.v_wire_count vm.stats.vm.v_cache_count vm.stats.vm.v_free_count", $memory);
+
+$totalMem = $memory[0] + $memory[1] + $memory[2] + $memory[3] + $memory[4];
+$freeMem = $memory[4];
+$usedMem = $totalMem - $freeMem;
+$memUsage = round(($usedMem * 100) / $totalMem, 0);
+
+echo " <img src='bar_left.gif' height='15' width='4' border='0' align='absmiddle'>";
+echo "<img src='bar_blue.gif' height='15' width='" . $memUsage . "' border='0' align='absmiddle'>";
+echo "<img src='bar_gray.gif' height='15' width='" . (100 - $memUsage) . "' border='0' align='absmiddle'>";
+echo "<img src='bar_right.gif' height='15' width='5' border='0' align='absmiddle'> ";
+echo $memUsage . "%";
+?>
+ </td>
+ </tr>
+ </table>
+ <?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php
new file mode 100755
index 0000000..b4cc30b
--- /dev/null
+++ b/usr/local/www/interfaces.php
@@ -0,0 +1,630 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_wan.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$wancfg = &$config['interfaces']['wan'];
+$optcfg = &$config['interfaces']['wan'];
+
+$pconfig['username'] = $config['pppoe']['username'];
+$pconfig['password'] = $config['pppoe']['password'];
+$pconfig['provider'] = $config['pppoe']['provider'];
+$pconfig['pppoe_dialondemand'] = $config['pppoe']['ondemand'];
+$pconfig['pppoe_idletimeout'] = $config['pppoe']['timeout'];
+
+$pconfig['pptp_username'] = $config['pptp']['username'];
+$pconfig['pptp_password'] = $config['pptp']['password'];
+$pconfig['pptp_local'] = $config['pptp']['local'];
+$pconfig['pptp_subnet'] = $config['pptp']['subnet'];
+$pconfig['pptp_remote'] = $config['pptp']['remote'];
+$pconfig['pptp_dialondemand'] = $config['pptp']['ondemand'];
+$pconfig['pptp_idletimeout'] = $config['pptp']['timeout'];
+
+$pconfig['bigpond_username'] = $config['bigpond']['username'];
+$pconfig['bigpond_password'] = $config['bigpond']['password'];
+$pconfig['bigpond_authserver'] = $config['bigpond']['authserver'];
+$pconfig['bigpond_authdomain'] = $config['bigpond']['authdomain'];
+$pconfig['bigpond_minheartbeatinterval'] = $config['bigpond']['minheartbeatinterval'];
+
+$pconfig['dhcphostname'] = $wancfg['dhcphostname'];
+
+if ($wancfg['ipaddr'] == "dhcp") {
+ $pconfig['type'] = "DHCP";
+} else if ($wancfg['ipaddr'] == "pppoe") {
+ $pconfig['type'] = "PPPoE";
+} else if ($wancfg['ipaddr'] == "pptp") {
+ $pconfig['type'] = "PPTP";
+} else if ($wancfg['ipaddr'] == "bigpond") {
+ $pconfig['type'] = "BigPond";
+} else {
+ $pconfig['type'] = "Static";
+ $pconfig['ipaddr'] = $wancfg['ipaddr'];
+ $pconfig['subnet'] = $wancfg['subnet'];
+ $pconfig['gateway'] = $wancfg['gateway'];
+}
+
+$pconfig['blockpriv'] = isset($wancfg['blockpriv']);
+$pconfig['spoofmac'] = $wancfg['spoofmac'];
+$pconfig['mtu'] = $wancfg['mtu'];
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+ require("interfaces_wlan.inc");
+ wireless_config_init();
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['type'] == "Static") {
+ $reqdfields = explode(" ", "ipaddr subnet gateway");
+ $reqdfieldsn = explode(",", "IP address,Subnet bit count,Gateway");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPPoE") {
+ if ($_POST['pppoe_dialondemand']) {
+ $reqdfields = explode(" ", "username password pppoe_dialondemand pppoe_idletimeout");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "username password");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPTP") {
+ if ($_POST['pptp_dialondemand']) {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote pptp_dialondemand pptp_idletimeout");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "BigPond") {
+ $reqdfields = explode(" ", "bigpond_username bigpond_password");
+ $reqdfieldsn = explode(",", "BigPond username,BigPond password");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ }
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+ if (($_POST['gateway'] && !is_ipaddr($_POST['gateway']))) {
+ $input_errors[] = "A valid gateway must be specified.";
+ }
+ if (($_POST['provider'] && !is_domain($_POST['provider']))) {
+ $input_errors[] = "The service name contains invalid characters.";
+ }
+ if ($_POST['pppoe_idletimeout'] && !is_numericint($_POST['pppoe_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['pptp_local'] && !is_ipaddr($_POST['pptp_local']))) {
+ $input_errors[] = "A valid PPTP local IP address must be specified.";
+ }
+ if (($_POST['pptp_subnet'] && !is_numeric($_POST['pptp_subnet']))) {
+ $input_errors[] = "A valid PPTP subnet bit count must be specified.";
+ }
+ if (($_POST['pptp_remote'] && !is_ipaddr($_POST['pptp_remote']))) {
+ $input_errors[] = "A valid PPTP remote IP address must be specified.";
+ }
+ if ($_POST['pptp_idletimeout'] && !is_numericint($_POST['pptp_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['bigpond_authserver'] && !is_domain($_POST['bigpond_authserver']))) {
+ $input_errors[] = "The authentication server name contains invalid characters.";
+ }
+ if (($_POST['bigpond_authdomain'] && !is_domain($_POST['bigpond_authdomain']))) {
+ $input_errors[] = "The authentication domain name contains invalid characters.";
+ }
+ if ($_POST['bigpond_minheartbeatinterval'] && !is_numericint($_POST['bigpond_minheartbeatinterval'])) {
+ $input_errors[] = "The minimum heartbeat interval must be an integer.";
+ }
+ if (($_POST['spoofmac'] && !is_macaddr($_POST['spoofmac']))) {
+ $input_errors[] = "A valid MAC address must be specified.";
+ }
+ if ($_POST['mtu'] && (($_POST['mtu'] < 576) || ($_POST['mtu'] > 1500))) {
+ $input_errors[] = "The MTU must be between 576 and 1500 bytes.";
+ }
+
+ /* Wireless interface? */
+ if (isset($optcfg['wireless'])) {
+ $wi_input_errors = wireless_config_post();
+ if ($wi_input_errors) {
+ $input_errors = array_merge($input_errors, $wi_input_errors);
+ }
+ }
+
+ if (!$input_errors) {
+
+ unset($wancfg['ipaddr']);
+ unset($wancfg['subnet']);
+ unset($wancfg['gateway']);
+ unset($wancfg['dhcphostname']);
+ unset($config['pppoe']['username']);
+ unset($config['pppoe']['password']);
+ unset($config['pppoe']['provider']);
+ unset($config['pppoe']['ondemand']);
+ unset($config['pppoe']['timeout']);
+ unset($config['pptp']['username']);
+ unset($config['pptp']['password']);
+ unset($config['pptp']['local']);
+ unset($config['pptp']['subnet']);
+ unset($config['pptp']['remote']);
+ unset($config['pptp']['ondemand']);
+ unset($config['pptp']['timeout']);
+ unset($config['bigpond']['username']);
+ unset($config['bigpond']['password']);
+ unset($config['bigpond']['authserver']);
+ unset($config['bigpond']['authdomain']);
+ unset($config['bigpond']['minheartbeatinterval']);
+
+ if ($_POST['type'] == "Static") {
+ $wancfg['ipaddr'] = $_POST['ipaddr'];
+ $wancfg['subnet'] = $_POST['subnet'];
+ $wancfg['gateway'] = $_POST['gateway'];
+ } else if ($_POST['type'] == "DHCP") {
+ $wancfg['ipaddr'] = "dhcp";
+ $wancfg['dhcphostname'] = $_POST['dhcphostname'];
+ } else if ($_POST['type'] == "PPPoE") {
+ $wancfg['ipaddr'] = "pppoe";
+ $config['pppoe']['username'] = $_POST['username'];
+ $config['pppoe']['password'] = $_POST['password'];
+ $config['pppoe']['provider'] = $_POST['provider'];
+ $config['pppoe']['ondemand'] = $_POST['pppoe_dialondemand'];
+ $config['pppoe']['timeout'] = $_POST['pppoe_idletimeout'];
+ } else if ($_POST['type'] == "PPTP") {
+ $wancfg['ipaddr'] = "pptp";
+ $config['pptp']['username'] = $_POST['pptp_username'];
+ $config['pptp']['password'] = $_POST['pptp_password'];
+ $config['pptp']['local'] = $_POST['pptp_local'];
+ $config['pptp']['subnet'] = $_POST['pptp_subnet'];
+ $config['pptp']['remote'] = $_POST['pptp_remote'];
+ $config['pptp']['ondemand'] = $_POST['pptp_dialondemand'];
+ $config['pptp']['timeout'] = $_POST['pptp_idletimeout'];
+ } else if ($_POST['type'] == "BigPond") {
+ $wancfg['ipaddr'] = "bigpond";
+ $config['bigpond']['username'] = $_POST['bigpond_username'];
+ $config['bigpond']['password'] = $_POST['bigpond_password'];
+ $config['bigpond']['authserver'] = $_POST['bigpond_authserver'];
+ $config['bigpond']['authdomain'] = $_POST['bigpond_authdomain'];
+ $config['bigpond']['minheartbeatinterval'] = $_POST['bigpond_minheartbeatinterval'];
+ }
+
+ $wancfg['blockpriv'] = $_POST['blockpriv'] ? true : false;
+ $wancfg['spoofmac'] = $_POST['spoofmac'];
+ $wancfg['mtu'] = $_POST['mtu'];
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = interfaces_wan_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: WAN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+}
+
+function enable_change_pptp(enable_change_pptp) {
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+}
+
+function type_change(enable_change,enable_change_pptp) {
+ switch (document.iform.type.selectedIndex) {
+ case 0:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 0;
+ document.iform.subnet.disabled = 0;
+ document.iform.gateway.disabled = 0;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 1:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 0;
+ break;
+ case 2:
+ document.iform.username.disabled = 0;
+ document.iform.password.disabled = 0;
+ document.iform.provider.disabled = 0;
+ document.iform.pppoe_dialondemand.disabled = 0;
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 3:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 0;
+ document.iform.pptp_password.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_subnet.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ document.iform.pptp_dialondemand.disabled = 0;
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 4:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 0;
+ document.iform.bigpond_password.disabled = 0;
+ document.iform.bigpond_authserver.disabled = 0;
+ document.iform.bigpond_authdomain.disabled = 0;
+ document.iform.bigpond_minheartbeatinterval.disabled = 0;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: WAN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="interfaces_wan.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="middle"><strong>Type</strong></td>
+ <td> <select name="type" class="formfld" id="type" onchange="type_change()">
+ <?php $opts = split(" ", "Static DHCP PPPoE PPTP BigPond");
+ foreach ($opts as $opt): ?>
+ <option <?php if ($opt == $pconfig['type']) echo "selected";?>>
+ <?=htmlspecialchars($opt);?>
+ </option>
+ <?php endforeach; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="4"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">General configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MAC address</td>
+ <td class="vtable"> <input name="spoofmac" type="text" class="formfld" id="spoofmac" size="30" value="<?=htmlspecialchars($pconfig['spoofmac']);?>">
+ <br>
+ This field can be used to modify (&quot;spoof&quot;) the MAC
+ address of the WAN interface<br>
+ (may be required with some cable connections)<br>
+ Enter a MAC address in the following format: xx:xx:xx:xx:xx:xx
+ or leave blank</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MTU</td>
+ <td class="vtable"> <input name="mtu" type="text" class="formfld" id="mtu" size="8" value="<?=htmlspecialchars($pconfig['mtu']);?>">
+ <br>
+ If you enter a value in this field, then MSS clamping for
+ TCP connections to the value entered above minus 40 (TCP/IP
+ header size) will be in effect. If you leave this field blank,
+ an MTU of 1492 bytes for PPPoE and 1500 bytes for all other
+ connection types will be assumed.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">Static IP configuration</td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">IP address</td>
+ <td class="vtable"> <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+ /
+ <select name="subnet" class="formfld" id="subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Gateway</td>
+ <td class="vtable"> <input name="gateway" type="text" class="formfld" id="gateway" size="20" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">DHCP client configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Hostname</td>
+ <td class="vtable"> <input name="dhcphostname" type="text" class="formfld" id="dhcphostname" size="40" value="<?=htmlspecialchars($pconfig['dhcphostname']);?>">
+ <br>
+ The value in this field is sent as the DHCP client identifier
+ and hostname when requesting a DHCP lease. Some ISPs may require
+ this (for client identification).</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">PPPoE configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="password" type="text" class="formfld" id="password" size="20" value="<?=htmlspecialchars($pconfig['password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Service name</td>
+ <td class="vtable"><input name="provider" type="text" class="formfld" id="provider" size="20" value="<?=htmlspecialchars($pconfig['provider']);?>">
+ <br> <span class="vexpl">Hint: this field can usually be left
+ empty</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pppoe_dialondemand" type="checkbox" id="pppoe_dialondemand" value="enable" <?php if ($pconfig['pppoe_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pppoe_idletimeout" type="text" class="formfld" id="pppoe_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pppoe_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">PPTP configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="pptp_username" type="text" class="formfld" id="pptp_username" size="20" value="<?=htmlspecialchars($pconfig['pptp_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="pptp_password" type="text" class="formfld" id="pptp_password" size="20" value="<?=htmlspecialchars($pconfig['pptp_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">Local IP address</td>
+ <td class="vtable"> <input name="pptp_local" type="text" class="formfld" id="pptp_local" size="20" value="<?=htmlspecialchars($pconfig['pptp_local']);?>">
+ /
+ <select name="pptp_subnet" class="formfld" id="pptp_subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['pptp_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">Remote IP address</td>
+ <td class="vtable"> <input name="pptp_remote" type="text" class="formfld" id="pptp_remote" size="20" value="<?=htmlspecialchars($pconfig['pptp_remote']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pptp_dialondemand" type="checkbox" id="pptp_dialondemand" value="enable" <?php if ($pconfig['pptp_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change_pptp(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pptp_idletimeout" type="text" class="formfld" id="pptp_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pptp_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">BigPond Cable configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="bigpond_username" type="text" class="formfld" id="bigpond_username" size="20" value="<?=htmlspecialchars($pconfig['bigpond_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="bigpond_password" type="text" class="formfld" id="bigpond_password" size="20" value="<?=htmlspecialchars($pconfig['bigpond_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication server</td>
+ <td class="vtable"><input name="bigpond_authserver" type="text" class="formfld" id="bigpond_authserver" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authserver']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the default (&quot;dce-server&quot;) is used. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication domain</td>
+ <td class="vtable"><input name="bigpond_authdomain" type="text" class="formfld" id="bigpond_authdomain" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authdomain']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the domain name assigned via DHCP will be used.<br>
+ <br>
+ Note: the BigPond client implicitly sets the &quot;Allow DNS server list to be overridden by DHCP/PPP on WAN&quot; on the System: General setup page. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Min. heartbeat interval</td>
+ <td class="vtable">
+ <input name="bigpond_minheartbeatinterval" type="text" class="formfld" id="bigpond_minheartbeatinterval" size="8" value="<?=htmlspecialchars($pconfig['bigpond_minheartbeatinterval']);?>">
+ seconds<br>
+ Setting this to a sensible value (e.g. 60 seconds) can protect against DoS attacks. </td>
+ </tr>
+ <?php /* Wireless interface? */
+ if (isset($optcfg['wireless']))
+ wireless_config_print();
+ ?>
+ <tr>
+ <td height="16" colspan="2" valign="top"></td>
+ </tr>
+ <tr>
+ <td valign="middle">&nbsp;</td>
+ <td class="vtable"> <input name="blockpriv" type="checkbox" id="blockpriv" value="yes" <?php if ($pconfig['blockpriv'] == "yes") echo "checked"; ?>>
+ <strong>Block private networks</strong><br>
+ When set, this option blocks traffic from IP addresses that
+ are reserved for private<br>
+ networks as per RFC 1918 (10/8, 172.16/12, 192.168/16) as
+ well as loopback addresses<br>
+ (127/8). You should generally leave this option turned on,
+ unless your WAN network<br>
+ lies in such a private address space, too.</td>
+ </tr>
+ <tr>
+ <td width="100" valign="top">&nbsp;</td>
+ <td> &nbsp;<br> <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change_pptp(true)&&enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_assign.php b/usr/local/www/interfaces_assign.php
new file mode 100755
index 0000000..0f57d30
--- /dev/null
+++ b/usr/local/www/interfaces_assign.php
@@ -0,0 +1,265 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_assign.php
+ part of m0n0wall (http://m0n0.ch/wall)
+ Written by Jim McBeath based on existing m0n0wall files
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+/*
+ In this file, "port" refers to the physical port name,
+ while "interface" refers to LAN, WAN, or OPTn.
+*/
+
+/* get list without VLAN interfaces */
+$portlist = get_interface_list();
+
+/* add VLAN interfaces */
+if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
+ $i = 0;
+ foreach ($config['vlans']['vlan'] as $vlan) {
+ $portlist['vlan' . $i] = $vlan;
+ $portlist['vlan' . $i]['isvlan'] = true;
+ $i++;
+ }
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+
+ /* input validation */
+
+ /* Build a list of the port names so we can see how the interfaces map */
+ $portifmap = array();
+ foreach ($portlist as $portname => $portinfo)
+ $portifmap[$portname] = array();
+
+ /* Go through the list of ports selected by the user,
+ build a list of port-to-interface mappings in portifmap */
+ foreach ($_POST as $ifname => $ifport) {
+ if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt'))
+ $portifmap[$ifport][] = strtoupper($ifname);
+ }
+
+ /* Deliver error message for any port with more than one assignment */
+ foreach ($portifmap as $portname => $ifnames) {
+ if (count($ifnames) > 1) {
+ $errstr = "Port " . $portname .
+ " was assigned to " . count($ifnames) .
+ " interfaces:";
+
+ foreach ($portifmap[$portname] as $ifn)
+ $errstr .= " " . $ifn;
+
+ $input_errors[] = $errstr;
+ }
+ }
+
+
+ if (!$input_errors) {
+ /* No errors detected, so update the config */
+ foreach ($_POST as $ifname => $ifport) {
+
+ if (($ifname == 'lan') || ($ifname == 'wan') ||
+ (substr($ifname, 0, 3) == 'opt')) {
+
+ if (!is_array($ifport)) {
+ $config['interfaces'][$ifname]['if'] = $ifport;
+
+ /* check for wireless interfaces, set or clear ['wireless'] */
+ if (preg_match("/^(wi|awi|an)/", $ifport)) {
+ if (!is_array($config['interfaces'][$ifname]['wireless']))
+ $config['interfaces'][$ifname]['wireless'] = array();
+ } else {
+ unset($config['interfaces'][$ifname]['wireless']);
+ }
+
+ /* make sure there is a name for OPTn */
+ if (substr($ifname, 0, 3) == 'opt') {
+ if (!isset($config['interfaces'][$ifname]['descr']))
+ $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+ }
+ }
+ }
+ }
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ $id = $_GET['id'];
+
+ unset($config['interfaces'][$id]); /* delete the specified OPTn */
+
+ /* shift down other OPTn interfaces to get rid of holes */
+ $i = substr($id, 3); /* the number of the OPTn port being deleted */
+ $i++;
+
+ /* look at the following OPTn ports */
+ while (is_array($config['interfaces']['opt' . $i])) {
+ $config['interfaces']['opt' . ($i - 1)] =
+ $config['interfaces']['opt' . $i];
+
+ if ($config['interfaces']['opt' . ($i - 1)]['descr'] == "OPT" . $i)
+ $config['interfaces']['opt' . ($i - 1)]['descr'] = "OPT" . ($i - 1);
+
+ unset($config['interfaces']['opt' . $i]);
+ $i++;
+ }
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_assign.php");
+ exit;
+}
+
+if ($_GET['act'] == "add") {
+ /* find next free optional interface number */
+ $i = 1;
+ while (is_array($config['interfaces']['opt' . $i]))
+ $i++;
+
+ $newifname = 'opt' . $i;
+ $config['interfaces'][$newifname] = array();
+ $config['interfaces'][$newifname]['descr'] = "OPT" . $i;
+
+ /* Find an unused port for this interface */
+ foreach ($portlist as $portname => $portinfo) {
+ $portused = false;
+ foreach ($config['interfaces'] as $ifname => $ifdata) {
+ if ($ifdata['if'] == $portname) {
+ $portused = true;
+ break;
+ }
+ }
+ if (!$portused) {
+ $config['interfaces'][$newifname]['if'] = $portname;
+ if (preg_match("/^(wi|awi|an)/", $portname))
+ $config['interfaces'][$newifname]['wireless'] = array();
+ break;
+ }
+ }
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_assign.php");
+ exit;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: Assign network ports");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Assign network ports</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="interfaces_assign.php" method="post" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Interface assignments</li>
+ <li class="tabinact"><a href="interfaces_vlan.php">VLANs</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Interface</td>
+ <td class="listhdr">Network port</td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ <?php foreach ($config['interfaces'] as $ifname => $iface):
+ if ($iface['descr'])
+ $ifdescr = $iface['descr'];
+ else
+ $ifdescr = strtoupper($ifname);
+ ?>
+ <tr>
+ <td class="listlr" valign="middle"><strong><?=$ifdescr;?></strong></td>
+ <td valign="middle" class="listr">
+ <select name="<?=$ifname;?>" class="formfld" id="<?=$ifname;?>">
+ <?php foreach ($portlist as $portname => $portinfo): ?>
+ <option value="<?=$portname;?>" <?php if ($portname == $iface['if']) echo "selected";?>>
+ <?php if ($portinfo['isvlan']) {
+ $descr = "VLAN {$portinfo['tag']} on {$portinfo['if']}";
+ if ($portinfo['descr'])
+ $descr .= " (" . $portinfo['descr'] . ")";
+ echo htmlspecialchars($descr);
+ } else
+ echo htmlspecialchars($portname . " (" . $portinfo['mac'] . ")");
+ ?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td valign="middle" class="list">
+ <?php if (($ifname != 'lan') && ($ifname != 'wan')): ?>
+ <a href="interfaces_assign.php?act=del&id=<?=$ifname;?>"><img src="x.gif" title="delete interface" width="17" height="17" border="0"></a>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ <?php if (count($config['interfaces']) < count($portlist)): ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list" nowrap>
+ <a href="interfaces_assign.php?act=add"><img src="plus.gif" title="add interface" width="17" height="17" border="0"></a>
+ </td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td class="list" colspan="3" height="10"></td>
+ </tr>
+ <?php endif; ?>
+</table>
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <p><span class="vexpl"><strong><span class="red">Warning:</span><br>
+ </strong>After you click &quot;Save&quot;, you must reboot the firewall to make the changes take effect. You may also have to do one or more of the following steps before you can access your firewall again: </span></p>
+ <ul>
+ <li><span class="vexpl">change the IP address of your computer</span></li>
+ <li><span class="vexpl">renew its DHCP lease</span></li>
+ <li><span class="vexpl">access the webGUI with the new IP address</span></li>
+ </ul></td>
+ </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_lan.php b/usr/local/www/interfaces_lan.php
new file mode 100755
index 0000000..66af153
--- /dev/null
+++ b/usr/local/www/interfaces_lan.php
@@ -0,0 +1,173 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_lan.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$lancfg = &$config['interfaces']['lan'];
+$optcfg = &$config['interfaces']['lan'];
+$pconfig['ipaddr'] = $config['interfaces']['lan']['ipaddr'];
+$pconfig['subnet'] = $config['interfaces']['lan']['subnet'];
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+ require("interfaces_wlan.inc");
+ wireless_config_init();
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ipaddr subnet");
+ $reqdfieldsn = explode(",", "IP address,Subnet bit count");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+
+ /* Wireless interface? */
+ if (isset($optcfg['wireless'])) {
+ $wi_input_errors = wireless_config_post();
+ if ($wi_input_errors) {
+ $input_errors = array_merge($input_errors, $wi_input_errors);
+ }
+ }
+
+ if (!$input_errors) {
+ $config['interfaces']['lan']['ipaddr'] = $_POST['ipaddr'];
+ $config['interfaces']['lan']['subnet'] = $_POST['subnet'];
+
+ $dhcpd_was_enabled = 0;
+ if (isset($config['dhcpd']['enable'])) {
+ unset($config['dhcpd']['enable']);
+ $dhcpd_was_enabled = 1;
+ }
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+
+ $savemsg = get_std_save_message(0);
+
+ if ($dhcpd_was_enabled)
+ $savemsg .= "<br>Note that the DHCP server has been disabled.<br>Please review its configuration " .
+ "and enable it again prior to rebooting.";
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: LAN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function gen_bits(ipaddr) {
+ if (ipaddr.search(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) != -1) {
+ var adr = ipaddr.split(/\./);
+ if (adr[0] > 255 || adr[1] > 255 || adr[2] > 255 || adr[3] > 255)
+ return "";
+ if (adr[0] == 0 && adr[1] == 0 && adr[2] == 0 && adr[3] == 0)
+ return "";
+
+ if (adr[0] <= 127)
+ return "8";
+ else if (adr[0] <= 191)
+ return "16";
+ else
+ return "24";
+ }
+ else
+ return "";
+}
+function ipaddr_change() {
+ document.iform.subnet.value = gen_bits(document.iform.ipaddr.value);
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: LAN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="interfaces_lan.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ipaddr" type="text" class="formfld" id="hostname" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
+ /
+ <select name="subnet" class="formfld" id="subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <?php /* Wireless interface? */
+ if (isset($optcfg['wireless']))
+ wireless_config_print();
+ ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Warning:<br>
+ </strong></span>after you click &quot;Save&quot;, you must
+ reboot your firewall for changes to take effect. You may also
+ have to do one or more of the following steps before you can
+ access your firewall again:
+ <ul>
+ <li>change the IP address of your computer</li>
+ <li>renew its DHCP lease</li>
+ <li>access the webGUI with the new IP address</li>
+ </ul>
+ </span></td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_opt.php b/usr/local/www/interfaces_opt.php
new file mode 100755
index 0000000..fffc17b
--- /dev/null
+++ b/usr/local/www/interfaces_opt.php
@@ -0,0 +1,276 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_opt.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+unset($index);
+if ($_GET['index'])
+ $index = $_GET['index'];
+else if ($_POST['index'])
+ $index = $_POST['index'];
+
+if (!$index)
+ exit;
+
+$optcfg = &$config['interfaces']['opt' . $index];
+$pconfig['descr'] = $optcfg['descr'];
+$pconfig['bridge'] = $optcfg['bridge'];
+$pconfig['ipaddr'] = $optcfg['ipaddr'];
+$pconfig['subnet'] = $optcfg['subnet'];
+$pconfig['enable'] = isset($optcfg['enable']);
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+ require("interfaces_wlan.inc");
+ wireless_config_init();
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+
+ /* description unique? */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index) {
+ if ($config['interfaces']['opt' . $i]['descr'] == $_POST['descr']) {
+ $input_errors[] = "An interface with the specified description already exists.";
+ }
+ }
+ }
+
+ if ($_POST['bridge']) {
+ /* double bridging? */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index) {
+ if ($config['interfaces']['opt' . $i]['bridge'] == $_POST['bridge']) {
+ $input_errors[] = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "the specified interface.";
+ } else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
+ $input_errors[] = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "this interface.";
+ }
+ }
+ }
+ if ($config['interfaces'][$_POST['bridge']]['bridge']) {
+ $input_errors[] = "The specified interface is already bridged to " .
+ "another interface.";
+ }
+ /* captive portal on? */
+ if (isset($config['captiveportal']['enable'])) {
+ $input_errors[] = "Interfaces cannot be bridged while the captive portal is enabled.";
+ }
+ } else {
+ $reqdfields = explode(" ", "descr ipaddr subnet");
+ $reqdfieldsn = explode(",", "Description,IP address,Subnet bit count");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+ }
+ }
+
+ /* Wireless interface? */
+ if (isset($optcfg['wireless'])) {
+ $wi_input_errors = wireless_config_post();
+ if ($wi_input_errors) {
+ $input_errors = array_merge($input_errors, $wi_input_errors);
+ }
+ }
+
+ if (!$input_errors) {
+ $optcfg['descr'] = $_POST['descr'];
+ $optcfg['ipaddr'] = $_POST['ipaddr'];
+ $optcfg['subnet'] = $_POST['subnet'];
+ $optcfg['bridge'] = $_POST['bridge'];
+ $optcfg['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = interfaces_optional_configure();
+
+ /* is this the captive portal interface? */
+ if (isset($config['captiveportal']['enable']) &&
+ ($config['captiveportal']['interface'] == ('opt' . $index))) {
+ captiveportal_configure();
+ }
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: Optional $index (" . htmlspecialchars($optcfg['descr']) . ")");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+ if ((document.iform.bridge.selectedIndex == 0) || enable_over) {
+ document.iform.ipaddr.disabled = 0;
+ document.iform.subnet.disabled = 0;
+ } else {
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ }
+}
+function gen_bits(ipaddr) {
+ if (ipaddr.search(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) != -1) {
+ var adr = ipaddr.split(/\./);
+ if (adr[0] > 255 || adr[1] > 255 || adr[2] > 255 || adr[3] > 255)
+ return 0;
+ if (adr[0] == 0 && adr[1] == 0 && adr[2] == 0 && adr[3] == 0)
+ return 0;
+
+ if (adr[0] <= 127)
+ return 23;
+ else if (adr[0] <= 191)
+ return 15;
+ else
+ return 7;
+ }
+ else
+ return 0;
+}
+function ipaddr_change() {
+ document.iform.subnet.selectedIndex = gen_bits(document.iform.ipaddr.value);
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Optional <?=$index;?> (<?=htmlspecialchars($optcfg['descr']);?>)</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if ($optcfg['if']): ?>
+ <form action="interfaces_opt.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable Optional <?=$index;?> interface</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="30" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">Enter a description (name) for the interface here.</span>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">IP configuration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Bridge with</td>
+ <td width="78%" class="vtable">
+<select name="bridge" class="formfld" id="bridge" onChange="enable_change(false)">
+ <option <?php if (!$pconfig['bridge']) echo "selected";?> value="">none</option>
+ <?php $opts = array('lan' => "LAN", 'wan' => "WAN");
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index)
+ $opts['opt' . $i] = "Optional " . $i . " (" .
+ $config['interfaces']['opt' . $i]['descr'] . ")";
+ }
+ foreach ($opts as $opt => $optname): ?>
+ <option <?php if ($opt == $pconfig['bridge']) echo "selected";?> value="<?=htmlspecialchars($opt);?>">
+ <?=htmlspecialchars($optname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
+ /
+ <select name="subnet" class="formfld" id="subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>><?=$i;?></option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+ <?php /* Wireless interface? */
+ if (isset($optcfg['wireless']))
+ wireless_config_print();
+ ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="index" type="hidden" value="<?=$index;?>">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>be sure to add firewall rules to permit traffic
+ through the interface. Firewall rules for an interface in
+ bridged mode have no effect on packets to hosts other than
+ m0n0wall itself, unless &quot;Enable filtering bridge&quot;
+ is checked on the <a href="system_advanced.php">System:
+ Advanced functions</a> page.</span></td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php else: ?>
+<p><strong>Optional <?=$index;?> has been disabled because there is no OPT<?=$index;?> interface.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_vlan.php b/usr/local/www/interfaces_vlan.php
new file mode 100755
index 0000000..f724ef3
--- /dev/null
+++ b/usr/local/www/interfaces_vlan.php
@@ -0,0 +1,149 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_vlan.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['vlans']['vlan']))
+ $config['vlans']['vlan'] = array();
+
+$a_vlans = &$config['vlans']['vlan'] ;
+
+function vlan_inuse($num) {
+ global $config, $g;
+
+ if ($config['interfaces']['lan']['if'] == "vlan{$num}")
+ return true;
+ if ($config['interfaces']['wan']['if'] == "vlan{$num}")
+ return true;
+
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($config['interfaces']['opt' . $i]['if'] == "vlan{$num}")
+ return true;
+ }
+
+ return false;
+}
+
+function renumber_vlan($if, $delvlan) {
+ if (!preg_match("/^vlan/", $if))
+ return $if;
+
+ $vlan = substr($if, 4);
+ if ($vlan > $delvlan)
+ return "vlan" . ($vlan - 1);
+ else
+ return $if;
+}
+
+if ($_GET['act'] == "del") {
+ /* check if still in use */
+ if (vlan_inuse($_GET['id'])) {
+ $input_errors[] = "This VLAN cannot be deleted because it is still being used as an interface.";
+ } else {
+ unset($a_vlans[$_GET['id']]);
+
+ /* renumber all interfaces that use VLANs */
+ $config['interfaces']['lan']['if'] = renumber_vlan($config['interfaces']['lan']['if'], $_GET['id']);
+ $config['interfaces']['wan']['if'] = renumber_vlan($config['interfaces']['wan']['if'], $_GET['id']);
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+ $config['interfaces']['opt' . $i]['if'] = renumber_vlan($config['interfaces']['opt' . $i]['if'], $_GET['id']);
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_vlan.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: Assign network ports: VLANs");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Assign network ports: VLANs</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="interfaces_assign.php">Interface assignments</a></li>
+ <li class="tabact">VLANs</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="20%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">VLAN tag</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_vlans as $vlan): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($vlan['if']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($vlan['tag']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($vlan['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="interfaces_vlan_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="interfaces_vlan.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this VLAN?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3">&nbsp;</td>
+ <td class="list"> <a href="interfaces_vlan_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="list"><p class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Not all drivers/NICs support 802.1Q VLAN tagging properly. On cards that do not explicitly support it, VLAN tagging will still work, but the reduced MTU may cause problems. See the m0n0wall homepage for information on supported cards. </p>
+ </td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_vlan_edit.php b/usr/local/www/interfaces_vlan_edit.php
new file mode 100755
index 0000000..7932e2d
--- /dev/null
+++ b/usr/local/www/interfaces_vlan_edit.php
@@ -0,0 +1,146 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_vlan_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['vlans']['vlan']))
+ $config['vlans']['vlan'] = array();
+
+$a_vlans = &$config['vlans']['vlan'];
+
+$portlist = get_interface_list();
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_vlans[$id]) {
+ $pconfig['if'] = $a_vlans[$id]['if'];
+ $pconfig['tag'] = $a_vlans[$id]['tag'];
+ $pconfig['descr'] = $a_vlans[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "if tag");
+ $reqdfieldsn = explode(",", "Parent interface,VLAN tag");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['tag'] && (!is_numericint($_POST['tag']) || ($_POST['tag'] < '1') || ($_POST['tag'] > '4094'))) {
+ $input_errors[] = "The VLAN tag must be an integer between 1 and 4094.";
+ }
+
+ foreach ($a_vlans as $vlan) {
+ if (isset($id) && ($a_vlans[$id]) && ($a_vlans[$id] === $vlan))
+ continue;
+
+ if (($vlan['if'] == $_POST['if']) && ($vlan['tag'] == $_POST['tag'])) {
+ $input_errors[] = "A VLAN with the tag {$vlan['tag']} is already defined on this interface.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $vlan = array();
+ $vlan['if'] = $_POST['if'];
+ $vlan['tag'] = $_POST['tag'];
+ $vlan['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_vlans[$id])
+ $a_vlans[$id] = $vlan;
+ else
+ $a_vlans[] = $vlan;
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_vlan.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title><?=gentitle("Interfaces: Assign network ports: VLANs: Edit");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Assign network ports: VLANs: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="interfaces_vlan_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">Parent interface</td>
+ <td width="78%" class="vtable">
+ <select name="if" class="formfld">
+ <?php
+ foreach ($portlist as $ifn => $ifinfo): ?>
+ <option value="<?=$ifn;?>" <?php if ($ifn == $pconfig['if']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifn . " (" . $ifinfo['mac'] . ")");?>
+ </option>
+ <?php endforeach; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">VLAN tag </td>
+ <td class="vtable">
+ <input name="tag" type="text" class="formfld" id="tag" size="6" value="<?=htmlspecialchars($pconfig['tag']);?>">
+ <br>
+ <span class="vexpl">802.1Q VLAN tag (between 1 and 4094) </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_vlans[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_wan.php b/usr/local/www/interfaces_wan.php
new file mode 100755
index 0000000..b4cc30b
--- /dev/null
+++ b/usr/local/www/interfaces_wan.php
@@ -0,0 +1,630 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_wan.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$wancfg = &$config['interfaces']['wan'];
+$optcfg = &$config['interfaces']['wan'];
+
+$pconfig['username'] = $config['pppoe']['username'];
+$pconfig['password'] = $config['pppoe']['password'];
+$pconfig['provider'] = $config['pppoe']['provider'];
+$pconfig['pppoe_dialondemand'] = $config['pppoe']['ondemand'];
+$pconfig['pppoe_idletimeout'] = $config['pppoe']['timeout'];
+
+$pconfig['pptp_username'] = $config['pptp']['username'];
+$pconfig['pptp_password'] = $config['pptp']['password'];
+$pconfig['pptp_local'] = $config['pptp']['local'];
+$pconfig['pptp_subnet'] = $config['pptp']['subnet'];
+$pconfig['pptp_remote'] = $config['pptp']['remote'];
+$pconfig['pptp_dialondemand'] = $config['pptp']['ondemand'];
+$pconfig['pptp_idletimeout'] = $config['pptp']['timeout'];
+
+$pconfig['bigpond_username'] = $config['bigpond']['username'];
+$pconfig['bigpond_password'] = $config['bigpond']['password'];
+$pconfig['bigpond_authserver'] = $config['bigpond']['authserver'];
+$pconfig['bigpond_authdomain'] = $config['bigpond']['authdomain'];
+$pconfig['bigpond_minheartbeatinterval'] = $config['bigpond']['minheartbeatinterval'];
+
+$pconfig['dhcphostname'] = $wancfg['dhcphostname'];
+
+if ($wancfg['ipaddr'] == "dhcp") {
+ $pconfig['type'] = "DHCP";
+} else if ($wancfg['ipaddr'] == "pppoe") {
+ $pconfig['type'] = "PPPoE";
+} else if ($wancfg['ipaddr'] == "pptp") {
+ $pconfig['type'] = "PPTP";
+} else if ($wancfg['ipaddr'] == "bigpond") {
+ $pconfig['type'] = "BigPond";
+} else {
+ $pconfig['type'] = "Static";
+ $pconfig['ipaddr'] = $wancfg['ipaddr'];
+ $pconfig['subnet'] = $wancfg['subnet'];
+ $pconfig['gateway'] = $wancfg['gateway'];
+}
+
+$pconfig['blockpriv'] = isset($wancfg['blockpriv']);
+$pconfig['spoofmac'] = $wancfg['spoofmac'];
+$pconfig['mtu'] = $wancfg['mtu'];
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+ require("interfaces_wlan.inc");
+ wireless_config_init();
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['type'] == "Static") {
+ $reqdfields = explode(" ", "ipaddr subnet gateway");
+ $reqdfieldsn = explode(",", "IP address,Subnet bit count,Gateway");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPPoE") {
+ if ($_POST['pppoe_dialondemand']) {
+ $reqdfields = explode(" ", "username password pppoe_dialondemand pppoe_idletimeout");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "username password");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPTP") {
+ if ($_POST['pptp_dialondemand']) {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote pptp_dialondemand pptp_idletimeout");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "BigPond") {
+ $reqdfields = explode(" ", "bigpond_username bigpond_password");
+ $reqdfieldsn = explode(",", "BigPond username,BigPond password");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ }
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+ $input_errors[] = "A valid subnet bit count must be specified.";
+ }
+ if (($_POST['gateway'] && !is_ipaddr($_POST['gateway']))) {
+ $input_errors[] = "A valid gateway must be specified.";
+ }
+ if (($_POST['provider'] && !is_domain($_POST['provider']))) {
+ $input_errors[] = "The service name contains invalid characters.";
+ }
+ if ($_POST['pppoe_idletimeout'] && !is_numericint($_POST['pppoe_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['pptp_local'] && !is_ipaddr($_POST['pptp_local']))) {
+ $input_errors[] = "A valid PPTP local IP address must be specified.";
+ }
+ if (($_POST['pptp_subnet'] && !is_numeric($_POST['pptp_subnet']))) {
+ $input_errors[] = "A valid PPTP subnet bit count must be specified.";
+ }
+ if (($_POST['pptp_remote'] && !is_ipaddr($_POST['pptp_remote']))) {
+ $input_errors[] = "A valid PPTP remote IP address must be specified.";
+ }
+ if ($_POST['pptp_idletimeout'] && !is_numericint($_POST['pptp_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['bigpond_authserver'] && !is_domain($_POST['bigpond_authserver']))) {
+ $input_errors[] = "The authentication server name contains invalid characters.";
+ }
+ if (($_POST['bigpond_authdomain'] && !is_domain($_POST['bigpond_authdomain']))) {
+ $input_errors[] = "The authentication domain name contains invalid characters.";
+ }
+ if ($_POST['bigpond_minheartbeatinterval'] && !is_numericint($_POST['bigpond_minheartbeatinterval'])) {
+ $input_errors[] = "The minimum heartbeat interval must be an integer.";
+ }
+ if (($_POST['spoofmac'] && !is_macaddr($_POST['spoofmac']))) {
+ $input_errors[] = "A valid MAC address must be specified.";
+ }
+ if ($_POST['mtu'] && (($_POST['mtu'] < 576) || ($_POST['mtu'] > 1500))) {
+ $input_errors[] = "The MTU must be between 576 and 1500 bytes.";
+ }
+
+ /* Wireless interface? */
+ if (isset($optcfg['wireless'])) {
+ $wi_input_errors = wireless_config_post();
+ if ($wi_input_errors) {
+ $input_errors = array_merge($input_errors, $wi_input_errors);
+ }
+ }
+
+ if (!$input_errors) {
+
+ unset($wancfg['ipaddr']);
+ unset($wancfg['subnet']);
+ unset($wancfg['gateway']);
+ unset($wancfg['dhcphostname']);
+ unset($config['pppoe']['username']);
+ unset($config['pppoe']['password']);
+ unset($config['pppoe']['provider']);
+ unset($config['pppoe']['ondemand']);
+ unset($config['pppoe']['timeout']);
+ unset($config['pptp']['username']);
+ unset($config['pptp']['password']);
+ unset($config['pptp']['local']);
+ unset($config['pptp']['subnet']);
+ unset($config['pptp']['remote']);
+ unset($config['pptp']['ondemand']);
+ unset($config['pptp']['timeout']);
+ unset($config['bigpond']['username']);
+ unset($config['bigpond']['password']);
+ unset($config['bigpond']['authserver']);
+ unset($config['bigpond']['authdomain']);
+ unset($config['bigpond']['minheartbeatinterval']);
+
+ if ($_POST['type'] == "Static") {
+ $wancfg['ipaddr'] = $_POST['ipaddr'];
+ $wancfg['subnet'] = $_POST['subnet'];
+ $wancfg['gateway'] = $_POST['gateway'];
+ } else if ($_POST['type'] == "DHCP") {
+ $wancfg['ipaddr'] = "dhcp";
+ $wancfg['dhcphostname'] = $_POST['dhcphostname'];
+ } else if ($_POST['type'] == "PPPoE") {
+ $wancfg['ipaddr'] = "pppoe";
+ $config['pppoe']['username'] = $_POST['username'];
+ $config['pppoe']['password'] = $_POST['password'];
+ $config['pppoe']['provider'] = $_POST['provider'];
+ $config['pppoe']['ondemand'] = $_POST['pppoe_dialondemand'];
+ $config['pppoe']['timeout'] = $_POST['pppoe_idletimeout'];
+ } else if ($_POST['type'] == "PPTP") {
+ $wancfg['ipaddr'] = "pptp";
+ $config['pptp']['username'] = $_POST['pptp_username'];
+ $config['pptp']['password'] = $_POST['pptp_password'];
+ $config['pptp']['local'] = $_POST['pptp_local'];
+ $config['pptp']['subnet'] = $_POST['pptp_subnet'];
+ $config['pptp']['remote'] = $_POST['pptp_remote'];
+ $config['pptp']['ondemand'] = $_POST['pptp_dialondemand'];
+ $config['pptp']['timeout'] = $_POST['pptp_idletimeout'];
+ } else if ($_POST['type'] == "BigPond") {
+ $wancfg['ipaddr'] = "bigpond";
+ $config['bigpond']['username'] = $_POST['bigpond_username'];
+ $config['bigpond']['password'] = $_POST['bigpond_password'];
+ $config['bigpond']['authserver'] = $_POST['bigpond_authserver'];
+ $config['bigpond']['authdomain'] = $_POST['bigpond_authdomain'];
+ $config['bigpond']['minheartbeatinterval'] = $_POST['bigpond_minheartbeatinterval'];
+ }
+
+ $wancfg['blockpriv'] = $_POST['blockpriv'] ? true : false;
+ $wancfg['spoofmac'] = $_POST['spoofmac'];
+ $wancfg['mtu'] = $_POST['mtu'];
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = interfaces_wan_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: WAN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+}
+
+function enable_change_pptp(enable_change_pptp) {
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+}
+
+function type_change(enable_change,enable_change_pptp) {
+ switch (document.iform.type.selectedIndex) {
+ case 0:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 0;
+ document.iform.subnet.disabled = 0;
+ document.iform.gateway.disabled = 0;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 1:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 0;
+ break;
+ case 2:
+ document.iform.username.disabled = 0;
+ document.iform.password.disabled = 0;
+ document.iform.provider.disabled = 0;
+ document.iform.pppoe_dialondemand.disabled = 0;
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 3:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 0;
+ document.iform.pptp_password.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_subnet.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ document.iform.pptp_dialondemand.disabled = 0;
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 4:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.disabled = 1;
+ document.iform.ipaddr.disabled = 1;
+ document.iform.subnet.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.pptp_username.disabled = 1;
+ document.iform.pptp_password.disabled = 1;
+ document.iform.pptp_local.disabled = 1;
+ document.iform.pptp_subnet.disabled = 1;
+ document.iform.pptp_remote.disabled = 1;
+ document.iform.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 0;
+ document.iform.bigpond_password.disabled = 0;
+ document.iform.bigpond_authserver.disabled = 0;
+ document.iform.bigpond_authdomain.disabled = 0;
+ document.iform.bigpond_minheartbeatinterval.disabled = 0;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: WAN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="interfaces_wan.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="middle"><strong>Type</strong></td>
+ <td> <select name="type" class="formfld" id="type" onchange="type_change()">
+ <?php $opts = split(" ", "Static DHCP PPPoE PPTP BigPond");
+ foreach ($opts as $opt): ?>
+ <option <?php if ($opt == $pconfig['type']) echo "selected";?>>
+ <?=htmlspecialchars($opt);?>
+ </option>
+ <?php endforeach; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="4"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">General configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MAC address</td>
+ <td class="vtable"> <input name="spoofmac" type="text" class="formfld" id="spoofmac" size="30" value="<?=htmlspecialchars($pconfig['spoofmac']);?>">
+ <br>
+ This field can be used to modify (&quot;spoof&quot;) the MAC
+ address of the WAN interface<br>
+ (may be required with some cable connections)<br>
+ Enter a MAC address in the following format: xx:xx:xx:xx:xx:xx
+ or leave blank</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MTU</td>
+ <td class="vtable"> <input name="mtu" type="text" class="formfld" id="mtu" size="8" value="<?=htmlspecialchars($pconfig['mtu']);?>">
+ <br>
+ If you enter a value in this field, then MSS clamping for
+ TCP connections to the value entered above minus 40 (TCP/IP
+ header size) will be in effect. If you leave this field blank,
+ an MTU of 1492 bytes for PPPoE and 1500 bytes for all other
+ connection types will be assumed.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">Static IP configuration</td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">IP address</td>
+ <td class="vtable"> <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+ /
+ <select name="subnet" class="formfld" id="subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Gateway</td>
+ <td class="vtable"> <input name="gateway" type="text" class="formfld" id="gateway" size="20" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">DHCP client configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Hostname</td>
+ <td class="vtable"> <input name="dhcphostname" type="text" class="formfld" id="dhcphostname" size="40" value="<?=htmlspecialchars($pconfig['dhcphostname']);?>">
+ <br>
+ The value in this field is sent as the DHCP client identifier
+ and hostname when requesting a DHCP lease. Some ISPs may require
+ this (for client identification).</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">PPPoE configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="password" type="text" class="formfld" id="password" size="20" value="<?=htmlspecialchars($pconfig['password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Service name</td>
+ <td class="vtable"><input name="provider" type="text" class="formfld" id="provider" size="20" value="<?=htmlspecialchars($pconfig['provider']);?>">
+ <br> <span class="vexpl">Hint: this field can usually be left
+ empty</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pppoe_dialondemand" type="checkbox" id="pppoe_dialondemand" value="enable" <?php if ($pconfig['pppoe_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pppoe_idletimeout" type="text" class="formfld" id="pppoe_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pppoe_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">PPTP configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="pptp_username" type="text" class="formfld" id="pptp_username" size="20" value="<?=htmlspecialchars($pconfig['pptp_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="pptp_password" type="text" class="formfld" id="pptp_password" size="20" value="<?=htmlspecialchars($pconfig['pptp_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">Local IP address</td>
+ <td class="vtable"> <input name="pptp_local" type="text" class="formfld" id="pptp_local" size="20" value="<?=htmlspecialchars($pconfig['pptp_local']);?>">
+ /
+ <select name="pptp_subnet" class="formfld" id="pptp_subnet">
+ <?php for ($i = 31; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['pptp_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td width="100" valign="top" class="vncellreq">Remote IP address</td>
+ <td class="vtable"> <input name="pptp_remote" type="text" class="formfld" id="pptp_remote" size="20" value="<?=htmlspecialchars($pconfig['pptp_remote']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pptp_dialondemand" type="checkbox" id="pptp_dialondemand" value="enable" <?php if ($pconfig['pptp_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change_pptp(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pptp_idletimeout" type="text" class="formfld" id="pptp_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pptp_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">BigPond Cable configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="bigpond_username" type="text" class="formfld" id="bigpond_username" size="20" value="<?=htmlspecialchars($pconfig['bigpond_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="bigpond_password" type="text" class="formfld" id="bigpond_password" size="20" value="<?=htmlspecialchars($pconfig['bigpond_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication server</td>
+ <td class="vtable"><input name="bigpond_authserver" type="text" class="formfld" id="bigpond_authserver" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authserver']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the default (&quot;dce-server&quot;) is used. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication domain</td>
+ <td class="vtable"><input name="bigpond_authdomain" type="text" class="formfld" id="bigpond_authdomain" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authdomain']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the domain name assigned via DHCP will be used.<br>
+ <br>
+ Note: the BigPond client implicitly sets the &quot;Allow DNS server list to be overridden by DHCP/PPP on WAN&quot; on the System: General setup page. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Min. heartbeat interval</td>
+ <td class="vtable">
+ <input name="bigpond_minheartbeatinterval" type="text" class="formfld" id="bigpond_minheartbeatinterval" size="8" value="<?=htmlspecialchars($pconfig['bigpond_minheartbeatinterval']);?>">
+ seconds<br>
+ Setting this to a sensible value (e.g. 60 seconds) can protect against DoS attacks. </td>
+ </tr>
+ <?php /* Wireless interface? */
+ if (isset($optcfg['wireless']))
+ wireless_config_print();
+ ?>
+ <tr>
+ <td height="16" colspan="2" valign="top"></td>
+ </tr>
+ <tr>
+ <td valign="middle">&nbsp;</td>
+ <td class="vtable"> <input name="blockpriv" type="checkbox" id="blockpriv" value="yes" <?php if ($pconfig['blockpriv'] == "yes") echo "checked"; ?>>
+ <strong>Block private networks</strong><br>
+ When set, this option blocks traffic from IP addresses that
+ are reserved for private<br>
+ networks as per RFC 1918 (10/8, 172.16/12, 192.168/16) as
+ well as loopback addresses<br>
+ (127/8). You should generally leave this option turned on,
+ unless your WAN network<br>
+ lies in such a private address space, too.</td>
+ </tr>
+ <tr>
+ <td width="100" valign="top">&nbsp;</td>
+ <td> &nbsp;<br> <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change_pptp(true)&&enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_wlan.inc b/usr/local/www/interfaces_wlan.inc
new file mode 100755
index 0000000..8861ce6
--- /dev/null
+++ b/usr/local/www/interfaces_wlan.inc
@@ -0,0 +1,182 @@
+<?php
+/*
+ interfaces_wlan.inc
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+function wireless_config_init() {
+ global $optcfg, $pconfig;
+
+ $pconfig['mode'] = $optcfg['wireless']['mode'];
+ $pconfig['ssid'] = $optcfg['wireless']['ssid'];
+ $pconfig['stationname'] = $optcfg['wireless']['stationname'];
+ $pconfig['channel'] = $optcfg['wireless']['channel'];
+ $pconfig['wep_enable'] = isset($optcfg['wireless']['wep']['enable']);
+
+ if (is_array($optcfg['wireless']['wep']['key'])) {
+ $i = 1;
+ foreach ($optcfg['wireless']['wep']['key'] as $wepkey) {
+ $pconfig['key' . $i] = $wepkey['value'];
+ if (isset($wepkey['txkey']))
+ $pconfig['txkey'] = $i;
+ $i++;
+ }
+ if (!isset($wepkey['txkey']))
+ $pconfig['txkey'] = 1;
+ }
+}
+
+function wireless_config_post() {
+ global $optcfg, $pconfig;
+
+ unset($input_errors);
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "mode ssid channel");
+ $reqdfieldsn = explode(",", "Mode,SSID,Channel");
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (!$input_errors) {
+ /* bridge check (hostap only!) */
+ if ($pconfig['bridge'] && ($pconfig['mode'] != "hostap"))
+ $input_errors[] = "Bridging a wireless interface is only possible in hostap mode.";
+ }
+ }
+
+ if (!$input_errors) {
+
+ $optcfg['wireless']['mode'] = $_POST['mode'];
+ $optcfg['wireless']['ssid'] = $_POST['ssid'];
+ $optcfg['wireless']['stationname'] = $_POST['stationname'];
+ $optcfg['wireless']['channel'] = $_POST['channel'];
+ $optcfg['wireless']['wep']['enable'] = $_POST['wep_enable'] ? true : false;
+
+ $optcfg['wireless']['wep']['key'] = array();
+ for ($i = 1; $i <= 4; $i++) {
+ if ($_POST['key' . $i]) {
+ $newkey = array();
+ $newkey['value'] = $_POST['key' . $i];
+ if ($_POST['txkey'] == $i)
+ $newkey['txkey'] = true;
+ $optcfg['wireless']['wep']['key'][] = $newkey;
+ }
+ }
+ }
+
+ return $input_errors;
+}
+
+function wireless_config_print() {
+ global $optcfg, $pconfig;
+?>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">Wireless configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Mode</td>
+ <td class="vtable"> <select name="mode" class="formfld" id="mode">
+ <?php
+ $opts = array();
+ if (strstr($optcfg['if'], "wi"))
+ $opts[] = "hostap";
+ $opts[] = "BSS";
+ $opts[] = "IBSS";
+ foreach ($opts as $opt): ?>
+ <option <?php if ($opt == $pconfig['mode']) echo "selected";?>>
+ <?=htmlspecialchars($opt);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ Note: IBSS mode is sometimes also called &quot;ad-hoc&quot;
+ mode;<br>
+ BSS mode is also known as &quot;infrastructure&quot; mode</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">SSID</td>
+ <td class="vtable"><input name="ssid" type="text" class="formfld" id="ssid" size="20" value="<?=htmlspecialchars($pconfig['ssid']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Channel</td>
+ <td class="vtable"><select name="channel" class="formfld" id="channel">
+ <?php
+ for ($i = 0; $i <= 14; $i++): ?>
+ <option <?php if ($i == $pconfig['channel']) echo "selected";?>>
+ <? echo($i==0 ? "Auto" : $i) ?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Station name</td>
+ <td class="vtable"><input name="stationname" type="text" class="formfld" id="stationname" size="20" value="<?=htmlspecialchars($pconfig['stationname']);?>">
+ <br>
+ Hint: this field can usually be left blank</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">WEP</td>
+ <td class="vtable"> <input name="wep_enable" type="checkbox" id="wep_enable" value="yes" <?php if ($pconfig['wep_enable'] == "yes") echo "checked"; ?>>
+ <strong>Enable WEP</strong><br>
+ &nbsp; <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;TX key&nbsp;</td>
+ </tr>
+ <tr>
+ <td>Key 1:&nbsp;&nbsp;</td>
+ <td> <input name="key1" type="text" class="formfld" id="key1" size="30" value="<?=htmlspecialchars($pconfig['key1']);?>"></td>
+ <td align="center"> <input name="txkey" type="radio" value="1" <?php if ($pconfig['txkey'] == 1) echo "checked";?>>
+ </td>
+ </tr>
+ <tr>
+ <td>Key 2:&nbsp;&nbsp;</td>
+ <td> <input name="key2" type="text" class="formfld" id="key2" size="30" value="<?=htmlspecialchars($pconfig['key2']);?>"></td>
+ <td align="center"> <input name="txkey" type="radio" value="2" <?php if ($pconfig['txkey'] == 2) echo "checked";?>></td>
+ </tr>
+ <tr>
+ <td>Key 3:&nbsp;&nbsp;</td>
+ <td> <input name="key3" type="text" class="formfld" id="key3" size="30" value="<?=htmlspecialchars($pconfig['key3']);?>"></td>
+ <td align="center"> <input name="txkey" type="radio" value="3" <?php if ($pconfig['txkey'] == 3) echo "checked";?>></td>
+ </tr>
+ <tr>
+ <td>Key 4:&nbsp;&nbsp;</td>
+ <td> <input name="key4" type="text" class="formfld" id="key4" size="30" value="<?=htmlspecialchars($pconfig['key4']);?>"></td>
+ <td align="center"> <input name="txkey" type="radio" value="4" <?php if ($pconfig['txkey'] == 4) echo "checked";?>></td>
+ </tr>
+ </table>
+ <br>
+ 40 (64) bit keys may be entered as 5 ASCII characters or 10
+ hex digits preceded by '0x'.<br>
+ 104 (128) bit keys may be entered as 13 ASCII characters or
+ 26 hex digits preceded by '0x'.</td>
+ </tr>
+<?php } ?>
diff --git a/usr/local/www/license.php b/usr/local/www/license.php
new file mode 100755
index 0000000..2cb9fdf
--- /dev/null
+++ b/usr/local/www/license.php
@@ -0,0 +1,187 @@
+#!/usr/local/bin/php
+<?php require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("License");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">License</p>
+ <p><strong>m0n0wall is Copyright &copy; 2002-2004 by Manuel Kasper
+ (<a href="mailto:mk@neon1.net">mk@neon1.net</a>).<br>
+ All rights reserved.</strong></p>
+ <p> Redistribution and use in source and binary forms, with or without<br>
+ modification, are permitted provided that the following conditions
+ are met:<br>
+ <br>
+ 1. Redistributions of source code must retain the above copyright
+ notice,<br>
+ this list of conditions and the following disclaimer.<br>
+ <br>
+ 2. Redistributions in binary form must reproduce the above copyright<br>
+ notice, this list of conditions and the following disclaimer in
+ the<br>
+ documentation and/or other materials provided with the distribution.<br>
+ <br>
+ <strong>THIS SOFTWARE IS PROVIDED &quot;AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES,<br>
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY<br>
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ SHALL THE<br>
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY,<br>
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ OF<br>
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS<br>
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN<br>
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE<br>
+ POSSIBILITY OF SUCH DAMAGE</strong>.</p>
+ <hr size="1">
+ <p>The following persons have contributed code to m0n0wall:</p>
+ <p>Bob Zoller (<a href="mailto:bob@kludgebox.com">bob@kludgebox.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Diagnostics: Ping
+ function; WLAN channel auto-select; DNS forwarder</font></em><br>
+ <br>
+ Michael Mee (<a href="mailto:mikemee2002@pobox.com">mikemee2002@pobox.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Timezone and NTP
+ client support</font></em><br>
+ <br>
+ Magne Andreassen (<a href="mailto:magne.andreassen@bluezone.no">magne.andreassen@bluezone.no</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Remote syslog'ing;
+ some code bits for DHCP server on optional interfaces</font></em><br>
+ <br>
+ Rob Whyte (<a href="mailto:rob@g-labs.com">rob@g-labs.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Idea/code bits
+ for encrypted webGUI passwords; minimalized SNMP agent</font></em><br>
+ <br>
+ Petr Verner (<a href="mailto:verner@ipps.cz">verner@ipps.cz</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Advanced outbound
+ NAT: destination selection</font></em><br>
+ <br>
+ Bruce A. Mah (<a href="mailto:bmah@acm.org">bmah@acm.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Filtering bridge
+ patches </font></em><br>
+ <br>
+ Jim McBeath (<a href="mailto:monowall@j.jimmc.org">monowall@j.jimmc.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Filter rule patches
+ (ordering, block/pass, disabled); better status page;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;webGUI assign network ports page </font></em><br>
+ <br>
+ Chris Olive (<a href="mailto:chris@technologEase.com">chris@technologEase.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">enhanced &quot;execute
+ command&quot; page</font></em><br>
+ <br>
+ Pauline Middelink (<a href="mailto:middelink@polyware.nl">middelink@polyware.nl</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">DHCP client: send hostname patch</font></em><br>
+ <br>
+ Björn Pålsson (<a href="mailto:bjorn@networksab.com">bjorn@networksab.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">DHCP lease list page</font></em><br>
+ <br>
+ Peter Allgeyer (<a href="mailto:allgeyer@web.de">allgeyer@web.de</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">&quot;reject&quot; type filter rules; dial-on-demand</font></em><br>
+ <br>
+ Thierry Lechat (<a href="mailto:dev@lechat.org">dev@lechat.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">SVG-based traffic grapher</font></em><br>
+ <br>
+ Steven Honson (<a href="mailto:steven@honson.org">steven@honson.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">per-user IP address assignments for PPTP VPN</font></em><br>
+ <br>
+ Kurt Inge Smådal (<a href="mailto:kurt@emsp.no">kurt@emsp.no</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">NAT on optional interfaces</font></em><br>
+ <br>
+ Dinesh Nair (<a href="mailto:dinesh@alphaque.com">dinesh@alphaque.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">captive portal: pass-through MAC/IP addresses, RADIUS authentication &amp; accounting;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666"></font></em>HTTP server concurrency limit</font></em><br>
+ <br>
+ Justin Ellison (<a href="mailto:justin@techadvise.com">justin@techadvise.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">traffic shaper TOS matching; magic shaper; DHCP deny unknown clients;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;IPsec user FQDNs; DHCP relay</font></em><br>
+ <br>
+ Fred Wright (<a href="mailto:fw@well.com">fw@well.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">ipfilter window scaling fix; ipnat ICMP checksum adjustment fix; IPsec dead SA fixes</font></em><br>
+ <br>
+ Michael Hanselmann (<a href="mailto:m0n0@hansmi.ch">m0n0@hansmi.ch</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">IDE hard disk standby</font></em><br>
+ <br>
+ Audun Larsen (<a href="mailto:larsen@xqus.com">larsen@xqus.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">CPU/memory usage display</font></em><br>
+ <br>
+ Peter Curran (<a href="mailto:peter@closeconsultants.com">peter@closeconsultants.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">OpenVPN support</font></em></p>
+ <hr size="1">
+ <p>m0n0wall is based upon/includes various free software packages,
+ listed below.<br>
+ The author of m0n0wall would like to thank the authors of these
+ software packages for their efforts.</p>
+ <p>FreeBSD (<a href="http://www.freebsd.org" target="_blank">http://www.freebsd.org</a>)<br>
+ Copyright &copy; 1994-2003 FreeBSD, Inc. All rights reserved.<br>
+ <br>
+ This product includes PHP, freely available from <a href="http://www.php.net/" target="_blank">http://www.php.net</a>.<br>
+ Copyright &copy; 1999 - 2003 The PHP Group. All rights reserved.<br>
+ <br>
+ mini_httpd (<a href="http://www.acme.com/software/mini_httpd" target="_blank">http://www.acme.com/software/mini_httpd)</a><br>
+ Copyright &copy; 1999, 2000 by Jef Poskanzer &lt;jef@acme.com&gt;.
+ All rights reserved.<br>
+ <br>
+ ISC DHCP server (<a href="http://www.isc.org/products/DHCP/" target="_blank">http://www.isc.org/products/DHCP</a>)<br>
+ Copyright &copy; 1996-2003 Internet Software Consortium. All rights
+ reserved.<br>
+ <br>
+ ipfilter (<a href="http://www.ipfilter.org" target="_blank">http://www.ipfilter.org</a>)<br>
+ Copyright &copy; 1993-2002 by Darren Reed.<br>
+ <br>
+ MPD - Multi-link PPP daemon for FreeBSD (<a href="http://www.dellroad.org/mpd" target="_blank">http://www.dellroad.org/mpd</a>)<br>
+ Copyright &copy; 2003-2004, Archie L. Cobbs, Michael Bretterklieber, Alexander Motin<br>
+All rights reserved.<br>
+ <br>
+ ez-ipupdate (<a href="http://www.gusnet.cx/proj/ez-ipupdate/" target="_blank">http://www.gusnet.cx/proj/ez-ipupdate</a>)<br>
+ Copyright &copy; 1998-2001 Angus Mackay. All rights reserved.<br>
+ <br>
+ Circular log support for FreeBSD syslogd (<a href="http://software.wwwi.com/syslogd/" target="_blank">http://software.wwwi.com/syslogd</a>)<br>
+ Copyright &copy; 2001 Jeff Wheelhouse (jdw@wwwi.com)<br>
+ <br>
+ Dnsmasq - a DNS forwarder for NAT firewalls (<a href="http://www.thekelleys.org.uk" target="_blank">http://www.thekelleys.org.uk</a>)<br>
+ Copyright &copy; 2000-2003 Simon Kelley.<br>
+ <br>
+ Racoon (<a href="http://www.kame.net/racoon" target="_blank">http://www.kame.net/racoon</a>)<br>
+ Copyright &copy; 1995-2002 WIDE Project. All rights reserved.<br>
+ <br>
+ msntp (<a href="http://www.hpcf.cam.ac.uk/export" target="_blank">http://www.hpcf.cam.ac.uk/export</a>)<br>
+ Copyright &copy; 1996, 1997, 2000 N.M. Maclaren, University of Cambridge.
+ All rights reserved.<br>
+ <br>
+ UCD-SNMP (<a href="http://www.ece.ucdavis.edu/ucd-snmp" target="_blank">http://www.ece.ucdavis.edu/ucd-snmp</a>)<br>
+ Copyright &copy; 1989, 1991, 1992 by Carnegie Mellon University.<br>
+ Copyright &copy; 1996, 1998-2000 The Regents of the University of
+ California. All rights reserved.<br>
+ Copyright &copy; 2001-2002, Network Associates Technology, Inc.
+ All rights reserved.<br>
+ Portions of this code are copyright &copy; 2001-2002, Cambridge
+ Broadband Ltd. All rights reserved.<br>
+ <br>
+ choparp (<a href="http://choparp.sourceforge.net/" target="_blank">http://choparp.sourceforge.net</a>)<br>
+ Copyright &copy; 1997 Takamichi Tateoka (tree@mma.club.uec.ac.jp)<br>
+ Copyright
+&copy; 2002 Thomas Quinot (thomas@cuivre.fr.eu.org)<br>
+ <br>
+ BPALogin (<a href="http://bpalogin.sourceforge.net/" target="_blank">http://bpalogin.sourceforge.net</a>) - lightweight portable BIDS2 login client<br>
+ Copyright &copy; 2001-3 Shane Hyde, and others.<br>
+ <br>
+ php-radius (<a href="http://www.mavetju.org/programming/php.php" target="_blank">http://www.mavetju.org/programming/php.php</a>)<br>
+ Copyright 2000, 2001, 2002 by Edwin Groothuis. All rights reserved.<br>
+ This product includes software developed by Edwin Groothuis.<br>
+ <br>
+ wol (<a href="http://ahh.sourceforge.net/wol" target="_blank">http://ahh.sourceforge.net/wol</a>)<br>
+ Copyright &copy; 2000,2001,2002,2003,2004 Thomas Krennwallner &lt;krennwallner@aon.at&gt;
+ <?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/logobig.jpg b/usr/local/www/logobig.jpg
new file mode 100755
index 0000000..d3143e7
--- /dev/null
+++ b/usr/local/www/logobig.jpg
Binary files differ
diff --git a/usr/local/www/reboot.php b/usr/local/www/reboot.php
new file mode 100755
index 0000000..0dbd6d1
--- /dev/null
+++ b/usr/local/www/reboot.php
@@ -0,0 +1,66 @@
+#!/usr/local/bin/php
+<?php
+/*
+ reboot.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+ if ($_POST['Submit'] != " No ") {
+ system_reboot();
+ $rebootmsg = "The system is rebooting now. This may take one minute.";
+ } else {
+ header("Location: index.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Reboot system");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Reboot system</p>
+<?php if ($rebootmsg): echo print_info_box($rebootmsg); else: ?>
+ <form action="reboot.php" method="post">
+ <p><strong>Are you sure you want to reboot the system?</strong></p>
+ <p>
+ <input name="Submit" type="submit" class="formbtn" value=" Yes ">
+ <input name="Submit" type="submit" class="formbtn" value=" No ">
+ </p>
+ </form>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php
new file mode 100755
index 0000000..99fb152
--- /dev/null
+++ b/usr/local/www/services_captiveportal.php
@@ -0,0 +1,396 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal'])) {
+ $config['captiveportal'] = array();
+ $config['captiveportal']['page'] = array();
+ $config['captiveportal']['timeout'] = 60;
+}
+
+if ($_GET['act'] == "viewhtml") {
+ echo base64_decode($config['captiveportal']['page']['htmltext']);
+ exit;
+} else if ($_GET['act'] == "viewerrhtml") {
+ echo base64_decode($config['captiveportal']['page']['errtext']);
+ exit;
+}
+
+$pconfig['cinterface'] = $config['captiveportal']['interface'];
+$pconfig['timeout'] = $config['captiveportal']['timeout'];
+$pconfig['idletimeout'] = $config['captiveportal']['idletimeout'];
+$pconfig['enable'] = isset($config['captiveportal']['enable']);
+$pconfig['radacct_enable'] = isset($config['captiveportal']['radacct_enable']);
+$pconfig['httpslogin_enable'] = isset($config['captiveportal']['httpslogin']);
+$pconfig['httpsname'] = $config['captiveportal']['httpsname'];
+$pconfig['cert'] = base64_decode($config['captiveportal']['certificate']);
+$pconfig['key'] = base64_decode($config['captiveportal']['private-key']);
+$pconfig['logoutwin_enable'] = isset($config['captiveportal']['logoutwin_enable']);
+$pconfig['nomacfilter'] = isset($config['captiveportal']['nomacfilter']);
+$pconfig['redirurl'] = $config['captiveportal']['redirurl'];
+$pconfig['radiusip'] = $config['captiveportal']['radiusip'];
+$pconfig['radiusport'] = $config['captiveportal']['radiusport'];
+$pconfig['radiusacctport'] = $config['captiveportal']['radiusacctport'];
+$pconfig['radiuskey'] = $config['captiveportal']['radiuskey'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "cinterface");
+ $reqdfieldsn = explode(",", "Interface");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ /* make sure no interfaces are bridged */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $coptif = &$config['interfaces']['opt' . $i];
+ if (isset($coptif['enable']) && $coptif['bridge']) {
+ $input_errors[] = "The captive portal cannot be used when one or more interfaces are bridged.";
+ break;
+ }
+ }
+
+ if ($_POST['httpslogin_enable']) {
+ if (!$_POST['cert'] || !$_POST['key']) {
+ $input_errors[] = "Certificate and key must be specified for HTTPS login.";
+ } else {
+ if (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))
+ $input_errors[] = "This certificate does not appear to be valid.";
+ if (!strstr($_POST['key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "This key does not appear to be valid.";
+ }
+
+ if (!$_POST['httpsname'] || !is_domain($_POST['httpsname'])) {
+ $input_errors[] = "The HTTPS server name must be specified for HTTPS login.";
+ }
+ }
+ }
+
+ if ($_POST['timeout'] && (!is_numeric($_POST['timeout']) || ($_POST['timeout'] < 1))) {
+ $input_errors[] = "The timeout must be at least 1 minute.";
+ }
+ if ($_POST['idletimeout'] && (!is_numeric($_POST['idletimeout']) || ($_POST['idletimeout'] < 1))) {
+ $input_errors[] = "The idle timeout must be at least 1 minute.";
+ }
+ if (($_POST['radiusip'] && !is_ipaddr($_POST['radiusip']))) {
+ $input_errors[] = "A valid IP address must be specified. [".$_POST['radiusip']."]";
+ }
+ if (($_POST['radiusport'] && !is_port($_POST['radiusport']))) {
+ $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
+ }
+ if (($_POST['radiusacctport'] && !is_port($_POST['radiusacctport']))) {
+ $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
+ }
+
+ if (!$input_errors) {
+ $config['captiveportal']['interface'] = $_POST['cinterface'];
+ $config['captiveportal']['timeout'] = $_POST['timeout'];
+ $config['captiveportal']['idletimeout'] = $_POST['idletimeout'];
+ $config['captiveportal']['enable'] = $_POST['enable'] ? true : false;
+ $config['captiveportal']['radacct_enable'] = $_POST['radacct_enable'] ? true : false;
+ $config['captiveportal']['httpslogin'] = $_POST['httpslogin_enable'] ? true : false;
+ $config['captiveportal']['httpsname'] = $_POST['httpsname'];
+ $config['captiveportal']['certificate'] = base64_encode($_POST['cert']);
+ $config['captiveportal']['private-key'] = base64_encode($_POST['key']);
+ $config['captiveportal']['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
+ $config['captiveportal']['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
+ $config['captiveportal']['redirurl'] = $_POST['redirurl'];
+ $config['captiveportal']['radiusip'] = $_POST['radiusip'];
+ $config['captiveportal']['radiusport'] = $_POST['radiusport'];
+ $config['captiveportal']['radiusacctport'] = $_POST['radiusacctport'];
+ $config['captiveportal']['radiuskey'] = $_POST['radiuskey'];
+
+ /* file upload? */
+ if (is_uploaded_file($_FILES['htmlfile']['tmp_name']))
+ $config['captiveportal']['page']['htmltext'] = base64_encode(file_get_contents($_FILES['htmlfile']['tmp_name']));
+ if (is_uploaded_file($_FILES['errfile']['tmp_name']))
+ $config['captiveportal']['page']['errtext'] = base64_encode(file_get_contents($_FILES['errfile']['tmp_name']));
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = captiveportal_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function radacct_change() {
+ if (document.iform.radacct_enable.checked) {
+ document.iform.logoutwin_enable.checked = 1;
+ }
+}
+
+function enable_change(enable_change) {
+ if (document.iform.enable.checked || enable_change) {
+ document.iform.cinterface.disabled = 0;
+ document.iform.idletimeout.disabled = 0;
+ document.iform.timeout.disabled = 0;
+ document.iform.redirurl.disabled = 0;
+ document.iform.radiusip.disabled = 0;
+ document.iform.radiusport.disabled = 0;
+ document.iform.radiuskey.disabled = 0;
+ document.iform.radacct_enable.disabled = 0;
+ document.iform.httpslogin_enable.disabled = 0;
+ document.iform.httpsname.disabled = 0;
+ document.iform.cert.disabled = 0;
+ document.iform.key.disabled = 0;
+ document.iform.logoutwin_enable.disabled = 0;
+ document.iform.nomacfilter.disabled = 0;
+ document.iform.htmlfile.disabled = 0;
+ document.iform.errfile.disabled = 0;
+ } else {
+ document.iform.cinterface.disabled = 1;
+ document.iform.idletimeout.disabled = 1;
+ document.iform.timeout.disabled = 1;
+ document.iform.redirurl.disabled = 1;
+ document.iform.radiusip.disabled = 1;
+ document.iform.radiusport.disabled = 1;
+ document.iform.radiuskey.disabled = 1;
+ document.iform.radacct_enable.disabled = 1;
+ document.iform.httpslogin_enable.disabled = 1;
+ document.iform.httpsname.disabled = 1;
+ document.iform.cert.disabled = 1;
+ document.iform.key.disabled = 1;
+ document.iform.logoutwin_enable.disabled = 1;
+ document.iform.nomacfilter.disabled = 1;
+ document.iform.htmlfile.disabled = 1;
+ document.iform.errfile.disabled = 1;
+ }
+ if (enable_change && document.iform.radacct_enable.checked) {
+ document.iform.logoutwin_enable.checked = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form action="services_captiveportal.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Captive portal</li>
+ <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
+ <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable captive portal </strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="cinterface" class="formfld" id="cinterface">
+ <?php $interfaces = array('lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']))
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['cinterface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface to run the captive portal on.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="idletimeout" type="text" class="formfld" id="idletimeout" size="6" value="<?=htmlspecialchars($pconfig['idletimeout']);?>">
+minutes<br>
+Clients will be disconnected after this amount of inactivity. They may log in again immediately, though. Leave this field blank for no idle timeout.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Hard timeout</td>
+ <td width="78%" class="vtable">
+ <input name="timeout" type="text" class="formfld" id="timeout" size="6" value="<?=htmlspecialchars($pconfig['timeout']);?>">
+ minutes<br>
+ Clients will be disconnected after this amount of time, regardless of activity. They may log in again immediately, though. Leave this field blank for no hard timeout (not recommended unless an idle timeout is set).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Logout popup window</td>
+ <td width="78%" class="vtable">
+ <input name="logoutwin_enable" type="checkbox" class="formfld" id="logoutwin_enable" value="yes" <?php if($pconfig['logoutwin_enable']) echo "checked"; ?>>
+ <strong>Enable logout popup window</strong><br>
+ If enabled, a popup window will appear when clients are allowed through the captive portal. This allows clients to explicitly disconnect themselves before the idle or hard timeout occurs. When RADIUS accounting is enabled, this option is implied.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Redirection URL</td>
+ <td class="vtable">
+ <input name="redirurl" type="text" class="formfld" id="redirurl" size="60" value="<?=htmlspecialchars($pconfig['redirurl']);?>">
+ <br>
+If you provide a URL here, clients will be redirected to that URL instead of the one they initially tried
+to access after they've authenticated.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MAC filtering </td>
+ <td class="vtable">
+ <input name="nomacfilter" type="checkbox" class="formfld" id="nomacfilter" value="yes" <?php if ($pconfig['nomacfilter']) echo "checked"; ?>>
+ <strong>Disable MAC filtering</strong><br>
+ If this option is set, no attempts will be made to ensure that the MAC address of clients stays the same while they're logged in. This is required when the MAC address of cannot be determined (usually because there are routers between m0n0wall and the clients).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">RADIUS server</td>
+ <td width="78%" class="vtable">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>IP address:</td>
+ <td><input name="radiusip" type="text" class="formfld" id="radiusip" size="20" value="<?=htmlspecialchars($pconfig['radiusip']);?>"></td>
+ </tr><tr>
+ <td>Port:</td>
+ <td><input name="radiusport" type="text" class="formfld" id="radiusport" size="5" value="<?=htmlspecialchars($pconfig['radiusport']);?>"></td>
+ </tr><tr>
+ <td>Shared secret:&nbsp;&nbsp;</td>
+ <td><input name="radiuskey" type="text" class="formfld" id="radiuskey" size="16" value="<?=htmlspecialchars($pconfig['radiuskey']);?>"> </td>
+ </tr>
+ <tr>
+ <td>Accounting:&nbsp;&nbsp;</td>
+ <td><input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" <?php if($pconfig['radacct_enable']) echo "checked"; ?> onClick="radacct_change()"></td>
+ </tr>
+ <tr>
+ <td>Accounting port:&nbsp;&nbsp;</td>
+ <td><input name="radiusacctport" type="text" class="formfld" id="radiusacctport" size="5" value="<?=htmlspecialchars($pconfig['radiusacctport']);?>"></td>
+ </tr></table>
+ <br>
+ Enter the IP address and port of the RADIUS server which users of the captive portal have to authenticate against. Leave blank to disable RADIUS authentication. Leave port number blank to use the default port (1812). Leave the RADIUS shared secret blank to not use a RADIUS shared secret. RADIUS accounting packets will also be sent to the RADIUS server if accounting is enabled (default port is 1813).
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS login</td>
+ <td class="vtable">
+ <input name="httpslogin_enable" type="checkbox" class="formfld" id="httpslogin_enable" value="yes" <?php if($pconfig['httpslogin_enable']) echo "checked"; ?>>
+ <strong>Enable HTTPS login</strong><br>
+ If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. This option only applies when RADIUS authentication is used. A server name, certificate and matching private key must also be specified below.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS server name </td>
+ <td class="vtable">
+ <input name="httpsname" type="text" class="formfld" id="httpsname" size="30" value="<?=htmlspecialchars($pconfig['httpsname']);?>"><br>
+ This name will be used in the form action for the HTTPS POST and should match the Common Name (CN) in your certificate (otherwise, the client browser will most likely display a security warning). Make sure captive portal clients can resolve this name in DNS. </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS certificate</td>
+ <td class="vtable">
+ <textarea name="cert" cols="65" rows="7" id="cert" class="formpre"><?=htmlspecialchars($pconfig['cert']);?></textarea>
+ <br>
+ Paste a signed certificate in X.509 PEM format here.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS private key</td>
+ <td class="vtable">
+ <textarea name="key" cols="65" rows="7" id="key" class="formpre"><?=htmlspecialchars($pconfig['key']);?></textarea>
+ <br>
+ Paste an RSA private key in PEM format here.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Portal page contents</td>
+ <td width="78%" class="vtable">
+ <input type="file" name="htmlfile" class="formfld" id="htmlfile"><br>
+ <?php if ($config['captiveportal']['page']['htmltext']): ?>
+ <a href="?act=viewhtml" target="_blank">View current page</a>
+ <br>
+ <br>
+ <?php endif; ?>
+ Upload an HTML file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to &quot;$PORTAL_ACTION$&quot;)
+with a submit button (name=&quot;accept&quot;). Include the &quot;auth_user&quot; and &quot;auth_pass&quot; input elements if RADIUS authentication is enabled. If RADIUS is enabled and no &quot;auth_user&quot; is present, authentication will always fail. If RADIUS is not enabled, you can omit both these input elements.
+When using HTTPS login, a hidden field with name=&quot;redirurl&quot; and value=&quot;$PORTAL_REDIRURL$&quot; has to be included as well. Example code for the form:<br>
+ <br>
+ <tt>&lt;form method=&quot;post&quot; action=&quot;$PORTAL_ACTION$&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_user&quot; type=&quot;text&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_pass&quot; type=&quot;password&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;redirurl&quot; type=&quot;hidden&quot; value=&quot;$PORTAL_REDIRURL$&quot;&gt;<br>
+&nbsp;&nbsp;&nbsp;&lt;input name=&quot;accept&quot; type=&quot;submit&quot; value=&quot;Continue&quot;&gt;<br>
+ &lt;/form&gt;</tt></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Authentication<br>
+ error page<br>
+ contents</td>
+ <td class="vtable">
+ <input name="errfile" type="file" class="formfld" id="errfile"><br>
+ <?php if ($config['captiveportal']['page']['errtext']): ?>
+ <a href="?act=viewerrhtml" target="_blank">View current page</a>
+ <br>
+ <br>
+ <?php endif; ?>
+The contents of the HTML file that you upload here are displayed when a RADIUS authentication error occurs.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>Changing any settings on this page will disconnect all clients! Don't forget to enable the DHCP server on your captive portal interface! Make sure that the default/maximum DHCP lease time is higher than the timeout entered on this page. Also, the DNS forwarder needs to be enabled for DNS lookups by unauthenticated clients to work. </span></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_ip.php b/usr/local/www/services_captiveportal_ip.php
new file mode 100755
index 0000000..b3d406a
--- /dev/null
+++ b/usr/local/www/services_captiveportal_ip.php
@@ -0,0 +1,152 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_ip.php
+ 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['allowedip']))
+ $config['captiveportal']['allowedip'] = array();
+
+allowedips_sort();
+$a_allowedips = &$config['captiveportal']['allowedip'] ;
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ $retval = captiveportal_allowedip_configure();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_allowedipsdirty_path)) {
+ config_lock();
+ unlink($d_allowedipsdirty_path);
+ config_unlock();
+ }
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_allowedips[$_GET['id']]) {
+ unset($a_allowedips[$_GET['id']]);
+ write_config();
+ touch($d_allowedipsdirty_path);
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal: Allowed IP addresses</p>
+<form action="services_captiveportal_ip.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_allowedipsdirty_path)): ?><p>
+<?php print_info_box_np("The captive portal IP address configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="services_captiveportal.php">Captive portal</a></li>
+ <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
+ <li class="tabact">Allowed IP addresses</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">IP address</td>
+ <td width="60%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_allowedips as $ip): ?>
+ <tr>
+ <td class="listlr">
+ <?php if($ip['dir'] == "to")
+ echo "any <img src=\"in.gif\" width=\"11\" height=\"11\" align=\"absmiddle\">";
+ ?>
+ <?=strtolower($ip['ip']);?>
+ <?php if($ip['dir'] == "from")
+ echo "<img src=\"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="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_captiveportal_ip.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this address?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2">&nbsp;</td>
+ <td class="list"> <a href="services_captiveportal_ip_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><p class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Adding allowed IP addresses 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">any <img src="in.gif" width="11" height="11" align="absmiddle"> x.x.x.x </span></td>
+ <td><span class="vexpl">All connections <strong>to</strong> the IP address are allowed</span></td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td>x.x.x.x <span class="vexpl"><img src="in.gif" width="11" height="11" align="absmiddle"></span> any&nbsp;&nbsp;&nbsp; </td>
+ <td><span class="vexpl">All connections <strong>from</strong> the IP address 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_ip_edit.php b/usr/local/www/services_captiveportal_ip_edit.php
new file mode 100755
index 0000000..4b1cecf
--- /dev/null
+++ b/usr/local/www/services_captiveportal_ip_edit.php
@@ -0,0 +1,152 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_ip_edit.php
+ 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['allowedip']))
+ $config['captiveportal']['allowedip'] = array();
+
+allowedips_sort();
+$a_allowedips = &$config['captiveportal']['allowedip'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_allowedips[$id]) {
+ $pconfig['ip'] = $a_allowedips[$id]['ip'];
+ $pconfig['descr'] = $a_allowedips[$id]['descr'];
+ $pconfig['dir'] = $a_allowedips[$id]['dir'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ip dir");
+ $reqdfieldsn = explode(",", "Allowed IP address,Direction");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+ $input_errors[] = "A valid IP address must be specified. [".$_POST['ip']."]";
+ }
+
+ foreach ($a_allowedips as $ipent) {
+ if (isset($id) && ($a_allowedips[$id]) && ($a_allowedips[$id] === $ipent))
+ continue;
+
+ if (($ipent['dir'] == $_POST['dir']) && ($ipent['ip'] == $_POST['ip'])){
+ $input_errors[] = "[" . $_POST['ip'] . "] already allowed." ;
+ break ;
+ }
+ }
+
+ if (!$input_errors) {
+ $ip = array();
+ $ip['ip'] = $_POST['ip'];
+ $ip['descr'] = $_POST['descr'];
+ $ip['dir'] = $_POST['dir'];
+
+ if (isset($id) && $a_allowedips[$id])
+ $a_allowedips[$id] = $ip;
+ else
+ $a_allowedips[] = $ip;
+
+ write_config();
+
+ touch($d_allowedipsdirty_path) ;
+
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal: Edit allowed IP address");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal: Edit allowed IP address</p>
+<?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">Direction</td>
+ <td width="78%" class="vtable">
+ <select name="dir" class="formfld">
+ <?php
+ $dirs = explode(" ", "From 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">Use <em>From</em> to always allow an IP address through the captive portal (without authentication).
+ Use <em>To</em> to allow access from all clients (even non-authenticated ones) behind the portal to this IP address.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ip" type="text" class="formfld" id="ip" size="17" value="<?=htmlspecialchars($pconfig['ip']);?>">
+ <br>
+ <span class="vexpl">IP address</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_allowedips[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_mac.php b/usr/local/www/services_captiveportal_mac.php
new file mode 100755
index 0000000..d38c58c
--- /dev/null
+++ b/usr/local/www/services_captiveportal_mac.php
@@ -0,0 +1,133 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_mac.php
+ 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['passthrumac']))
+ $config['captiveportal']['passthrumac'] = array();
+
+passthrumacs_sort();
+$a_passthrumacs = &$config['captiveportal']['passthrumac'] ;
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ $retval = captiveportal_passthrumac_configure();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_passthrumacsdirty_path)) {
+ config_lock();
+ unlink($d_passthrumacsdirty_path);
+ config_unlock();
+ }
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_passthrumacs[$_GET['id']]) {
+ unset($a_passthrumacs[$_GET['id']]);
+ write_config();
+ touch($d_passthrumacsdirty_path);
+ header("Location: services_captiveportal_mac.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal: Pass-through MAC addresses</p>
+<form action="services_captiveportal_mac.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_passthrumacsdirty_path)): ?><p>
+<?php print_info_box_np("The captive portal MAC address configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="services_captiveportal.php">Captive portal</a></li>
+ <li class="tabact">Pass-through MAC</li>
+ <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">MAC address</td>
+ <td width="60%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_passthrumacs as $mac): ?>
+ <tr>
+ <td class="listlr">
+ <?=strtolower($mac['mac']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($mac['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_captiveportal_mac_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_captiveportal_mac.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this host?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2">&nbsp;</td>
+ <td class="list"> <a href="services_captiveportal_mac_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><span class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Adding MAC addresses as pass-through MACs allows them access through the captive portal automatically without being taken to the portal page. The pass-through MACs can change their IP addresses on the fly and upon the next access, the pass-through tables are changed accordingly. Pass-through MACs will however still be disconnected after the captive portal timeout period.</span></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_mac_edit.php b/usr/local/www/services_captiveportal_mac_edit.php
new file mode 100755
index 0000000..f763bac
--- /dev/null
+++ b/usr/local/www/services_captiveportal_mac_edit.php
@@ -0,0 +1,134 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_mac_edit.php
+ 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['passthrumac']))
+ $config['captiveportal']['passthrumac'] = array();
+
+passthrumacs_sort();
+$a_passthrumacs = &$config['captiveportal']['passthrumac'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_passthrumacs[$id]) {
+ $pconfig['mac'] = $a_passthrumacs[$id]['mac'];
+ $pconfig['descr'] = $a_passthrumacs[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "mac");
+ $reqdfieldsn = explode(",", "MAC address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+ $input_errors[] = "A valid MAC address must be specified. [".$_POST['mac']."]";
+ }
+
+ foreach ($a_passthrumacs as $macent) {
+ if (isset($id) && ($a_passthrumacs[$id]) && ($a_passthrumacs[$id] === $macent))
+ continue;
+
+ if ($macent['mac'] == $_POST['mac']){
+ $input_errors[] = "[" . $_POST['mac'] . "] already allowed." ;
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $mac = array();
+ $mac['mac'] = $_POST['mac'];
+ $mac['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_passthrumacs[$id])
+ $a_passthrumacs[$id] = $mac;
+ else
+ $a_passthrumacs[] = $mac;
+
+ write_config();
+
+ touch($d_passthrumacsdirty_path) ;
+
+ header("Location: services_captiveportal_mac.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal: Edit pass-through MAC address");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal: Edit pass-through MAC address</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_captiveportal_mac_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">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac" type="text" class="formfld" id="mac" size="17" value="<?=htmlspecialchars($pconfig['mac']);?>">
+ <br>
+ <span class="vexpl">MAC address (6 hex octets separated by colons)</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_passthrumacs[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dhcp.php b/usr/local/www/services_dhcp.php
new file mode 100755
index 0000000..5b35b6a
--- /dev/null
+++ b/usr/local/www/services_dhcp.php
@@ -0,0 +1,337 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dhcp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$if = $_GET['if'];
+if ($_POST['if'])
+ $if = $_POST['if'];
+
+$iflist = array("lan" => "LAN");
+
+for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $oc = $config['interfaces']['opt' . $i];
+
+ if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge'])) {
+ $iflist['opt' . $i] = $oc['descr'];
+ }
+}
+
+if (!$if || !isset($iflist[$if]))
+ $if = "lan";
+
+$pconfig['range_from'] = $config['dhcpd'][$if]['range']['from'];
+$pconfig['range_to'] = $config['dhcpd'][$if]['range']['to'];
+$pconfig['deftime'] = $config['dhcpd'][$if]['defaultleasetime'];
+$pconfig['maxtime'] = $config['dhcpd'][$if]['maxleasetime'];
+list($pconfig['wins1'],$pconfig['wins2']) = $config['dhcpd'][$if]['winsserver'];
+$pconfig['enable'] = isset($config['dhcpd'][$if]['enable']);
+$pconfig['denyunknown'] = isset($config['dhcpd'][$if]['denyunknown']);
+
+$ifcfg = $config['interfaces'][$if];
+
+if (!is_array($config['dhcpd'][$if]['staticmap'])) {
+ $config['dhcpd'][$if]['staticmap'] = array();
+}
+staticmaps_sort($if);
+$a_maps = &$config['dhcpd'][$if]['staticmap'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "range_from range_to");
+ $reqdfieldsn = explode(",", "Range begin,Range end");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['range_from'] && !is_ipaddr($_POST['range_from']))) {
+ $input_errors[] = "A valid range must be specified.";
+ }
+ if (($_POST['range_to'] && !is_ipaddr($_POST['range_to']))) {
+ $input_errors[] = "A valid range must be specified.";
+ }
+ if (($_POST['wins1'] && !is_ipaddr($_POST['wins1'])) || ($_POST['wins2'] && !is_ipaddr($_POST['wins2']))) {
+ $input_errors[] = "A valid IP address must be specified for the primary/secondary WINS server.";
+ }
+ if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
+ $input_errors[] = "The default lease time must be at least 60 seconds.";
+ }
+ if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
+ $input_errors[] = "The maximum lease time must be at least 60 seconds and higher than the default lease time.";
+ }
+
+ if (!$input_errors) {
+ /* make sure the range lies within the current subnet */
+ $subnet_start = (ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));
+ $subnet_end = (ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet'])));
+
+ if ((ip2long($_POST['range_from']) < $subnet_start) || (ip2long($_POST['range_from']) > $subnet_end) ||
+ (ip2long($_POST['range_to']) < $subnet_start) || (ip2long($_POST['range_to']) > $subnet_end)) {
+ $input_errors[] = "The specified range lies outside of the current subnet.";
+ }
+
+ if (ip2long($_POST['range_from']) > ip2long($_POST['range_to']))
+ $input_errors[] = "The range is invalid (first element higher than second element).";
+
+ /* make sure that the DHCP Relay isn't enabled on this interface */
+ if (isset($config['dhcrelay'][$if]['enable']))
+ $input_errors[] = "You must disable the DHCP relay on the {$iflist[$if]} interface before enabling the DHCP server.";
+ }
+ }
+
+ if (!$input_errors) {
+ $config['dhcpd'][$if]['range']['from'] = $_POST['range_from'];
+ $config['dhcpd'][$if]['range']['to'] = $_POST['range_to'];
+ $config['dhcpd'][$if]['defaultleasetime'] = $_POST['deftime'];
+ $config['dhcpd'][$if]['maxleasetime'] = $_POST['maxtime'];
+ $config['dhcpd'][$if]['enable'] = $_POST['enable'] ? true : false;
+ $config['dhcpd'][$if]['denyunknown'] = $_POST['denyunknown'] ? true : false;
+
+ unset($config['dhcpd'][$if]['winsserver']);
+ if ($_POST['wins1'])
+ $config['dhcpd'][$if]['winsserver'][] = $_POST['wins1'];
+ if ($_POST['wins2'])
+ $config['dhcpd'][$if]['winsserver'][] = $_POST['wins2'];
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_dhcpd_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_staticmapsdirty_path))
+ unlink($d_staticmapsdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_maps[$_GET['id']]) {
+ unset($a_maps[$_GET['id']]);
+ write_config();
+ touch($d_staticmapsdirty_path);
+ header("Location: services_dhcp.php?if={$if}");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DHCP server");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+ if (document.iform.enable.checked || enable_over) {
+ document.iform.range_from.disabled = 0;
+ document.iform.range_to.disabled = 0;
+ document.iform.wins1.disabled = 0;
+ document.iform.wins2.disabled = 0;
+ document.iform.deftime.disabled = 0;
+ document.iform.maxtime.disabled = 0;
+ } else {
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ document.iform.wins1.disabled = 1;
+ document.iform.wins2.disabled = 1;
+ document.iform.deftime.disabled = 1;
+ document.iform.maxtime.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP server</p>
+<form action="services_dhcp.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_staticmapsdirty_path)): ?><p>
+<?php print_info_box_np("The static mapping configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+<?php foreach ($iflist as $ifent => $ifname):
+ if ($ifent == $if): ?>
+ <li class="tabact"><?=htmlspecialchars($ifname);?></li>
+<?php else: ?>
+ <li class="tabinact"><a href="services_dhcp.php?if=<?=$ifent;?>"><?=htmlspecialchars($ifname);?></a></li>
+<?php endif; ?>
+<?php endforeach; ?>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable DHCP server on
+ <?=htmlspecialchars($iflist[$if]);?>
+ interface</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="denyunknown" type="checkbox" value="yes" <?php if ($pconfig['denyunknown']) echo "checked"; ?>>
+ <strong>Deny unknown clients</strong><br>
+ If this is checked, only the clients defined below will get DHCP leases from this server. </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Subnet</td>
+ <td width="78%" class="vtable">
+ <?=gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Subnet
+ mask</td>
+ <td width="78%" class="vtable">
+ <?=gen_subnet_mask($ifcfg['subnet']);?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Available
+ range</td>
+ <td width="78%" class="vtable">
+ <?=long2ip(ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));?>
+ -
+ <?=long2ip(ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet']))); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Range</td>
+ <td width="78%" class="vtable">
+ <input name="range_from" type="text" class="formfld" id="range_from" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>">
+ &nbsp;to&nbsp; <input name="range_to" type="text" class="formfld" id="range_to" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>"></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">WINS servers</td>
+ <td width="78%" class="vtable">
+ <input name="wins1" type="text" class="formfld" id="wins1" size="20" value="<?=htmlspecialchars($pconfig['wins1']);?>"><br>
+ <input name="wins2" type="text" class="formfld" id="wins2" size="20" value="<?=htmlspecialchars($pconfig['wins2']);?>"></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Default lease
+ time</td>
+ <td width="78%" class="vtable">
+ <input name="deftime" type="text" class="formfld" id="deftime" size="10" value="<?=htmlspecialchars($pconfig['deftime']);?>">
+ seconds<br>
+ This is used for clients that do not ask for a specific
+ expiration time.<br>
+ The default is 7200 seconds.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Maximum lease
+ time</td>
+ <td width="78%" class="vtable">
+ <input name="maxtime" type="text" class="formfld" id="maxtime" size="10" value="<?=htmlspecialchars($pconfig['maxtime']);?>">
+ seconds<br>
+ This is the maximum lease time for clients that ask
+ for a specific expiration time.<br>
+ The default is 86400 seconds.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="if" type="hidden" value="<?=$if;?>">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>The DNS servers entered in <a href="system.php">System:
+ General setup</a> (or the <a href="services_dnsmasq.php">DNS
+ forwarder</a>, if enabled) </span><span class="vexpl">will
+ be assigned to clients by the DHCP server.<br>
+ <br>
+ The DHCP lease table can be viewed on the <a href="diag_dhcp_leases.php">Diagnostics:
+ DHCP leases</a> page.<br>
+ </span></p></td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="35%" class="listhdrr">MAC address </td>
+ <td width="20%" class="listhdrr">IP address</td>
+ <td width="35%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_maps as $mapent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($mapent['mac']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($mapent['ipaddr']);?>&nbsp;
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($mapent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_dhcp_edit.php?if=<?=$if;?>&id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_dhcp.php?if=<?=$if;?>&act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3"></td>
+ <td class="list"> <a href="services_dhcp_edit.php?if=<?=$if;?>"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dhcp_edit.php b/usr/local/www/services_dhcp_edit.php
new file mode 100755
index 0000000..80f64a9
--- /dev/null
+++ b/usr/local/www/services_dhcp_edit.php
@@ -0,0 +1,176 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dhcp_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$if = $_GET['if'];
+if ($_POST['if'])
+ $if = $_POST['if'];
+
+if (!$if) {
+ header("Location: services_dhcp.php");
+ exit;
+}
+
+if (!is_array($config['dhcpd'][$if]['staticmap'])) {
+ $config['dhcpd'][$if]['staticmap'] = array();
+}
+staticmaps_sort($if);
+$a_maps = &$config['dhcpd'][$if]['staticmap'];
+$ifcfg = &$config['interfaces'][$if];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_maps[$id]) {
+ $pconfig['mac'] = $a_maps[$id]['mac'];
+ $pconfig['ipaddr'] = $a_maps[$id]['ipaddr'];
+ $pconfig['descr'] = $a_maps[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "mac");
+ $reqdfieldsn = explode(",", "MAC address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+ if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+ $input_errors[] = "A valid MAC address must be specified.";
+ }
+
+ /* check for overlaps */
+ foreach ($a_maps as $mapent) {
+ if (isset($id) && ($a_maps[$id]) && ($a_maps[$id] === $mapent))
+ continue;
+
+ if (($mapent['mac'] == $_POST['mac']) || ($_POST['ipaddr'] && (ip2long($mapent['ipaddr']) == ip2long($_POST['ipaddr'])))) {
+ $input_errors[] = "This IP or MAC address already exists.";
+ break;
+ }
+ }
+
+ /* make sure it's not within the dynamic subnet */
+ if ($_POST['ipaddr']) {
+ $dynsubnet_start = ip2long($config['dhcpd'][$if]['range']['from']);
+ $dynsubnet_end = ip2long($config['dhcpd'][$if]['range']['to']);
+ $lansubnet_start = (ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));
+ $lansubnet_end = (ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet'])));
+
+ if ((ip2long($_POST['ipaddr']) >= $dynsubnet_start) &&
+ (ip2long($_POST['ipaddr']) <= $dynsubnet_end)) {
+ $input_errors[] = "Static IP addresses may not lie within the dynamic client range.";
+ }
+ if ((ip2long($_POST['ipaddr']) < $lansubnet_start) ||
+ (ip2long($_POST['ipaddr']) > $lansubnet_end)) {
+ $input_errors[] = "The IP address must lie in the {$ifcfg['descr']} subnet.";
+ }
+ }
+
+ if (!$input_errors) {
+ $mapent = array();
+ $mapent['mac'] = $_POST['mac'];
+ $mapent['ipaddr'] = $_POST['ipaddr'];
+ $mapent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_maps[$id])
+ $a_maps[$id] = $mapent;
+ else
+ $a_maps[] = $mapent;
+
+ touch($d_staticmapsdirty_path);
+
+ write_config();
+
+ header("Location: services_dhcp.php?if={$if}");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DHCP: Edit static mapping");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP: Edit static mapping</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_dhcp_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">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac" type="text" class="formfld" id="mac" size="30" value="<?=htmlspecialchars($pconfig['mac']);?>">
+ <br>
+ <span class="vexpl">Enter a MAC address in the following format:
+ xx:xx:xx:xx:xx:xx</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+ <br>
+ If no IP address is given, one will be dynamically allocated from the pool.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_maps[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ <input name="if" type="hidden" value="<?=$if;?>">
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dhcp_relay.php b/usr/local/www/services_dhcp_relay.php
new file mode 100755
index 0000000..674077c
--- /dev/null
+++ b/usr/local/www/services_dhcp_relay.php
@@ -0,0 +1,229 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dhcp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Justin Ellison <justin@techadvise.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.
+*/
+
+function get_wan_dhcp_server() {
+ global $config, $g;
+ $dhclientfn = $g['vardb_path'] . "/dhclient.leases";
+ $leases = file($dhclientfn);
+ /* Start at the end, work backwards finding the latest lease for the WAN */
+ for ($i = (count($leases)-1); $i >= 0; $i--) {
+ if ($leases[$i] == "}") {
+ unset($iface);
+ unset($dhcpserver);
+ } elseif (strstr($leases[$i],"interface")) {
+ preg_match("/\s+interface \"(\w+)\";/",$leases[$i],$iface);
+ } elseif (strstr($leases[$i],"dhcp-server-identifier")) {
+ preg_match("/\s+dhcp-server-identifier (\d+\.\d+\.\d+\.\d+);/",$leases[$i],$dhcpserver);
+ }
+ if ($iface == $config['interfaces']['wan'] && isset($dhcpserver)) {
+ break;
+ }
+ }
+ return $dhcpserver[1];
+}
+
+
+require("guiconfig.inc");
+
+$if = $_GET['if'];
+if ($_POST['if'])
+ $if = $_POST['if'];
+
+$iflist = array("lan" => "LAN");
+
+for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $oc = $config['interfaces']['opt' . $i];
+
+ if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge'])) {
+ $iflist['opt' . $i] = $oc['descr'];
+ }
+}
+
+if (!$if || !isset($iflist[$if]))
+ $if = "lan";
+
+$pconfig['enable'] = isset($config['dhcrelay'][$if]['enable']);
+$pconfig['server'] = $config['dhcrelay']['server'];
+$pconfig['proxydhcp'] = isset($config['dhcrelay']['proxydhcp']);
+$pconfig['agentoption'] = isset($config['dhcrelay']['agentoption']);
+
+$ifcfg = $config['interfaces'][$if];
+
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ if (isset($_POST['proxydhcp']))
+ $_POST['server'] = get_wan_dhcp_server();
+ $reqdfields = explode(" ", "server");
+ $reqdfieldsn = explode(",", "Destination Server");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['server'] && !is_ipaddr($_POST['server'])))
+ $input_errors[] = "A valid Destination Server IP address must be specified.";
+
+ if (!$input_errors) {
+ /* make sure that the DHCP server isn't enabled on this interface */
+ if (isset($config['dhcpd'][$if]['enable']))
+ $input_errors[] = "You must disable the DHCP server on the {$iflist[$if]} interface before enabling the DHCP Relay.";
+ /* make sure that the DHCP server isn't running on any of the implied interfaces */
+ foreach ($config['interfaces'] as $ifname => $ifcfg) {
+ $subnet = $ifcfg['ipaddr'] . "/" . $ifcfg['subnet'];
+ if (ip_in_subnet($_POST['server'],$subnet))
+ $destif = $ifname;
+ }
+ if (!isset($destif))
+ $destif = "wan";
+ if (isset($config['dhcpd'][$destif]['enable']))
+ $input_errors[] = "You must disable the DHCP server on the {$destif} interface before enabling the DHCP Relay.";
+
+ /* if proxydhcp is selected, make sure DHCP is enabled on WAN */
+ if (isset($config['dhcrelay']['proxydhcp']) && $config['interfaces']['wan']['ipaddr'] != "dhcp")
+ $input_errors[] = "You must have DHCP active on the WAN interface before enabling the DHCP proxy option.";
+ }
+ }
+
+ if (!$input_errors) {
+ $config['dhcrelay']['agentoption'] = $_POST['agentoption'] ? true : false;
+ $config['dhcrelay']['proxydhcp'] = $_POST['proxydhcp'] ? true : false;
+ $config['dhcrelay']['server'] = $_POST['server'];
+ $config['dhcrelay'][$if]['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_dhcrelay_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DHCP relay");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+ if (document.iform.enable.checked || enable_over) {
+ document.iform.server.disabled = 0;
+ document.iform.agentoption.disabled = 0;
+ document.iform.proxydhcp.disabled = 0;
+ } else {
+ document.iform.server.disabled = 1;
+ document.iform.agentoption.disabled = 1;
+ document.iform.proxydhcp.disabled = 1;
+ }
+ if (document.iform.proxydhcp.checked) {
+ document.iform.server.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP relay</p>
+<form action="services_dhcp_relay.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+<?php foreach ($iflist as $ifent => $ifname):
+ if ($ifent == $if): ?>
+ <li class="tabact"><?=htmlspecialchars($ifname);?></li>
+<?php else: ?>
+ <li class="tabinact"><a href="services_dhcp_relay.php?if=<?=$ifent;?>"><?=htmlspecialchars($ifname);?></a></li>
+<?php endif; ?>
+<?php endforeach; ?>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable DHCP relay on
+ <?=htmlspecialchars($iflist[$if]);?>
+ interface</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="agentoption" type="checkbox" value="yes" <?php if ($pconfig['agentoption']) echo "checked"; ?>>
+ <strong>Append circuit ID and agent ID to requests</strong><br>
+ If this is checked, the DHCP relay will append the circuit ID (m0n0wall interface number) and the agent ID to the DHCP request.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Destination server</td>
+ <td width="78%" class="vtable">
+ <input name="proxydhcp" type="checkbox" value="yes" <?php if ($pconfig['proxydhcp']) echo "checked"; ?> onClick="enable_change(false)"> Proxy requests to DHCP server on WAN subnet
+ <br><br><input name="server" type="text" class="formfld" id="server" size="20" value="<?=htmlspecialchars($pconfig['server']);?>">
+ <br>
+ This is the IP address of the server to which the DHCP packet is relayed. Select "Proxy requests to DHCP server on WAN subnet" to relay DHCP packets to the server that was used on the WAN interface.
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="if" type="hidden" value="<?=$if;?>">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dnsmasq.php b/usr/local/www/services_dnsmasq.php
new file mode 100755
index 0000000..c69bb85
--- /dev/null
+++ b/usr/local/www/services_dnsmasq.php
@@ -0,0 +1,168 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dnsmasq.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Bob Zoller <bob@kludgebox.com> and 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.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['enable'] = isset($config['dnsmasq']['enable']);
+$pconfig['regdhcp'] = isset($config['dnsmasq']['regdhcp']);
+
+if (!is_array($config['dnsmasq']['hosts'])) {
+ $config['dnsmasq']['hosts'] = array();
+}
+hosts_sort();
+$a_hosts = &$config['dnsmasq']['hosts'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ $config['dnsmasq']['enable'] = ($_POST['enable']) ? true : false;
+ $config['dnsmasq']['regdhcp'] = ($_POST['regdhcp']) ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_dnsmasq_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_hostsdirty_path))
+ unlink($d_hostsdirty_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_hosts[$_GET['id']]) {
+ unset($a_hosts[$_GET['id']]);
+ write_config();
+ touch($d_hostsdirty_path);
+ header("Location: services_dnsmasq.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DNS forwarder");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DNS forwarder</p>
+<form action="services_dnsmasq.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_hostsdirty_path)): ?><p>
+<?php print_info_box_np("The DNS forwarder configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td class="vtable"><p>
+ <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+ <strong>Enable DNS forwarder<br>
+ </strong></p></td>
+ </tr>
+ <tr>
+ <td class="vtable"><p>
+ <input name="regdhcp" type="checkbox" id="regdhcp" value="yes" <?php if ($pconfig['regdhcp'] == "yes") echo "checked";?>>
+ <strong>Register DHCP leases in DNS forwarder<br>
+ </strong>If this option is set, then machines that specify
+ their hostname when requesting a DHCP lease will be registered
+ in the DNS forwarder, so that their name can be resolved.
+ You should also set the domain in <a href="system.php">System:
+ General setup</a> to the proper value.</p>
+ </td>
+ </tr>
+ <tr>
+ <td> <input name="submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ <tr>
+ <td><p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>If the DNS forwarder is enabled, the DHCP
+ service (if enabled) will automatically serve the LAN IP
+ address as a DNS server to DHCP clients so they will use
+ the forwarder. The DNS forwarder will use the DNS servers
+ entered in <a href="system.php">System: General setup</a>
+ or those obtained via DHCP or PPP on WAN if the &quot;Allow
+ DNS server list to be overridden by DHCP/PPP on WAN&quot;</span>
+ is checked. If you don't use that option (or if you use
+ a static IP address on WAN), you must manually specify at
+ least one DNS server on the <a href="system.php">System:
+ General setup</a> page.<br>
+ <br>
+ You may enter records that override the results from the
+ forwarders below.</p></td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="20%" class="listhdrr">Host</td>
+ <td width="25%" class="listhdrr">Domain</td>
+ <td width="20%" class="listhdrr">IP</td>
+ <td width="25%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_hosts as $hostent): ?>
+ <tr>
+ <td class="listlr">
+ <?=strtolower($hostent['host']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=strtolower($hostent['domain']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=$hostent['ip'];?>&nbsp;
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($hostent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_dnsmasq_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_dnsmasq.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this host?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4"></td>
+ <td class="list"> <a href="services_dnsmasq_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dnsmasq_edit.php b/usr/local/www/services_dnsmasq_edit.php
new file mode 100755
index 0000000..810a415
--- /dev/null
+++ b/usr/local/www/services_dnsmasq_edit.php
@@ -0,0 +1,160 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dnsmasq_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Bob Zoller <bob@kludgebox.com> and 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['dnsmasq']['hosts'])) {
+ $config['dnsmasq']['hosts'] = array();
+}
+hosts_sort();
+$a_hosts = &$config['dnsmasq']['hosts'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_hosts[$id]) {
+ $pconfig['host'] = $a_hosts[$id]['host'];
+ $pconfig['domain'] = $a_hosts[$id]['domain'];
+ $pconfig['ip'] = $a_hosts[$id]['ip'];
+ $pconfig['descr'] = $a_hosts[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "domain ip");
+ $reqdfieldsn = explode(",", "Domain,IP address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['host'] && !is_hostname($_POST['host']))) {
+ $input_errors[] = "A valid host must be specified.";
+ }
+ if (($_POST['domain'] && !is_domain($_POST['domain']))) {
+ $input_errors[] = "A valid domain must be specified.";
+ }
+ if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+ $input_errors[] = "A valid IP address must be specified.";
+ }
+
+ /* check for overlaps */
+ foreach ($a_hosts as $hostent) {
+ if (isset($id) && ($a_hosts[$id]) && ($a_hosts[$id] === $hostent))
+ continue;
+
+ if (($hostent['host'] == $_POST['host']) && ($hostent['domain'] == $_POST['domain'])) {
+ $input_errors[] = "This host/domain already exists.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $hostent = array();
+ $hostent['host'] = $_POST['host'];
+ $hostent['domain'] = $_POST['domain'];
+ $hostent['ip'] = $_POST['ip'];
+ $hostent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_hosts[$id])
+ $a_hosts[$id] = $hostent;
+ else
+ $a_hosts[] = $hostent;
+
+ touch($d_hostsdirty_path);
+
+ write_config();
+
+ header("Location: services_dnsmasq.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DNS forwarder: Edit host");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DNS forwarder: Edit host</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_dnsmasq_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncell">Host</td>
+ <td width="78%" class="vtable">
+ <input name="host" type="text" class="formfld" id="host" size="40" value="<?=htmlspecialchars($pconfig['host']);?>">
+ <br> <span class="vexpl">Name of the host, without
+ domain part<br>
+ e.g. <em>myhost</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Domain</td>
+ <td width="78%" class="vtable">
+ <input name="domain" type="text" class="formfld" id="domain" size="40" value="<?=htmlspecialchars($pconfig['domain']);?>">
+ <br> <span class="vexpl">Domain of the host<br>
+ e.g. <em>blah.com</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ip" type="text" class="formfld" id="ip" size="40" value="<?=htmlspecialchars($pconfig['ip']);?>">
+ <br> <span class="vexpl">IP address of the host<br>
+ e.g. <em>192.168.100.100</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_hosts[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dyndns.php b/usr/local/www/services_dyndns.php
new file mode 100755
index 0000000..e4864e6
--- /dev/null
+++ b/usr/local/www/services_dyndns.php
@@ -0,0 +1,197 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dyndns.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['username'] = $config['dyndns']['username'];
+$pconfig['password'] = $config['dyndns']['password'];
+$pconfig['host'] = $config['dyndns']['host'];
+$pconfig['mx'] = $config['dyndns']['mx'];
+$pconfig['type'] = $config['dyndns']['type'];
+$pconfig['enable'] = isset($config['dyndns']['enable']);
+$pconfig['wildcard'] = isset($config['dyndns']['wildcard']);
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "host username password type");
+ $reqdfieldsn = explode(",", "Hostname,Username,Password,Service type");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ }
+
+ if (($_POST['host'] && !is_domain($_POST['host']))) {
+ $input_errors[] = "The host name contains invalid characters.";
+ }
+ if (($_POST['mx'] && !is_domain($_POST['mx']))) {
+ $input_errors[] = "The MX contains invalid characters.";
+ }
+ if (($_POST['username'] && !is_dyndns_username($_POST['username']))) {
+ $input_errors[] = "The username contains invalid characters.";
+ }
+
+ if (!$input_errors) {
+ $config['dyndns']['type'] = $_POST['type'];
+ $config['dyndns']['username'] = $_POST['username'];
+ $config['dyndns']['password'] = $_POST['password'];
+ $config['dyndns']['host'] = $_POST['host'];
+ $config['dyndns']['mx'] = $_POST['mx'];
+ $config['dyndns']['wildcard'] = $_POST['wildcard'] ? true : false;
+ $config['dyndns']['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ /* nuke the cache file */
+ config_lock();
+ services_dyndns_reset();
+ $retval = services_dyndns_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Dynamic DNS client");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+ if (document.iform.enable.checked || enable_change) {
+ document.iform.host.disabled = 0;
+ document.iform.mx.disabled = 0;
+ document.iform.type.disabled = 0;
+ document.iform.wildcard.disabled = 0;
+ document.iform.username.disabled = 0;
+ document.iform.password.disabled = 0;
+ } else {
+ document.iform.host.disabled = 1;
+ document.iform.mx.disabled = 1;
+ document.iform.type.disabled = 1;
+ document.iform.wildcard.disabled = 1;
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Dynamic DNS client</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="services_dyndns.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable Dynamic DNS client</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Service type</td>
+ <td width="78%" class="vtable">
+<select name="type" class="formfld" id="type">
+ <?php $types = explode(",", "DynDNS,DHS,ODS,DyNS,HN.ORG,ZoneEdit,GNUDip,DynDNS (static),DynDNS (custom),easyDNS,EZ-IP,TZO");
+ $vals = explode(" ", "dyndns dhs ods dyns hn zoneedit gnudip dyndns-static dyndns-custom easydns ezip tzo");
+ $j = 0; for ($j = 0; $j < count($vals); $j++): ?>
+ <option value="<?=$vals[$j];?>" <?php if ($vals[$j] == $pconfig['type']) echo "selected";?>>
+ <?=htmlspecialchars($types[$j]);?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hostname</td>
+ <td width="78%" class="vtable">
+ <input name="host" type="text" class="formfld" id="host" size="30" value="<?=htmlspecialchars($pconfig['host']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">MX</td>
+ <td width="78%" class="vtable">
+ <input name="mx" type="text" class="formfld" id="mx" size="30" value="<?=htmlspecialchars($pconfig['mx']);?>">
+ <br>
+ Set this option only if you need a special MX record. Not
+ all services support this.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Wildcards</td>
+ <td width="78%" class="vtable">
+ <input name="wildcard" type="checkbox" id="wildcard" value="yes" <?php if ($pconfig['wildcard'] == "yes") echo "checked"; ?>>
+ Enable Wildcard</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Username</td>
+ <td width="78%" class="vtable">
+ <input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Password</td>
+ <td width="78%" class="vtable">
+ <input name="password" type="password" class="formfld" id="password" size="20" value="<?=htmlspecialchars($pconfig['password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>You must configure a DNS server in <a href="system.php">System:
+ General setup</a> or allow the DNS server list to be overridden
+ by DHCP/PPP on WAN for the DynDNS client to work.</span></td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_proxyarp.php b/usr/local/www/services_proxyarp.php
new file mode 100755
index 0000000..ecb7315
--- /dev/null
+++ b/usr/local/www/services_proxyarp.php
@@ -0,0 +1,124 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_proxyarp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['proxyarp']['proxyarpnet'])) {
+ $config['proxyarp']['proxyarpnet'] = array();
+}
+proxyarp_sort();
+$a_proxyarp = &$config['proxyarp']['proxyarpnet'];
+
+if ($_POST) {
+ $pconfig = $_POST;
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_proxyarp_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ if ($retval == 0) {
+ if (file_exists($d_proxyarpdirty_path))
+ unlink($d_proxyarpdirty_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_proxyarp[$_GET['id']]) {
+ unset($a_proxyarp[$_GET['id']]);
+ write_config();
+ touch($d_proxyarpdirty_path);
+ header("Location: services_proxyarp.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Proxy ARP");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Proxy ARP</p>
+<form action="services_proxyarp.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_proxyarpdirty_path)): ?><p>
+<?php print_info_box_np("The proxy ARP configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="40%" class="listhdrr">Network</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_proxyarp as $arpent): ?>
+ <tr>
+ <td class="listlr">
+ <?php if (isset($arpent['network'])) {
+ list($sa,$sn) = explode("/", $arpent['network']);
+ if ($sn == 32)
+ echo $sa;
+ else
+ echo $arpent['network'];
+ } else if (isset($arpent['range']))
+ echo $arpent['range']['from'] . "-" . $arpent['range']['to'];
+ ?>&nbsp;
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($arpent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_proxyarp_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_proxyarp.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this network?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list"> <a href="services_proxyarp_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </form>
+ <p class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>Proxy ARP can be used if you need m0n0wall to send ARP
+ replies on the WAN interface for other IP addresses than its own WAN
+ IP address (e.g. for 1:1, advanced outbound or server NAT). It is not
+ necessary if you have a subnet routed to you or if you use PPPoE/PPTP, and it only works if
+ the WAN interface is configured with a static IP address or DHCP.</p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_proxyarp_edit.php b/usr/local/www/services_proxyarp_edit.php
new file mode 100755
index 0000000..2c5bd6c
--- /dev/null
+++ b/usr/local/www/services_proxyarp_edit.php
@@ -0,0 +1,231 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_proxyarp_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['proxyarp']['proxyarpnet'])) {
+ $config['proxyarp']['proxyarpnet'] = array();
+}
+proxyarp_sort();
+$a_proxyarp = &$config['proxyarp']['proxyarpnet'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_proxyarp[$id]) {
+ if (isset($a_proxyarp[$id]['network']))
+ list($pconfig['subnet'], $pconfig['subnet_bits']) = explode("/", $a_proxyarp[$id]['network']);
+ else if (isset($a_proxyarp[$id]['range'])) {
+ $pconfig['range_from'] = $a_proxyarp[$id]['range']['from'];
+ $pconfig['range_to'] = $a_proxyarp[$id]['range']['to'];
+ }
+ $pconfig['descr'] = $a_proxyarp[$id]['descr'];
+} else {
+ $pconfig['subnet_bits'] = 32;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['type'] == "single") {
+ $reqdfields = explode(" ", "subnet");
+ $reqdfieldsn = explode(",", "Address");
+ $_POST['subnet_bits'] = 32;
+ } else if ($_POST['type'] == "network") {
+ $reqdfields = explode(" ", "subnet subnet_bits");
+ $reqdfieldsn = explode(",", "Network,Network mask");
+ } else if ($_POST['type'] == "range") {
+ $reqdfields = explode(" ", "range_from range_to");
+ $reqdfieldsn = explode(",", "Range start,Range end");
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ((($_POST['type'] != "range") && $_POST['subnet'] && !is_ipaddr($_POST['subnet']))) {
+ $input_errors[] = "A valid address must be specified.";
+ }
+ if ((($_POST['type'] == "range") && $_POST['range_from'] && !is_ipaddr($_POST['range_from']))) {
+ $input_errors[] = "A valid range start must be specified.";
+ }
+ if ((($_POST['type'] == "range") && $_POST['range_to'] && !is_ipaddr($_POST['range_to']))) {
+ $input_errors[] = "A valid range end must be specified.";
+ }
+
+ /* check for overlaps */
+ foreach ($a_proxyarp as $arpent) {
+ if (isset($id) && ($a_proxyarp[$id]) && ($a_proxyarp[$id] === $arpent))
+ continue;
+
+ if (($_POST['type'] == "range") && isset($arpent['range'])) {
+ if (($_POST['range_from'] == $arpent['range']['from']) &&
+ ($_POST['range_to'] == $arpent['range']['to'])) {
+ $input_errors[] = "This range already exists.";
+ break;
+ }
+ } else if (isset($arpent['network'])) {
+ if (($arpent['network'] == "{$_POST['subnet']}/{$_POST['subnet_bits']}")) {
+ $input_errors[] = "This network already exists.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+ $arpent = array();
+ if ($_POST['type'] == "range") {
+ $arpent['range']['from'] = $_POST['range_from'];
+ $arpent['range']['to'] = $_POST['range_to'];
+ } else
+ $arpent['network'] = $_POST['subnet'] . "/" . $_POST['subnet_bits'];
+ $arpent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_proxyarp[$id])
+ $a_proxyarp[$id] = $arpent;
+ else
+ $a_proxyarp[] = $arpent;
+
+ touch($d_proxyarpdirty_path);
+
+ write_config();
+
+ header("Location: services_proxyarp.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Proxy ARP: Edit");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+ switch (document.iform.type.selectedIndex) {
+ case 0: // single
+ document.iform.subnet.disabled = 0;
+ document.iform.subnet_bits.disabled = 1;
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ break;
+ case 1: // network
+ document.iform.subnet.disabled = 0;
+ document.iform.subnet_bits.disabled = 0;
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ break;
+ case 2: // range
+ document.iform.subnet.disabled = 1;
+ document.iform.subnet_bits.disabled = 1;
+ document.iform.range_from.disabled = 0;
+ document.iform.range_to.disabled = 0;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Proxy ARP: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_proxyarp_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="top" class="vncellreq">Network</td>
+ <td class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="type" class="formfld" onChange="typesel_change()">
+ <option value="single" <?php if (!$pconfig['range_from'] && $pconfig['subnet_bits'] == 32) echo "selected"; ?>>
+ Single address</option>
+ <option value="network" <?php if (!$pconfig['range_from'] && $pconfig['subnet_bits'] != 32) echo "selected"; ?>>
+ Network</option>
+ <option value="range" <?php if ($pconfig['range_from']) echo "selected"; ?>>
+ Range</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="subnet" type="text" class="formfld" id="subnet" size="20" value="<?=htmlspecialchars($pconfig['subnet']);?>">
+ /
+ <select name="subnet_bits" class="formfld" id="select">
+ <?php for ($i = 31; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet_bits']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Range:&nbsp;&nbsp;</td>
+ <td><input name="range_from" type="text" class="formfld" id="range_from" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>">
+-
+ <input name="range_to" type="text" class="formfld" id="range_to" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_proxyarp[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_snmp.php b/usr/local/www/services_snmp.php
new file mode 100755
index 0000000..e7c4464
--- /dev/null
+++ b/usr/local/www/services_snmp.php
@@ -0,0 +1,145 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_snmp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['snmpd'])) {
+ $config['snmpd'] = array();
+ $config['snmpd']['rocommunity'] = "public";
+}
+
+$pconfig['syslocation'] = $config['snmpd']['syslocation'];
+$pconfig['syscontact'] = $config['snmpd']['syscontact'];
+$pconfig['rocommunity'] = $config['snmpd']['rocommunity'];
+$pconfig['enable'] = isset($config['snmpd']['enable']);
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "rocommunity");
+ $reqdfieldsn = explode(",", "Community");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ }
+
+ if (!$input_errors) {
+ $config['snmpd']['syslocation'] = $_POST['syslocation'];
+ $config['snmpd']['syscontact'] = $_POST['syscontact'];
+ $config['snmpd']['rocommunity'] = $_POST['rocommunity'];
+ $config['snmpd']['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_snmpd_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: SNMP");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+ if (document.iform.enable.checked || enable_change) {
+ document.iform.syslocation.disabled = 0;
+ document.iform.syscontact.disabled = 0;
+ document.iform.rocommunity.disabled = 0;
+ } else {
+ document.iform.syslocation.disabled = 1;
+ document.iform.syscontact.disabled = 1;
+ document.iform.rocommunity.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: SNMP</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="services_snmp.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable SNMP agent</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">System location</td>
+ <td width="78%" class="vtable">
+ <input name="syslocation" type="text" class="formfld" id="syslocation" size="40" value="<?=htmlspecialchars($pconfig['syslocation']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">System contact</td>
+ <td width="78%" class="vtable">
+ <input name="syscontact" type="text" class="formfld" id="syscontact" size="40" value="<?=htmlspecialchars($pconfig['syscontact']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Community</td>
+ <td width="78%" class="vtable">
+ <input name="rocommunity" type="text" class="formfld" id="rocommunity" size="40" value="<?=htmlspecialchars($pconfig['rocommunity']);?>">
+ <br>
+ In most cases, &quot;public&quot; is used here</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_wol.php b/usr/local/www/services_wol.php
new file mode 100755
index 0000000..1ee5946
--- /dev/null
+++ b/usr/local/www/services_wol.php
@@ -0,0 +1,162 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_wol.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['wol']['wolentry'])) {
+ $config['wol']['wolentry'] = array();
+}
+wol_sort();
+$a_wol = &$config['wol']['wolentry'];
+
+if ($_POST || $_GET['mac']) {
+ unset($input_errors);
+
+ if ($_GET['mac']) {
+ $mac = $_GET['mac'];
+ $if = $_GET['if'];
+ } else {
+ $mac = $_POST['mac_input'];
+ $if = $_POST['interface'];
+ }
+
+ /* input validation */
+ if (!$mac || !is_macaddr($mac))
+ $input_errors[] = "A valid MAC address must be specified.";
+ if (!$if)
+ $input_errors[] = "A valid interface must be specified.";
+
+ if (!$input_errors) {
+ /* determine broadcast address */
+ $bcip = gen_subnet_max($config['interfaces'][$if]['ipaddr'],
+ $config['interfaces'][$if]['subnet']);
+
+ mwexec("/usr/local/bin/wol -i {$bcip} {$mac}");
+ $savemsg = "Sent magic packet to {$mac}.";
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_wol[$_GET['id']]) {
+ unset($a_wol[$_GET['id']]);
+ write_config();
+ header("Location: services_wol.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Wake on LAN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Wake on LAN</font></p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="services_wol.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+ <?php $interfaces = array('lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']) &&
+ !$config['interfaces']['opt' . $i]['bridge'])
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $if) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface the host to be woken up is connected to.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac_input" type="text" class="formfld" id="mac_input" size="20" value="<?=htmlspecialchars($mac);?>">
+ <br>
+ Enter a MAC address <span class="vexpl"> in the following format: xx:xx:xx:xx:xx:xx</span></td></tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Send">
+ </td>
+ </tr>
+ </table>
+ <span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>This service can be used to wake up (power on) computers by sending special &quot;Magic Packets&quot;. The NIC in the computer that is to be woken up must support Wake on LAN and has to be configured properly (WOL cable, BIOS settings). </span><br>
+ <br>
+ You may store MAC addresses below for your convenience.
+Click the MAC address to wake up a computer. <br>
+&nbsp;
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="15%" class="listhdrr">Interface</td>
+ <td width="25%" class="listhdrr">MAC address</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_wol as $wolent): ?>
+ <tr>
+ <td class="listlr">
+ <?php if ($wolent['interface'] == "lan")
+ echo "LAN";
+ else
+ echo $config['interfaces'][$wolent['interface']]['descr'];
+ ?>&nbsp;
+ </td>
+ <td class="listr">
+ <a href="?mac=<?=$wolent['mac'];?>&if=<?=$wolent['interface'];?>"><?=strtolower($wolent['mac']);?></a>&nbsp;
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($wolent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_wol_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_wol.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3"></td>
+ <td class="list"> <a href="services_wol_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_wol_edit.php b/usr/local/www/services_wol_edit.php
new file mode 100755
index 0000000..1d483f7
--- /dev/null
+++ b/usr/local/www/services_wol_edit.php
@@ -0,0 +1,143 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_wol_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['wol']['wolentry'])) {
+ $config['wol']['wolentry'] = array();
+}
+wol_sort();
+$a_wol = &$config['wol']['wolentry'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_wol[$id]) {
+ $pconfig['interface'] = $a_wol[$id]['interface'];
+ $pconfig['mac'] = $a_wol[$id]['mac'];
+ $pconfig['descr'] = $a_wol[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface mac");
+ $reqdfieldsn = explode(",", "Interface,MAC address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+ $input_errors[] = "A valid MAC address must be specified.";
+ }
+
+ if (!$input_errors) {
+ $wolent = array();
+ $wolent['interface'] = $_POST['interface'];
+ $wolent['mac'] = $_POST['mac'];
+ $wolent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_wol[$id])
+ $a_wol[$id] = $wolent;
+ else
+ $a_wol[] = $wolent;
+
+ write_config();
+
+ header("Location: services_wol.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Wake on LAN: Edit entry");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Wake on LAN: Edit entry</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_wol_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">Interface</td>
+ <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+ <?php $interfaces = array('lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']) &&
+ !$config['interfaces']['opt' . $i]['bridge'])
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface this host is connected to.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac" type="text" class="formfld" id="mac" size="20" value="<?=htmlspecialchars($pconfig['mac']);?>">
+ <br>
+ <span class="vexpl">Enter a MAC address in the following format:
+ xx:xx:xx:xx:xx:xx<em></em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_wol[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status.php b/usr/local/www/status.php
new file mode 100755
index 0000000..0b54797
--- /dev/null
+++ b/usr/local/www/status.php
@@ -0,0 +1,150 @@
+#!/usr/local/bin/php
+<?php
+/* Run various commands and collect their output into HTML tables.
+ * Jim McBeath <jimmc@macrovision.com> Nov 2003
+ *
+ * (modified for m0n0wall by Manuel Kasper <mk@neon1.net>)
+ */
+
+/* Execute a command, with a title, and generate an HTML table
+ * showing the results.
+ */
+function doCmdT($title, $command) {
+ echo "<p>\n";
+ echo "<a name=\"" . $title . "\">\n";
+ echo "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
+ echo "<tr><td class=\"listtopic\">" . $title . "</td></tr>\n";
+ echo "<tr><td class=\"listlr\"><pre>"; /* no newline after pre */
+
+ if ($command == "dumpconfigxml") {
+ $fd = @fopen("/conf/config.xml", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = fgets($fd);
+ /* remove password tag contents */
+ $line = preg_replace("/<password>.*?<\\/password>/", "<password>xxxxx</password>", $line);
+ $line = preg_replace("/<pre-shared-key>.*?<\\/pre-shared-key>/", "<pre-shared-key>xxxxx</pre-shared-key>", $line);
+ $line = str_replace("\t", " ", $line);
+ echo htmlspecialchars($line,ENT_NOQUOTES);
+ }
+ }
+ fclose($fd);
+ } else {
+ exec ($command . " 2>&1", $execOutput, $execStatus);
+ for ($i = 0; isset($execOutput[$i]); $i++) {
+ if ($i > 0) {
+ echo "\n";
+ }
+ echo htmlspecialchars($execOutput[$i],ENT_NOQUOTES);
+ }
+ }
+ echo "</pre></tr>\n";
+ echo "</table>\n";
+}
+
+/* Execute a command, giving it a title which is the same as the command. */
+function doCmd($command) {
+ doCmdT($command,$command);
+}
+
+/* Define a command, with a title, to be executed later. */
+function defCmdT($title, $command) {
+ global $commands;
+ $title = htmlspecialchars($title,ENT_NOQUOTES);
+ $commands[] = array($title, $command);
+}
+
+/* Define a command, with a title which is the same as the command,
+ * to be executed later.
+ */
+function defCmd($command) {
+ defCmdT($command,$command);
+}
+
+/* List all of the commands as an index. */
+function listCmds() {
+ global $commands;
+ echo "<p>This status page includes the following information:\n";
+ echo "<ul>\n";
+ for ($i = 0; isset($commands[$i]); $i++ ) {
+ echo "<li><strong><a href=\"#" . $commands[$i][0] . "\">" . $commands[$i][0] . "</a></strong>\n";
+ }
+ echo "</ul>\n";
+}
+
+/* Execute all of the commands which were defined by a call to defCmd. */
+function execCmds() {
+ global $commands;
+ for ($i = 0; isset($commands[$i]); $i++ ) {
+ doCmdT($commands[$i][0], $commands[$i][1]);
+ }
+}
+
+/* Set up all of the commands we want to execute. */
+defCmdT("System uptime","uptime");
+defCmdT("Interfaces","/sbin/ifconfig -a");
+
+defCmdT("Routing tables","netstat -nr");
+
+defCmdT("ipfw show", "/sbin/ipfw show");
+defCmdT("pfctl -s nat ", "/sbin/pfctl -s nat");
+defCmdT("pfctl -s rules", "/sbin/pfctl -s rules");
+defCmdT("pfctl -s all"," /sbin/pfctl -s all");
+
+defCmdT("resolv.conf","cat /etc/resolv.conf");
+
+defCmdT("Processes","ps xauww");
+defCmdT("dhcpd.conf","cat /var/etc/dhcpd.conf");
+defCmdT("ez-ipupdate.cache","cat /conf/ez-ipupdate.cache");
+
+defCmdT("df","/bin/df");
+
+defCmdT("racoon.conf","cat /var/etc/racoon.conf");
+defCmdT("SPD","/usr/sbin/setkey -DP");
+defCmdT("SAD","/usr/sbin/setkey -D");
+
+defCmdT("last 200 system log entries","/usr/sbin/clog /var/log/system.log 2>&1 | tail -n 200");
+defCmdT("last 50 filter log entries","/usr/sbin/clog /var/log/filter.log 2>&1 | tail -n 50");
+
+defCmd("ls /conf");
+defCmd("ls /var/run");
+defCmdT("config.xml","dumpconfigxml");
+
+$pageTitle = "m0n0wall: status";
+
+exec("/bin/date", $dateOutput, $dateStatus);
+$currentDate = $dateOutput[0];
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=$pageTitle;?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+<!--
+pre {
+ margin: 0px;
+ font-family: courier new, courier;
+ font-weight: normal;
+ font-size: 9pt;
+}
+-->
+</style>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<p><span class="pgtitle"><?=$pageTitle;?></span><br>
+<strong><?=$currentDate;?></strong>
+<p><span class="red"><strong>Note: make sure to remove any sensitive information
+(passwords, maybe also IP addresses) before posting
+information from this page in public places (like mailing lists)!</strong></span><br>
+Passwords in config.xml have been automatically removed.
+
+<?php listCmds(); ?>
+
+<?php execCmds(); ?>
+
+</body>
+</html>
diff --git a/usr/local/www/status_captiveportal.php b/usr/local/www/status_captiveportal.php
new file mode 100755
index 0000000..80f2eff
--- /dev/null
+++ b/usr/local/www/status_captiveportal.php
@@ -0,0 +1,128 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_captiveportal.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Status: Captive portal");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Status: Captive portal</p>
+<?php
+
+if ($_GET['act'] == "del") {
+ captiveportal_disconnect_client($_GET['id']);
+}
+
+flush();
+
+function clientcmp($a, $b) {
+ global $order;
+ return strcmp($a[$order], $b[$order]);
+}
+
+$cpdb = array();
+captiveportal_lock();
+$fp = @fopen("{$g['vardb_path']}/captiveportal.db","r");
+
+if ($fp) {
+ while (!feof($fp)) {
+ $line = trim(fgets($fp));
+ if ($line) {
+ $cpent = explode(",", $line);
+ if ($_GET['showact'])
+ $cpent[4] = captiveportal_get_last_activity($cpent[1]);
+ $cpdb[] = $cpent;
+ }
+ }
+
+ fclose($fp);
+
+ if ($_GET['order']) {
+ if ($_GET['order'] == "ip")
+ $order = 2;
+ else if ($_GET['order'] == "mac")
+ $order = 3;
+ else if ($_GET['order'] == "lastact")
+ $order = 4;
+ else
+ $order = 0;
+ usort($cpdb, "clientcmp");
+ }
+}
+captiveportal_unlock();
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr"><a href="?order=ip&showact=<?=$_GET['showact'];?>">IP address</a></td>
+ <td class="listhdrr"><a href="?order=mac&showact=<?=$_GET['showact'];?>">MAC address</a></td>
+ <?php if ($_GET['showact']): ?>
+ <td class="listhdrr"><a href="?order=start&showact=<?=$_GET['showact'];?>">Session start</a></td>
+ <td class="listhdr"><a href="?order=lastact&showact=<?=$_GET['showact'];?>">Last activity</a></td>
+ <?php else: ?>
+ <td class="listhdr"><a href="?order=start&showact=<?=$_GET['showact'];?>">Session start</a></td>
+ <?php endif; ?>
+ <td class="list"></td>
+ </tr>
+<?php foreach ($cpdb as $cpent): ?>
+ <tr>
+ <td class="listlr"><?=$cpent[2];?></td>
+ <td class="listr"><?=$cpent[3];?>&nbsp;</td>
+ <td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent[0]));?></td>
+ <?php if ($_GET['showact']): ?>
+ <td class="listr"><?php if ($cpent[4]) echo htmlspecialchars(date("m/d/Y H:i:s", $cpent[4]));?></td>
+ <?php endif; ?>
+ <td valign="middle" class="list" nowrap>
+ <a href="?order=<?=$_GET['order'];?>&showact=<?=$_GET['showact'];?>&act=del&id=<?=$cpent[1];?>" onclick="return confirm('Do you really want to disconnect this client?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+<?php endforeach; ?>
+</table>
+<p>
+<form action="status_captiveportal.php" method="GET">
+<input type="hidden" name="order" value="<?=$_GET['order'];?>">
+<?php if ($_GET['showact']): ?>
+<input type="hidden" name="showact" value="0">
+<input type="submit" class="formbtn" value="Don't show last activity">
+<?php else: ?>
+<input type="hidden" name="showact" value="1">
+<input type="submit" class="formbtn" value="Show last activity">
+<?php endif; ?>
+</form>
+</p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_graph.php b/usr/local/www/status_graph.php
new file mode 100755
index 0000000..15330fd
--- /dev/null
+++ b/usr/local/www/status_graph.php
@@ -0,0 +1,80 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_graph.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$curif = "wan";
+if ($_GET['if'])
+ $curif = $_GET['if'];
+
+if ($curif == "wan")
+ $ifnum = get_real_wan_interface();
+else
+ $ifnum = $config['interfaces'][$curif]['if'];
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Status: Traffic graph");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Status: Traffic graph</p>
+<?php
+$ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+
+for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+}
+?>
+<form name="form1" action="" method="get" style="padding-bottom: 10px; margin-bottom: 14px; border-bottom: 1px solid #999999">
+Interface:
+<select name="if" class="formfld" onchange="document.form1.submit()">
+<?php
+foreach ($ifdescrs as $ifn => $ifd) {
+ echo "<option value=\"$ifn\"";
+ if ($ifn == $curif) echo " selected";
+ echo ">" . htmlspecialchars($ifd) . "</option>\n";
+}
+?>
+</select>
+</form>
+<div align="center">
+<embed src="graph.php?ifnum=<?=$ifnum;?>&ifname=<?=rawurlencode($ifdescrs[$curif]);?>" type="image/svg+xml"
+ width="550" height="275" pluginspage="http://www.adobe.com/svg/viewer/install/auto" />
+</div>
+<p><span class="red"><strong>Note:</strong></span> the <a href="http://www.adobe.com/svg/viewer/install/" target="_blank">Adobe SVG viewer</a> is required to view the graph.
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_interfaces.php b/usr/local/www/status_interfaces.php
new file mode 100755
index 0000000..480312b
--- /dev/null
+++ b/usr/local/www/status_interfaces.php
@@ -0,0 +1,283 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_interfaces.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+function get_interface_info($ifdescr) {
+
+ global $config, $g;
+
+ $ifinfo = array();
+
+ /* find out interface name */
+ if ($ifdescr == "wan")
+ $ifinfo['if'] = get_real_wan_interface();
+ else
+ $ifinfo['if'] = $config['interfaces'][$ifdescr]['if'];
+
+ /* run netstat to determine link info */
+ unset($linkinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
+ $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+ if (preg_match("/\*$/", $linkinfo[0])) {
+ $ifinfo['status'] = "down";
+ } else {
+ $ifinfo['status'] = "up";
+ }
+
+ if (($ifinfo['if'] != $g['pppoe_interface']) && (!strstr($ifinfo['if'],'tun'))) {
+ $ifinfo['macaddr'] = $linkinfo[3];
+ $ifinfo['inpkts'] = $linkinfo[4];
+ $ifinfo['inerrs'] = $linkinfo[5];
+ $ifinfo['inbytes'] = $linkinfo[6];
+ $ifinfo['outpkts'] = $linkinfo[7];
+ $ifinfo['outerrs'] = $linkinfo[8];
+ $ifinfo['outbytes'] = $linkinfo[9];
+ $ifinfo['collisions'] = $linkinfo[10];
+ } else {
+ $ifinfo['inpkts'] = $linkinfo[3];
+ $ifinfo['inbytes'] = $linkinfo[5];
+ $ifinfo['outpkts'] = $linkinfo[6];
+ $ifinfo['outbytes'] = $linkinfo[8];
+ }
+
+ if ($ifinfo['status'] == "up") {
+ /* run netstat to determine inet info */
+ unset($inetinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f inet", $inetinfo);
+ $inetinfo = preg_split("/\s+/", $inetinfo[1]);
+
+ $ifinfo['ipaddr'] = $inetinfo[3];
+
+ if ($ifdescr == "wan") {
+ /* run netstat to determine the default gateway */
+ unset($netstatrninfo);
+ exec("/usr/bin/netstat -rnf inet", $netstatrninfo);
+
+ foreach ($netstatrninfo as $nsr) {
+ if (preg_match("/^default\s*(\S+)/", $nsr, $matches)) {
+ $ifinfo['gateway'] = $matches[1];
+ }
+ }
+ }
+
+ /* try to determine netmask and media with ifconfig */
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ foreach ($ifconfiginfo as $ici) {
+ if (preg_match("/netmask (\S+)/", $ici, $matches) && !$ifinfo['subnet']) {
+ if (preg_match("/^0x/", $matches[1])) {
+ $ifinfo['subnet'] = long2ip(hexdec($matches[1]));
+ }
+ }
+ if (!isset($config['interfaces'][$ifdescr]['wireless'])) {
+ /* don't list media/speed for wireless cards, as it always
+ displays 2 Mbps even though clients can connect at 11 Mbps */
+ if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
+ $ifinfo['media'] = $matches[1];
+ } else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
+ $ifinfo['media'] = $matches[1];
+ }
+ }
+ if (preg_match("/status: (.*)$/", $ici, $matches)) {
+ if ($matches[1] != "active")
+ $ifinfo['status'] = $matches[1];
+ }
+ if (preg_match("/channel (\S*)/", $ici, $matches)) {
+ $ifinfo['channel'] = $matches[1];
+ }
+ if (preg_match("/ssid (\S*)/", $ici, $matches)) {
+ $ifinfo['ssid'] = $matches[1];
+ }
+ }
+
+ /* PPPoE only: get media from underlying ethernet interface */
+ if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pppoe")) {
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $config['interfaces']['wan']['if'], $ifconfiginfo);
+
+ foreach ($ifconfiginfo as $ici) {
+ if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
+ $ifinfo['media'] = $matches[1];
+ } else if (preg_match("/ether (.*)/", $ici, $matches)) {
+ $ifinfo['macaddr'] = $matches[1];
+ }
+ }
+
+ /* get pppoe link status for dial on demand */
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pppoelink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pppoelink'] = "down";
+ }
+ }
+
+ /* get ppptp link status for dial on demand */
+ if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pptp")) {
+
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pptplink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pptplink'] = "down";
+ }
+ }
+ }
+
+ return $ifinfo;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Status: Interfaces");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">Status: Interfaces</p>
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <?php $i = 0; $ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+ }
+
+ foreach ($ifdescrs as $ifdescr => $ifname):
+ $ifinfo = get_interface_info($ifdescr);
+ ?>
+ <?php if ($i): ?>
+ <tr>
+ <td colspan="8" class="list" height="12"></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <td colspan="2" class="listtopic">
+ <?=htmlspecialchars($ifname);?>
+ interface</td>
+ </tr>
+ <tr>
+ <td width="22%" class="listhdrr">Status</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['status']);?>
+ </td>
+ </tr><?php if ($ifinfo['pppoelink']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">PPPoE</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['pppoelink']);?>
+ </td>
+ </tr><?php endif; if ($ifinfo['pptplink']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">PPTP</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['pptplink']);?>
+ </td>
+ </tr><?php endif; if ($ifinfo['macaddr']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">MAC address</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['macaddr']);?>
+ </td>
+ </tr><?php endif; if ($ifinfo['status'] != "down"): ?>
+ <?php if ($ifinfo['ipaddr']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">IP address</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['ipaddr']);?>
+ &nbsp; </td>
+ </tr><?php endif; ?><?php if ($ifinfo['subnet']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Subnet mask</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['subnet']);?>
+ </td>
+ </tr><?php endif; ?><?php if ($ifinfo['gateway']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Gateway</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['gateway']);?>
+ </td>
+ </tr><?php endif; ?><?php if ($ifinfo['media']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Media</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['media']);?>
+ </td>
+ </tr><?php endif; ?><?php if ($ifinfo['channel']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Channel</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['channel']);?>
+ </td>
+ </tr><?php endif; ?><?php if ($ifinfo['ssid']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">SSID</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['ssid']);?>
+ </td>
+ </tr><?php endif; ?>
+ <tr>
+ <td width="22%" class="listhdrr">In/out packets</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['inpkts'] . "/" . $ifinfo['outpkts'] . " (" .
+ format_bytes($ifinfo['inbytes']) . "/" . format_bytes($ifinfo['outbytes']) . ")");?>
+ </td>
+ </tr><?php if (isset($ifinfo['inerrs'])): ?>
+ <tr>
+ <td width="22%" class="listhdrr">In/out errors</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['inerrs'] . "/" . $ifinfo['outerrs']);?>
+ </td>
+ </tr><?php endif; ?><?php if (isset($ifinfo['collisions'])): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Collisions</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['collisions']);?>
+ </td>
+ </tr><?php endif; ?>
+ <?php endif; ?>
+ <?php $i++; endforeach; ?>
+ </table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_wireless.php b/usr/local/www/status_wireless.php
new file mode 100755
index 0000000..c87c8d6
--- /dev/null
+++ b/usr/local/www/status_wireless.php
@@ -0,0 +1,189 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_wireless.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+function get_wireless_info($ifdescr) {
+
+ global $config, $g;
+
+ $ifinfo = array();
+ $ifinfo['if'] = $config['interfaces'][$ifdescr]['if'];
+
+ /* get signal strength cache */
+ exec("/usr/sbin/wicontrol -i " . $ifinfo['if'] . " -C", $sscache);
+
+ $ifinfo['sscache'] = array();
+ foreach ($sscache as $ss) {
+ if ($ss) {
+ $ssa = preg_split("/\s+/", $ss);
+ $sscent = array();
+ $sscent['mac'] = chop($ssa[1], ",");
+ $sscent['ipaddr'] = chop($ssa[2], ",");
+ $sscent['sig'] = chop($ssa[4], ",");
+ $sscent['noise'] = chop($ssa[6], ",");
+ $sscent['qual'] = chop($ssa[8], ",");
+ $ifinfo['sscache'][] = $sscent;
+ }
+ }
+
+ /* if in hostap mode: get associated stations */
+ if ($config['interfaces'][$ifdescr]['wireless']['mode'] == "hostap") {
+ exec("/usr/sbin/wicontrol -i " . $ifinfo['if'] . " -l", $aslist);
+
+ $ifinfo['aslist'] = array();
+ array_shift($aslist);
+ foreach ($aslist as $as) {
+ if ($as) {
+ $asa = preg_split("/\s+/", $as);
+ $aslent = array();
+ $aslent['mac'] = $asa[0];
+ $aslent['rates'] = substr($asa[4], strpos($asa[4], "<")+1,
+ strpos($asa[4], ">")-strpos($asa[4], "<")-1);
+ $aslent['sig'] = substr($asa[5], strpos($asa[5], "=")+1);
+ $ifinfo['aslist'][] = $aslent;
+ }
+ }
+ }
+
+ return $ifinfo;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Status: Wireless");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">Status: Wireless</p>
+ <?php $i = 0; $ifdescrs = array();
+
+ if (is_array($config['interfaces']['wan']['wireless']) &&
+ strstr($config['interfaces']['wan']['if'], "wi"))
+ $ifdescrs['wan'] = 'WAN';
+
+ if (is_array($config['interfaces']['lan']['wireless']) &&
+ strstr($config['interfaces']['lan']['if'], "wi"))
+ $ifdescrs['lan'] = 'LAN';
+
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ if (is_array($config['interfaces']['opt' . $j]['wireless']) &&
+ isset($config['interfaces']['opt' . $j]['enable']) &&
+ strstr($config['interfaces']['opt' . $j]['if'], "wi"))
+ $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+ }
+
+ if (count($ifdescrs) > 0): ?>
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <?php
+ foreach ($ifdescrs as $ifdescr => $ifname):
+ $ifinfo = get_wireless_info($ifdescr);
+ ?>
+ <?php if ($i): ?>
+ <tr>
+ <td colspan="8" class="list" height="12"></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <td colspan="2" class="listtopic">
+ <?=htmlspecialchars($ifname);?> interface (SSID &quot;<?=htmlspecialchars($config['interfaces'][$ifdescr]['wireless']['ssid']);?>&quot;)</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="listhdrr">Signal strength
+ cache</td>
+ <td width="78%" class="listrpad">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">MAC address</td>
+ <td width="25%" class="listhdrr">IP address</td>
+ <td width="15%" class="listhdrr">Signal</td>
+ <td width="15%" class="listhdrr">Noise</td>
+ <td width="15%" class="listhdr">Quality</td>
+ </tr>
+ <?php foreach ($ifinfo['sscache'] as $ss): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($ss['mac']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($ss['ipaddr']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($ss['sig']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($ss['noise']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($ss['qual']);?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </table></td>
+ </tr><?php if ($ifinfo['aslist']): ?>
+ <tr>
+ <td width="22%" valign="top" class="listhdrr">Associated stations
+ </td>
+ <td width="78%" class="listrpad">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="40%" class="listhdrr">MAC address</td>
+ <td width="40%" class="listhdrr">TX rates</td>
+ <td width="20%" class="listhdrr">Signal</td>
+ </tr>
+ <?php foreach ($ifinfo['aslist'] as $as): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($as['mac']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($as['rates']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($as['sig']);?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </table></td>
+ </tr><?php endif; ?>
+ <?php $i++; endforeach; ?>
+ </table>
+<?php else: ?>
+<p><strong>No supported wireless interfaces were found for status display.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system.php b/usr/local/www/system.php
new file mode 100755
index 0000000..90e9502
--- /dev/null
+++ b/usr/local/www/system.php
@@ -0,0 +1,260 @@
+#!/usr/local/bin/php
+<?php
+/*
+ system.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['hostname'] = $config['system']['hostname'];
+$pconfig['domain'] = $config['system']['domain'];
+list($pconfig['dns1'],$pconfig['dns2']) = $config['system']['dnsserver'];
+$pconfig['dnsallowoverride'] = isset($config['system']['dnsallowoverride']);
+$pconfig['username'] = $config['system']['username'];
+if (!$pconfig['username'])
+ $pconfig['username'] = "admin";
+$pconfig['webguiproto'] = $config['system']['webgui']['protocol'];
+if (!$pconfig['webguiproto'])
+ $pconfig['webguiproto'] = "http";
+$pconfig['webguiport'] = $config['system']['webgui']['port'];
+$pconfig['timezone'] = $config['system']['timezone'];
+$pconfig['timeupdateinterval'] = $config['system']['time-update-interval'];
+$pconfig['timeservers'] = $config['system']['timeservers'];
+
+if (!isset($pconfig['timeupdateinterval']))
+ $pconfig['timeupdateinterval'] = 300;
+if (!$pconfig['timezone'])
+ $pconfig['timezone'] = "Etc/UTC";
+if (!$pconfig['timeservers'])
+ $pconfig['timeservers'] = "pool.ntp.org";
+
+function is_timezone($elt) {
+ return !preg_match("/\/$/", $elt);
+}
+
+exec('/usr/bin/tar -tzf /usr/share/zoneinfo.tgz', $timezonelist);
+$timezonelist = array_filter($timezonelist, 'is_timezone');
+sort($timezonelist);
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = split(" ", "hostname domain username");
+ $reqdfieldsn = split(",", "Hostname,Domain,Username");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['hostname'] && !is_hostname($_POST['hostname'])) {
+ $input_errors[] = "The hostname may only contain the characters a-z, 0-9 and '-'.";
+ }
+ if ($_POST['domain'] && !is_domain($_POST['domain'])) {
+ $input_errors[] = "The domain may only contain the characters a-z, 0-9, '-' and '.'.";
+ }
+ if (($_POST['dns1'] && !is_ipaddr($_POST['dns1'])) || ($_POST['dns2'] && !is_ipaddr($_POST['dns2']))) {
+ $input_errors[] = "A valid IP address must be specified for the primary/secondary DNS server.";
+ }
+ if ($_POST['username'] && !preg_match("/^[a-zA-Z0-9]*$/", $_POST['username'])) {
+ $input_errors[] = "The username may only contain the characters a-z, A-Z and 0-9.";
+ }
+ if ($_POST['webguiport'] && (!is_numericint($_POST['webguiport']) ||
+ ($_POST['webguiport'] < 1) || ($_POST['webguiport'] > 65535))) {
+ $input_errors[] = "A valid TCP/IP port must be specified for the webGUI port.";
+ }
+ if (($_POST['password']) && ($_POST['password'] != $_POST['password2'])) {
+ $input_errors[] = "The passwords do not match.";
+ }
+
+ $t = (int)$_POST['timeupdateinterval'];
+ if (($t < 0) || (($t > 0) && ($t < 6)) || ($t > 1440)) {
+ $input_errors[] = "The time update interval must be either 0 (disabled) or between 6 and 1440.";
+ }
+ foreach (explode(' ', $_POST['timeservers']) as $ts) {
+ if (!is_domain($ts)) {
+ $input_errors[] = "A NTP Time Server name may only contain the characters a-z, 0-9, '-' and '.'.";
+ }
+ }
+
+ if (!$input_errors) {
+ $config['system']['hostname'] = strtolower($_POST['hostname']);
+ $config['system']['domain'] = strtolower($_POST['domain']);
+ $oldwebguiproto = $config['system']['webgui']['protocol'];
+ $config['system']['username'] = $_POST['username'];
+ $config['system']['webgui']['protocol'] = $pconfig['webguiproto'];
+ $oldwebguiport = $config['system']['webgui']['port'];
+ $config['system']['webgui']['port'] = $pconfig['webguiport'];
+ $config['system']['timezone'] = $_POST['timezone'];
+ $config['system']['timeservers'] = strtolower($_POST['timeservers']);
+ $config['system']['time-update-interval'] = $_POST['timeupdateinterval'];
+
+ unset($config['system']['dnsserver']);
+ if ($_POST['dns1'])
+ $config['system']['dnsserver'][] = $_POST['dns1'];
+ if ($_POST['dns2'])
+ $config['system']['dnsserver'][] = $_POST['dns2'];
+
+ $config['system']['dnsallowoverride'] = $_POST['dnsallowoverride'] ? true : false;
+
+ if ($_POST['password']) {
+ $config['system']['password'] = crypt($_POST['password']);
+ }
+
+ write_config();
+
+ if (($oldwebguiproto != $config['system']['webgui']['protocol']) ||
+ ($oldwebguiport != $config['system']['webgui']['port']))
+ touch($d_sysrebootreqd_path);
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = system_hostname_configure();
+ $retval |= system_hosts_generate();
+ $retval |= system_resolvconf_generate();
+ $retval |= system_password_configure();
+ $retval |= services_dnsmasq_configure();
+ $retval |= system_timezone_configure();
+ $retval |= system_ntp_configure();
+ config_unlock();
+ }
+
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: General setup");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">System: General setup</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form action="system.php" method="post">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hostname</td>
+ <td width="78%" class="vtable"> <input name="hostname" type="text" class="formfld" id="hostname" size="40" value="<?=htmlspecialchars($pconfig['hostname']);?>">
+ <br> <span class="vexpl">name of the firewall host, without
+ domain part<br>
+ e.g. <em>firewall</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Domain</td>
+ <td width="78%" class="vtable"> <input name="domain" type="text" class="formfld" id="domain" size="40" value="<?=htmlspecialchars($pconfig['domain']);?>">
+ <br> <span class="vexpl">e.g. <em>mycorp.com</em> </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">DNS servers</td>
+ <td width="78%" class="vtable"> <p>
+ <input name="dns1" type="text" class="formfld" id="dns1" size="20" value="<?=htmlspecialchars($pconfig['dns1']);?>">
+ <br>
+ <input name="dns2" type="text" class="formfld" id="dns22" size="20" value="<?=htmlspecialchars($pconfig['dns2']);?>">
+ <br>
+ <span class="vexpl">IP addresses; these are also used for
+ the DHCP service, DNS forwarder and for PPTP VPN clients<br>
+ <br>
+ <input name="dnsallowoverride" type="checkbox" id="dnsallowoverride" value="yes" <?php if ($pconfig['dnsallowoverride'] == "yes") echo "checked"; ?>>
+ <strong>Allow DNS server list to be overridden by DHCP/PPP
+ on WAN</strong><br>
+ If this option is set, m0n0wall will use DNS servers assigned
+ by a DHCP/PPP server on WAN for its own purposes (including
+ the DNS forwarder). They will not be assigned to DHCP and
+ PPTP VPN clients, though.</span></p></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Username</td>
+ <td class="vtable"> <input name="username" type="text" class="formfld" id="username" size="20" value="<?=$pconfig['username'];?>">
+ <br>
+ <span class="vexpl">If you want
+ to change the username for accessing the webGUI, enter it
+ here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Password</td>
+ <td width="78%" class="vtable"> <input name="password" type="password" class="formfld" id="password" size="20">
+ <br> <input name="password2" type="password" class="formfld" id="password2" size="20">
+ &nbsp;(confirmation) <br> <span class="vexpl">If you want
+ to change the password for accessing the webGUI, enter it
+ here twice.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">webGUI protocol</td>
+ <td width="78%" class="vtable"> <input name="webguiproto" type="radio" value="http" <?php if ($pconfig['webguiproto'] == "http") echo "checked"; ?>>
+ HTTP &nbsp;&nbsp;&nbsp; <input type="radio" name="webguiproto" value="https" <?php if ($pconfig['webguiproto'] == "https") echo "checked"; ?>>
+ HTTPS</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">webGUI port</td>
+ <td class="vtable"> <input name="webguiport" type="text" class="formfld" id="webguiport" size="5" value="<?=htmlspecialchars($pconfig['webguiport']);?>">
+ <br>
+ <span class="vexpl">Enter a custom port number for the webGUI
+ above if you want to override the default (80 for HTTP, 443
+ for HTTPS).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Time zone</td>
+ <td width="78%" class="vtable"> <select name="timezone" id="timezone">
+ <?php foreach ($timezonelist as $value): ?>
+ <option value="<?=htmlspecialchars($value);?>" <?php if ($value == $pconfig['timezone']) echo "selected"; ?>>
+ <?=htmlspecialchars($value);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Select the location closest
+ to you</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Time update interval</td>
+ <td width="78%" class="vtable"> <input name="timeupdateinterval" type="text" class="formfld" id="timeupdateinterval" size="4" value="<?=htmlspecialchars($pconfig['timeupdateinterval']);?>">
+ <br> <span class="vexpl">Minutes between network time sync.;
+ 300 recommended, or 0 to disable </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">NTP time server</td>
+ <td width="78%" class="vtable"> <input name="timeservers" type="text" class="formfld" id="timeservers" size="40" value="<?=htmlspecialchars($pconfig['timeservers']);?>">
+ <br> <span class="vexpl">Use a space to separate multiple
+ hosts (only one required). Remember to set up at least one
+ DNS server if you enter a host name here!</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system_advanced.php b/usr/local/www/system_advanced.php
new file mode 100755
index 0000000..dbc665a
--- /dev/null
+++ b/usr/local/www/system_advanced.php
@@ -0,0 +1,289 @@
+#!/usr/local/bin/php
+<?php
+/*
+ system_advanced.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['filteringbridge_enable'] = isset($config['bridge']['filteringbridge']);
+$pconfig['ipv6nat_enable'] = isset($config['diag']['ipv6nat']['enable']);
+$pconfig['ipv6nat_ipaddr'] = $config['diag']['ipv6nat']['ipaddr'];
+$pconfig['cert'] = base64_decode($config['system']['webgui']['certificate']);
+$pconfig['key'] = base64_decode($config['system']['webgui']['private-key']);
+$pconfig['disableconsolemenu'] = isset($config['system']['disableconsolemenu']);
+$pconfig['disablefirmwarecheck'] = isset($config['system']['disablefirmwarecheck']);
+$pconfig['expanddiags'] = isset($config['system']['webgui']['expanddiags']);
+if ($g['platform'] == "generic-pc")
+ $pconfig['harddiskstandby'] = $config['system']['harddiskstandby'];
+$pconfig['noantilockout'] = isset($config['system']['webgui']['noantilockout']);
+$pconfig['tcpidletimeout'] = $config['filter']['tcpidletimeout'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['ipv6nat_enable'] && !is_ipaddr($_POST['ipv6nat_ipaddr'])) {
+ $input_errors[] = "You must specify an IP address to NAT IPv6 packets.";
+ }
+ if ($_POST['tcpidletimeout'] && !is_numericint($_POST['tcpidletimeout'])) {
+ $input_errors[] = "The TCP idle timeout must be an integer.";
+ }
+ if (($_POST['cert'] && !$_POST['key']) || ($_POST['key'] && !$_POST['cert'])) {
+ $input_errors[] = "Certificate and key must always be specified together.";
+ } else if ($_POST['cert'] && $_POST['key']) {
+ if (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))
+ $input_errors[] = "This certificate does not appear to be valid.";
+ if (!strstr($_POST['key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "This key does not appear to be valid.";
+ }
+
+ if (!$input_errors) {
+ $config['bridge']['filteringbridge'] = $_POST['filteringbridge_enable'] ? true : false;
+ $config['diag']['ipv6nat']['enable'] = $_POST['ipv6nat_enable'] ? true : false;
+ $config['diag']['ipv6nat']['ipaddr'] = $_POST['ipv6nat_ipaddr'];
+ $oldcert = $config['system']['webgui']['certificate'];
+ $oldkey = $config['system']['webgui']['private-key'];
+ $config['system']['webgui']['certificate'] = base64_encode($_POST['cert']);
+ $config['system']['webgui']['private-key'] = base64_encode($_POST['key']);
+ $config['system']['disableconsolemenu'] = $_POST['disableconsolemenu'] ? true : false;
+ $config['system']['disablefirmwarecheck'] = $_POST['disablefirmwarecheck'] ? true : false;
+ $config['system']['webgui']['expanddiags'] = $_POST['expanddiags'] ? true : false;
+ if ($g['platform'] == "generic-pc") {
+ $oldharddiskstandby = $config['system']['harddiskstandby'];
+ $config['system']['harddiskstandby'] = $_POST['harddiskstandby'];
+ }
+ $config['system']['webgui']['noantilockout'] = $_POST['noantilockout'] ? true : false;
+ $config['filter']['tcpidletimeout'] = $_POST['tcpidletimeout'];
+
+ write_config();
+
+ if (($config['system']['webgui']['certificate'] != $oldcert)
+ || ($config['system']['webgui']['private-key'] != $oldkey)) {
+ touch($d_sysrebootreqd_path);
+ } else if (($g['platform'] == "generic-pc") && ($config['system']['harddiskstandby'] != $oldharddiskstandby)) {
+ if (!$config['system']['harddiskstandby']) {
+ // Reboot needed to deactivate standby due to a stupid ATA-protocol
+ touch($d_sysrebootreqd_path);
+ unset($config['system']['harddiskstandby']);
+ } else {
+ // No need to set the standby-time if a reboot is needed anyway
+ system_set_harddisk_standby();
+ }
+ }
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = filter_configure();
+ $retval |= interfaces_optional_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: Advanced functions");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+ if (document.iform.ipv6nat_enable.checked || enable_over) {
+ document.iform.ipv6nat_ipaddr.disabled = 0;
+ } else {
+ document.iform.ipv6nat_ipaddr.disabled = 1;
+ }
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <p class="pgtitle">System: Advanced functions</p>
+ <?php if ($input_errors) print_input_errors($input_errors); ?>
+ <?php if ($savemsg) print_info_box($savemsg); ?>
+ <p><span class="vexpl"><span class="red"><strong>Note: </strong></span>the
+ options on this page are intended for use by advanced users only,
+ and there's <strong>NO</strong> support for them.</span></p>
+ <form action="system_advanced.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">IPv6 tunneling</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="ipv6nat_enable" type="checkbox" id="ipv6nat_enable" value="yes" <?php if ($pconfig['ipv6nat_enable']) echo "checked"; ?> onclick="enable_change(false)">
+ <strong>NAT encapsulated IPv6 packets (IP protocol 41/RFC2893)
+ to:</strong><br> <br> <input name="ipv6nat_ipaddr" type="text" class="formfld" id="ipv6nat_ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipv6nat_ipaddr']);?>">
+ &nbsp;(IP address)<span class="vexpl"><br>
+ Don't forget to add a firewall rule to permit IPv6 packets!</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Filtering bridge</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="filteringbridge_enable" type="checkbox" id="filteringbridge_enable" value="yes" <?php if ($pconfig['filteringbridge_enable']) echo "checked"; ?>>
+ <strong>Enable filtering bridge</strong><span class="vexpl"><br>
+ This will cause bridged packets to pass through the packet
+ filter in the same way as routed packets do (by default bridged
+ packets are always passed). If you enable this option, you'll
+ have to add filter rules to selectively permit traffic from
+ bridged interfaces.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">webGUI SSL certificate/key</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="cert" cols="65" rows="7" id="cert" class="formpre"><?=htmlspecialchars($pconfig['cert']);?></textarea>
+ <br>
+ Paste a signed certificate in X.509 PEM format here.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Key</td>
+ <td width="78%" class="vtable">
+ <textarea name="key" cols="65" rows="7" id="key" class="formpre"><?=htmlspecialchars($pconfig['key']);?></textarea>
+ <br>
+ Paste an RSA private key in PEM format here.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Miscellaneous</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Console menu </td>
+ <td width="78%" class="vtable">
+ <input name="disableconsolemenu" type="checkbox" id="disableconsolemenu" value="yes" <?php if ($pconfig['disableconsolemenu']) echo "checked"; ?>>
+ <strong>Disable console menu</strong><span class="vexpl"><br>
+ Changes to this option will take effect after a reboot.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Firmware version check </td>
+ <td class="vtable">
+ <input name="disablefirmwarecheck" type="checkbox" id="disablefirmwarecheck" value="yes" <?php if ($pconfig['disablefirmwarecheck']) echo "checked"; ?>>
+ <strong>Disable firmware version check</strong><span class="vexpl"><br>
+ This will cause m0n0wall not to check for newer firmware versions when the <a href="system_firmware.php">System: Firmware</a> page is viewed.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">TCP idle timeout </td>
+ <td class="vtable"> <span class="vexpl">
+ <input name="tcpidletimeout" type="text" class="formfld" id="tcpidletimeout" size="8" value="<?=htmlspecialchars($pconfig['tcpidletimeout']);?>">
+ seconds<br>
+ Idle TCP connections will be removed from the state table after no packets have been received for the specified number of seconds. Don't set this too high or your state table could become full of connections that have been improperly shut down. The default is 2.5 hours.</span></td>
+ </tr>
+<?php if ($g['platform'] == "generic-pc"): ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Hard disk standby time </td>
+ <td width="78%" class="vtable">
+ <select name="harddiskstandby" class="formfld">
+ <?php
+ /* Values from ATA-2
+ http://www.t13.org/project/d0948r3-ATA-2.pdf
+ Page 66 */
+ $sbvals = explode(" ", "0.5,6 1,12 2,24 3,36 4,48 5,60 7.5,90 10,120 15,180 20,240 30,241 60,242");
+ ?>
+ <option value="" <?php if(!$pconfig['harddiskstandby']) echo('selected');?>>Always on</option>
+ <?php
+ foreach ($sbvals as $sbval):
+ list($min,$val) = explode(",", $sbval); ?>
+ <option value="<?=$val;?>" <?php if($pconfig['harddiskstandby'] == $val) echo('selected');?>><?=$min;?> minutes</option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ Puts the hard disk into standby mode when the selected amount of time after the last
+ access has elapsed. <em>Do not set this for CF cards.</em></td>
+ </tr>
+<?php endif; ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Navigation</td>
+ <td width="78%" class="vtable">
+ <input name="expanddiags" type="checkbox" id="expanddiags" value="yes" <?php if ($pconfig['expanddiags']) echo "checked"; ?>>
+ <strong>Keep diagnostics in navigation expanded </strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">webGUI anti-lockout</td>
+ <td width="78%" class="vtable">
+ <input name="noantilockout" type="checkbox" id="noantilockout" value="yes" <?php if ($pconfig['noantilockout']) echo "checked"; ?>>
+ <strong>Disable webGUI anti-lockout rule</strong><br>
+ By default, access to the webGUI on the LAN interface is always permitted, regardless of the user-defined filter rule set. Enable this feature to control webGUI access (make sure to have a filter rule in place that allows you in, or you will lock yourself out!).<br>
+ Hint:
+ the &quot;set LAN IP address&quot; option in the console menu resets this setting as well.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+ <script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system_firmware.php b/usr/local/www/system_firmware.php
new file mode 100755
index 0000000..e008813
--- /dev/null
+++ b/usr/local/www/system_firmware.php
@@ -0,0 +1,206 @@
+#!/usr/local/bin/php
+<?php
+/*
+ system_firmware.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+$d_isfwfile = 1; require("guiconfig.inc");
+
+/* checks with m0n0.ch to see if a newer firmware version is available;
+ returns any HTML message it gets from the server */
+function check_firmware_version() {
+ global $g;
+ $post = "platform=" . rawurlencode($g['platform']) .
+ "&version=" . rawurlencode(trim(file_get_contents("/etc/version")));
+
+ $rfd = @fsockopen("m0n0.ch", 80, $errno, $errstr, 3);
+ if ($rfd) {
+ $hdr = "POST /wall/checkversion.php HTTP/1.0\r\n";
+ $hdr .= "Content-Type: application/x-www-form-urlencoded\r\n";
+ $hdr .= "User-Agent: m0n0wall-webGUI/1.0\r\n";
+ $hdr .= "Host: m0n0.ch\r\n";
+ $hdr .= "Content-Length: " . strlen($post) . "\r\n\r\n";
+
+ fwrite($rfd, $hdr);
+ fwrite($rfd, $post);
+
+ $inhdr = true;
+ $resp = "";
+ while (!feof($rfd)) {
+ $line = fgets($rfd);
+ if ($inhdr) {
+ if (trim($line) == "")
+ $inhdr = false;
+ } else {
+ $resp .= $line;
+ }
+ }
+
+ fclose($rfd);
+
+ return $resp;
+ }
+
+ return null;
+}
+
+if ($_POST && !file_exists($d_firmwarelock_path)) {
+
+ unset($input_errors);
+ unset($sig_warning);
+
+ if (stristr($_POST['Submit'], "Enable"))
+ $mode = "enable";
+ else if (stristr($_POST['Submit'], "Disable"))
+ $mode = "disable";
+ else if (stristr($_POST['Submit'], "Upgrade") || $_POST['sig_override'])
+ $mode = "upgrade";
+ else if ($_POST['sig_no'])
+ unlink("{$g['ftmp_path']}/firmware.img");
+
+ if ($mode) {
+ if ($mode == "enable") {
+ exec_rc_script("/etc/rc.firmware enable");
+ touch($d_fwupenabled_path);
+ } else if ($mode == "disable") {
+ exec_rc_script("/etc/rc.firmware disable");
+ if (file_exists($d_fwupenabled_path))
+ unlink($d_fwupenabled_path);
+ } else if ($mode == "upgrade") {
+ if (is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
+ /* verify firmware image(s) */
+ if (!stristr($_FILES['ulfile']['name'], $g['platform']) && !$_POST['sig_override'])
+ $input_errors[] = "The uploaded image file is not for this platfom ({$g['platform']}).";
+ else if (!file_exists($_FILES['ulfile']['tmp_name'])) {
+ /* probably out of memory for the MFS */
+ $input_errors[] = "Image upload failed (out of memory?)";
+ exec_rc_script("/etc/rc.firmware disable");
+ if (file_exists($d_fwupenabled_path))
+ unlink($d_fwupenabled_path);
+ } else {
+ /* move the image so PHP won't delete it */
+ rename($_FILES['ulfile']['tmp_name'], "{$g['ftmp_path']}/firmware.img");
+
+ /* check digital signature */
+ $sigchk = verify_digital_signature("{$g['ftmp_path']}/firmware.img");
+
+ if ($sigchk == 1)
+ $sig_warning = "The digital signature on this image is invalid.";
+ else if ($sigchk == 2)
+ $sig_warning = "This image is not digitally signed.";
+ else if (($sigchk == 3) || ($sigchk == 4))
+ $sig_warning = "There has been an error verifying the signature on this image.";
+
+ if (!verify_gzip_file("{$g['ftmp_path']}/firmware.img")) {
+ $input_errors[] = "The image file is corrupt.";
+ unlink("{$g['ftmp_path']}/firmware.img");
+ }
+ }
+ }
+
+ if (!$input_errors && !file_exists($d_firmwarelock_path) && (!$sig_warning || $_POST['sig_override'])) {
+ /* fire up the update script in the background */
+ touch($d_firmwarelock_path);
+ exec_rc_script_async("/etc/rc.firmware upgrade {$g['ftmp_path']}/firmware.img");
+
+ $savemsg = "The firmware is now being installed. The firewall will reboot automatically.";
+ }
+ }
+ }
+} else {
+ if (!isset($config['system']['disablefirmwarecheck']))
+ $fwinfo = check_firmware_version();
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: Firmware");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Firmware</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if ($fwinfo) echo $fwinfo; ?>
+<?php if (!in_array($g['platform'], $fwupplatforms)): ?>
+<p><strong>Firmware uploading is not supported on this platform.</strong></p>
+<?php elseif ($sig_warning && !$input_errors): ?>
+<form action="system_firmware.php" method="post">
+<?php
+$sig_warning = "<strong>" . $sig_warning . "</strong><br>This means that the image you uploaded " .
+ "is not an official/supported image and may lead to unexpected behavior or security " .
+ "compromises. Only install images that come from sources that you trust, and make sure ".
+ "that the image has not been tampered with.<br><br>".
+ "Do you want to install this image anyway (on your own risk)?";
+print_info_box($sig_warning);
+?>
+<input name="sig_override" type="submit" class="formbtn" id="sig_override" value=" Yes ">
+<input name="sig_no" type="submit" class="formbtn" id="sig_no" value=" No ">
+</form>
+<?php else: ?>
+ <?php if (!file_exists($d_firmwarelock_path)): ?>
+ <p>Click &quot;Enable firmware
+ upload&quot; below, then choose the image file (<?=$g['platform'];?>-*.img)
+ to be uploaded.<br>Click &quot;Upgrade firmware&quot;
+ to start the upgrade process.</p>
+ <form action="system_firmware.php" method="post" enctype="multipart/form-data">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <?php if (!file_exists($d_sysrebootreqd_path)): ?>
+ <?php if (!file_exists($d_fwupenabled_path)): ?>
+ <input name="Submit" type="submit" class="formbtn" value="Enable firmware upload">
+ <?php else: ?>
+ <input name="Submit" type="submit" class="formbtn" value="Disable firmware upload">
+ <br><br>
+ <strong>Firmware image file: </strong>&nbsp;<input name="ulfile" type="file" class="formfld">
+ <br><br>
+ <input name="Submit" type="submit" class="formbtn" value="Upgrade firmware">
+ <?php endif; else: ?>
+ <strong>You must reboot the system before you can upgrade the firmware.</strong>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Warning:<br>
+ </strong></span>DO NOT abort the firmware upgrade once it
+ has started. The firewall will reboot automatically after
+ storing the new firmware. The configuration will be maintained.</span></td>
+ </tr>
+ </table>
+</form>
+<?php endif; endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system_routes.php b/usr/local/www/system_routes.php
new file mode 100755
index 0000000..c4abdff
--- /dev/null
+++ b/usr/local/www/system_routes.php
@@ -0,0 +1,126 @@
+#!/usr/local/bin/php
+<?php
+/*
+ system_routes.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['staticroutes']['route']))
+ $config['staticroutes']['route'] = array();
+
+staticroutes_sort();
+$a_routes = &$config['staticroutes']['route'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ $retval = system_routing_configure();
+ $retval |= filter_configure();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_staticroutesdirty_path)) {
+ config_lock();
+ unlink($d_staticroutesdirty_path);
+ config_unlock();
+ }
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_routes[$_GET['id']]) {
+ unset($a_routes[$_GET['id']]);
+ write_config();
+ touch($d_staticroutesdirty_path);
+ header("Location: system_routes.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: Static routes");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Static routes</p>
+<form action="system_routes.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_staticroutesdirty_path)): ?><p>
+<?php print_info_box_np("The static route configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="15%" class="listhdrr">Interface</td>
+ <td width="25%" class="listhdrr">Network</td>
+ <td width="20%" class="listhdrr">Gateway</td>
+ <td width="30%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_routes as $route): ?>
+ <tr>
+ <td class="listlr">
+ <?php
+ $iflabels = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+ $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+ echo htmlspecialchars($iflabels[$route['interface']]); ?>
+ </td>
+ <td class="listr">
+ <?=strtolower($route['network']);?>
+ </td>
+ <td class="listr">
+ <?=strtolower($route['gateway']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($route['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="system_routes_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="system_routes.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this route?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4"></td>
+ <td class="list"> <a href="system_routes_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system_routes_edit.php b/usr/local/www/system_routes_edit.php
new file mode 100755
index 0000000..826a5f1
--- /dev/null
+++ b/usr/local/www/system_routes_edit.php
@@ -0,0 +1,176 @@
+#!/usr/local/bin/php
+<?php
+/*
+ system_routes_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['staticroutes']['route']))
+ $config['staticroutes']['route'] = array();
+
+staticroutes_sort();
+$a_routes = &$config['staticroutes']['route'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_routes[$id]) {
+ $pconfig['interface'] = $a_routes[$id]['interface'];
+ list($pconfig['network'],$pconfig['network_subnet']) =
+ explode('/', $a_routes[$id]['network']);
+ $pconfig['gateway'] = $a_routes[$id]['gateway'];
+ $pconfig['descr'] = $a_routes[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface network network_subnet gateway");
+ $reqdfieldsn = explode(",", "Interface,Destination network,Destination network bit count,Gateway");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['network'] && !is_ipaddr($_POST['network']))) {
+ $input_errors[] = "A valid destination network must be specified.";
+ }
+ if (($_POST['network_subnet'] && !is_numeric($_POST['network_subnet']))) {
+ $input_errors[] = "A valid destination network bit count must be specified.";
+ }
+ if (($_POST['gateway'] && !is_ipaddr($_POST['gateway']))) {
+ $input_errors[] = "A valid gateway IP address must be specified.";
+ }
+
+ /* check for overlaps */
+ $osn = gen_subnet($_POST['network'], $_POST['network_subnet']) . "/" . $_POST['network_subnet'];
+ foreach ($a_routes as $route) {
+ if (isset($id) && ($a_routes[$id]) && ($a_routes[$id] === $route))
+ continue;
+
+ if ($route['network'] == $osn) {
+ $input_errors[] = "A route to this destination network already exists.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $route = array();
+ $route['interface'] = $_POST['interface'];
+ $route['network'] = $osn;
+ $route['gateway'] = $_POST['gateway'];
+ $route['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_routes[$id])
+ $a_routes[$id] = $route;
+ else
+ $a_routes[] = $route;
+
+ touch($d_staticroutesdirty_path);
+
+ write_config();
+
+ header("Location: system_routes.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("System: Static routes: Edit route");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Static routes: Edit route</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="system_routes_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">Interface</td>
+ <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+ <?php $interfaces = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface this route applies to.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Destination network</td>
+ <td width="78%" class="vtable">
+ <input name="network" type="text" class="formfld" id="network" size="20" value="<?=htmlspecialchars($pconfig['network']);?>">
+ /
+ <select name="network_subnet" class="formfld" id="network_subnet">
+ <?php for ($i = 32; $i >= 1; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['network_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br> <span class="vexpl">Destination network for this static route</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Gateway</td>
+ <td width="78%" class="vtable">
+ <input name="gateway" type="text" class="formfld" id="gateway" size="40" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+ <br> <span class="vexpl">Gateway to be used to reach the destination network</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_routes[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_ipsec.php b/usr/local/www/vpn_ipsec.php
new file mode 100755
index 0000000..cea915a
--- /dev/null
+++ b/usr/local/www/vpn_ipsec.php
@@ -0,0 +1,192 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_ipsec.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['tunnel'])) {
+ $config['ipsec']['tunnel'] = array();
+}
+$a_ipsec = &$config['ipsec']['tunnel'];
+$wancfg = &$config['interfaces']['wan'];
+
+$pconfig['enable'] = isset($config['ipsec']['enable']);
+
+if ($_POST) {
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path))
+ $retval = vpn_ipsec_configure();
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_ipsecconfdirty_path))
+ unlink($d_ipsecconfdirty_path);
+ }
+ } else if ($_POST['submit']) {
+ $pconfig = $_POST;
+
+ $config['ipsec']['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = vpn_ipsec_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_ipsecconfdirty_path))
+ unlink($d_ipsecconfdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_ipsec[$_GET['id']]) {
+ unset($a_ipsec[$_GET['id']]);
+ write_config();
+ touch($d_ipsecconfdirty_path);
+ header("Location: vpn_ipsec.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: IPsec");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Tunnels</li>
+ <li class="tabinact"><a href="vpn_ipsec_mobile.php">Mobile clients</a></li>
+ <li class="tabinact"><a href="vpn_ipsec_keys.php">Pre-shared keys</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td class="vtable"><p><span class="vexpl"> </span>
+ <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+ <strong>Enable IPsec<br>
+ </strong></p></td>
+ </tr>
+ <tr>
+ <td> <input name="submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td nowrap class="listhdrr">Local net<br>
+ Remote net</td>
+ <td class="listhdrr">Interface<br>Remote gw</td>
+ <td class="listhdrr">P1 mode</td>
+ <td class="listhdrr">P1 Enc. Algo</td>
+ <td class="listhdrr">P1 Hash Algo</td>
+ <td class="listhdr">Description</td>
+ <td class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_ipsec as $ipsecent):
+ if (isset($ipsecent['disabled'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ } else {
+ $spans = $spane = "";
+ }
+ ?>
+ <tr valign="top">
+ <td nowrap class="listlr"><?=$spans;?>
+ <?php if ($ipsecent['local-subnet']['network'])
+ echo strtoupper($ipsecent['local-subnet']['network']);
+ else
+ echo $ipsecent['local-subnet']['address'];
+ ?>
+ <br>
+ <?=$ipsecent['remote-subnet'];?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?php if ($ipsecent['interface']) {
+ $iflabels = array('lan' => 'LAN', 'wan' => 'WAN');
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+ $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+ $if = htmlspecialchars($iflabels[$ipsecent['interface']]);
+ } else
+ $if = "WAN";
+
+ echo $if . "<br>" . $ipsecent['remote-gateway'];
+ ?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?=$ipsecent['p1']['mode'];?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?=$p1_ealgos[$ipsecent['p1']['encryption-algorithm']];?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?=$p1_halgos[$ipsecent['p1']['hash-algorithm']];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?=htmlspecialchars($ipsecent['descr']);?>&nbsp;
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"> <a href="vpn_ipsec_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_ipsec.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this tunnel?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="6"></td>
+ <td class="list"> <a href="vpn_ipsec_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_ipsec_edit.php b/usr/local/www/vpn_ipsec_edit.php
new file mode 100755
index 0000000..f0fafde
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_edit.php
@@ -0,0 +1,527 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_ipsec_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['tunnel'])) {
+ $config['ipsec']['tunnel'] = array();
+}
+$a_ipsec = &$config['ipsec']['tunnel'];
+
+$specialsrcdst = explode(" ", "lan");
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+function is_specialnet($net) {
+ global $specialsrcdst;
+
+ if (in_array($net, $specialsrcdst))
+ return true;
+ else
+ return false;
+}
+
+function address_to_pconfig($adr, &$padr, &$pmask) {
+
+ if ($adr['network'])
+ $padr = $adr['network'];
+ else if ($adr['address']) {
+ list($padr, $pmask) = explode("/", $adr['address']);
+ if (is_null($pmask))
+ $pmask = 32;
+ }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask) {
+
+ $adr = array();
+
+ if (is_specialnet($padr))
+ $adr['network'] = $padr;
+ else {
+ $adr['address'] = $padr;
+ if ($pmask != 32)
+ $adr['address'] .= "/" . $pmask;
+ }
+}
+
+if (isset($id) && $a_ipsec[$id]) {
+ $pconfig['disabled'] = isset($a_ipsec[$id]['disabled']);
+ $pconfig['auto'] = isset($a_ipsec[$id]['auto']);
+
+ if (!isset($a_ipsec[$id]['local-subnet']))
+ $pconfig['localnet'] = "lan";
+ else
+ address_to_pconfig($a_ipsec[$id]['local-subnet'], $pconfig['localnet'], $pconfig['localnetmask']);
+
+ if ($a_ipsec[$id]['interface'])
+ $pconfig['interface'] = $a_ipsec[$id]['interface'];
+ else
+ $pconfig['interface'] = "wan";
+
+ list($pconfig['remotenet'],$pconfig['remotebits']) = explode("/", $a_ipsec[$id]['remote-subnet']);
+ $pconfig['remotegw'] = $a_ipsec[$id]['remote-gateway'];
+ $pconfig['p1mode'] = $a_ipsec[$id]['p1']['mode'];
+
+ if (isset($a_ipsec[$id]['p1']['myident']['myaddress']))
+ $pconfig['p1myidentt'] = 'myaddress';
+ else if (isset($a_ipsec[$id]['p1']['myident']['address'])) {
+ $pconfig['p1myidentt'] = 'address';
+ $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['address'];
+ } else if (isset($a_ipsec[$id]['p1']['myident']['fqdn'])) {
+ $pconfig['p1myidentt'] = 'fqdn';
+ $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['fqdn'];
+ } else if (isset($a_ipsec[$id]['p1']['myident']['ufqdn'])) {
+ $pconfig['p1myidentt'] = 'user_fqdn';
+ $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['ufqdn'];
+ }
+
+ $pconfig['p1ealgo'] = $a_ipsec[$id]['p1']['encryption-algorithm'];
+ $pconfig['p1halgo'] = $a_ipsec[$id]['p1']['hash-algorithm'];
+ $pconfig['p1dhgroup'] = $a_ipsec[$id]['p1']['dhgroup'];
+ $pconfig['p1lifetime'] = $a_ipsec[$id]['p1']['lifetime'];
+ $pconfig['p1pskey'] = $a_ipsec[$id]['p1']['pre-shared-key'];
+ $pconfig['p2proto'] = $a_ipsec[$id]['p2']['protocol'];
+ $pconfig['p2ealgos'] = $a_ipsec[$id]['p2']['encryption-algorithm-option'];
+ $pconfig['p2halgos'] = $a_ipsec[$id]['p2']['hash-algorithm-option'];
+ $pconfig['p2pfsgroup'] = $a_ipsec[$id]['p2']['pfsgroup'];
+ $pconfig['p2lifetime'] = $a_ipsec[$id]['p2']['lifetime'];
+ $pconfig['descr'] = $a_ipsec[$id]['descr'];
+
+} else {
+ /* defaults */
+ $pconfig['interface'] = "wan";
+ $pconfig['localnet'] = "lan";
+ $pconfig['p1mode'] = "aggressive";
+ $pconfig['p1myidentt'] = "myaddress";
+ $pconfig['p1ealgo'] = "3des";
+ $pconfig['p1halgo'] = "sha1";
+ $pconfig['p1dhgroup'] = "2";
+ $pconfig['p2proto'] = "esp";
+ $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+ $pconfig['p2halgos'] = explode(",", "hmac_sha1,hmac_md5");
+ $pconfig['p2pfsgroup'] = "0";
+}
+
+if ($_POST) {
+ if (is_specialnet($_POST['localnettype'])) {
+ $_POST['localnet'] = $_POST['localnettype'];
+ $_POST['localnetmask'] = 0;
+ } else if ($_POST['localnettype'] == "single") {
+ $_POST['localnetmask'] = 32;
+ }
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "localnet remotenet remotebits remotegw p1pskey p2ealgos p2halgos");
+ $reqdfieldsn = explode(",", "Local network,Remote network,Remote network bits,Remote gateway,Pre-Shared Key,P2 Encryption Algorithms,P2 Hash Algorithms");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (!is_specialnet($_POST['localnettype'])) {
+ if (($_POST['localnet'] && !is_ipaddr($_POST['localnet']))) {
+ $input_errors[] = "A valid local network IP address must be specified.";
+ }
+ if (($_POST['localnetmask'] && !is_numeric($_POST['localnetmask']))) {
+ $input_errors[] = "A valid local network bit count must be specified.";
+ }
+ }
+ if (($_POST['p1lifetime'] && !is_numeric($_POST['p1lifetime']))) {
+ $input_errors[] = "The P1 lifetime must be an integer.";
+ }
+ if (($_POST['p2lifetime'] && !is_numeric($_POST['p2lifetime']))) {
+ $input_errors[] = "The P2 lifetime must be an integer.";
+ }
+ if ($_POST['remotebits'] && (!is_numeric($_POST['remotebits']) || ($_POST['remotebits'] <= 0) || ($_POST['remotebits'] > 32))) {
+ $input_errors[] = "The remote network bits are invalid.";
+ }
+ if (($_POST['remotenet'] && !is_ipaddr($_POST['remotenet']))) {
+ $input_errors[] = "A valid remote network address must be specified.";
+ }
+ if (($_POST['remotegw'] && !is_ipaddr($_POST['remotegw']))) {
+ $input_errors[] = "A valid remote gateway address must be specified.";
+ }
+ if ((($_POST['p1myidentt'] == "address") && !is_ipaddr($_POST['p1myident']))) {
+ $input_errors[] = "A valid IP address for 'My identifier' must be specified.";
+ }
+ if ((($_POST['p1myidentt'] == "fqdn") && !is_domain($_POST['p1myident']))) {
+ $input_errors[] = "A valid domain name for 'My identifier' must be specified.";
+ }
+ if ($_POST['p1myidentt'] == "user_fqdn") {
+ $ufqdn = explode("@",$_POST['p1myident']);
+ if (!is_domain($ufqdn[1]))
+ $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified.";
+ }
+
+ if ($_POST['p1myidentt'] == "myaddress")
+ $_POST['p1myident'] = "";
+
+ if (!$input_errors) {
+ $ipsecent['disabled'] = $_POST['disabled'] ? true : false;
+ $ipsecent['auto'] = $_POST['auto'] ? true : false;
+ $ipsecent['interface'] = $pconfig['interface'];
+ pconfig_to_address($ipsecent['local-subnet'], $_POST['localnet'], $_POST['localnetmask']);
+ $ipsecent['remote-subnet'] = $_POST['remotenet'] . "/" . $_POST['remotebits'];
+ $ipsecent['remote-gateway'] = $_POST['remotegw'];
+ $ipsecent['p1']['mode'] = $_POST['p1mode'];
+
+ $ipsecent['p1']['myident'] = array();
+ switch ($_POST['p1myidentt']) {
+ case 'myaddress':
+ $ipsecent['p1']['myident']['myaddress'] = true;
+ break;
+ case 'address':
+ $ipsecent['p1']['myident']['address'] = $_POST['p1myident'];
+ break;
+ case 'fqdn':
+ $ipsecent['p1']['myident']['fqdn'] = $_POST['p1myident'];
+ break;
+ case 'user_fqdn':
+ $ipsecent['p1']['myident']['ufqdn'] = $_POST['p1myident'];
+ break;
+ }
+
+ $ipsecent['p1']['encryption-algorithm'] = $_POST['p1ealgo'];
+ $ipsecent['p1']['hash-algorithm'] = $_POST['p1halgo'];
+ $ipsecent['p1']['dhgroup'] = $_POST['p1dhgroup'];
+ $ipsecent['p1']['lifetime'] = $_POST['p1lifetime'];
+ $ipsecent['p1']['pre-shared-key'] = $_POST['p1pskey'];
+ $ipsecent['p2']['protocol'] = $_POST['p2proto'];
+ $ipsecent['p2']['encryption-algorithm-option'] = $_POST['p2ealgos'];
+ $ipsecent['p2']['hash-algorithm-option'] = $_POST['p2halgos'];
+ $ipsecent['p2']['pfsgroup'] = $_POST['p2pfsgroup'];
+ $ipsecent['p2']['lifetime'] = $_POST['p2lifetime'];
+ $ipsecent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_ipsec[$id])
+ $a_ipsec[$id] = $ipsecent;
+ else
+ $a_ipsec[] = $ipsecent;
+
+ write_config();
+ touch($d_ipsecconfdirty_path);
+
+ header("Location: vpn_ipsec.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: IPsec: Edit tunnel");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+ switch (document.iform.localnettype.selectedIndex) {
+ case 0: /* single */
+ document.iform.localnet.disabled = 0;
+ document.iform.localnetmask.value = "";
+ document.iform.localnetmask.disabled = 1;
+ break;
+ case 1: /* network */
+ document.iform.localnet.disabled = 0;
+ document.iform.localnetmask.disabled = 0;
+ break;
+ default:
+ document.iform.localnet.value = "";
+ document.iform.localnet.disabled = 1;
+ document.iform.localnetmask.value = "";
+ document.iform.localnetmask.disabled = 1;
+ break;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec: Edit tunnel</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="vpn_ipsec_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">Mode</td>
+ <td width="78%" class="vtable"> Tunnel</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
+ <strong>Disable this tunnel</strong><br>
+ <span class="vexpl">Set this option to disable this tunnel without
+ removing it from the list.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Auto-establish</td>
+ <td width="78%" class="vtable">
+ <input name="auto" type="checkbox" id="auto" value="yes" <?php if ($pconfig['auto']) echo "checked"; ?>>
+ <strong>Automatically establish this tunnel</strong><br>
+ <span class="vexpl">Set this option to automatically re-establish this tunnel after reboots/reconfigures. If this is not set, the tunnel is established on demand.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable"> <select name="interface" class="formfld">
+ <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Select the interface for the local endpoint of this tunnel.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Local subnet</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type:&nbsp;&nbsp;</td>
+ <td><select name="localnettype" class="formfld" onChange="typesel_change()">
+ <?php $sel = is_specialnet($pconfig['localnet']); ?>
+ <option value="single" <?php if (($pconfig['localnetmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+ Single host</option>
+ <option value="network" <?php if (!$sel) echo "selected"; ?>>
+ Network</option>
+ <option value="lan" <?php if ($pconfig['localnet'] == "lan") { echo "selected"; } ?>>
+ LAN subnet</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address:&nbsp;&nbsp;</td>
+ <td><input name="localnet" type="text" class="formfld" id="localnet" size="20" value="<?php if (!is_specialnet($pconfig['localnet'])) echo htmlspecialchars($pconfig['localnet']);?>">
+ /
+ <select name="localnetmask" class="formfld" id="localnetmask">
+ <?php for ($i = 31; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['localnetmask']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select> </td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Remote subnet</td>
+ <td width="78%" class="vtable">
+ <input name="remotenet" type="text" class="formfld" id="remotenet" size="20" value="<?=$pconfig['remotenet'];?>">
+ /
+ <select name="remotebits" class="formfld" id="remotebits">
+ <?php for ($i = 32; $i > 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['remotebits']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Remote gateway</td>
+ <td width="78%" class="vtable">
+ <input name="remotegw" type="text" class="formfld" id="remotegw" size="20" value="<?=$pconfig['remotegw'];?>">
+ <br>
+ Enter the public IP address of the remote gateway</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here
+ for your reference (not parsed).</span></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Phase 1 proposal
+ (Authentication)</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Negotiation mode</td>
+ <td width="78%" class="vtable">
+<select name="p1mode" class="formfld">
+ <?php $modes = explode(" ", "main aggressive"); foreach ($modes as $mode): ?>
+ <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1mode']) echo "selected"; ?>>
+ <?=htmlspecialchars($mode);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Aggressive is faster, but
+ less secure.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">My identifier</td>
+ <td width="78%" class="vtable">
+<select name="p1myidentt" class="formfld">
+ <?php foreach ($my_identifier_list as $mode => $modename): ?>
+ <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1myidentt']) echo "selected"; ?>>
+ <?=htmlspecialchars($modename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="p1myident" type="text" class="formfld" id="p1myident" size="30" value="<?=$pconfig['p1myident'];?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td>
+ <td width="78%" class="vtable">
+<select name="p1ealgo" class="formfld">
+ <?php foreach ($p1_ealgos as $algo => $algoname): ?>
+ <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1ealgo']) echo "selected"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting
+ chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hash algorithm</td>
+ <td width="78%" class="vtable">
+<select name="p1halgo" class="formfld">
+ <?php foreach ($p1_halgos as $algo => $algoname): ?>
+ <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1halgo']) echo "selected"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting
+ chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">DH key group</td>
+ <td width="78%" class="vtable">
+<select name="p1dhgroup" class="formfld">
+ <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?>
+ <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p1dhgroup']) echo "selected"; ?>>
+ <?=htmlspecialchars($keygroup);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024
+ bit, 5 = 1536 bit</em><br>
+ Must match the setting chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Lifetime</td>
+ <td width="78%" class="vtable">
+ <input name="p1lifetime" type="text" class="formfld" id="p1lifetime" size="20" value="<?=$pconfig['p1lifetime'];?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Pre-Shared Key</td>
+ <td width="78%" class="vtable">
+ <input name="p1pskey" type="text" class="formfld" id="p1pskey" size="40" value="<?=htmlspecialchars($pconfig['p1pskey']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Phase 2 proposal
+ (SA/Key Exchange)</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Protocol</td>
+ <td width="78%" class="vtable">
+<select name="p2proto" class="formfld">
+ <?php foreach ($p2_protos as $proto => $protoname): ?>
+ <option value="<?=$proto;?>" <?php if ($proto == $pconfig['p2proto']) echo "selected"; ?>>
+ <?=htmlspecialchars($protoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">ESP is encryption, AH is
+ authentication only </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td>
+ <td width="78%" class="vtable">
+ <?php foreach ($p2_ealgos as $algo => $algoname): ?>
+ <input type="checkbox" name="p2ealgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2ealgos'])) echo "checked"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ <br>
+ <?php endforeach; ?>
+ <br>
+ Hint: use 3DES for best compatibility or if you have a hardware
+ crypto accelerator card. Blowfish is usually the fastest in
+ software encryption. </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hash algorithms</td>
+ <td width="78%" class="vtable">
+ <?php foreach ($p2_halgos as $algo => $algoname): ?>
+ <input type="checkbox" name="p2halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2halgos'])) echo "checked"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ <br>
+ <?php endforeach; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">PFS key group</td>
+ <td width="78%" class="vtable">
+<select name="p2pfsgroup" class="formfld">
+ <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?>
+ <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p2pfsgroup']) echo "selected"; ?>>
+ <?=htmlspecialchars($keygroupname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024
+ bit, 5 = 1536 bit</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Lifetime</td>
+ <td width="78%" class="vtable">
+ <input name="p2lifetime" type="text" class="formfld" id="p2lifetime" size="20" value="<?=$pconfig['p2lifetime'];?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_ipsec[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_ipsec_keys.php b/usr/local/www/vpn_ipsec_keys.php
new file mode 100755
index 0000000..f0a9330
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_keys.php
@@ -0,0 +1,107 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_ipsec_keys.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobilekey'])) {
+ $config['ipsec']['mobilekey'] = array();
+}
+ipsec_mobilekey_sort();
+$a_secret = &$config['ipsec']['mobilekey'];
+
+if ($_GET['act'] == "del") {
+ if ($a_secret[$_GET['id']]) {
+ unset($a_secret[$_GET['id']]);
+ write_config();
+ touch($d_ipsecconfdirty_path);
+ header("Location: vpn_ipsec_keys.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: IPsec");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_ipsec.php">Tunnels</a></li>
+ <li class="tabinact"><a href="vpn_ipsec_mobile.php">Mobile clients</a></li>
+ <li class="tabact">Pre-shared keys</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="80%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Identifier</td>
+ <td class="listhdr">Pre-shared key</td>
+ <td class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_secret as $secretent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($secretent['ident']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($secretent['pre-shared-key']);?>
+ </td>
+ <td class="list" nowrap> <a href="vpn_ipsec_keys_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_ipsec_keys.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this pre-shared key?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list"> <a href="vpn_ipsec_keys_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_ipsec_keys_edit.php b/usr/local/www/vpn_ipsec_keys_edit.php
new file mode 100755
index 0000000..8fe589e
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_keys_edit.php
@@ -0,0 +1,135 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_ipsec_keys_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobilekey'])) {
+ $config['ipsec']['mobilekey'] = array();
+}
+ipsec_mobilekey_sort();
+$a_secret = &$config['ipsec']['mobilekey'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_secret[$id]) {
+ $pconfig['ident'] = $a_secret[$id]['ident'];
+ $pconfig['psk'] = $a_secret[$id]['pre-shared-key'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ident psk");
+ $reqdfieldsn = explode(",", "Identifier,Pre-shared key");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9@\.\-]/", $_POST['ident']))
+ $input_errors[] = "The identifier contains invalid characters.";
+
+ if (!$input_errors && !(isset($id) && $a_secret[$id])) {
+ /* make sure there are no dupes */
+ foreach ($a_secret as $secretent) {
+ if ($secretent['ident'] == $_POST['ident']) {
+ $input_errors[] = "Another entry with the same identifier already exists.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+
+ if (isset($id) && $a_secret[$id])
+ $secretent = $a_secret[$id];
+
+ $secretent['ident'] = $_POST['ident'];
+ $secretent['pre-shared-key'] = $_POST['psk'];
+
+ if (isset($id) && $a_secret[$id])
+ $a_secret[$id] = $secretent;
+ else
+ $a_secret[] = $secretent;
+
+ write_config();
+ touch($d_ipsecconfdirty_path);
+
+ header("Location: vpn_ipsec_keys.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: IPsec: Edit pre-shared key");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec: Edit pre-shared key</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="vpn_ipsec_keys_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td valign="top" class="vncellreq">Identifier</td>
+ <td class="vtable">
+ <input name="ident" type="text" class="formfld" id="ident" size="30" value="<?=$pconfig['ident'];?>">
+ <br>
+This can be either an IP address, fully qualified domain name or an e-mail address.
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Pre-shared key</td>
+ <td width="78%" class="vtable">
+ <input name="psk" type="text" class="formfld" id="psk" size="40" value="<?=htmlspecialchars($pconfig['psk']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_secret[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_ipsec_mobile.php b/usr/local/www/vpn_ipsec_mobile.php
new file mode 100755
index 0000000..3031a45
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_mobile.php
@@ -0,0 +1,330 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_ipsec_mobile.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobileclients'])) {
+ $config['ipsec']['mobileclients'] = array();
+}
+$a_ipsec = &$config['ipsec']['mobileclients'];
+
+if (count($a_ipsec) == 0) {
+ /* defaults */
+ $pconfig['p1mode'] = "aggressive";
+ $pconfig['p1myidentt'] = "myaddress";
+ $pconfig['p1ealgo'] = "3des";
+ $pconfig['p1halgo'] = "sha1";
+ $pconfig['p1dhgroup'] = "2";
+ $pconfig['p2proto'] = "esp";
+ $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+ $pconfig['p2halgos'] = explode(",", "hmac_sha1,hmac_md5");
+ $pconfig['p2pfsgroup'] = "0";
+} else {
+ $pconfig['enable'] = isset($a_ipsec['enable']);
+ $pconfig['p1mode'] = $a_ipsec['p1']['mode'];
+
+ if (isset($a_ipsec['p1']['myident']['myaddress']))
+ $pconfig['p1myidentt'] = 'myaddress';
+ else if (isset($a_ipsec['p1']['myident']['address'])) {
+ $pconfig['p1myidentt'] = 'address';
+ $pconfig['p1myident'] = $a_ipsec['p1']['myident']['address'];
+ } else if (isset($a_ipsec['p1']['myident']['fqdn'])) {
+ $pconfig['p1myidentt'] = 'fqdn';
+ $pconfig['p1myident'] = $a_ipsec['p1']['myident']['fqdn'];
+ } else if (isset($a_ipsec['p1']['myident']['ufqdn'])) {
+ $pconfig['p1myidentt'] = 'user_fqdn';
+ $pconfig['p1myident'] = $a_ipsec['p1']['myident']['ufqdn'];
+ }
+
+ $pconfig['p1ealgo'] = $a_ipsec['p1']['encryption-algorithm'];
+ $pconfig['p1halgo'] = $a_ipsec['p1']['hash-algorithm'];
+ $pconfig['p1dhgroup'] = $a_ipsec['p1']['dhgroup'];
+ $pconfig['p1lifetime'] = $a_ipsec['p1']['lifetime'];
+ $pconfig['p2proto'] = $a_ipsec['p2']['protocol'];
+ $pconfig['p2ealgos'] = $a_ipsec['p2']['encryption-algorithm-option'];
+ $pconfig['p2halgos'] = $a_ipsec['p2']['hash-algorithm-option'];
+ $pconfig['p2pfsgroup'] = $a_ipsec['p2']['pfsgroup'];
+ $pconfig['p2lifetime'] = $a_ipsec['p2']['lifetime'];
+}
+
+if ($_POST) {
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "p2ealgos p2halgos");
+ $reqdfieldsn = explode(",", "P2 Encryption Algorithms,P2 Hash Algorithms");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['p1lifetime'] && !is_numeric($_POST['p1lifetime']))) {
+ $input_errors[] = "The P1 lifetime must be an integer.";
+ }
+ if (($_POST['p2lifetime'] && !is_numeric($_POST['p2lifetime']))) {
+ $input_errors[] = "The P2 lifetime must be an integer.";
+ }
+ if ((($_POST['p1myidentt'] == "address") && !is_ipaddr($_POST['p1myident']))) {
+ $input_errors[] = "A valid IP address for 'My identifier' must be specified.";
+ }
+ if ((($_POST['p1myidentt'] == "fqdn") && !is_domain($_POST['p1myident']))) {
+ $input_errors[] = "A valid domain name for 'My identifier' must be specified.";
+ }
+ if ($_POST['p1myidentt'] == "user_fqdn") {
+ $ufqdn = explode("@",$_POST['p1myident']);
+ if (!is_domain($ufqdn[1]))
+ $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified.";
+ }
+
+ if ($_POST['p1myidentt'] == "myaddress")
+ $_POST['p1myident'] = "";
+
+ if (!$input_errors) {
+ $ipsecent = array();
+ $ipsecent['enable'] = $_POST['enable'] ? true : false;
+ $ipsecent['p1']['mode'] = $_POST['p1mode'];
+
+ $ipsecent['p1']['myident'] = array();
+ switch ($_POST['p1myidentt']) {
+ case 'myaddress':
+ $ipsecent['p1']['myident']['myaddress'] = true;
+ break;
+ case 'address':
+ $ipsecent['p1']['myident']['address'] = $_POST['p1myident'];
+ break;
+ case 'fqdn':
+ $ipsecent['p1']['myident']['fqdn'] = $_POST['p1myident'];
+ break;
+ case 'user_fqdn':
+ $ipsecent['p1']['myident']['ufqdn'] = $_POST['p1myident'];
+ break;
+ }
+
+ $ipsecent['p1']['encryption-algorithm'] = $_POST['p1ealgo'];
+ $ipsecent['p1']['hash-algorithm'] = $_POST['p1halgo'];
+ $ipsecent['p1']['dhgroup'] = $_POST['p1dhgroup'];
+ $ipsecent['p1']['lifetime'] = $_POST['p1lifetime'];
+ $ipsecent['p2']['protocol'] = $_POST['p2proto'];
+ $ipsecent['p2']['encryption-algorithm-option'] = $_POST['p2ealgos'];
+ $ipsecent['p2']['hash-algorithm-option'] = $_POST['p2halgos'];
+ $ipsecent['p2']['pfsgroup'] = $_POST['p2pfsgroup'];
+ $ipsecent['p2']['lifetime'] = $_POST['p2lifetime'];
+
+ $a_ipsec = $ipsecent;
+
+ write_config();
+ touch($d_ipsecconfdirty_path);
+
+ header("Location: vpn_ipsec_mobile.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: IPsec");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+</form>
+<form action="vpn_ipsec_mobile.php" method="post" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_ipsec.php">Tunnels</a></li>
+ <li class="tabact">Mobile clients</li>
+ <li class="tabinact"><a href="vpn_ipsec_keys.php">Pre-shared keys</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?>>
+ <strong>Allow mobile clients</strong></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Phase 1 proposal
+ (Authentication)</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Negotiation mode</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1mode" class="formfld">
+ <?php $modes = explode(" ", "main aggressive"); foreach ($modes as $mode): ?>
+ <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1mode']) echo "selected"; ?>>
+ <?=htmlspecialchars($mode);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Aggressive is faster, but
+ less secure.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">My identifier</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1myidentt" class="formfld">
+ <?php foreach ($my_identifier_list as $mode => $modename): ?>
+ <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1myidentt']) echo "selected"; ?>>
+ <?=htmlspecialchars($modename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <input name="p1myident" type="text" class="formfld" id="p1myident" size="30" value="<?=$pconfig['p1myident'];?>">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1ealgo" class="formfld">
+ <?php foreach ($p1_ealgos as $algo => $algoname): ?>
+ <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1ealgo']) echo "selected"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting
+ chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hash algorithm</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1halgo" class="formfld">
+ <?php foreach ($p1_halgos as $algo => $algoname): ?>
+ <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1halgo']) echo "selected"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting
+ chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">DH key group</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1dhgroup" class="formfld">
+ <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?>
+ <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p1dhgroup']) echo "selected"; ?>>
+ <?=htmlspecialchars($keygroup);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024
+ bit, 5 = 1536 bit</em><br>
+ Must match the setting chosen on the remote side. </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Lifetime</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+ <input name="p1lifetime" type="text" class="formfld" id="p1lifetime" size="20" value="<?=$pconfig['p1lifetime'];?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Phase 2 proposal
+ (SA/Key Exchange)</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Protocol</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p2proto" class="formfld">
+ <?php foreach ($p2_protos as $proto => $protoname): ?>
+ <option value="<?=$proto;?>" <?php if ($proto == $pconfig['p2proto']) echo "selected"; ?>>
+ <?=htmlspecialchars($protoname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">ESP is encryption, AH is
+ authentication only </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+ <?php foreach ($p2_ealgos as $algo => $algoname): ?>
+ <input type="checkbox" name="p2ealgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2ealgos'])) echo "checked"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ <br>
+ <?php endforeach; ?>
+ <br>
+ Hint: use 3DES for best compatibility or if you have a hardware
+ crypto accelerator card. Blowfish is usually the fastest in
+ software encryption. </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hash algorithms</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+ <?php foreach ($p2_halgos as $algo => $algoname): ?>
+ <input type="checkbox" name="p2halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2halgos'])) echo "checked"; ?>>
+ <?=htmlspecialchars($algoname);?>
+ <br>
+ <?php endforeach; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">PFS key group</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p2pfsgroup" class="formfld">
+ <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?>
+ <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p2pfsgroup']) echo "selected"; ?>>
+ <?=htmlspecialchars($keygroupname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024
+ bit, 5 = 1536 bit</em></span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Lifetime</td>
+ <td width="78%" bgcolor="#FFFFFF" class="vtable">
+ <input name="p2lifetime" type="text" class="formfld" id="p2lifetime" size="20" value="<?=$pconfig['p2lifetime'];?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_openvpn.php b/usr/local/www/vpn_openvpn.php
new file mode 100755
index 0000000..6fd3e1e
--- /dev/null
+++ b/usr/local/www/vpn_openvpn.php
@@ -0,0 +1,366 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tun_iface'] = "tun0";
+ $config['ovpn']['server']['psh_options'] = array();
+ /* Initialise with some sensible defaults */
+ $config['ovpn']['server']['port'] = 5000;
+ $config['ovpn']['server']['proto'] = 'UDP';
+ $config['ovpn']['server']['maxcli'] = 25;
+ $config['ovpn']['server']['crypto'] = 'BF-CBC';
+ $config['ovpn']['server']['dupcn'] = true;
+ $config['ovpn']['server']['verb'] = 1;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "tun_iface bind_iface ipblock");
+ $reqdfieldsn = explode(",", "Tunnel type,Interface binding,IP address block start");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ }
+
+ /* need a test here to make sure prefix and max_clients are coherent */
+
+ /* Sort out the cert+key files */
+ if (is_null($_POST['ca_cert']))
+ $input_errors[] = "You must provide a CA certificate file";
+ elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (is_null($_POST['srv_cert']))
+ $input_errors[] = "You must provide a server certificate file";
+ elseif (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['srv_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The server certificate does not appear to be valid.";
+
+ if (is_null($_POST['srv_key']))
+ $input_errors[] = "You must provide a server key file";
+ elseif (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['srv_key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "The server key does not appear to be valid.";
+
+ if (is_null($_POST['dh_param']))
+ $input_errors[] = "You must provide a DH parameters file";
+ elseif (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") || !strstr($_POST['dh_param'], "END DH PARAMETERS"))
+ $input_errors[] = "The DH parameters do not appear to be valid.";
+
+ if (!$input_errors) {
+ $server =& $config['ovpn']['server'];
+ $server['enable'] = $_POST['enable'] ? true : false;
+
+ /* Make sure that the tunnel interface type has not changed */
+ if ($server['tun_iface'] != $_POST['tun_iface']){
+ $server['tun_iface'] = $_POST['tun_iface'];
+ touch($d_sysrebootreqd_path);
+ }
+
+ $server['bind_iface'] = $_POST['bind_iface'];
+ $server['port'] = $_POST['port'];
+ $server['proto'] = $_POST['proto'];
+
+ /* Make sure the IP address and/or prefix have not changed */
+ if ($server['ipblock'] != $_POST['ipblock']){
+ $server['ipblock'] = $_POST['ipblock'];
+ touch($d_sysrebootreqd_path);
+ }
+ if ($server['prefix'] != $_POST['prefix']){
+ $server['prefix'] = $_POST['prefix'];
+ touch($d_sysrebootreqd_path);
+ }
+
+ $server['maxcli'] = $_POST['maxcli'];
+ $server['crypto'] = $_POST['crypto'];
+ $server['cli2cli'] = $_POST['cli2cli'] ? true : false;
+ $server['dupcn'] = $_POST['dupcn'] ? true : false;
+ $server['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
+ $server['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
+ if ($_POST['psh_rtedelay'])
+ $server['psh_options']['rtedelay'] = $_POST['psh_rtedelay_int'];
+ if ($_POST['psh_ping'])
+ $server['psh_options']['ping'] = $_POST['psh_ping_int'];
+ if ($_POST['psh_pingexit'])
+ $server['psh_options']['pingexit'] = $_POST['psh_pingexit_int'];
+ if ($_POST['psh_pingrst'])
+ $server['psh_options']['pingrst'] = $_POST['psh_pingrst_int'];
+ if ($_POST['inact'])
+ $server['psh_options']['inact'] = $_POST['psh_inact_int'];
+ $server['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $server['srv_cert'] = base64_encode($_POST['srv_cert']);
+ $server['srv_key'] = base64_encode($_POST['srv_key']);
+ $server['dh_param'] = base64_encode($_POST['dh_param']);
+
+ write_config();
+
+ $retval = 0;
+ if (file_exists($d_sysrebootreqd_path)) {
+ /* Rewrite interface definitions */
+ $retval = ovpn_server_iface();
+ }
+ else{
+ ovpn_lock();
+ $retval = ovpn_config_server();
+ ovpn_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+
+/* Simply take a copy of the array */
+$pconfig = $config['ovpn']['server'];
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: OpenVPN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
+
+<form action="vpn_openvpn.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Server</li>
+ <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong><table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="enable" type="checkbox" value="yes" <?php if (isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Enable OpenVPN server </strong></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel type</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="tun_iface" class="formfld" value="tun0" <?php if ($pconfig['tun_iface'] == 'tun0') echo "checked"; ?>>
+ TUN&nbsp;
+ <input type="radio" name="tun_iface" class="formfld" value="tap0" <?php if ($pconfig['tun_iface'] == 'tap0') echo "checked"; ?>>
+ TAP
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">OpenVPN protocol/port</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="proto" class="formfld" value="UDP" <?php if ($pconfig['proto'] == 'UDP') echo "checked"; ?>>
+ UDP&nbsp;
+ <input type="radio" name="proto" class="formfld" value="TCP" <?php if ($pconfig['proto'] == 'TCP') echo "checked"; ?>>
+ TCP<br><br>
+ Port:
+ <input name="port" type="text" class="formfld" size="5" maxlength="5" value="<?= $pconfig['port']; ?>"><br>
+ Enter the port number to use for the server (default is 5000).</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface binding</td>
+ <td width="78%" class="vtable">
+ <select name="bind_iface" class="formfld">
+ <?php
+ $interfaces = ovpn_real_interface_list();
+ foreach ($interfaces as $key => $iface):
+ ?>
+ <option value="<?=$key;?>" <?php if ($key == $pconfig['bind_iface']) echo "selected"; ?>> <?= $iface;?>
+ </option>
+ <?php endforeach;?>
+ </select>
+ <span class="vexpl"><br>
+ Choose an interface for the OpenVPN server to listen on.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address block</td>
+ <td width="78%" class="vtable">
+ <input name="ipblock" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ipblock']);?>">
+ /
+ <select name="prefix" class="formfld">
+ <?php for ($i = 29; $i > 19; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['prefix']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br>
+ Enter the IP address block for the OpenVPN server and clients to use.<br>
+ <br>
+ Maximum number of simultaneous clients:
+ <input name="maxcli" type="text" class="formfld" size="3" maxlength="3" value="<?=htmlspecialchars($pconfig['maxcli']);?>">
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+ <br>
+ Paste a CA certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_cert']));?></textarea>
+ <br>
+ Paste a server certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server key</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_key']));?></textarea>
+ <br>Paste the server RSA private key here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">DH parameters</td>
+ <td width="78%" class="vtable">
+ <textarea name="dh_param" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['dh_param']));?></textarea>
+ <br>
+ Paste the Diffie-Hellman parameters in PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Crypto</td>
+ <td width="78%" class="vtable">
+ <select name="crypto" class="formfld">
+ <?php $cipher_list = ovpn_get_cipher_list();
+ foreach($cipher_list as $key => $value){
+ ?>
+ <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+ <?= $value ?>
+ </option>
+ <?php
+ }
+ ?>
+ </select>
+ <br>
+ Select a data channel encryption cipher.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Internal routing mode</td>
+ <td width="78%" class="vtable">
+ <input name="cli2cli" type="checkbox" value="yes" <?php if (isset($pconfig['cli2cli'])) echo "checked"; ?>>
+ <strong>Enable client-to-client routing</strong><br>
+ If this option is on, clients are allowed to talk to each other.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client authentication</td>
+ <td width="78%" class="vtable">
+ <input name="dupcn" type="checkbox" value="yes" <?php if (isset($pconfig['dupcn'])) echo "checked"; ?>>
+ <strong>Permit duplicate client certificates</strong><br>
+ If this option is on, clients with duplicate certificates will not be disconnected.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client-push options</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
+ Redirect-gateway</td>
+ <td>&nbsp;</td>
+ <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
+ Local</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
+ <td width="16">&nbsp;</td>
+ <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
+ Inactive</td>
+ <td>&nbsp;</td>
+ <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact']?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst']?>"> seconds</td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>Changing any settings on this page will disconnect all clients!</span>
+ </td>
+ </tr>
+ </table> </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_openvpn_cli.php b/usr/local/www/vpn_openvpn_cli.php
new file mode 100755
index 0000000..3bd3d93
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_cli.php
@@ -0,0 +1,148 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_cli.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['client'])){
+ $config['ovpn']['client'] = array();
+ $config['ovpn']['client']['tunnel'] = array();
+}
+
+$ovpncli =& $config['ovpn']['client']['tunnel'];
+
+if ($_POST['apply']) {
+ $retval = 0;
+ if (file_exists($d_sysrebootreqd_path)) {
+ /* Rewrite interface definitions */
+ $retval = ovpn_client_iface();
+ }
+ else{
+ ovpn_lock();
+ $retval = ovpn_config_client();
+ ovpn_unlock();
+ }
+ if (file_exists($d_ovpnclidirty_path))
+ unlink($d_ovpnclidirty_path);
+ $savemsg = get_std_save_message($retval);
+}
+
+if ($_GET['act'] == "del") {
+ if ($ovpncli[$_GET['id']]) {
+ unset($ovpncli[$_GET['id']]);
+ write_config();
+ ovpn_client_kill($_GET['id']);
+ touch($d_ovpnclidirty_path);
+ header("Location: vpn_openvpn_cli.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: OpenVPN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnclidirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_cli.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpnclidirty_path)): ?><p>
+<?php print_info_box_np("The OpenVPN client configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_openvpn.php">Server</a></li>
+ <li class="tabact">Client</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">Interface</td>
+ <td width="30%" class="listhdrr">Server address</td>
+ <td width="10%" class="listhdrr" align="middle">Version</td>
+ <td width="40%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+
+ <?php $i = 0; foreach ($ovpncli as $client):
+ if (!isset($client['enable'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ } else {
+ $spans = $spane = "";
+ }
+ ?>
+
+ <tr>
+ <td class="listlr"><?=$spans;?>
+ <?= $client['if'].":".$client['cport'];?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?= $client['saddr'].":".$client['sport'];?>
+ <?=$spane;?></td>
+ <td align="middle" class="listr"><?=$spans;?>
+ <?= $client['ver'];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?= $client['descr'];?>
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_cli_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_cli.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client configuration?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4">&nbsp;</td>
+ <td class="list"> <a href="vpn_openvpn_cli_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_openvpn_cli_edit.php b/usr/local/www/vpn_openvpn_cli_edit.php
new file mode 100755
index 0000000..4c27709
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_cli_edit.php
@@ -0,0 +1,353 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_cli_edit.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['client'])){
+ $config['ovpn']['client'] = array();
+ $config['ovpn']['client']['tunnel'] = array();
+}
+
+function getnxt_if($type) {
+ /* find the first available device of type $type */
+ global $config;
+ $a_client = $config['ovpn']['client']['tunnel'];
+ $max = ($type == 'tun') ? 17 : 4;
+ for ($i = 1; $i < $max ; $i++) {
+ $hit = false;
+ foreach ($a_client as $client) {
+ if ($client['iface'] == $type . $i) {
+ $hit = true;
+ break;
+ }
+ }
+ if (!$hit)
+ return $type . $i;
+ }
+ return false;
+}
+
+
+function getnxt_port() {
+ /* Get first unused port */
+ global $config;
+ $a_client = $config['ovpn']['client']['tunnel'];
+ $port = 5001;
+ while (true) {
+ $hit = false;
+ foreach ($a_client as $client) {
+ if ($client['cport'] == $port) {
+ $hit = true;
+ break;
+ }
+ }
+ if (!$hit)
+ return $port;
+ $port++;
+ }
+ return false; /* should never get here */
+}
+
+
+$ovpncli =& $config['ovpn']['client']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $ovpncli[$id]) {
+ $pconfig = $config['ovpn']['client']['tunnel'][$id];
+ if (isset($ovpncli[$id]['pull']))
+ $pconfig['pull'] = true;
+}
+else {
+ /* creating - set defaults */
+ $pconfig = array();
+ $pconfig['type'] = 'tun';
+ $pconfig['proto'] = 'udp';
+ $pconfig['sport'] = '5000';
+ $pconfig['ver'] = '2';
+ $pconfig['crypto'] = 'BF-CBC';
+ $pconfig['pull'] = true;
+ $pconfig['enable'] = true;
+}
+
+if (isset($_POST['pull'])) {
+ /* Called from form */
+ unset($input_errors);
+ if (is_null($_POST['ca_cert']))
+ $input_errors[] = "You must provide a CA certificate file";
+ elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (is_null($_POST['cli_cert']))
+ $input_errors[] = "You must provide a client certificate file";
+ elseif (!strstr($_POST['cli_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cli_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The client certificate does not appear to be valid.";
+
+ if (is_null($_POST['cli_key']))
+ $input_errors[] = "You must provide a client key file";
+ elseif (!strstr($_POST['cli_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['cli_key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "The client key does not appear to be valid.";
+
+ if (!$input_errors) {
+ if (isset($id)) {
+ /* Editing an existing entry */
+ $ovpnent = $ovpncli[$id];
+ /* Test Server type hasn't changed */
+ if ($ovpnent['type'] != $_POST['type']) {
+ $nxt_if = getnxt_if($_POST['type']);
+ if (!$nxt_if)
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+ else
+ $ovpnent['if'] = $nxt_if;
+ /* Need to reboot in order to create interfaces cleanly */
+ touch($d_sysrebootreqd_path);
+ }
+ /* Has the enable/disable state changed? */
+ if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+ touch($d_sysrebootreqd_path);
+ touch($d_ovpnclidirty_path);
+ ovpn_client_kill($id);
+ ovpn_client_iface_del($id);
+ }
+ if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+ touch($d_sysrebootreqd_path);
+ touch($d_ovpnclidirty_path);
+ }
+ }
+ else {
+ /* Creating a new entry */
+ $ovpnent = array();
+ $nxt_if = getnxt_if($_POST['type']);
+ if (!$nxt_if)
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+ else
+ $ovpnent['if'] = $nxt_if;
+ $ovpnent['cport'] = getnxt_port();
+ /* I think we have to reboot to have the interface created cleanly */
+ touch($d_sysrebootreqd_path);
+ }
+ $ovpnent['type'] = $_POST['type'];
+ $ovpnent['proto'] = $_POST['proto'];
+ $ovpnent['sport'] = $_POST['sport'];
+ $ovpnent['ver'] = $_POST['ver'];
+ $ovpnent['saddr'] = $_POST['saddr'];
+ $ovpnent['descr'] = $_POST['descr'];
+ $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $ovpnent['cli_cert'] = base64_encode($_POST['cli_cert']);
+ $ovpnent['cli_key'] = base64_encode($_POST['cli_key']);
+ $ovpnent['crypto'] = $_POST['crypto'];
+ $ovpnent['pull'] = true; //This is a fixed config for this version
+ $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
+
+
+ if (isset($id) && $ovpncli[$id]){
+ $ovpncli[$id] = $ovpnent;
+ }
+ else{
+ $ovpncli[] = $ovpnent;
+ }
+
+ write_config();
+ touch($d_ovpnclidirty_path);
+ header("Location: vpn_openvpn_cli.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN: Edit client");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: OpenVPN: Edit client</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+
+<form action="vpn_openvpn_cli_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Disable this client</strong><br>
+ <span class="vexpl">Set this option to disable this client without removing it from the list.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Server information</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Tunnel type</td>
+ <td class="vtable">
+ <input name="type" type="radio" class="formfld" value="tun" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>> TUN&nbsp;
+<input name="type" type="radio" class="formfld" value="tap" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>> TAP</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel protocol</td>
+ <td width="78%" class="vtable">
+<input name="proto" type="radio" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>> UDP&nbsp;
+<input name="proto" type="radio" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>> TCP<br>
+ <span class="vexpl">Important: These settings must match the server's configuration.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Port</td>
+ <td width="78%" class="vtable">
+ <input name="sport" type="text" class="formfld" size="5" maxlength="5" value="<?=htmlspecialchars($pconfig['sport']);?>"><br>
+ Enter the server's port number (default is 5000).</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Address</td>
+ <td width="78%" class="vtable">
+ <input name="saddr" type="text" class="formfld" size="20" maxlength="255" value="<?=htmlspecialchars($pconfig['saddr']);?>">
+ <br>
+ Enter the server's IP address or FQDN.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Version</td>
+ <td width="78%" class="vtable">
+ <input name="ver" type="radio" class="formfld" value="2" <?php if ($pconfig['ver'] == '2') echo "checked"; ?>> 2.0&nbsp;
+ <input name="ver" type="radio" class="formfld" value="1" <?php if ($pconfig['ver'] == '1') echo "checked"; ?>> 1.x
+ <br>
+ Specify which version of the OpenVPN protocol the server runs.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here for your reference (not parsed).</span></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Client configuration</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Interface</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Port</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+ <br>
+ Paste a CA certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Client certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="cli_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['cli_cert']));?></textarea>
+ <br>
+ Paste a client certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Client key</td>
+ <td width="78%" class="vtable">
+ <textarea name="cli_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['cli_key']));?></textarea>
+ <br>Paste the client RSA private key here.</td>
+ </tr>
+
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Crypto</td>
+ <td width="78%" class="vtable">
+ <select name="crypto" class="formfld">
+ <?php $cipher_list = ovpn_get_cipher_list();
+ foreach($cipher_list as $key => $value){
+ ?>
+ <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+ <?= $value ?>
+ </option>
+ <?php
+ }
+ ?>
+ </select>
+ <br>
+ Select the data channel encryption cipher. This must match the setting on the server.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Options</td>
+ <td width="78%" class="vtable">
+ <input type="checkbox" name="pull" value="yes" <?php if ($pconfig['pull']) echo "checked"; ?>>
+ Client-pull</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id)): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp.php b/usr/local/www/vpn_pptp.php
new file mode 100755
index 0000000..b796639
--- /dev/null
+++ b/usr/local/www/vpn_pptp.php
@@ -0,0 +1,309 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_pptp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['radius'])) {
+ $config['pptpd']['radius'] = array();
+}
+$pptpcfg = &$config['pptpd'];
+
+$pconfig['remoteip'] = $pptpcfg['remoteip'];
+$pconfig['localip'] = $pptpcfg['localip'];
+$pconfig['redir'] = $pptpcfg['redir'];
+$pconfig['mode'] = $pptpcfg['mode'];
+$pconfig['req128'] = isset($pptpcfg['req128']);
+$pconfig['radiusenable'] = isset($pptpcfg['radius']['enable']);
+$pconfig['radacct_enable'] = isset($pptpcfg['radius']['accounting']);
+$pconfig['radiusserver'] = $pptpcfg['radius']['server'];
+$pconfig['radiussecret'] = $pptpcfg['radius']['secret'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['mode'] == "server") {
+ $reqdfields = explode(" ", "localip remoteip");
+ $reqdfieldsn = explode(",", "Server address,Remote start address");
+
+ if ($_POST['radiusenable']) {
+ $reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
+ $reqdfieldsn = array_merge($reqdfieldsn,
+ explode(",", "RADIUS server address,RADIUS shared secret"));
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['localip'] && !is_ipaddr($_POST['localip']))) {
+ $input_errors[] = "A valid server address must be specified.";
+ }
+ if (($_POST['subnet'] && !is_ipaddr($_POST['remoteip']))) {
+ $input_errors[] = "A valid remote start address must be specified.";
+ }
+ if (($_POST['radiusserver'] && !is_ipaddr($_POST['radiusserver']))) {
+ $input_errors[] = "A valid RADIUS server address must be specified.";
+ }
+
+ if (!$input_errors) {
+ $_POST['remoteip'] = $pconfig['remoteip'] = gen_subnet($_POST['remoteip'], $g['pptp_subnet']);
+ $subnet_start = ip2long($_POST['remoteip']);
+ $subnet_end = ip2long($_POST['remoteip']) + $g['n_pptp_units'] - 1;
+
+ if ((ip2long($_POST['localip']) >= $subnet_start) &&
+ (ip2long($_POST['localip']) <= $subnet_end)) {
+ $input_errors[] = "The specified server address lies in the remote subnet.";
+ }
+ if ($_POST['localip'] == $config['interfaces']['lan']['ipaddr']) {
+ $input_errors[] = "The specified server address is equal to the LAN interface address.";
+ }
+ }
+ } else if ($_POST['mode'] == "redir") {
+ $reqdfields = explode(" ", "redir");
+ $reqdfieldsn = explode(",", "PPTP redirection target address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['redir'] && !is_ipaddr($_POST['redir']))) {
+ $input_errors[] = "A valid target address must be specified.";
+ }
+ }
+
+ if (!$input_errors) {
+ $pptpcfg['remoteip'] = $_POST['remoteip'];
+ $pptpcfg['redir'] = $_POST['redir'];
+ $pptpcfg['localip'] = $_POST['localip'];
+ $pptpcfg['mode'] = $_POST['mode'];
+ $pptpcfg['req128'] = $_POST['req128'] ? true : false;
+ $pptpcfg['radius']['enable'] = $_POST['radiusenable'] ? true : false;
+ $pptpcfg['radius']['accounting'] = $_POST['radacct_enable'] ? true : false;
+ $pptpcfg['radius']['server'] = $_POST['radiusserver'];
+ $pptpcfg['radius']['secret'] = $_POST['radiussecret'];
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = vpn_pptpd_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title><?=gentitle("VPN: PPTP");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function get_radio_value(obj)
+{
+ for (i = 0; i < obj.length; i++) {
+ if (obj[i].checked)
+ return obj[i].value;
+ }
+ return null;
+}
+
+function enable_change(enable_over) {
+ if ((get_radio_value(document.iform.mode) == "server") || enable_over) {
+ document.iform.remoteip.disabled = 0;
+ document.iform.localip.disabled = 0;
+ document.iform.req128.disabled = 0;
+ document.iform.radiusenable.disabled = 0;
+
+ if (document.iform.radiusenable.checked || enable_over) {
+ document.iform.radacct_enable.disabled = 0;
+ document.iform.radiusserver.disabled = 0;
+ document.iform.radiussecret.disabled = 0;
+ } else {
+ document.iform.radacct_enable.disabled = 1;
+ document.iform.radiusserver.disabled = 1;
+ document.iform.radiussecret.disabled = 1;
+ }
+ } else {
+ document.iform.remoteip.disabled = 1;
+ document.iform.localip.disabled = 1;
+ document.iform.req128.disabled = 1;
+ document.iform.radiusenable.disabled = 1;
+ document.iform.radacct_enable.disabled = 1;
+ document.iform.radiusserver.disabled = 1;
+ document.iform.radiussecret.disabled = 1;
+ }
+ if ((get_radio_value(document.iform.mode) == "redir") || enable_over) {
+ document.iform.redir.disabled = 0;
+ } else {
+ document.iform.redir.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP</p>
+<form action="vpn_pptp.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Configuration</li>
+ <li class="tabinact"><a href="vpn_pptp_users.php">Users</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="mode" type="radio" onclick="enable_change(false)" value="off"
+ <?php if (($pconfig['mode'] != "server") && ($pconfig['mode'] != "redir")) echo "checked";?>>
+ Off</td>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input type="radio" name="mode" value="redir" onclick="enable_change(false)" <?php if ($pconfig['mode'] == "redir") echo "checked"; ?>>
+ Redirect incoming PPTP connections to:</td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">PPTP redirection</td>
+ <td width="78%" class="vtable">
+ <input name="redir" type="text" class="formfld" id="redir" size="20" value="<?=htmlspecialchars($pconfig['redir']);?>">
+ <br>
+ Enter the IP address of a host which will accept incoming
+ PPTP connections.</td>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input type="radio" name="mode" value="server" onclick="enable_change(false)" <?php if ($pconfig['mode'] == "server") echo "checked"; ?>>
+ Enable PPTP server</td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Max. concurrent
+ connections</td>
+ <td width="78%" class="vtable">
+ <?=$g['n_pptp_units'];?>
+ </td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server address</td>
+ <td width="78%" class="vtable">
+ <input name="localip" type="text" class="formfld" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>">
+ <br>
+ Enter the IP address the PPTP server should use on its side
+ for all clients.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Remote address
+ range</td>
+ <td width="78%" class="vtable">
+ <input name="remoteip" type="text" class="formfld" id="remoteip" size="20" value="<?=htmlspecialchars($pconfig['remoteip']);?>">
+ /
+ <?=$g['pptp_subnet'];?>
+ <br>
+ Specify the starting address for the client IP address subnet.<br>
+ The PPTP server will assign
+ <?=$g['n_pptp_units'];?>
+ addresses, starting at the address entered above, to clients.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">RADIUS</td>
+ <td width="78%" class="vtable">
+ <p>
+ <input name="radiusenable" type="checkbox" id="radiusenable" onclick="enable_change(false)" value="yes" <?php if ($pconfig['radiusenable'] == "yes") echo "checked"; ?>>
+ <strong>Use a RADIUS server for authentication<br>
+ </strong>When set, all users will be authenticated using
+ the RADIUS server specified below. The local user database
+ will not be used.<br>
+ <br>
+ <input name="radacct_enable" type="checkbox" id="radacct_enable" onclick="enable_change(false)" value="yes" <?php if ($pconfig['radacct_enable'] == "yes") echo "checked"; ?>>
+ <strong>Enable RADIUS accounting <br>
+ </strong>Sends accounting packets to the RADIUS server. </p></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">RADIUS server </td>
+ <td width="78%" class="vtable">
+ <p>
+ <input name="radiusserver" type="text" class="formfld" id="radiusserver" size="20" value="<?=htmlspecialchars($pconfig['radiusserver']);?>">
+ <br>
+ Enter the IP address of the RADIUS server.</p></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">RADIUS shared secret</td>
+ <td width="78%" valign="top" class="vtable">
+ <p>
+ <input name="radiussecret" type="password" class="formfld" id="radiussecret" size="20" value="<?=htmlspecialchars($pconfig['radiussecret']);?>">
+ <br>
+ Enter the shared secret that will be used to authenticate
+ to the RADIUS server.</p></td>
+ </tr>
+ <tr>
+ <td height="16" colspan="2" valign="top"></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="middle">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="req128" type="checkbox" id="req128" value="yes" <?php if ($pconfig['req128'] == "yes") echo "checked"; ?>>
+ <strong>Require 128-bit encryption</strong><br>
+ When set, 128-bit encryption will be accepted. Otherwise,
+ 40-bit and 56-bit encryption will be accepted, too. Note that
+ encryption will always be forced on PPTP connections (i.e.
+ unencrypted connections will not be accepted).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>don't forget to add a firewall rule to permit
+ traffic from PPTP clients!</span></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp_users.php b/usr/local/www/vpn_pptp_users.php
new file mode 100755
index 0000000..0122734
--- /dev/null
+++ b/usr/local/www/vpn_pptp_users.php
@@ -0,0 +1,126 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_pptp_users.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['user'])) {
+ $config['pptpd']['user'] = array();
+}
+pptpd_users_sort();
+$a_secret = &$config['pptpd']['user'];
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = vpn_pptpd_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_pptpuserdirty_path))
+ unlink($d_pptpuserdirty_path);
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_secret[$_GET['id']]) {
+ unset($a_secret[$_GET['id']]);
+ write_config();
+ touch($d_pptpuserdirty_path);
+ header("Location: vpn_pptp_users.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: PPTP: Users");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP: Users</p>
+<form action="vpn_pptp_users.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (isset($config['pptpd']['radius']['enable']))
+ print_info_box("Warning: RADIUS is enabled. The local user database will not be used."); ?>
+<?php if (file_exists($d_pptpuserdirty_path)): ?><p>
+<?php print_info_box_np("The PPTP user list has been modified.<br>You must apply the changes in order for them to take effect.<br><b>Warning: this will terminate all current PPTP sessions!</b>");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_pptp.php">Configuration</a></li>
+ <li class="tabact">Users</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td colspan="3" class="tabcont">
+ <table width="80%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Username</td>
+ <td class="listhdr">IP address</td>
+ <td class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_secret as $secretent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($secretent['name']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($secretent['ip']);?>&nbsp;
+ </td>
+ <td class="list" nowrap> <a href="vpn_pptp_users_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_pptp_users.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this user?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list"> <a href="vpn_pptp_users_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp_users_edit.php b/usr/local/www/vpn_pptp_users_edit.php
new file mode 100755
index 0000000..1b681ee
--- /dev/null
+++ b/usr/local/www/vpn_pptp_users_edit.php
@@ -0,0 +1,159 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_pptp_users_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 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.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['user'])) {
+ $config['pptpd']['user'] = array();
+}
+pptpd_users_sort();
+$a_secret = &$config['pptpd']['user'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_secret[$id]) {
+ $pconfig['username'] = $a_secret[$id]['name'];
+ $pconfig['ip'] = $a_secret[$id]['ip'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if (isset($id) && ($a_secret[$id])) {
+ $reqdfields = explode(" ", "username");
+ $reqdfieldsn = explode(",", "Username");
+ } else {
+ $reqdfields = explode(" ", "username password");
+ $reqdfieldsn = explode(",", "Username,Password");
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['username']))
+ $input_errors[] = "The username contains invalid characters.";
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['password']))
+ $input_errors[] = "The password contains invalid characters.";
+
+ if (($_POST['password']) && ($_POST['password'] != $_POST['password2'])) {
+ $input_errors[] = "The passwords do not match.";
+ }
+ if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+ $input_errors[] = "The IP address entered is not valid.";
+ }
+
+ if (!$input_errors && !(isset($id) && $a_secret[$id])) {
+ /* make sure there are no dupes */
+ foreach ($a_secret as $secretent) {
+ if ($secretent['name'] == $_POST['username']) {
+ $input_errors[] = "Another entry with the same username already exists.";
+ break;
+ }
+ }
+ }
+
+ if (!$input_errors) {
+
+ if (isset($id) && $a_secret[$id])
+ $secretent = $a_secret[$id];
+
+ $secretent['name'] = $_POST['username'];
+ $secretent['ip'] = $_POST['ip'];
+
+ if ($_POST['password'])
+ $secretent['password'] = $_POST['password'];
+
+ if (isset($id) && $a_secret[$id])
+ $a_secret[$id] = $secretent;
+ else
+ $a_secret[] = $secretent;
+
+ write_config();
+ touch($d_pptpuserdirty_path);
+
+ header("Location: vpn_pptp_users.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: PPTP: Users: Edit");?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP: Users: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="vpn_pptp_users_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">Username</td>
+ <td width="78%" class="vtable">
+<input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>">
+ </td>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Password</td>
+ <td width="78%" class="vtable">
+ <input name="password" type="password" class="formfld" id="password" size="20">
+ <br> <input name="password2" type="password" class="formfld" id="password2" size="20">
+ &nbsp;(confirmation)<?php if (isset($id) && $a_secret[$id]): ?><br>
+ <span class="vexpl">If you want to change the users' password,
+ enter it here twice.</span><?php endif; ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ip" type="text" class="formfld" id="ip" size="20" value="<?=htmlspecialchars($pconfig['ip']);?>">
+ <br><span class="vexpl">If you want the user to be assigned a specific IP address, enter it here.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_secret[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/sbin/config_lock.sh b/usr/sbin/config_lock.sh
new file mode 100755
index 0000000..a84d855
--- /dev/null
+++ b/usr/sbin/config_lock.sh
@@ -0,0 +1,9 @@
+#! /usr/local/bin/php -f
+
+
+<?php
+
+require_once("config.inc");
+config_unlock();
+
+?>
diff --git a/usr/sbin/config_unlock.sh b/usr/sbin/config_unlock.sh
new file mode 100755
index 0000000..f534abc
--- /dev/null
+++ b/usr/sbin/config_unlock.sh
@@ -0,0 +1,9 @@
+#! /usr/local/bin/php -f
+
+
+<?php
+
+require_once("config.inc");
+config_lock();
+
+?>
OpenPOWER on IntegriCloud