From: mkasper Date: Sat, 7 Jan 2006 22:32:13 +0000 (+0000) Subject: Import m0n0wall 1.1 files. X-Git-Url: https://git.gsnw.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6701349d71b8db601d5541a1d7314ab62196fd63;p=m0n0chwall.git Import m0n0wall 1.1 files. git-svn-id: https://svn.m0n0.ch/wall/trunk@4 e36fee2c-cc09-0410-a7cc-ebac5c6737de --- diff --git a/captiveportal/index.php b/captiveportal/index.php new file mode 100644 index 0000000..4b14fb7 --- /dev/null +++ b/captiveportal/index.php @@ -0,0 +1,341 @@ +#!/usr/local/bin/php +. + 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']; + +/* find MAC address for client */ +if ($clientip) { + $clientmac = arp_get_mac_by_ip($clientip); + if (!$clientmac) { + /* unable to find MAC address - shouldn't happen! - bail out */ + exit; + } +} + +if (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 */ + + $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r"); + if($fd) { + $line = trim(fgets($fd)); + if($line) + list($radiusip,$radiusport,$radiuskey) = explode(",",$line) ; + } + fclose($fd) ; + + if($_POST['auth_user'] && $_POST['auth_pass']) { + $auth_val = RADIUS_AUTHENTICATION($_POST['auth_user'], + $_POST['auth_pass'], + $radiusip,$radiusport, + $radiuskey) ; + if ($auth_val == 2) { + portal_allow($clientip, $clientmac,$_POST['auth_user']) ; + if(isset($config['captiveportal']['radacct_enable'])) { + $auth_val = RADIUS_ACCOUNTING_START($_POST['auth_user'], + $radiusip,$radiusport, + $radiuskey) ; + } + } 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'] && ($clientmac == $_POST['logout_id']) ) { + disconnect_client($_POST['logout_id']) ; + echo << +Disconnecting... + + +You've been disconnected. + + + + + +EOD; +} else { + /* display captive portal page */ + readfile("{$g['varetc_path']}/captiveportal.html"); +} + +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 ; + + /* 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 */ + $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 passthru mac 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) ; + } + + /* find entry and delete it */ + + for ($i = 0; $i < count($cpdb); $i++) { + if(!strcasecmp($cpdb[$i][3],$clientmac)) { + if(isset($config['captiveportal']['radacct_enable']) && + file_exists("{$g['vardb_path']}/captiveportal_radius.db")) { + RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno + $cpdb[$i][4], // username + $cpdb[$i][0], // start time + $config['captiveportal']['radiusip'], + $config['captiveportal']['radiusport'], + $config['captiveportal']['radiuskey'] ) ; + } + 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 for clientmac */ + fwrite($fd, time().",{$ruleno},{$clientip},{$clientmac},{$clientuser}\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(isset($config['captiveportal']['logoutwin_enable'])) { + echo << +Redirecting... + + +Redirecting to http://{$orig_host}{$orig_request}... + + + + + +EOD; + } else { + header("Location: http://" . $orig_host . $orig_request); + } +} + +/* 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 mac address + by Dinesh Nair Thu Jul 29 18:46:38 MYT 2004 + */ +function disconnect_client($macaddr) { + + 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) ; + } + + /* find entry */ + for ($i = 0; $i < count($cpdb); $i++) { + if ($cpdb[$i][3] == $macaddr) { + /* this client needs to be deleted - remove ipfw rules */ + if(isset($config['captiveportal']['radacct_enable']) && + file_exists("{$g['vardb_path']}/captiveportal_radius.db")) { + RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno + $cpdb[$i][4], // username + $cpdb[$i][0], // start time + $config['captiveportal']['radiusip'], + $config['captiveportal']['radiusport'], + $config['captiveportal']['radiuskey'] ) ; + } + 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"); + } + } + + portal_unlock(); +} +?> diff --git a/captiveportal/radius_accounting.inc b/captiveportal/radius_accounting.inc new file mode 100644 index 0000000..d7c9129 --- /dev/null +++ b/captiveportal/radius_accounting.inc @@ -0,0 +1,247 @@ + + 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,$radiusip,$radiusport,$radiuskey) { + $sharedsecret=$radiuskey ; + # $debug = 1 ; + + $radiusport=getservbyname("radacct","udp"); + + exec("/bin/hostname", $nasHostname) ; + if(!$nasHostname[0]) + $nasHostname[0] = "quewall" ; + + $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 "
radius-port: $radiusport
radius-host: $radiusip
username: $username
\n"; + + $thisidentifier=rand()%256; + $sessionid = $username."-".$nasHostname[0] ; + + $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 "
writing $length bytes
\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,$start_time,$radiusip,$radiusport,$radiuskey) { + $sharedsecret=$radiuskey ; + # $debug = 1 ; + + $radiusport=getservbyname("radacct","udp"); + + 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 "
radius-port: $radiusport
radius-host: $radiusip
username: $username
\n"; + + $thisidentifier=rand()%256; + $sessionid = $username."-".$nasHostname[0] ; + + $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 "
writing $length bytes
\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/captiveportal/radius_authentication.inc b/captiveportal/radius_authentication.inc new file mode 100644 index 0000000..c81836f --- /dev/null +++ b/captiveportal/radius_authentication.inc @@ -0,0 +1,136 @@ + + // 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 ; + + if(!$radiusport) + $radiusport=0 ; + + // check your /etc/services. Some radius servers + // listen on port 1812, some on 1645. + if ($radiusport==0) + $radiusport=getservbyname("radius","udp"); + + 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 "
radius-port: $radiusport
radius-host: $radiusip
username: $username
\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 "
writing $length bytes
\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 "
key: $key
password: $password
\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/phpconf/config.xml b/phpconf/config.xml index 40f58ac..4726d6b 100644 --- a/phpconf/config.xml +++ b/phpconf/config.xml @@ -22,6 +22,7 @@ --> + @@ -37,8 +38,9 @@ sis1 + dhcp - + @@ -72,6 +74,15 @@ --> + dyndns @@ -178,9 +196,25 @@ --> + + + + diff --git a/phpconf/inc/captiveportal.inc b/phpconf/inc/captiveportal.inc new file mode 100644 index 0000000..344d432 --- /dev/null +++ b/phpconf/inc/captiveportal.inc @@ -0,0 +1,566 @@ +. + 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. +*/ + +/* include all configuration functions */ +require_once("functions.inc"); +require_once("radius_accounting.inc") ; + +function captiveportal_configure() { + global $config, $g; + + if (isset($config['captiveportal']['enable']) && + (($config['captiveportal']['interface'] == "lan") || + isset($config['interfaces'][$config['captiveportal']['interface']]['enable']))) { + + if ($g['booting']) + echo "Starting captive portal... "; + + /* kill any running mini_httpd */ + killbypid("{$g['varrun_path']}/mini_httpd.cp.pid"); + + /* kill any running minicron */ + killbypid("{$g['varrun_path']}/minicron.pid"); + + /* generate ipfw rules */ + $cprules = captiveportal_rules_generate(); + + /* make sure ipfw is loaded */ + mwexec("/sbin/kldload ipfw"); + + /* stop accounting on all clients */ + captiveportal_radius_stop_all() ; + + /* remove old information */ + unlink_if_exists("{$g['vardb_path']}/captiveportal.nextrule"); + unlink_if_exists("{$g['vardb_path']}/captiveportal.db"); + unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db"); + unlink_if_exists("{$g['vardb_path']}/captiveportal_ip.db"); + unlink_if_exists("{$g['vardb_path']}/captiveportal_radius.db"); + + /* write portal page */ + if ($config['captiveportal']['page']['htmltext']) + $htmltext = base64_decode($config['captiveportal']['page']['htmltext']); + else { + /* example/template page */ + $htmltext = << + +m0n0wall captive portal + + +

m0n0wall captive portal

+

This is the default captive portal page. Please upload your own custom HTML file on the Services: Captive portal screen in the m0n0wall webGUI.

+
+ +
+ + + +EOD; + } + + $fd = @fopen("{$g['varetc_path']}/captiveportal.html", "w"); + if ($fd) { + fwrite($fd, $htmltext); + fclose($fd); + } + + /* write error page */ + if ($config['captiveportal']['page']['errtext']) + $errtext = base64_decode($config['captiveportal']['page']['errtext']); + else { + /* example page */ + $errtext = << + +Authentication error + + +

Authentication error

+ +Username and/or password invalid. +

+Go back +
+ + + +EOD; + } + + $fd = @fopen("{$g['varetc_path']}/captiveportal-error.html", "w"); + if ($fd) { + fwrite($fd, $errtext); + fclose($fd); + } + + /* load rules */ + mwexec("/sbin/ipfw -f delete set 1"); + mwexec("/sbin/ipfw -f delete set 2"); + mwexec("/sbin/ipfw -f delete set 3"); + + /* XXX - seems like ipfw cannot accept rules directly on stdin, + so we have to write them to a temporary file first */ + $fd = @fopen("{$g['tmp_path']}/ipfw.cp.rules", "w"); + if (!$fd) { + printf("Cannot open ipfw.cp.rules in captiveportal_configure()\n"); + return 1; + } + + fwrite($fd, $cprules); + fclose($fd); + + mwexec("/sbin/ipfw {$g['tmp_path']}/ipfw.cp.rules"); + + unlink("{$g['tmp_path']}/ipfw.cp.rules"); + + /* filter on layer2 as well so we can check MAC addresses */ + mwexec("/sbin/sysctl net.link.ether.ipfw=1"); + + chdir($g['captiveportal_path']); + + /* start web server */ + mwexec("/usr/local/sbin/mini_httpd -a -M 0 -u root -maxproc 16" . + " -p 8000 -i {$g['varrun_path']}/mini_httpd.cp.pid"); + + /* start pruning process (interval = 60 seconds) */ + mwexec("/usr/local/bin/minicron 60 {$g['varrun_path']}/minicron.pid " . + "/etc/rc.prunecaptiveportal"); + + /* generate passthru mac database */ + captiveportal_passthrumac_configure() ; + /* create allowed ip database and insert ipfw rules to make it so */ + captiveportal_allowedip_configure() ; + + /* generate radius server database */ + if($config['captiveportal']['radiusip']) { + $radiusip = $config['captiveportal']['radiusip'] ; + + if($config['captiveportal']['radiusport']) + $radiusport = $config['captiveportal']['radiusport'] ; + + if($config['captiveportal']['radiuskey']) + $radiuskey = $config['captiveportal']['radiuskey'] ; + + $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db", "w"); + if (!$fd) { + printf("Error: cannot open radius DB file in captiveportal_configure().\n"); + return 1; + } else { + fwrite($fd,$radiusip . "," . $radiusport . "," . $radiuskey) ; + } + fclose($fd) ; + } + + + if ($g['booting']) + echo "done\n"; + + } else { + killbypid("{$g['varrun_path']}/mini_httpd.cp.pid"); + killbypid("{$g['varrun_path']}/minicron.pid"); + captiveportal_radius_stop_all() ; + mwexec("/sbin/sysctl net.link.ether.ipfw=0"); + if (!isset($config['shaper']['enable'])) { + /* unload ipfw */ + mwexec("/sbin/kldunload ipfw"); + } else { + /* shaper is on - just remove our rules */ + mwexec("/sbin/ipfw -f delete set 1"); + mwexec("/sbin/ipfw -f delete set 2"); + mwexec("/sbin/ipfw -f delete set 3"); + } + } + + return 0; +} + +function captiveportal_rules_generate() { + global $config, $g; + + $cpifn = $config['captiveportal']['interface']; + $cpif = $config['interfaces'][$cpifn]['if']; + $cpip = $config['interfaces'][$cpifn]['ipaddr']; + + /* note: the captive portal daemon inserts all pass rules for authenticated + clients as skipto 50000 rules to make traffic shaping work */ + + $cprules = ""; + + /* captive portal on LAN interface? */ + if ($cpifn == "lan") { + /* add anti-lockout rules */ + $cprules .= <<= $timeout) + $timedout = true; + } + + /* if an idle timeout is specified, get last activity timestamp from ipfw */ + if (!$timedout && $idletimeout) { + $lastact = captiveportal_get_last_activity($cpdb[$i][1]); + if ($lastact && ((time() - $lastact) >= $idletimeout)) + $timedout = true; + } + + if ($timedout) { + /* this client needs to be deleted - remove ipfw rules */ + if(isset($config['captiveportal']['radacct_enable']) && + file_exists("{$g['vardb_path']}/captiveportal_radius.db")) { + RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno + $cpdb[$i][4], // username + $cpdb[$i][0], // start time + $config['captiveportal']['radiusip'], + $config['captiveportal']['radiusport'], + $config['captiveportal']['radiuskey'] ) ; + } + mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000)); + unset($cpdb[$i]); + } + } + + /* write database */ + captiveportal_write_db($cpdb); + + captiveportal_unlock(); +} + +/* remove a single client by ipfw rule number */ +function captiveportal_disconnect_client($id) { + + global $g, $config; + + captiveportal_lock(); + + /* read database */ + $cpdb = captiveportal_read_db(); + + /* find entry */ + for ($i = 0; $i < count($cpdb); $i++) { + if ($cpdb[$i][1] == $id) { + /* this client needs to be deleted - remove ipfw rules */ + if(isset($config['captiveportal']['radacct_enable']) && + file_exists("{$g['vardb_path']}/captiveportal_radius.db")) { + RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno + $cpdb[$i][4], // username + $cpdb[$i][0], // start time + $config['captiveportal']['radiusip'], + $config['captiveportal']['radiusport'], + $config['captiveportal']['radiuskey'] ) ; + } + mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000)); + unset($cpdb[$i]); + break; + } + } + + /* write database */ + captiveportal_write_db($cpdb); + + captiveportal_unlock(); +} + +/* send RADIUS acct stop for all current clients */ +function captiveportal_radius_stop_all() { + global $g, $config ; + + if(!isset($config['captiveportal']['radacct_enable']) || + !file_exists("{$g['vardb_path']}/captiveportal_radius.db")) { + return ; + } + + captiveportal_lock() ; + $cpdb = captiveportal_read_db() ; + for ($i = 0; $i < count($cpdb); $i++) { + RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno + $cpdb[$i][4], // username + $cpdb[$i][0], // start time + $config['captiveportal']['radiusip'], + $config['captiveportal']['radiusport'], + $config['captiveportal']['radiuskey'] ) ; + } + captiveportal_unlock() ; +} + +function captiveportal_passthrumac_configure() { + global $config, $g; + + /* clear out passthru macs, if necessary */ + if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) { + unlink("{$g['vardb_path']}/captiveportal_mac.db"); + } + + if (is_array($config['captiveportal']['passthrumac'])) { + + $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db", "w"); + if (!$fd) { + printf("Error: cannot open passthru mac DB file in captiveportal_passthrumac_configure().\n"); + return 1; + } + + foreach ($config['captiveportal']['passthrumac'] as $macent) { + /* record passthru mac so it can be recognized and let thru */ + fwrite($fd, $macent['mac'] . "\n"); + } + + fclose($fd); + } + + return 0; +} + +function captiveportal_allowedip_configure() { + global $config, $g; + + captiveportal_lock() ; + + /* clear out existing allowed ips, if necessary */ + if (file_exists("{$g['vardb_path']}/captiveportal_ip.db")) { + $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "r"); + if ($fd) { + while (!feof($fd)) { + $line = trim(fgets($fd)); + if($line) { + list($ip,$rule) = explode(",",$line); + mwexec("/sbin/ipfw delete $rule") ; + } + } + } + fclose($fd) ; + unlink("{$g['vardb_path']}/captiveportal_ip.db"); + } + + /* 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 */ + + if (is_array($config['captiveportal']['allowedip'])) { + + $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "w"); + if (!$fd) { + printf("Error: cannot open allowed ip DB file in captiveportal_allowedip_configure().\n"); + captiveportal_unlock() ; + return 1; + } + + foreach ($config['captiveportal']['allowedip'] as $ipent) { + /* record allowed ip so it can be recognized and removed later */ + fwrite($fd, $ipent['ip'] . "," . $ruleno ."\n"); + /* insert ipfw rule to allow ip thru */ + if($ipent['dir'] == "from") { + mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from ".$ipent['ip']." to any in") ; + mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to ".$ipent['ip']." out") ; + } else { + mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to ".$ipent['ip']." in") ; + mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from ".$ipent['ip']." to any out") ; + } + $ruleno++ ; + if ($ruleno > 19899) + $ruleno = 10000; + } + + fclose($fd); + + /* write next rule number */ + $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w"); + if ($fd) { + fwrite($fd, $ruleno); + fclose($fd); + } + } + + captiveportal_unlock() ; + return 0; +} + +/* get last activity timestamp given ipfw rule number */ +function captiveportal_get_last_activity($ruleno) { + + exec("/sbin/ipfw -T list {$ruleno} 2>/dev/null", $ipfwoutput); + + /* in */ + if ($ipfwoutput[0]) { + $ri = explode(" ", $ipfwoutput[0]); + if ($ri[1]) + return $ri[1]; + } + + return 0; +} + +/* read captive portal DB into array */ +function captiveportal_read_db() { + + global $g; + + $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); + } + return $cpdb; +} + +/* write captive portal DB */ +function captiveportal_write_db($cpdb) { + + global $g; + + $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w"); + if ($fd) { + foreach ($cpdb as $cpent) { + fwrite($fd, join(",", $cpent) . "\n"); + } + fclose($fd); + } +} + +/* lock captive portal information, decide that the lock file is stale after + 10 seconds */ +function captiveportal_lock() { + + global $g; + + $lockfile = "{$g['varrun_path']}/captiveportal.lock"; + + $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 configuration file */ +function captiveportal_unlock() { + + global $g; + + $lockfile = "{$g['varrun_path']}/captiveportal.lock"; + + if (file_exists($lockfile)) + unlink($lockfile); +} + +?> diff --git a/phpconf/inc/config.inc b/phpconf/inc/config.inc index ad3ecc0..5dd98ee 100644 --- a/phpconf/inc/config.inc +++ b/phpconf/inc/config.inc @@ -52,12 +52,16 @@ if ($g['booting']) { $cfgdevice = $cfgpartition = "fd0"; $cfgfstype = "msdos"; } else { - /* probe ad0...ad3 until we find the one with config.xml */ - for ($cfgn = 0; $cfgn <= 3; $cfgn++) { - if (mwexec("/sbin/mount -r /dev/ad{$cfgn}a {$g['cf_path']}") == 0) { + /* probe kernel known disks until we find one with config.xml */ + $disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks")))); + foreach ($disks as $mountdisk) { + /* skip mfs mounted filesystems */ + if (strstr($mountdisk, "md")) + continue; + if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) { if (file_exists("{$g['cf_conf_path']}/config.xml")) { /* found it */ - $cfgdevice = "ad" . $cfgn; + $cfgdevice = $mountdisk; $cfgpartition = $cfgdevice . "a"; $cfgfstype = "ufs"; echo "Found configuration on $cfgdevice.\n"; @@ -77,9 +81,9 @@ if ($g['booting']) { ******************************************************************************* -* FATAL ERROR * -* The device that contains the configuration file (config.xml) could not be * -* found. m0n0wall cannot continue booting. * +* FATAL ERROR * +* The device that contains the configuration file (config.xml) could not be * +* found. m0n0wall cannot continue booting. * ******************************************************************************* @@ -151,11 +155,11 @@ if (!$noparseconfig) { ******************************************************************************* -* WARNING! * +* WARNING! * * The current configuration has been created with a newer version of m0n0wall * -* than this one! This can lead to serious misbehavior and even security * -* holes! You are urged to either upgrade to a newer version of m0n0wall or * -* revert to the default configuration immediately! * +* than this one! This can lead to serious misbehavior and even security * +* holes! You are urged to either upgrade to a newer version of m0n0wall or * +* revert to the default configuration immediately! * ******************************************************************************* diff --git a/phpconf/inc/filter.inc b/phpconf/inc/filter.inc index 74e74b8..7150c7d 100644 --- a/phpconf/inc/filter.inc +++ b/phpconf/inc/filter.inc @@ -74,6 +74,19 @@ function filter_configure() { fwrite($fd, $ipfrules); pclose($fd); + /* set up MSS clamping */ + $wanif = get_real_wan_interface(); + + if ($config['interfaces']['wan']['mtu']) + $mssclamp = $config['interfaces']['wan']['mtu'] - 40; + else if ($config['interfaces']['wan']['ipaddr'] == "pppoe") + $mssclamp = 1452; + else + $mssclamp = 0; + + mwexec("/sbin/sysctl net.inet.ipf.fr_mssif={$wanif}"); + mwexec("/sbin/sysctl net.inet.ipf.fr_mssclamp={$mssclamp}"); + if ($g['booting']) echo "done\n"; @@ -92,7 +105,7 @@ function filter_flush_state_table() { return mwexec("/sbin/ipf -FS"); } -function filter_nat_rules_generate_if($if, $src, $dst, $target, $mssclamp) { +function filter_nat_rules_generate_if($if, $src, $dst, $target) { if ($target) $tgt = $target . "/32"; @@ -100,9 +113,9 @@ function filter_nat_rules_generate_if($if, $src, $dst, $target, $mssclamp) { $tgt = "0/32"; $natrule = << {$tgt} proxy port ftp ftp/tcp $mssclamp -map $if $src $dst -> {$tgt} portmap tcp/udp auto $mssclamp -map $if $src $dst -> {$tgt} $mssclamp +map $if $src $dst -> {$tgt} proxy port ftp ftp/tcp +map $if $src $dst -> {$tgt} portmap tcp/udp auto +map $if $src $dst -> {$tgt} EOD; @@ -118,13 +131,6 @@ function filter_nat_rules_generate() { $pptpdcfg = $config['pptpd']; $wanif = get_real_wan_interface(); - if ($wancfg['mtu']) - $mssclamp = "mssclamp " . ($wancfg['mtu'] - 40); - else if ($wancfg['ipaddr'] == "pppoe") - $mssclamp = "mssclamp 1452"; - else - $mssclamp = ""; - $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']); $natrules = ""; @@ -136,7 +142,13 @@ function filter_nat_rules_generate() { $sn = 32; else $sn = $natent['subnet']; - $natrules .= "bimap {$wanif} {$natent['internal']}/{$sn} -> {$natent['external']}/{$sn}\n"; + + if (!$natent['interface'] || ($natent['interface'] == "wan")) + $natif = $wanif; + else + $natif = $config['interfaces'][$natent['interface']]['if']; + + $natrules .= "bimap {$natif} {$natent['internal']}/{$sn} -> {$natent['external']}/{$sn}\n"; } } @@ -157,23 +169,42 @@ function filter_nat_rules_generate() { } $src .= $obent['source']['network']; - $natrules .= filter_nat_rules_generate_if($wanif, $src, $dst, - $obent['target'], $mssclamp); + if (!$obent['interface'] || ($obent['interface'] == "wan")) + $natif = $wanif; + else + $natif = $config['interfaces'][$obent['interface']]['if']; + + $natrules .= filter_nat_rules_generate_if($natif, $src, $dst, + $obent['target']); } } } else { /* standard outbound rules (one for each interface) */ $natrules .= filter_nat_rules_generate_if($wanif, - $lansa . "/" . $lancfg['subnet'], "", null, $mssclamp); + $lansa . "/" . $lancfg['subnet'], "", null); /* optional interfaces */ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) { $optcfg = $config['interfaces']['opt' . $i]; - if (isset($optcfg['enable'])) { + if (isset($optcfg['enable']) && !$optcfg['bridge']) { $optsa = gen_subnet($optcfg['ipaddr'], $optcfg['subnet']); $natrules .= filter_nat_rules_generate_if($wanif, - $optsa . "/" . $optcfg['subnet'], "", null, $mssclamp); + $optsa . "/" . $optcfg['subnet'], "", null); + } + } + + /* PPTP subnet */ + if ($pptpdcfg['mode'] == "server") { + $natrules .= filter_nat_rules_generate_if($wanif, + $pptpdcfg['remoteip'] . "/" . $g['pptp_subnet'], "", null); + } + + /* static routes */ + if (is_array($config['staticroutes']['route'])) { + foreach ($config['staticroutes']['route'] as $route) { + $natrules .= filter_nat_rules_generate_if($wanif, + $route['network'], "", null); } } } @@ -198,18 +229,21 @@ function filter_nat_rules_generate() { else $extaddr = "0/0"; + if (!$rule['interface'] || ($rule['interface'] == "wan")) + $natif = $wanif; + else + $natif = $config['interfaces'][$rule['interface']]['if']; + if ((!$extport[1]) || ($extport[0] == $extport[1])) { $natrules .= - "rdr $wanif {$extaddr} port {$extport[0]} -> {$target} " . + "rdr $natif {$extaddr} port {$extport[0]} -> {$target} " . "port {$rule['local-port']} {$rule['protocol']}"; } else { $natrules .= - "rdr $wanif {$extaddr} port {$extport[0]}-{$extport[1]} " . + "rdr $natif {$extaddr} port {$extport[0]}-{$extport[1]} " . "-> {$target} " . "port {$rule['local-port']} {$rule['protocol']}"; } - - $natrules .= " {$mssclamp}"; $natrules .= "\n"; } @@ -226,7 +260,7 @@ function filter_nat_rules_generate() { # PPTP rdr $wanif 0/0 port 0 -> $pptpdtarget port 0 gre -rdr $wanif 0/0 port 1723 -> $pptpdtarget port 1723 tcp {$mssclamp} +rdr $wanif 0/0 port 1723 -> $pptpdtarget port 1723 tcp EOD; } @@ -262,15 +296,21 @@ function filter_rules_generate() { $oic['if'] = $oc['if']; if ($oc['bridge']) { - $oic['ip'] = $config['interfaces'][$oc['bridge']]['ipaddr']; - $oic['sn'] = $config['interfaces'][$oc['bridge']]['subnet']; + if (!strstr($oc['bridge'], "opt") || + isset($config['interfaces'][$oc['bridge']]['enable'])) { + if (is_ipaddr($config['interfaces'][$oc['bridge']]['ipaddr'])) { + $oic['ip'] = $config['interfaces'][$oc['bridge']]['ipaddr']; + $oic['sn'] = $config['interfaces'][$oc['bridge']]['subnet']; + $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']); + } + } $oic['bridge'] = 1; } else { $oic['ip'] = $oc['ipaddr']; $oic['sn'] = $oc['subnet']; + $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']); } - $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']); $optcfg['opt' . $i] = $oic; $ifgroups['opt' . $i] = ($i * 100) + 200; } @@ -308,7 +348,7 @@ EOD; /* allow access to DHCP server on optional interfaces */ foreach ($optcfg as $on => $oc) { - if (isset($config['dhcpd'][$on]['enable'])) { + if (isset($config['dhcpd'][$on]['enable']) && (!$oc['bridge'])) { $ipfrules .= << $oc) { - $ipfrules .= filter_rules_spoofcheck_generate($on, $oc['if'], $oc['sa'], $oc['sn'], $log); + if ($oc['ip']) + $ipfrules .= filter_rules_spoofcheck_generate($on, $oc['if'], $oc['sa'], $oc['sn'], $log); } /* block private networks on WAN? */ @@ -393,7 +466,8 @@ EOD; $ipfrules .= filter_rules_ipsec_generate($lanif, $lanip); foreach ($optcfg as $on => $oc) { - $ipfrules .= filter_rules_ipsec_generate($oc['if'], $oc['ip']); + if ($oc['ip']) + $ipfrules .= filter_rules_ipsec_generate($oc['if'], $oc['ip']); } } @@ -466,6 +540,17 @@ EOD; pass in quick proto gre from any to $pptpdtarget keep state group 200 pass in quick proto tcp from any to $pptpdtarget port = 1723 keep state group 200 +EOD; + } + + /* BigPond client enabled? */ + if ($wancfg['ipaddr'] == "bigpond") { + + $ipfrules .= << diff --git a/phpconf/inc/globals.inc b/phpconf/inc/globals.inc index 33d0291..0068b3a 100644 --- a/phpconf/inc/globals.inc +++ b/phpconf/inc/globals.inc @@ -32,6 +32,7 @@ $g = array( "varrun_path" => "/var/run", "varetc_path" => "/var/etc", "vardb_path" => "/var/db", + "varlog_path" => "/var/log", "etc_path" => "/etc", "tmp_path" => "/tmp", "conf_path" => "/conf", @@ -40,6 +41,7 @@ $g = array( "cf_path" => "/cf", "cf_conf_path" => "/cf/conf", "www_path" => "/usr/local/www", + "captiveportal_path" => "/usr/local/captiveportal", "xml_rootobj" => "m0n0wall", "pppoe_interface" => "ng0", "n_pptp_units" => 16, diff --git a/phpconf/inc/interfaces.inc b/phpconf/inc/interfaces.inc index 8986d1a..0fda400 100644 --- a/phpconf/inc/interfaces.inc +++ b/phpconf/inc/interfaces.inc @@ -39,6 +39,48 @@ function interfaces_loopback_configure() { return 0; } +function interfaces_vlan_configure() { + global $config, $g; + + if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) { + + /* load the VLAN module */ + mwexec("/sbin/kldload if_vlan"); + + /* devices with native VLAN support */ + $vlan_native_supp = explode(" ", "bge em gx nge ti txp"); + + /* devices with long frame support */ + $vlan_long_supp = explode(" ", "dc fxp sis ste tl tx xl"); + + $i = 0; + + foreach ($config['vlans']['vlan'] as $vlan) { + + $cmd = "/sbin/ifconfig vlan{$i} create vlan " . + escapeshellarg($vlan['tag']) . " vlandev " . + escapeshellarg($vlan['if']); + + /* get driver name */ + for ($j = 0; $j < strlen($vlan['if']); $j++) { + if ($vlan['if'][$j] >= '0' && $vlan['if'][$j] <= '9') + break; + } + $drvname = substr($vlan['if'], 0, $j); + + if (in_array($drvname, $vlan_native_supp)) + $cmd .= " link0"; + else if (in_array($drvname, $vlan_long_supp)) + $cmd .= " mtu 1500"; + + mwexec($cmd); + $i++; + } + } + + return 0; +} + function interfaces_lan_configure() { global $config, $g; @@ -270,6 +312,14 @@ function interfaces_wan_configure() { if (file_exists("{$g['varetc_path']}/mpd.links")) { unlink("{$g['varetc_path']}/mpd.links"); } + /* remove ipsec.wanip, if it exists */ + if (file_exists("{$g['vardb_path']}/ipsec.wanip")) { + unlink("{$g['vardb_path']}/ipsec.wanip"); + } + /* remove bigpond.wanip, if it exists */ + if (file_exists("{$g['vardb_path']}/bigpond.wanip")) { + unlink("{$g['vardb_path']}/bigpond.wanip"); + } } /* remove all addresses first */ @@ -298,6 +348,11 @@ function interfaces_wan_configure() { interfaces_wan_pptp_configure(); break; + case 'bigpond': + /* just configure DHCP for now; fire up bpalogin when we've got the lease */ + interfaces_wan_dhcp_configure(); + break; + default: mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " . escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet'])); @@ -401,8 +456,10 @@ pppoe: set link mtu 1492 set ipcp yes vjcomp set ipcp ranges 0.0.0.0/0 0.0.0.0/0 + set ipcp enable req-pri-dns + set ipcp enable req-sec-dns open iface - + EOD; fwrite($fd, $mpdconf); @@ -420,7 +477,9 @@ pppoe: set link type pppoe set pppoe iface {$wancfg['if']} set pppoe service "{$pppoecfg['provider']}" - + set pppoe enable originate + set pppoe disable incoming + EOD; fwrite($fd, $mpdconf); @@ -462,8 +521,10 @@ pptp: set link accept chap set ipcp no vjcomp set ipcp ranges 0.0.0.0/0 0.0.0.0/0 + set ipcp enable req-pri-dns + set ipcp enable req-sec-dns open - + EOD; fwrite($fd, $mpdconf); @@ -479,11 +540,11 @@ EOD; $mpdconf = << /dev/null 2>&1 &"); } function system_reboot_sync() { global $g; + system_reboot_cleanup(); + mwexec("/etc/rc.reboot > /dev/null 2>&1"); } +function system_reboot_cleanup() { + captiveportal_radius_stop_all(); +} + function system_do_shell_commands() { global $config, $g; @@ -453,6 +461,25 @@ function system_do_shell_commands() { } } +function system_do_extensions() { + global $config, $g; + + if (!is_dir("{$g['etc_path']}/inc/ext")) + return; + + $dh = @opendir("{$g['etc_path']}/inc/ext"); + if ($dh) { + while (($extd = readdir($dh)) !== false) { + if (($extd === ".") || ($extd === "..")) + continue; + $rcfile = "{$g['etc_path']}/inc/ext/" . $extd . "/rc"; + if (file_exists($rcfile)) + passthru($rcfile); + } + closedir($dh); + } +} + function system_console_configure() { global $config, $g; @@ -463,4 +490,31 @@ function system_console_configure() { } } +function system_dmesg_save() { + global $g; + + exec("/sbin/dmesg", $dmesg); + + /* find last copyright line (output from previous boots may be present) */ + $lastcpline = 0; + + for ($i = 0; $i < count($dmesg); $i++) { + if (strstr($dmesg[$i], "Copyright (c) 1992-")) + $lastcpline = $i; + } + + $fd = fopen("{$g['varlog_path']}/dmesg.boot", "w"); + if (!$fd) { + printf("Error: cannot open dmesg.boot in system_dmesg_save().\n"); + return 1; + } + + for ($i = $lastcpline; $i < count($dmesg); $i++) + fwrite($fd, $dmesg[$i] . "\n"); + + fclose($fd); + + return 0; +} + ?> diff --git a/phpconf/inc/util.inc b/phpconf/inc/util.inc index cf5fecb..0d74480 100644 --- a/phpconf/inc/util.inc +++ b/phpconf/inc/util.inc @@ -53,12 +53,12 @@ function gen_subnet($ipaddr, $bits) { return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits)); } -/* return the highest address in the subnet given a host address and a subnet bit count */ +/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */ function gen_subnet_max($ipaddr, $bits) { if (!is_ipaddr($ipaddr) || !is_numeric($bits)) return ""; - return long2ip(ip2long($ipaddr) | gen_subnet_mask_long($bits)); + return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits)); } /* returns a subnet mask (long given a bit count) */ @@ -76,6 +76,10 @@ function gen_subnet_mask($bits) { return long2ip(gen_subnet_mask_long($bits)); } +function is_numericint($arg) { + return (preg_match("/[^0-9]/", $arg) ? false : true); +} + /* returns true if $ipaddr is a valid dotted IPv4 address */ function is_ipaddr($ipaddr) { if (!is_string($ipaddr)) @@ -210,7 +214,8 @@ function is_port($port) { return true; } -/* returns a list of interfaces with MAC addresses */ +/* returns a list of interfaces with MAC addresses + (skips VLAN and other virtual interfaces) */ function get_interface_list() { global $g; @@ -228,8 +233,9 @@ function get_interface_list() { if (substr($ifname, -1) == "*") $ifname = substr($ifname, 0, strlen($ifname) - 1); - if (!preg_match("/^(ppp|sl|gif|faith|lo|ng|tun)/", $ifname)) { + if (!preg_match("/^(ppp|sl|gif|faith|lo|ng|tun|vlan)/", $ifname)) { $iflist[$ifname] = array(); + $iflist[$ifname]['mac'] = chop($alink[3]); $iflist[$ifname]['up'] = false; @@ -389,4 +395,20 @@ function verify_digital_signature($fname) { escapeshellarg($fname)); } +/* obtain MAC address given an IP address by looking at the ARP table */ +function arp_get_mac_by_ip($ip) { + exec("/usr/sbin/arp -n {$ip}", $arpoutput); + + if ($arpoutput[0]) { + $arpi = explode(" ", $arpoutput[0]); + $macaddr = $arpi[3]; + if (is_macaddr($macaddr)) + return $macaddr; + else + return false; + } + + return false; +} + ?> diff --git a/phpconf/inc/vpn.inc b/phpconf/inc/vpn.inc index df33dc5..097b14b 100644 --- a/phpconf/inc/vpn.inc +++ b/phpconf/inc/vpn.inc @@ -53,7 +53,9 @@ function vpn_ipsec_configure($ipchg = false) { $syscfg = $config['system']; $ipseccfg = $config['ipsec']; $lancfg = $config['interfaces']['lan']; + $lanip = $lancfg['ipaddr']; $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']); + $lansn = $lancfg['subnet']; if ($g['booting']) { if (!isset($ipseccfg['enable'])) @@ -97,6 +99,10 @@ function vpn_ipsec_configure($ipchg = false) { } $spdconf = ""; + + $spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n"; + $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; + foreach ($ipseccfg['tunnel'] as $tunnel) { if (isset($tunnel['disabled'])) @@ -155,8 +161,11 @@ function vpn_ipsec_configure($ipchg = false) { $myident = $tunnel['p1']['myident']['address']; } else if (isset($tunnel['p1']['myident']['fqdn'])) { $myidentt = "fqdn"; - $myident = $tunnel['p1']['myident']['fqdn']; - } + $myident = $tunnel['p1']['myident']['fqdn']; + } else if (isset($tunnel['p1']['myident']['ufqdn'])) { + $myidentt = "user_fqdn"; + $myident = $tunnel['p1']['myident']['ufqdn']; + } $racoonconf .= << 4094)) { + echo "\nInvalid VLAN tag '{$vlan['tag']}'\n"; + continue; + } + + $config['vlans']['vlan'][] = $vlan; + } + } ?> diff --git a/phpconf/rc.newwanip b/phpconf/rc.newwanip index e99059a..4e0d8cd 100644 --- a/phpconf/rc.newwanip +++ b/phpconf/rc.newwanip @@ -46,7 +46,13 @@ /* reconfigure IPsec tunnels */ vpn_ipsec_configure(true); - /* regenerate resolv.conf if DNS overrides are allowed */ - if (isset($config['system']['dnsallowoverride'])) + /* regenerate resolv.conf if DNS overrides are allowed or the BigPond + client is enabled */ + if (isset($config['system']['dnsallowoverride']) || + ($config['interfaces']['wan']['ipaddr'] == "bigpond")) system_resolvconf_generate(true); + + /* fire up the BigPond client, if necessary */ + if ($config['interfaces']['wan']['ipaddr'] == "bigpond") + interfaces_wan_bigpond_configure(); ?> diff --git a/phpconf/rc.prunecaptiveportal b/phpconf/rc.prunecaptiveportal new file mode 100644 index 0000000..108b029 --- /dev/null +++ b/phpconf/rc.prunecaptiveportal @@ -0,0 +1,37 @@ +#!/usr/local/bin/php -f +. + 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. +*/ + + /* parse the configuration and include all functions used below */ + require_once("config.inc"); + require_once("functions.inc"); + + captiveportal_prune_old(); +?> diff --git a/webgui/diag_backup.php b/webgui/diag_backup.php index cdeda0a..0224427 100644 --- a/webgui/diag_backup.php +++ b/webgui/diag_backup.php @@ -78,9 +78,9 @@ if ($_POST) {

Diagnostics: Backup/restore

- -
+ + diff --git a/webgui/diag_defaults.php b/webgui/diag_defaults.php index b47c7ff..95d00d6 100644 --- a/webgui/diag_defaults.php +++ b/webgui/diag_defaults.php @@ -53,8 +53,8 @@ if ($_POST) {

Diagnostics: Factory defaults

- - + +

If you click "Yes", 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 diff --git a/webgui/diag_ipsec_sad.php b/webgui/diag_ipsec_sad.php index 0930de9..7c5f2d5 100644 --- a/webgui/diag_ipsec_sad.php +++ b/webgui/diag_ipsec_sad.php @@ -43,13 +43,14 @@ require("guiconfig.inc");

Diagnostics: IPsec

Backup configuration
+ - - - - - -
+
    +
  • SAD
  • +
  • SPD
  • +
+
SADSPD 
+

Diagnostics: IPsec

+ - - - - - -
+
    +
  • SAD
  • +
  • SPD
  • +
+
SADSPD 
+

Diagnostics: System logs

+ - - - - - - - -
+ +
SystemFirewallDHCPSettings 
+
diff --git a/webgui/diag_logs_dhcp.php b/webgui/diag_logs_dhcp.php index 64fb4cb..75bc392 100644 --- a/webgui/diag_logs_dhcp.php +++ b/webgui/diag_logs_dhcp.php @@ -73,15 +73,16 @@ function dump_clog($logfile, $tail, $withorig = true) {

Diagnostics: System logs

+ - - - - - - - -
+ +
SystemFirewallDHCPSettings 
+
diff --git a/webgui/diag_logs_filter.php b/webgui/diag_logs_filter.php index 5f8c733..07a8e23 100644 --- a/webgui/diag_logs_filter.php +++ b/webgui/diag_logs_filter.php @@ -60,6 +60,61 @@ function dump_clog($logfile, $tail, $withorig = true) { } } +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; +} + ?> @@ -73,15 +128,48 @@ function dump_clog($logfile, $tail, $withorig = true) {

Diagnostics: System logs

- - - - - - - - - + +
SystemFirewallDHCPSettings 
+
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ Last firewall log entries
ActTimeIfSourceDestinationProto
+ + +
+
@@ -89,6 +177,7 @@ function dump_clog($logfile, $tail, $withorig = true) {
+
diff --git a/webgui/diag_logs_settings.php b/webgui/diag_logs_settings.php index 3a53e9f..1e495fc 100644 --- a/webgui/diag_logs_settings.php +++ b/webgui/diag_logs_settings.php @@ -39,6 +39,7 @@ $pconfig['dhcp'] = isset($config['syslog']['dhcp']); $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; @@ -66,6 +67,7 @@ if ($_POST) { $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(); @@ -110,19 +112,20 @@ function enable_change(enable_over) {

Diagnostics: System logs

- -
+ + + - - - - - - - -
+ +
SystemFirewallDHCPSettings 
+ @@ -144,6 +147,12 @@ function enable_change(enable_over) { implicit default block rule will not be logged anymore if you uncheck this option. Per-rule logging options are not affected. + + + +
 
  > + Show raw filter logs
+ Hint: If this is checked, filter logs are shown as generated by the packet filter, without any formatting. This will reveal more detailed information.
  onClick="enable_change(false)"> diff --git a/webgui/diag_resetstate.php b/webgui/diag_resetstate.php index 058ed5a..64cab46 100644 --- a/webgui/diag_resetstate.php +++ b/webgui/diag_resetstate.php @@ -58,7 +58,7 @@ if ($_POST) {

Diagnostics: Reset state

- + diff --git a/webgui/exec.php b/webgui/exec.php index 80b5d3d..86c6f36 100644 --- a/webgui/exec.php +++ b/webgui/exec.php @@ -189,13 +189,14 @@ on your own risk!

" ); - puts( "\$ " . htmlspecialchars($_POST['txtCommand']) ); + puts("
");
+   puts("\$ " . htmlspecialchars($_POST['txtCommand']));
    putenv("PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
-   $ph = popen( $_POST['txtCommand'], "r" );
-   while ($line = fgets( $ph )) echo htmlspecialchars( $line );
-   pclose( $ph );
-   puts( "
" ); + putenv("SCRIPT_FILENAME=" . strtok($_POST['txtCommand'], " ")); /* PHP scripts */ + $ph = popen($_POST['txtCommand'], "r" ); + while ($line = fgets($ph)) echo htmlspecialchars($line); + pclose($ph); + puts(""); } ?> diff --git a/webgui/fbegin.inc b/webgui/fbegin.inc index c908229..df453b7 100644 --- a/webgui/fbegin.inc +++ b/webgui/fbegin.inc @@ -9,8 +9,8 @@ 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"; + tri_open.src = "/tri_o.gif"; + tri_closed.src = "/tri_c.gif"; } } @@ -19,19 +19,25 @@ function showhide(tspan, tri) { triel = document.getElementById(tri); if (tspanel.style.display == 'none') { tspanel.style.display = ''; - triel.src = "tri_o.gif"; + triel.src = "/tri_o.gif"; } else { tspanel.style.display = 'none'; - triel.src = "tri_c.gif"; + triel.src = "/tri_c.gif"; } } -->
- - +
 webGUI + + + +
 webGUI Configuration +   +
+
@@ -39,65 +45,87 @@ function showhide(tspan, tri) {
System
-      General +      General setup
-      Static +      Static routes
-      Firmware
-      Advanced
+      Firmware
+      Advanced
Interfaces - (assign) + (assign)
-      LAN
-      WAN
+      LAN
+      WAN
-      
+      
Firewall
-      Rules
-      NAT
-      Traffic +      Rules
+      NAT
+      Traffic shaper
-      Aliases
+      Aliases
Services
-      DNS forwarder
-      Dynamic +      DNS forwarder
+      Dynamic DNS
-      DHCP
-      SNMP
-      Proxy ARP
+      DHCP
+      SNMP
+      Proxy ARP
+      Captive portal
+      Wake on LAN
VPN
-      IPsec
-      PPTP
-           Users
+      IPsec
+      PPTP
Status
-      System
-      Interfaces
-      Wireless
+      System
+      Interfaces
+      Traffic graph
+      Wireless
+ +      Captive portal
+ + + Extensions
+ - Diagnostics
+ Diagnostics
- Diagnostics
+ Diagnostics
- + All rights reserved.  [view license]
\ No newline at end of file +
diff --git a/webgui/fend.inc b/webgui/fend.inc index f1f5d89..eb5f601 100644 --- a/webgui/fend.inc +++ b/webgui/fend.inc @@ -2,6 +2,6 @@
m0n0wall is © 2002-2004 by Manuel Kasper. - All rights reserved.  [view license]
\ No newline at end of file diff --git a/webgui/firewall_aliases.php b/webgui/firewall_aliases.php index 639292a..185c423 100644 --- a/webgui/firewall_aliases.php +++ b/webgui/firewall_aliases.php @@ -80,7 +80,7 @@ if ($_GET['act'] == "del") {

Firewall: Aliases

- +

You must apply the changes in order for them to take effect.");?>

diff --git a/webgui/firewall_aliases_edit.php b/webgui/firewall_aliases_edit.php index d608be8..b656d7a 100644 --- a/webgui/firewall_aliases_edit.php +++ b/webgui/firewall_aliases_edit.php @@ -139,7 +139,6 @@ function typesel_change() {

Firewall: Aliases: Edit alias

- diff --git a/webgui/firewall_nat.php b/webgui/firewall_nat.php index 7df148d..51cc301 100644 --- a/webgui/firewall_nat.php +++ b/webgui/firewall_nat.php @@ -81,33 +81,43 @@ if ($_GET['act'] == "del") {

Firewall: NAT

- +

You must apply the changes in order for them to take effect.");?>

+ - - - - - - - -
+ +
InboundServer NAT1:1Outbound 
+ + - + - - + + - + - +
If Proto Ext. port rangeNAT IP
(ext. IP)
NAT IP Int. port rangeDescriptionDescription
+ + + @@ -124,7 +134,7 @@ if ($_GET['act'] == "del") { (" . $natent['external-address'] . ")"; + echo "
(ext.: " . $natent['external-address'] . ")"; ?>
@@ -145,7 +155,7 @@ if ($_GET['act'] == "del") {
diff --git a/webgui/firewall_nat_1to1.php b/webgui/firewall_nat_1to1.php index d3ab765..aedf0c3 100644 --- a/webgui/firewall_nat_1to1.php +++ b/webgui/firewall_nat_1to1.php @@ -81,31 +81,40 @@ if ($_GET['act'] == "del") {

Firewall: NAT

- +

You must apply the changes in order for them to take effect.");?>

- +
- - - - - - - -
+ +
InboundServer NAT1:1Outbound 
+ + - + - + @@ -121,7 +130,7 @@ if ($_GET['act'] == "del") { - +
Interface External IP Internal IPDescriptionDescription
+ + +
diff --git a/webgui/firewall_nat_1to1_edit.php b/webgui/firewall_nat_1to1_edit.php index 135650a..c39fb16 100644 --- a/webgui/firewall_nat_1to1_edit.php +++ b/webgui/firewall_nat_1to1_edit.php @@ -44,6 +44,9 @@ if (isset($_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 @@ -51,6 +54,7 @@ if (isset($id) && $a_1to1[$id]) { $pconfig['descr'] = $a_1to1[$id]['descr']; } else { $pconfig['subnet'] = 32; + $pconfig['interface'] = "wan"; } if ($_POST) { @@ -59,8 +63,8 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - $reqdfields = explode(" ", "external internal"); - $reqdfieldsn = explode(",", "External subnet,Internal subnet"); + $reqdfields = explode(" ", "interface external internal"); + $reqdfieldsn = explode(",", "Interface,External subnet,Internal subnet"); do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); @@ -119,6 +123,7 @@ if ($_POST) { $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; @@ -146,9 +151,26 @@ if ($_POST) {

Firewall: NAT: Edit 1:1

- + + + +
Interface +
+ Choose which interface this rule applies to.
+ Hint: in most cases, you'll want to use WAN here.
External subnet diff --git a/webgui/firewall_nat_edit.php b/webgui/firewall_nat_edit.php index a3f4719..2c4fcef 100644 --- a/webgui/firewall_nat_edit.php +++ b/webgui/firewall_nat_edit.php @@ -48,6 +48,11 @@ if (isset($id) && $a_nat[$id]) { $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) { @@ -66,8 +71,8 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - $reqdfields = explode(" ", "proto beginport localip localbeginport"); - $reqdfieldsn = explode(",", "Protocol,Start port,NAT IP,Local port"); + $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); @@ -91,10 +96,17 @@ if ($_POST) { $_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; @@ -123,6 +135,7 @@ if ($_POST) { $natent['target'] = $_POST['localip']; $natent['local-port'] = $_POST['localbeginport']; + $natent['interface'] = $_POST['interface']; $natent['descr'] = $_POST['descr']; if (isset($id) && $a_nat[$id]) @@ -135,7 +148,7 @@ if ($_POST) { if ($_POST['autoadd']) { /* auto-generate a matching firewall rule */ $filterent = array(); - $filterent['interface'] = "wan"; + $filterent['interface'] = $_POST['interface']; $filterent['protocol'] = $_POST['proto']; $filterent['source']['any'] = ""; $filterent['destination']['address'] = $_POST['localip']; @@ -202,21 +215,39 @@ function ext_rep_change() {

Firewall: NAT: Edit

- + + + + diff --git a/webgui/firewall_nat_out.php b/webgui/firewall_nat_out.php index 6c812ea..7dd4d40 100644 --- a/webgui/firewall_nat_out.php +++ b/webgui/firewall_nat_out.php @@ -83,21 +83,21 @@ if ($_GET['act'] == "del") {

Firewall: NAT

- +

You must apply the changes in order for them to take effect.");?>

-
Interface +
+ Choose which interface this rule applies to.
+ Hint: in most cases, you'll want to use WAN here.
External address
- If you want this rule to apply to another IP address than m0n0wall's WAN IP address, +
+ + 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 Server NAT page first).
+
- - - - - - - -
+ +
InboundServer NAT1:1Outbound 
+

@@ -124,15 +124,24 @@ if ($_GET['act'] == "del") {  
+ - - + + - + - +
Interface Source Destination TargetDescriptionDescription
+ + + @@ -162,7 +171,7 @@ if ($_GET['act'] == "del") {
diff --git a/webgui/firewall_nat_out_edit.php b/webgui/firewall_nat_out_edit.php index b9625f8..4d9b5b7 100644 --- a/webgui/firewall_nat_out_edit.php +++ b/webgui/firewall_nat_out_edit.php @@ -62,11 +62,15 @@ if (isset($id) && $a_out[$id]) { 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) { @@ -80,8 +84,8 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - $reqdfields = explode(" ", "source source_subnet destination destination_subnet"); - $reqdfieldsn = explode(",", "Source,Source bit count,Destination,Destination bit count"); + $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); @@ -127,15 +131,18 @@ if ($_POST) { if (isset($id) && ($a_out[$id]) && ($a_out[$id] === $natent)) continue; - if ($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 (!$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) { @@ -143,6 +150,7 @@ if ($_POST) { $natent['source']['network'] = $osn; $natent['descr'] = $_POST['descr']; $natent['target'] = $_POST['target']; + $natent['interface'] = $_POST['interface']; if ($ext == "any") $natent['destination']['any'] = true; @@ -196,9 +204,26 @@ function typesel_change() {

Firewall: NAT: Edit outbound mapping

- + + + + + Packets matching this rule will be mapped to the IP address given here. Leave blank to use the selected interface's IP address. diff --git a/webgui/firewall_nat_server.php b/webgui/firewall_nat_server.php index bebceeb..6fda65a 100644 --- a/webgui/firewall_nat_server.php +++ b/webgui/firewall_nat_server.php @@ -94,24 +94,24 @@ if ($_GET['act'] == "del") {

Firewall: NAT

- +

You must apply the changes in order for them to take effect.");?>

-
Interface +
+ Choose which interface this rule applies to.
+ Hint: in most cases, you'll want to use WAN here.
Source @@ -256,7 +281,7 @@ function typesel_change() {
- Packets matching this rule will be mapped to the IP address given here. Leave blank to use the WAN interface's IP address.
Description
+
- - - - - - - -
+ +
InboundServer NAT1:1Outbound 
+ - + diff --git a/webgui/firewall_nat_server_edit.php b/webgui/firewall_nat_server_edit.php index 6baafb2..2943694 100644 --- a/webgui/firewall_nat_server_edit.php +++ b/webgui/firewall_nat_server_edit.php @@ -90,9 +90,14 @@ if ($_POST) { $natent['ipaddr'] = $_POST['ipaddr']; $natent['descr'] = $_POST['descr']; - if (isset($id) && $a_snat[$id]) + 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 + } else $a_snat[] = $natent; touch($d_natconfdirty_path); @@ -116,11 +121,10 @@ if ($_POST) {

Firewall: NAT: Edit Server NAT

-
External IPExternal IP address Description
- + - +
External IPExternal IP address diff --git a/webgui/firewall_rules.php b/webgui/firewall_rules.php index ed44d69..7e2bd2a 100644 --- a/webgui/firewall_rules.php +++ b/webgui/firewall_rules.php @@ -86,6 +86,14 @@ if ($_GET['act'] == "del") { 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; + } } ?> @@ -101,7 +109,7 @@ if ($_GET['act'] == "del") {

Firewall: Rules

- +

You must apply the changes in order for them to take effect.");?>

@@ -146,56 +154,61 @@ if ($_GET['act'] == "del") { $iconfn = "block"; } else $iconfn = "pass"; - if (isset($filterent['disabled'])) + if (isset($filterent['disabled'])) { + $textss = ""; + $textse = ""; $iconfn .= "_d"; + } else { + $textss = $textse = ""; + } ?> - + -
+
- + - + - + - + - + -   +   - edit rule + 0) && ($a_filter[$i-1]['interface'] == $filterent['interface'])): ?> - move up +
- delete rule + - move down + - add a new rule based on this one +
add new rule
diff --git a/webgui/firewall_rules_edit.php b/webgui/firewall_rules_edit.php index ca78a7f..307db2e 100644 --- a/webgui/firewall_rules_edit.php +++ b/webgui/firewall_rules_edit.php @@ -422,7 +422,6 @@ function dst_rep_change() {

Firewall: Rules: Edit

-
@@ -468,7 +467,7 @@ Hint: the difference between block and reject is that with reject, a packet (TCP
Protocol

+ - - - - - - -

+ IP packet length, TCP flags.
+ +
RulesPipesQueues 
+ - - - - @@ -204,19 +242,25 @@ if ($_GET['act'] == "del") { + + + - - + + + + +

@@ -144,53 +162,73 @@ if ($_GET['act'] == "del") {

"; + $textse = ""; + } 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 htmlspecialchars($iflabels[$shaperent['interface']]); - if ($shaperent['direction']) - echo "
"; + echo $textss . htmlspecialchars($iflabels[$shaperent['interface']]); + echo "
"; + echo ""; + if ($shaperent['direction'] != "in") + echo ""; + if ($shaperent['direction'] != "out") + echo ""; + echo "" . $textse;; ?>
- + +
Port: - +
+
Port: - +
+ Pipe " . - ($shaperent['targetpipe']+1) . ""; - else if (isset($shaperent['targetqueue'])) - echo "Queue " . - ($shaperent['targetqueue']+1) . ""; - ?> + if (isset($shaperent['targetpipe'])) { + if ($a_pipe[$shaperent['targetpipe']]['descr']) + $desc = htmlspecialchars($a_pipe[$shaperent['targetpipe']]['descr']); + else + $desc = "Pipe " . ($shaperent['targetpipe']+1); + echo "{$desc}"; + } 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 "{$desc}"; + } + ?> - +   edit rule + 0): ?> - move up +
- delete rule + - move down + - add a new rule based on this one +
incoming (as seen by firewall)outgoing (as seen by firewall)
outgoing (as seen by firewall)incoming (disabled)outgoing (disabled)

Note:
the first rule that matches a packet will be executed.
The following match patterns are not shown in the list above: - IP packet length, TCP flags.

diff --git a/webgui/firewall_shaper_edit.php b/webgui/firewall_shaper_edit.php index 14b39f5..242f319 100644 --- a/webgui/firewall_shaper_edit.php +++ b/webgui/firewall_shaper_edit.php @@ -134,9 +134,11 @@ if (isset($id) && $a_shaper[$id]) { } $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"; @@ -158,7 +160,7 @@ if (isset($_GET['dup'])) if ($_POST) { - if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "tcp/udp")) { + if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "any")) { $_POST['srcbeginport'] = 0; $_POST['srcendport'] = 0; $_POST['dstbeginport'] = 0; @@ -209,6 +211,15 @@ if ($_POST) { $_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") @@ -311,8 +322,10 @@ if ($_POST) { $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; @@ -421,7 +434,7 @@ function typesel_change() { } function proto_change() { - if (document.iform.proto.selectedIndex < 3) { + if (document.iform.proto.selectedIndex < 2 || document.iform.proto.selectedIndex == 8) { portsenabled = 1; } else { portsenabled = 0; @@ -444,7 +457,6 @@ function dst_rep_change() {

Firewall: Traffic shaper: Edit rule

- 0)): ?>
@@ -474,6 +486,13 @@ function dst_rep_change() { Choose a pipe or queue where packets that match this rule should be sent. + + + + + + + + diff --git a/webgui/firewall_shaper_magic.php b/webgui/firewall_shaper_magic.php new file mode 100644 index 0000000..bcacf79 --- /dev/null +++ b/webgui/firewall_shaper_magic.php @@ -0,0 +1,423 @@ +#!/usr/local/bin/php + + Copyright (C) 2004 Dinesh Nair + + 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 wipe_magic () { + global $config; + + /* wipe previous */ + $types=array("pipe","queue","rule"); + foreach ($types as $type) { + foreach (array_keys($config['shaper'][$type]) as $num) { + if (substr($config['shaper'][$type][$num]['descr'],0,2) == "m_") { + unset($config['shaper'][$type][$num]); + } + } + } + /* Although we don't delete user-defined rules, it's probably best to + disable the shaper to prevent bad things from happening */ + $config['shaper']['enable'] = FALSE; +} + +function populate_p2p(&$rulei) { + global $config; + + /* To add p2p clients, push Descr,Protocol,Start,End onto p2plist */ + $p2plist[] = array('BitTorrent','tcp','6881','6999','both'); + $p2plist[] = array('DirectConnect','','412','412','source'); + $p2plist[] = array('DirectFileExpress','','1044','1045','source'); + $p2plist[] = array('FastTrack','','1214','1214','source'); + $p2plist[] = array('CuteMX','','2340','2340','source'); + $p2plist[] = array('iMest','','4329','4329','source'); + $p2plist[] = array('EDonkey2000','','4661','4665','source'); + $p2plist[] = array('SongSpy','','5190','5190','source'); + $p2plist[] = array('HotlineConnect','','5500','5503','source'); + $p2plist[] = array('Gnutella','','6346','6346','source'); + $p2plist[] = array('dcc','','6666','6668','source'); + $p2plist[] = array('Napster','','6699','6701','source'); + $p2plist[] = array('Aimster','','7668','7668','source'); + $p2plist[] = array('BuddyShare','','7788','7788','source'); + $p2plist[] = array('Scour','','8311','8311','source'); + $p2plist[] = array('OpenNap','','8888','8889','source'); + $p2plist[] = array('hotComm','','28864','28865','source'); + + /* Set up/down p2p as lowest weight */ + $direction = array("in","out"); + foreach ($p2plist as $p2pclient) { + foreach ($direction as $dir) { + foreach (array('source','destination') as $srcdest) { + if (($p2pclient[4] == $srcdest) || ($p2pclient[4] == 'both')) { + $config['shaper']['rule'][$rulei]['descr'] = "m_P2P $p2pclient[0]"; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "$dir"; + $config['shaper']['rule'][$rulei]['source']['any'] = 1; + $config['shaper']['rule'][$rulei]['destination']['any'] = 1; + $config['shaper']['rule'][$rulei][$srcdest]['port'] = $p2pclient[2]."-".$p2pclient[3]; + if($p2pclient[1] != '') + $config['shaper']['rule'][$rulei]['protocol'] = $p2pclient[1]; + if ($dir == "out") { + $config['shaper']['rule'][$rulei]['targetqueue'] = 4; + } else { + $config['shaper']['rule'][$rulei]['targetqueue'] = 6; + } + $rulei++; + } + } + } + } +} + +function create_magic ($maxup, $maxdown, $p2plow,$maskq) { + global $config; + + $config['shaper']['enable'] = TRUE; + $pipei = 0; + $queuei = 0; + $rulei = 0; + + /* Create new pipes */ + $config['shaper']['pipe'][$pipei]['descr'] = "m_Total Upload"; + $config['shaper']['pipe'][$pipei]['bandwidth'] = round($maxup * .90); + $pipei++; + $config['shaper']['pipe'][$pipei]['descr'] = "m_Total Download"; + $config['shaper']['pipe'][$pipei]['bandwidth'] = round($maxdown * .95); + $pipei++; + + /* Create new queues */ + $config['shaper']['queue'][$queuei]['descr'] = "m_High Priority #1 Upload"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 0; + $config['shaper']['queue'][$queuei]['weight'] = 50; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_High Priority #2 Upload"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 0; + $config['shaper']['queue'][$queuei]['weight'] = 30; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_High Priority #3 Upload"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 0; + $config['shaper']['queue'][$queuei]['weight'] = 15; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_Bulk Upload"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 0; + $config['shaper']['queue'][$queuei]['weight'] = 4; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_Hated Upload"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 0; + $config['shaper']['queue'][$queuei]['weight'] = 1; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_Bulk Download"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 1; + $config['shaper']['queue'][$queuei]['weight'] = 30; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_Hated Download"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 1; + $config['shaper']['queue'][$queuei]['weight'] = 10; + $queuei++; + $config['shaper']['queue'][$queuei]['descr'] = "m_High Priority Download"; + $config['shaper']['queue'][$queuei]['targetpipe'] = 1; + $config['shaper']['queue'][$queuei]['weight'] = 60; + $queuei++; + if ($maskq) { + for ($i = 0; $i < $queuei; $i++) { + if (stristr($config['shaper']['queue'][$i]['descr'],"upload")) { + $config['shaper']['queue'][$i]['mask'] = 'source'; + } else if (stristr($config['shaper']['queue'][$i]['descr'],"download")) { + $config['shaper']['queue'][$i]['mask'] = 'destination'; + } + } + } + + /* Create new rules */ + if ($p2plow) + populate_p2p($rulei); + + $config['shaper']['rule'][$rulei]['descr'] = "m_Small Pkt Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 0; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['iplen'] = "0-100"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_Outbound DNS Query"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 0; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['port'] = 53; + $config['shaper']['rule'][$rulei]['protocol'] = "udp"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_AH Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 0; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "ah"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_ESP Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 0; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "esp"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_GRE Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 0; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "gre"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_ICMP Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 1; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "icmp"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_TCP ACK Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 2; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['iplen'] = "0-80"; + $config['shaper']['rule'][$rulei]['protocol'] = "tcp"; + $config['shaper']['rule'][$rulei]['tcpflags'] = "ack"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_Catch-All Upload"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 3; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "out"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_ICMP Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 7; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "icmp"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_Small Pkt Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 7; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['iplen'] = "0-100"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_AH Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 7; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "ah"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_ESP Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 7; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "esp"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_GRE Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 7; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['protocol'] = "gre"; + $rulei++; + $config['shaper']['rule'][$rulei]['descr'] = "m_Catch-All Download"; + $config['shaper']['rule'][$rulei]['targetqueue'] = 5; + $config['shaper']['rule'][$rulei]['interface'] = "wan"; + $config['shaper']['rule'][$rulei]['direction'] = "in"; + $config['shaper']['rule'][$rulei]['source']['any'] = TRUE; + $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE; + $rulei++; +} + +require("guiconfig.inc"); + +if (!is_array($config['shaper']['rule'])) { + $config['shaper']['rule'] = array(); +} +if (!is_array($config['shaper']['pipe'])) { + $config['shaper']['pipe'] = array(); +} +if (!is_array($config['shaper']['queue'])) { + $config['shaper']['queue'] = array(); +} + +$a_shaper = &$config['shaper']['rule']; +$a_queues = &$config['shaper']['queue']; +$a_pipes = &$config['shaper']['pipe']; + +$pconfig['p2plow'] = isset($config['shaper']['magic']['p2plow']); +$pconfig['maskq'] = isset($config['shaper']['magic']['maskq']); +$pconfig['maxup'] = $config['shaper']['magic']['maxup']; +$pconfig['maxdown'] = $config['shaper']['magic']['maxdown']; + +if ($_POST) { + + if ($_POST['install']) { + unset($input_errors); + $pconfig = $_POST; + $reqdfields = explode(" ", "maxup maxdown"); + $reqdfieldsn = explode(",", "Max. Upload,Max.Download"); + do_input_validation($_POST,$reqdfields, $reqdfieldsn, &$input_errors); + if (($_POST['maxup'] && !is_numericint($_POST['maxup']))) { + $input_errors[] = "The max upload bandwidth must be an integer."; + } + if (($_POST['maxdown'] && !is_numericint($_POST['maxdown']))) { + $input_errors[] = "The max download bandwidth must be an integer."; + } + if (!$input_errors) { + if ($_POST['install']) { + unset ($config['shaper']); + create_magic($_POST['maxup'],$_POST['maxdown'],$_POST['p2plow']?TRUE:FALSE,$_POST['maskq']?TRUE:FALSE); + touch($d_shaperconfdirty_path); + } + $config['shaper']['magic']['p2plow'] = $_POST['p2plow'] ? TRUE : FALSE; + $config['shaper']['magic']['maskq'] = $_POST['maskq'] ? TRUE : FALSE; + $config['shaper']['magic']['maxup'] = $_POST['maxup']; + $config['shaper']['magic']['maxdown'] = $_POST['maxdown']; + write_config(); + } + } + if ($_POST['remove']) { + wipe_magic(); + $note = '

Note: The traffic shaper has been disabled.
All of your user-defined rules/pipes/queues are still intact.

'; + touch($d_shaperconfdirty_path); + write_config(); + } + if ($_POST['apply']) { + $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); + } + } +} + +?> + + + +m0n0wall webGUI - Firewall: Traffic shaper + + + + + + +

Firewall: Traffic shaper

+ + +

+You must apply the changes in order for them to take effect.$note");?>
+

+ +
Disabled + > + Disable this rule
+ Set this option to disable this rule without removing it from the list.
Interface
Protocol
IP Type of Service (TOS) + + + + + + + + +
+ + > + yes    > + no    > + don't care
+ Use this to match packets according to their IP TOS values. +
IP packet length
+ + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
 

+ > + Set P2P traffic to lowest priority
+

 

+ > + Share bandwidth evenly on LAN
+

Downstream
+ speed
+ + kbps
+ Enter the speed of your WAN downstream link here.
Upstream
+ speed
+ kbps
+ Enter the speed of your WAN upstream link here.
 

+ +   + +

+

All existing traffic shaper rules/pipes/queues will be deleted once "Install/Update" has been pressed! Backup your configuration before proceeding!

+

Note:
+
By entering your maximum upload and download values and pressing the "Install/Update" button, the magic shaper will do its best to create the optimum shaping rules, queues, and pipes for you. These rules will help ensure that interactive traffic remains acceptable while the upstream bandwidth is being consumed by heavy traffic.

+
+ + + + diff --git a/webgui/firewall_shaper_pipes.php b/webgui/firewall_shaper_pipes.php index e80500a..3c5b2c0 100644 --- a/webgui/firewall_shaper_pipes.php +++ b/webgui/firewall_shaper_pipes.php @@ -101,20 +101,22 @@ if ($_GET['act'] == "del") {

Firewall: Traffic shaper

- +

You must apply the changes in order for them to take effect.");?>

+ - - - - - - -
+ +
RulesPipesQueues 
+ diff --git a/webgui/firewall_shaper_pipes_edit.php b/webgui/firewall_shaper_pipes_edit.php index 80650c7..867a990 100644 --- a/webgui/firewall_shaper_pipes_edit.php +++ b/webgui/firewall_shaper_pipes_edit.php @@ -97,7 +97,6 @@ if ($_POST) {

Firewall: Traffic shaper: Edit pipe

-
No.
diff --git a/webgui/firewall_shaper_queues.php b/webgui/firewall_shaper_queues.php index 8a8bf76..bab5192 100644 --- a/webgui/firewall_shaper_queues.php +++ b/webgui/firewall_shaper_queues.php @@ -38,6 +38,7 @@ if (!is_array($config['shaper']['queue'])) { $config['shaper']['queue'] = array(); } $a_queues = &$config['shaper']['queue']; +$a_pipe = &$config['shaper']['pipe']; if ($_GET['act'] == "del") { if ($a_queues[$_GET['id']]) { @@ -84,25 +85,27 @@ if ($_GET['act'] == "del") {

Firewall: Traffic shaper

- +

You must apply the changes in order for them to take effect.");?>

+ - - - - - - -
+ +
RulesPipesQueues 
+ - - + + @@ -112,7 +115,13 @@ if ($_GET['act'] == "del") { + + diff --git a/webgui/interfaces_opt.php b/webgui/interfaces_opt.php index b5cb192..bedf3ac 100644 --- a/webgui/interfaces_opt.php +++ b/webgui/interfaces_opt.php @@ -89,6 +89,10 @@ if ($_POST) { $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"); @@ -125,6 +129,12 @@ if ($_POST) { 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); @@ -177,7 +187,7 @@ function ipaddr_change() {

Interfaces: Optional ()

- +
No.PipeWeightPipeWeight Mask Description - diff --git a/webgui/firewall_shaper_queues_edit.php b/webgui/firewall_shaper_queues_edit.php index 48e4ef7..5e659ab 100644 --- a/webgui/firewall_shaper_queues_edit.php +++ b/webgui/firewall_shaper_queues_edit.php @@ -94,7 +94,6 @@ if ($_POST) {

Firewall: Traffic shaper: Edit queue

- 0)): ?> diff --git a/webgui/graph.php b/webgui/graph.php new file mode 100644 index 0000000..7fac8f3 --- /dev/null +++ b/webgui/graph.php @@ -0,0 +1,325 @@ +#!/usr/local/bin/php -f + and Manuel Kasper . + 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('' . "\n");?> + + + + + + + + + + + In + Out + + + + Switch to bytes/s + AutoScale () + + Graph shows last seconds + "/> + + + + + + \ No newline at end of file diff --git a/webgui/gui.css b/webgui/gui.css index b019c31..3a31c09 100644 --- a/webgui/gui.css +++ b/webgui/gui.css @@ -100,6 +100,10 @@ a { font-size: 11px; color: #FFFFFF; } +.hostname { + font-size: 11px; + color: #FFFFFF; +} .vnsepcellr { background-color: #BBBBBB; padding-right: 20px; @@ -229,26 +233,34 @@ a { padding-top: 5px; padding-bottom: 5px; } -.tabinact { - border-left: 1px solid #999999; +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; - padding-right: 8px; - padding-left: 8px; - padding-top: 5px; - padding-bottom: 5px; color: #FFFFFF; - font-weight: bold; + padding: 0; + white-space: nowrap; } -.tabact { - font-size: 11px; +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; - padding-right: 8px; - padding-left: 8px; - padding-top: 5px; - padding-bottom: 5px; color: #000000; - font-weight: bold; + padding: 5px 8px 5px 8px; + white-space: nowrap; } .tabcont { background-color: #EEEEEE; diff --git a/webgui/guiconfig.inc b/webgui/guiconfig.inc index 8cd038a..437fab3 100644 --- a/webgui/guiconfig.inc +++ b/webgui/guiconfig.inc @@ -37,6 +37,10 @@ if (!$omit_nocacheheaders) { 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"; @@ -50,6 +54,8 @@ $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"; if (file_exists($d_firmwarelock_path)) { if (!$d_isfwfile) { @@ -60,14 +66,11 @@ if (file_exists($d_firmwarelock_path)) { } } -/* parse the configuration and include all configuration functions */ -require_once("config.inc"); -require_once("functions.inc"); - /* 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"); @@ -87,7 +90,8 @@ $fwupplatforms = array('net45xx', 'net48xx', 'generic-pc', 'wrap'); /* IPsec defines */ $my_identifier_list = array('myaddress' => 'My IP address', 'address' => 'IP address', - 'fqdn' => 'Domain name'); + 'fqdn' => 'Domain name', + 'user_fqdn' => 'User FQDN'); $p1_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish', 'cast128' => 'CAST128'); @@ -108,7 +112,7 @@ function do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors function print_input_errors($input_errors) { echo "

\n"; - echo "\n"; + echo "\n"; echo "
"; echo "

The following input errors were detected:

    \n"; @@ -153,7 +157,7 @@ function verify_gzip_file($fname) { function print_info_box_np($msg) { echo "\n"; - echo "\n"; + echo "\n"; echo "
    "; echo $msg; echo "
    "; @@ -182,7 +186,7 @@ function get_std_save_message($ok) { if ($ok == 0) { if (file_exists($d_sysrebootreqd_path)) - return "The changes have been saved. You must reboot your firewall for changes to take effect."; + return "The changes have been saved. You must reboot your firewall for changes to take effect."; else return "The changes have been applied successfully."; } else { @@ -391,8 +395,34 @@ function proxyarp_sort() { usort($config['proxyarp']['proxyarpnet'], "proxyarpcmp"); } -function is_numericint($arg) { - return (preg_match("/[^0-9]/", $arg) ? false : true); +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"); } ?> diff --git a/webgui/ifstats.cgi b/webgui/ifstats.cgi new file mode 100644 index 0000000..944e95e Binary files /dev/null and b/webgui/ifstats.cgi differ diff --git a/webgui/in_d.gif b/webgui/in_d.gif new file mode 100644 index 0000000..689f6a4 Binary files /dev/null and b/webgui/in_d.gif differ diff --git a/webgui/index.php b/webgui/index.php index e3a2908..dddee31 100644 --- a/webgui/index.php +++ b/webgui/index.php @@ -32,14 +32,17 @@ require("guiconfig.inc"); /* find out whether there's hardware encryption (hifn) */ -exec("/sbin/dmesg", $dmesg); - unset($hwcrypto); -foreach ($dmesg as $dmesgl) { - if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches)) { - $hwcrypto = $matches[1]; - break; +$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); } ?> @@ -93,9 +96,28 @@ foreach ($dmesg as $dmesgl) {
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); + ?>
diff --git a/webgui/interfaces_assign.php b/webgui/interfaces_assign.php index e992d96..8e79882 100644 --- a/webgui/interfaces_assign.php +++ b/webgui/interfaces_assign.php @@ -37,8 +37,19 @@ require("guiconfig.inc"); 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); @@ -48,7 +59,7 @@ if ($_POST) { /* Build a list of the port names so we can see how the interfaces map */ $portifmap = array(); foreach ($portlist as $portname => $portinfo) - $portifmap[] = array($portname => array()); + $portifmap[$portname] = array(); /* Go through the list of ports selected by the user, build a list of port-to-interface mappings in portifmap */ @@ -65,7 +76,7 @@ if ($_POST) { " interfaces:"; foreach ($portifmap[$portname] as $ifn) - $errstr .= " " . $ifn; + $errstr .= " " . $ifn; $input_errors[] = $errstr; } @@ -101,7 +112,6 @@ if ($_POST) { write_config(); touch($d_sysrebootreqd_path); - /* message is set up below based on existence of bootreqd file */ } } @@ -133,34 +143,30 @@ if ($_GET['act'] == "del") { } if ($_GET['act'] == "add") { - $i = 0; + /* find next free optional interface number */ + $i = 1; + while (is_array($config['interfaces']['opt' . $i])) + $i++; - while (1) { - $newifname = 'opt' . ($i+1); - - if (!is_array($config['interfaces'][$newifname])) { - $config['interfaces'][$newifname] = array(); - $config['interfaces'][$newifname]['descr'] = "OPT" . ($i+1); - - /* 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; - } + $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; } - $i++; } write_config(); @@ -184,14 +190,19 @@ if ($_GET['act'] == "add") { - - - - + +
Interface assignments + + + + - - - - - - - - - -
+
    +
  • Interface assignments
  • +
  • VLANs
  • +
+
- + $iface): ?> @@ -201,14 +212,21 @@ if ($_GET['act'] == "add") { @@ -216,33 +234,20 @@ if ($_GET['act'] == "add") {
InterfaceNetwork portNetwork port  
- delete interface +
- add interface +
-
  -
  Warning:
-
After you click "Save", 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: +

Warning:
+
After you click "Save", 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:

    -
  • change the IP address of your computer
  • -
  • renew it's DHCP lease
  • -
  • access the webGUI with the new IP address
  • -
-
+
  • change the IP address of your computer
  • +
  • renew its DHCP lease
  • +
  • access the webGUI with the new IP address
  • +
    diff --git a/webgui/interfaces_lan.php b/webgui/interfaces_lan.php index 72101fe..069fecd 100644 --- a/webgui/interfaces_lan.php +++ b/webgui/interfaces_lan.php @@ -161,7 +161,7 @@ function ipaddr_change() { access your firewall again:
    • change the IP address of your computer
    • -
    • renew it's DHCP lease
    • +
    • renew its DHCP lease
    • access the webGUI with the new IP address
    diff --git a/webgui/interfaces_vlan.php b/webgui/interfaces_vlan.php new file mode 100644 index 0000000..3dca4f8 --- /dev/null +++ b/webgui/interfaces_vlan.php @@ -0,0 +1,149 @@ +#!/usr/local/bin/php +. + 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; + } +} + +?> + + + +m0n0wall webGUI - Interfaces: Assign network ports: VLANs + + + + + + +

    Interfaces: Assign network ports: VLANs

    + + +
    + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    InterfaceVLAN tagDescription
    + + + + +   + +  
     

    + Note:
    +
    + 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.

    +
     
    +
    + + + diff --git a/webgui/interfaces_vlan_edit.php b/webgui/interfaces_vlan_edit.php new file mode 100644 index 0000000..7c3c87a --- /dev/null +++ b/webgui/interfaces_vlan_edit.php @@ -0,0 +1,147 @@ +#!/usr/local/bin/php +. + 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; + } +} +?> + + + +m0n0wall webGUI - Interfaces: Assign network ports: VLANs: Edit + + + + + + +

    Interfaces: Assign network ports: VLANs: Edit

    + + + + + + + + + + + + + + + + + + + +
    Parent interface +
    VLAN tag + +
    + 802.1Q VLAN tag (between 1 and 4094)
    Description + +
    You may enter a description here + for your reference (not parsed).
      + + + + +
    + + + + diff --git a/webgui/interfaces_wan.php b/webgui/interfaces_wan.php index f3ecbd0..7c6b406 100644 --- a/webgui/interfaces_wan.php +++ b/webgui/interfaces_wan.php @@ -44,6 +44,12 @@ $pconfig['pptp_local'] = $config['pptp']['local']; $pconfig['pptp_subnet'] = $config['pptp']['subnet']; $pconfig['pptp_remote'] = $config['pptp']['remote']; +$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") { @@ -52,6 +58,8 @@ if ($wancfg['ipaddr'] == "dhcp") { $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']; @@ -81,11 +89,15 @@ if ($_POST) { do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); } else if ($_POST['type'] == "PPPoE") { $reqdfields = explode(" ", "username password"); - $reqdfieldsn = explode(",", "PPPoE Username,PPPoE Password"); + $reqdfieldsn = explode(",", "PPPoE username,PPPoE password"); do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); } else if ($_POST['type'] == "PPTP") { $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"); + $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); } @@ -110,6 +122,15 @@ if ($_POST) { if (($_POST['pptp_remote'] && !is_ipaddr($_POST['pptp_remote']))) { $input_errors[] = "A valid PPTP remote IP address must be specified."; } + 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."; } @@ -139,6 +160,11 @@ if ($_POST) { unset($config['pptp']['local']); unset($config['pptp']['subnet']); unset($config['pptp']['remote']); + 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']; @@ -159,6 +185,13 @@ if ($_POST) { $config['pptp']['local'] = $_POST['pptp_local']; $config['pptp']['subnet'] = $_POST['pptp_subnet']; $config['pptp']['remote'] = $_POST['pptp_remote']; + } 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; @@ -199,6 +232,11 @@ function type_change() { document.iform.pptp_local.disabled = 1; document.iform.pptp_subnet.disabled = 1; document.iform.pptp_remote.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: @@ -213,6 +251,11 @@ function type_change() { document.iform.pptp_local.disabled = 1; document.iform.pptp_subnet.disabled = 1; document.iform.pptp_remote.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: @@ -227,6 +270,11 @@ function type_change() { document.iform.pptp_local.disabled = 1; document.iform.pptp_subnet.disabled = 1; document.iform.pptp_remote.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: @@ -241,6 +289,30 @@ function type_change() { document.iform.pptp_local.disabled = 0; document.iform.pptp_subnet.disabled = 0; document.iform.pptp_remote.disabled = 0; + 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.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.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; } @@ -253,13 +325,13 @@ function type_change() {

    Interfaces: WAN

    - +
    + + + + + + + + + + + + + + + + + + + + + + + + + + DHCP lease list page

    Peter Allgeyer (allgeyer@web.de)
    -     "reject" type filter rules

    +     "reject" type filter rules
    +
    + Thierry Lechat (dev@lechat.org)
    +     SVG-based traffic grapher
    +
    + Steven Honson (steven@honson.org)
    +     per-user IP address assignments for PPTP VPN
    +
    + Kurt Inge Smådal (kurt@emsp.no)
    +     NAT on optional interfaces
    +
    + Dinesh Nair (dinesh@alphaque.com)
    +     captive portal: pass-through MAC/IP addresses, RADIUS authentication & accounting;
    +     HTTP server concurrency limit

    +
    + Justin Ellison (justin@techadvise.com)
    +     traffic shaper TOS matching; magic shaper; DHCP deny unknown clients;
    +     IPsec user FQDNs

    +
    + Fred Wright (fw@well.com)
    +     ipfilter window scaling fix; ipnat ICMP checksum adjustment fix


    m0n0wall is based upon/includes various free software packages, listed below.
    @@ -111,8 +131,8 @@ Copyright © 1993-2002 by Darren Reed.

    MPD - Multi-link PPP daemon for FreeBSD (http://www.dellroad.org/mpd)
    - Copyright © 1995-1999 Whistle Communications, Inc. All rights - reserved.
    + Copyright © 2003-2004, Archie L. Cobbs, Michael Bretterklieber, Alexander Motin
    +All rights reserved.

    ez-ipupdate (http://www.gusnet.cx/proj/ez-ipupdate)
    Copyright © 1998-2001 Angus Mackay. All rights reserved.
    @@ -142,7 +162,17 @@ choparp (http://choparp.sourceforge.net)
    Copyright © 1997 Takamichi Tateoka (tree@mma.club.uec.ac.jp)
    Copyright -© 2002 Thomas Quinot (thomas@cuivre.fr.eu.org) - +© 2002 Thomas Quinot (thomas@cuivre.fr.eu.org)
    +
    + BPALogin (http://bpalogin.sourceforge.net) - lightweight portable BIDS2 login client
    + Copyright © 2001-3 Shane Hyde, and others.
    +
    + php-radius (http://www.mavetju.org/programming/php.php)
    + Copyright 2000, 2001, 2002 by Edwin Groothuis. All rights reserved.
    + This product includes software developed by Edwin Groothuis.
    +
    + wol (http://ahh.sourceforge.net/wol)
    + Copyright © 2000,2001,2002,2003,2004 Thomas Krennwallner <krennwallner@aon.at> + diff --git a/webgui/out_d.gif b/webgui/out_d.gif new file mode 100644 index 0000000..2b8d9d9 Binary files /dev/null and b/webgui/out_d.gif differ diff --git a/webgui/reboot.php b/webgui/reboot.php index 548d4f4..1eeff86 100644 --- a/webgui/reboot.php +++ b/webgui/reboot.php @@ -52,7 +52,7 @@ if ($_POST) {

    Reboot system

    - +

    Are you sure you want to reboot the system?

    diff --git a/webgui/services_captiveportal.php b/webgui/services_captiveportal.php new file mode 100644 index 0000000..8f9af28 --- /dev/null +++ b/webgui/services_captiveportal.php @@ -0,0 +1,303 @@ +#!/usr/local/bin/php +. + 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['logoutwin_enable'] = isset($config['captiveportal']['logoutwin_enable']); +$pconfig['radiusip'] = $config['captiveportal']['radiusip']; +$pconfig['radiusport'] = $config['captiveportal']['radiusport']; +$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['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 (!$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']['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false; + $config['captiveportal']['radiusip'] = $_POST['radiusip']; + $config['captiveportal']['radiusport'] = $_POST['radiusport']; + $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); + } +} +?> + + + +m0n0wall webGUI - Services: Captive portal + + + + + + + +

    Services: Captive portal

    + + + +
    Type Remote IP address
    BigPond Cable configuration
    Username +
    Password +
    Authentication server +
    + If this field is left empty, the default ("dce-server") is used.
    Authentication domain +
    + If this field is left empty, the domain name assigned via DHCP will be used.
    +
    + Note: the BigPond client implicitly sets the "Allow DNS server list to be overridden by DHCP/PPP on WAN" on the System: General setup page.
    Min. heartbeat interval + + seconds
    + Setting this to a sensible value (e.g. 60 seconds) can protect against DoS attacks.
    + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + onClick="enable_change(false)"> + Enable captive portal
    Interface +
    + Choose which interface to run the captive portal on.
    Idle timeout + +minutes
    +Clients will be disconnected after this amount of inactivity. They may log in again immediately, though. Leave this field blank for no idle timeout.
    Hard timeout + + minutes
    + 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).
    Logout popup window + > +
    + 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.
    RADIUS server + + + + + + + + + + + + + +
    IP address:
    Port:
    Shared secret:  
    RADIUS accounting:   onClick="radacct_change()">
    +
    + 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 port 1813 of the RADIUS server if RADIUS accounting is enabled. +
    Portal page contents +
    + + View current page +
    +
    + + Upload an HTML file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to the page itself) +with a submit button (name="accept"). Include the "auth_user" and "auth_pass" input elements if RADIUS authentication is enabled. If RADIUS is enabled and no "auth_user" is present, authentication will always fail. If RADIUS is not enabled, you can omit both these input elements. +Example code for the button:
    +
    <form method="post" action="">
    +    <input name="accept" type="submit" value="Continue">
    +    <input name="auth_user" type="text">
    +    <input name="auth_pass" type="password">
    + </form>
    Authentication
    + error page
    + contents
    +
    + + View current page +
    +
    + +The contents of the HTML file that you upload here are displayed when a RADIUS authentication error occurs.
      + +
     Note:
    +
    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.
    +
    +
    + + + + diff --git a/webgui/services_captiveportal_ip.php b/webgui/services_captiveportal_ip.php new file mode 100644 index 0000000..b78196b --- /dev/null +++ b/webgui/services_captiveportal_ip.php @@ -0,0 +1,152 @@ +#!/usr/local/bin/php + + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Captive portal: Allowed IP addresses + + + + + + +

    Services: Captive portal: Allowed IP addresses

    +
    + +

    +You must apply the changes in order for them to take effect.");?>
    +

    + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + +
    IP addressDescription
    + "; + ?> + + any"; + ?> + +   + +  
     

    + Note:
    +
    + 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 from addresses, it may be used to always allow pass-through access from a client behind the captive portal.

    + + + + + + + + + + + + +
    any x.x.x.x All connections to the IP address are allowed
    x.x.x.x any    All connections from the IP address are allowed
     
    +
    +
    + + + diff --git a/webgui/services_captiveportal_ip_edit.php b/webgui/services_captiveportal_ip_edit.php new file mode 100644 index 0000000..5148a6d --- /dev/null +++ b/webgui/services_captiveportal_ip_edit.php @@ -0,0 +1,152 @@ +#!/usr/local/bin/php + + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Captive portal: Edit allowed IP address + + + + + + +

    Services: Captive portal: Edit allowed IP address

    + +
    + + + + + + + + + + + + + + + + + +
    Direction + +
    + Use From to always allow an IP address through the captive portal (without authentication). + Use To to allow access from all clients (even non-authenticated ones) behind the portal to this IP address.
    IP address + +
    + IP address
    Description + +
    You may enter a description here + for your reference (not parsed).
      + + + + +
    +
    + + + diff --git a/webgui/services_captiveportal_mac.php b/webgui/services_captiveportal_mac.php new file mode 100644 index 0000000..e8e76b5 --- /dev/null +++ b/webgui/services_captiveportal_mac.php @@ -0,0 +1,133 @@ +#!/usr/local/bin/php + + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Captive portal: Pass-through MAC addresses + + + + + + +

    Services: Captive portal: Pass-through MAC addresses

    +
    + +

    +You must apply the changes in order for them to take effect.");?>
    +

    + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + +
    MAC addressDescription
    + + +   + +  
     
    + Note:
    +
    + 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.
     
    +
    +
    + + + diff --git a/webgui/services_captiveportal_mac_edit.php b/webgui/services_captiveportal_mac_edit.php new file mode 100644 index 0000000..57bdde5 --- /dev/null +++ b/webgui/services_captiveportal_mac_edit.php @@ -0,0 +1,134 @@ +#!/usr/local/bin/php + + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Captive portal: Edit pass-through MAC address + + + + + + +

    Services: Captive portal: Edit pass-through MAC address

    + +
    + + + + + + + + + + + + + +
    MAC address + +
    + MAC address (6 hex octets separated by colons)
    Description + +
    You may enter a description here + for your reference (not parsed).
      + + + + +
    +
    + + + diff --git a/webgui/services_dhcp.php b/webgui/services_dhcp.php index 6c08690..28670f7 100644 --- a/webgui/services_dhcp.php +++ b/webgui/services_dhcp.php @@ -54,6 +54,7 @@ $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]; @@ -112,6 +113,7 @@ if ($_POST) { $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']) @@ -180,24 +182,25 @@ function enable_change(enable_over) {

    Services: DHCP

    - +

    You must apply the changes in order for them to take effect.");?>

    - - $ifname): + +
  • - +
  • - - - + + + -
    +
      + $ifname): if ($ifent == $if): ?> -
     
    + @@ -207,6 +210,13 @@ function enable_change(enable_over) { interface + + + + +

     
      +> + Deny unknown clients
    + If this is checked, only the clients defined below will get DHCP leases from this server.
    Subnet @@ -278,26 +288,24 @@ function enable_change(enable_over) {
    The DHCP lease table can be viewed on the Diagnostics: DHCP leases page.
    -
    - You may enter static mappings between IP and MAC addresses - below.

     
    - - + + + + + + + + + + +
    IP address MAC address DescriptionIP addressDescription
    - + - +     diff --git a/webgui/services_dhcp_edit.php b/webgui/services_dhcp_edit.php index 86ce158..bb43457 100644 --- a/webgui/services_dhcp_edit.php +++ b/webgui/services_dhcp_edit.php @@ -63,8 +63,8 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - $reqdfields = explode(" ", "mac ipaddr"); - $reqdfieldsn = explode(",", "MAC address,IP address"); + $reqdfields = explode(" ", "mac"); + $reqdfieldsn = explode(",", "MAC address"); do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); @@ -80,25 +80,27 @@ if ($_POST) { if (isset($id) && ($a_maps[$id]) && ($a_maps[$id] === $mapent)) continue; - if (($mapent['mac'] == $_POST['mac']) || (ip2long($mapent['ipaddr']) == ip2long($_POST['ipaddr']))) { + 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 */ - $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 ($_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) { @@ -133,15 +135,8 @@ if ($_POST) {

    Services: DHCP: Edit static mapping

    - - - - - + + + + - + diff --git a/webgui/services_dnsmasq_edit.php b/webgui/services_dnsmasq_edit.php index b48e22f..b7f26e3 100644 --- a/webgui/services_dnsmasq_edit.php +++ b/webgui/services_dnsmasq_edit.php @@ -113,7 +113,6 @@ if ($_POST) {

    Services: DNS forwarder: Edit host

    -
    IP address - -
    MAC address @@ -150,6 +145,13 @@ if ($_POST) { Enter a MAC address in the following format: xx:xx:xx:xx:xx:xx
    IP address + +
    + If no IP address is given, one will be dynamically allocated from the pool.
    Description diff --git a/webgui/services_dnsmasq.php b/webgui/services_dnsmasq.php index af4acd0..a08ffb3 100644 --- a/webgui/services_dnsmasq.php +++ b/webgui/services_dnsmasq.php @@ -85,7 +85,7 @@ if ($_GET['act'] == "del") {

    Services: DNS forwarder

    - +

    You must apply the changes in order for them to take effect.");?>

    @@ -136,7 +136,7 @@ if ($_GET['act'] == "del") {
    Host Domain IPDescriptionDescription
    diff --git a/webgui/services_dyndns.php b/webgui/services_dyndns.php index e12098b..85d2394 100644 --- a/webgui/services_dyndns.php +++ b/webgui/services_dyndns.php @@ -118,7 +118,7 @@ function enable_change(enable_change) {

    Services: Dynamic DNS client

    - +
    diff --git a/webgui/services_proxyarp.php b/webgui/services_proxyarp.php index 9591063..2c0c8f5 100644 --- a/webgui/services_proxyarp.php +++ b/webgui/services_proxyarp.php @@ -76,7 +76,7 @@ if ($_GET['act'] == "del") {

    Services: Proxy ARP

    - +

    You must apply the changes in order for them to take effect.");?>

    @@ -84,7 +84,7 @@ if ($_GET['act'] == "del") {
    - + diff --git a/webgui/services_proxyarp_edit.php b/webgui/services_proxyarp_edit.php index a9ee249..50d6fc6 100644 --- a/webgui/services_proxyarp_edit.php +++ b/webgui/services_proxyarp_edit.php @@ -163,7 +163,6 @@ function typesel_change() {

    Services: Proxy ARP: Edit

    -
    NetworkDescriptionDescription
    diff --git a/webgui/services_snmp.php b/webgui/services_snmp.php index 7d02cfe..6f8e9f7 100644 --- a/webgui/services_snmp.php +++ b/webgui/services_snmp.php @@ -99,7 +99,7 @@ function enable_change(enable_change) {

    Services: SNMP

    - +
    diff --git a/webgui/services_wol.php b/webgui/services_wol.php new file mode 100644 index 0000000..93664a2 --- /dev/null +++ b/webgui/services_wol.php @@ -0,0 +1,162 @@ +#!/usr/local/bin/php +. + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Wake on LAN + + + + + + +

    Services: Wake on LAN

    + + + +
    + + + + + + + + + + + +
    Interface +
    + Choose which interface the host to be woken up is connected to.
    MAC address + +
    + Enter a MAC address in the following format: xx:xx:xx:xx:xx:xx
      + +
    + Note:
    +
    This service can be used to wake up (power on) computers by sending special "Magic Packets". 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).

    +
    + You may store MAC addresses below for your convenience. +Click the MAC address to wake up a computer.
    +  + + + + + + + + + + + + + + + + + + + +
    InterfaceMAC addressDescription
    +   + +   + +   + +  
    + + + + diff --git a/webgui/services_wol_edit.php b/webgui/services_wol_edit.php new file mode 100644 index 0000000..9af7f5e --- /dev/null +++ b/webgui/services_wol_edit.php @@ -0,0 +1,143 @@ +#!/usr/local/bin/php +. + 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; + } +} +?> + + + +m0n0wall webGUI - Services: Wake on LAN: Edit entry + + + + + + +

    Services: Wake on LAN: Edit entry

    + +
    + + + + + + + + + + + + + + + + + +
    Interface +
    + Choose which interface this host is connected to.
    MAC address + +
    + Enter a MAC address in the following format: + xx:xx:xx:xx:xx:xx
    Description + +
    You may enter a description here + for your reference (not parsed).
      + + + + +
    +
    + + + diff --git a/webgui/status_captiveportal.php b/webgui/status_captiveportal.php new file mode 100644 index 0000000..ffce109 --- /dev/null +++ b/webgui/status_captiveportal.php @@ -0,0 +1,128 @@ +#!/usr/local/bin/php +. + 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"); +?> + + + +m0n0wall webGUI - Status: Captive portal + + + + + + +

    Status: Captive portal

    + + + + + + + + + + + + + + + + + + + + + + + + +
    IP addressMAC addressSession startLast activitySession start
    +
    +

    +

    + + + + + + + + +
    +

    + + + diff --git a/webgui/status_graph.php b/webgui/status_graph.php new file mode 100644 index 0000000..490522b --- /dev/null +++ b/webgui/status_graph.php @@ -0,0 +1,80 @@ +#!/usr/local/bin/php +. + 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']; +?> + + + +m0n0wall webGUI - Status: Traffic graph + + + + + + +

    Status: Traffic graph

    + 'WAN', 'lan' => 'LAN'); + +for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) { + $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr']; +} +?> +
    +Interface: + +
    +
    + +
    +

    Note: the Adobe SVG viewer is required to view the graph. + + + diff --git a/webgui/status_interfaces.php b/webgui/status_interfaces.php index a7923ef..017e072 100644 --- a/webgui/status_interfaces.php +++ b/webgui/status_interfaces.php @@ -56,9 +56,12 @@ function get_interface_info($ifdescr) { if ($ifinfo['if'] != $g['pppoe_interface']) { $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]; @@ -101,6 +104,8 @@ function get_interface_info($ifdescr) { 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)) { @@ -220,7 +225,20 @@ function get_interface_info($ifdescr) {

    In/out errors + +
    Collisions + +
    diff --git a/webgui/system.php b/webgui/system.php index faa9d60..c3d50a2 100644 --- a/webgui/system.php +++ b/webgui/system.php @@ -161,7 +161,7 @@ if ($_POST) {

    System: General setup

    - +
    @@ -187,10 +187,10 @@ if ($_POST) { the DHCP service, DNS forwarder and for PPTP VPN clients

    > - Allow DNS server list to be overridden by DHCP + Allow DNS server list to be overridden by DHCP/PPP on WAN
    If this option is set, m0n0wall will use DNS servers assigned - by a DHCP server on WAN for its own purposes (including + 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.

    diff --git a/webgui/system_advanced.php b/webgui/system_advanced.php index c0dde29..e43087d 100644 --- a/webgui/system_advanced.php +++ b/webgui/system_advanced.php @@ -37,6 +37,7 @@ $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']); if ($_POST) { @@ -65,6 +66,7 @@ if ($_POST) { $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; write_config(); @@ -107,7 +109,7 @@ function enable_change(enable_over) {

    System: Advanced functions

    - +

    Note: the options on this page are intended for use by advanced users only, and there's NO support for them.

    @@ -192,6 +194,13 @@ function enable_change(enable_over) { > Disable console menu
    Changes to this option will take effect after a reboot.
    + +
    + + diff --git a/webgui/system_firmware.php b/webgui/system_firmware.php index 421b62b..cd54f9c 100644 --- a/webgui/system_firmware.php +++ b/webgui/system_firmware.php @@ -96,7 +96,13 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { /* 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 { + 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"); @@ -127,7 +133,8 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { } } } else { - $fwinfo = check_firmware_version(); + if (!isset($config['system']['disablefirmwarecheck'])) + $fwinfo = check_firmware_version(); } ?> @@ -142,7 +149,7 @@ if ($_POST && !file_exists($d_firmwarelock_path)) {

    System: Firmware

    - +

    Firmware uploading is not supported on this platform.

    @@ -150,7 +157,7 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { " . $sig_warning . "

    This means that the image you uploaded " . - "is not an official supported image and may lead to unexpected behavior or security " . + "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.

    ". "Do you want to install this image anyway (on your own risk)?"; diff --git a/webgui/system_routes.php b/webgui/system_routes.php index b63b410..438a74c 100644 --- a/webgui/system_routes.php +++ b/webgui/system_routes.php @@ -80,7 +80,7 @@ if ($_GET['act'] == "del") {

    System: Static routes

    - +

    You must apply the changes in order for them to take effect.");?>

    diff --git a/webgui/system_routes_edit.php b/webgui/system_routes_edit.php index a267dbe..6d092fa 100644 --- a/webgui/system_routes_edit.php +++ b/webgui/system_routes_edit.php @@ -115,7 +115,6 @@ if ($_POST) {

    System: Static routes: Edit route

    -
      + > + Disable firmware version check
    + This will cause m0n0wall not to check for newer firmware versions when the System: Firmware page is viewed.
     
    diff --git a/webgui/vpn_ipsec.php b/webgui/vpn_ipsec.php index 255454e..07f2ea0 100644 --- a/webgui/vpn_ipsec.php +++ b/webgui/vpn_ipsec.php @@ -93,20 +93,21 @@ if ($_GET['act'] == "del") {

    VPN: IPsec

    - +

    You must apply the changes in order for them to take effect.");?>

    + - - - - - - -
    + +
    TunnelsMobile clientsPre-shared keys 
    +

    diff --git a/webgui/vpn_ipsec_edit.php b/webgui/vpn_ipsec_edit.php index b6a13c0..6f633d2 100644 --- a/webgui/vpn_ipsec_edit.php +++ b/webgui/vpn_ipsec_edit.php @@ -57,7 +57,7 @@ function address_to_pconfig($adr, &$padr, &$pmask) { $padr = $adr['network']; else if ($adr['address']) { list($padr, $pmask) = explode("/", $adr['address']); - if (!$pmask) + if (is_null($pmask)) $pmask = 32; } } @@ -100,7 +100,10 @@ if (isset($id) && $a_ipsec[$id]) { } 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']; @@ -175,6 +178,11 @@ if ($_POST) { 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'] = ""; @@ -198,6 +206,9 @@ if ($_POST) { 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']; @@ -260,7 +271,6 @@ function typesel_change() {

    VPN: IPsec: Edit tunnel

    - @@ -311,7 +321,7 @@ function typesel_change() {
    /

    + - - - - - - -
    + +
    TunnelsMobile clientsPre-shared keys 
    + diff --git a/webgui/vpn_ipsec_mobile.php b/webgui/vpn_ipsec_mobile.php index d1bea14..05aa797 100644 --- a/webgui/vpn_ipsec_mobile.php +++ b/webgui/vpn_ipsec_mobile.php @@ -59,7 +59,10 @@ if (count($a_ipsec) == 0) { } 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']; @@ -94,6 +97,11 @@ if ($_POST) { 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'] = ""; @@ -114,6 +122,9 @@ if ($_POST) { 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']; @@ -156,14 +167,15 @@ if ($_POST) {
    Identifier
    + - - - - - - -
    + +
    TunnelsMobile clientsPre-shared keys 
    + diff --git a/webgui/vpn_pptp.php b/webgui/vpn_pptp.php index 90e7d8c..4d0a64f 100644 --- a/webgui/vpn_pptp.php +++ b/webgui/vpn_pptp.php @@ -171,9 +171,18 @@ function enable_change(enable_over) {

    VPN: PPTP

    + - - + +
     
    + + + + +
    +
      +
    • Configuration
    • +
    • Users
    • +
    +
    @@ -278,6 +287,9 @@ function enable_change(enable_over) { traffic from PPTP clients!
     
    +