summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xusr/local/www/diag_logs_filter_dynamic.php432
-rw-r--r--usr/local/www/themes/metallic/all.css116
2 files changed, 527 insertions, 21 deletions
diff --git a/usr/local/www/diag_logs_filter_dynamic.php b/usr/local/www/diag_logs_filter_dynamic.php
new file mode 100755
index 0000000..9790a89
--- /dev/null
+++ b/usr/local/www/diag_logs_filter_dynamic.php
@@ -0,0 +1,432 @@
+<?php
+/* $Id$ */
+/*
+ diag_logs_filter.php
+ part of pfSesne by Scott Ullrich
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$filter_logfile = "{$g['varlog_path']}/filter.log";
+
+/* AJAX related routines */
+handle_ajax();
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear']) {
+ exec("killall syslogd");
+ exec("/usr/sbin/clog -i -s 262144 /var/log/filter.log");
+ system_syslogd_start();
+}
+
+/* format filter logs */
+function conv_clog($logfile, $tail = 50) {
+ global $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" : "";
+
+ $logarr = "";
+ exec("/usr/sbin/clog {$logfile} | /usr/bin/tail {$sor} -n {$tail}", $logarr);
+
+ $filterlog = array();
+
+ $counter = 0;
+
+ foreach ($logarr as $logent) {
+
+ $log_split = "";
+
+ /* pf: 6. 272592 rule 218/0(match): block in on fxp0: X.XXX.XXX.XXX.4503 > XX.X.XXX.X.6881: S 1163549441:1163549441(0) win 65535 <mss 1432,nop,nop,sackOK> */
+
+ preg_match("/(.*)\s(.*)\spf:.*rule (.*)\(match\):\s(\w+)\sin\son\s(\w+:)\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,7})\s([\<|\>])\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,7}):.*/",$logent,$log_split);
+
+ if($log_split[5] == "")
+ preg_match("/(.*)\s(.*)\spf:.*rule (.*)\(match\):\s(\w+)\sin\son\s(\w+:)\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\s([\<|\>])\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):.*/",$logent,$log_split);
+
+ $logent = strtoupper($logent);
+
+ $do_not_display = false;
+ if(stristr($logent, "UDP") == true)
+ $flent['proto'] = "UDP";
+ else if(stristr($logent, "TCP") == true)
+ $flent['proto'] = "TCP";
+ else if(stristr($logent, "ICMP") == true)
+ $flent['proto'] = "ICMP";
+ else if(stristr($logent, "HSRP") == true)
+ $flent['proto'] = "HSRP";
+ else if(stristr($logent, "ESP") == true)
+ $flent['proto'] = "ESP";
+ else if(stristr($logent, "AH") == true)
+ $flent['proto'] = "AH";
+ else if(stristr($logent, "GRE") == true)
+ $flent['proto'] = "GRE";
+ else if(stristr($logent, "IGMP") == true)
+ $flent['proto'] = "IGMP";
+ else if(stristr($logent, "CARP") == true)
+ $flent['proto'] = "CARP";
+ else if(stristr($logent, "PFSYNC") == true)
+ $flent['proto'] = "PFSYNC";
+ else
+ $do_not_display = true;
+
+ $flent['time'] = $log_split[1];
+ $flent['act'] = $log_split[4];
+ $flent['interface'] = strtoupper(convert_real_interface_to_friendly_interface_name(str_replace(":","",$log_split[5])));
+
+ if($flent['proto'] == "TCP" or $flent['proto'] == "UDP") {
+ $flent['src'] = convert_port_period_to_colon($log_split[6]);
+ $flent['dst'] = convert_port_period_to_colon($log_split[8]);
+ } else {
+ $flent['src'] = $log_split[6];
+ $flent['dst'] = $log_split[8];
+ }
+
+ $tmp = split("/", $log_split[3]);
+ $flent['rulenum'] = $tmp[0];
+
+ if($flent['src'] == "" or $flent['dst'] == "" or $do_not_display == true) {
+ /* do not display me! */
+ } else {
+ $counter++;
+ $filterlog[] = $flent;
+ }
+
+ }
+
+ return $filterlog;
+}
+
+function convert_port_period_to_colon($addr) {
+ $addr_split = split("\.", $addr);
+ if($addr_split[4] == "")
+ $newvar = $addr_split[0] . "." . $addr_split[1] . "." . $addr_split[2] . "." . $addr_split[3];
+ else
+ $newvar = $addr_split[0] . "." . $addr_split[1] . "." . $addr_split[2] . "." . $addr_split[3] . ":" . $addr_split[4];
+ if($newvar == "...")
+ return $addr;
+ return $newvar;
+}
+
+function format_ipf_ip($ipfip) {
+ list($ip,$port) = explode(",", $ipfip);
+ if (!$port)
+ return $ip;
+
+ return $ip . ", port " . $port;
+}
+
+$filterlog = conv_clog($filter_logfile, $nentries);
+
+$pgtitle = "Diagnostics: System logs: Firewall";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script>
+<script src="/javascript/scriptaculous/scriptaculous.js" type="text/javascript"></script>
+<script language="javascript">
+ lastsawtime = '<?php echo time(); ?>;';
+ var lines = Array();
+ var timer;
+ var updateDelay = 4000;
+ var isBusy = false;
+ var isPaused = false;
+<?php
+ if(isset($config['syslog']['reverse']))
+ echo " var isReverse = true;\n";
+ else
+ echo " var isReverse = false;\n";
+?>
+</script>
+<br>
+<table width="100%">
+ <tr>
+ <td>
+ <div class="pgtitle"><?=$pgtitle?></div>
+ </td>
+ <td align="right">
+ Pause:<input valign="middle" type="checkbox" onClick="javascript:toggle_pause();">
+ </td>
+ </tr>
+</table>
+<br>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+<?php
+ $tab_array = array();
+ $tab_array[] = array("System", false, "diag_logs.php");
+ $tab_array[] = array("Firewall", true, "diag_logs_filter.php");
+ $tab_array[] = array("DHCP", false, "diag_logs_dhcp.php");
+ $tab_array[] = array("Portal Auth", false, "diag_logs_auth.php");
+ $tab_array[] = array("IPSEC VPN", false, "diag_logs_ipsec.php");
+ $tab_array[] = array("PPTP VPN", false, "diag_logs_vpn.php");
+ $tab_array[] = array("Load Balance", false, "diag_logs_slbd.php");
+ $tab_array[] = array("Settings", false, "diag_logs_settings.php");
+ display_top_tabs($tab_array);
+?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <div id="log">
+ <div class="listtopic">
+ Last <?php echo $nentries; ?> records
+ </div>
+ <div class="log-header">
+ <span class="log-action">Act</span>
+ <span class="log-time">Time</span>
+ <span class="log-interface">If</span>
+ <span class="log-source">Source</span>
+ <span class="log-destination">Destination</span>
+ <span class="log-protocol">Proto</span>
+ </div>
+ <?php $counter=0; foreach ($filterlog as $filterent): ?>
+ <?php
+ if(isset($config['syslog']['reverse'])) {
+ /* honour reverse logging setting */
+ if($counter == 0)
+ $activerow = " id=\"firstrow\"";
+ else
+ $activerow = "";
+
+ } else {
+ /* non-reverse logging */
+ if($counter == count($filterlog))
+ $activerow = " id=\"firstrow\"";
+ else
+ $activerow = "";
+ }
+ ?>
+ <div class="log-entry" <?php echo $activerow; ?>>
+ <span class="log-action" nowrap><a href="#" onClick="javascript:getURL('diag_logs_filter.php?getrulenum=<?php echo $filterent['rulenum']; ?>', outputrule);">
+ <?php
+ if (strstr(strtolower($filterent['act']), "p"))
+ $img = "/themes/metallic/images/icons/icon_pass.gif";
+ else if(strstr(strtolower($filterent['act']), "r"))
+ $img = "/themes/metallic/images/icons/icon_reject.gif";
+ else
+ $img = "/themes/metallic/images/icons/icon_block.gif";
+ ?>
+ <img border="0" src="<?=$img;?>" width="11" height="11" align="absmiddle"></a></span>
+ <span class="log-time" ><?=htmlspecialchars($filterent['time']);?></span>
+ <span class="log-interface" ><?=htmlspecialchars(convert_real_interface_to_friendly_interface_name($filterent['interface']));?></span>
+ <span class="log-source" ><?=htmlspecialchars($filterent['src']);?></span>
+ <span class="log-destination" ><?=htmlspecialchars($filterent['dst']);?></span>
+ <span class="log-protocol" ><?=htmlspecialchars($filterent['proto']);?></span>
+ </div>
+ <?php $counter++; endforeach; ?>
+ </div>
+ </div>
+ </td>
+ </tr>
+</table>
+<script language="javascript">
+if (typeof getURL == 'undefined') {
+ getURL = function(url, callback) {
+ if (!url)
+ throw 'No URL for getURL';
+ try {
+ if (typeof callback.operationComplete == 'function')
+ callback = callback.operationComplete;
+ } catch (e) {}
+ if (typeof callback != 'function')
+ throw 'No callback function for getURL';
+ var http_request = null;
+ if (typeof XMLHttpRequest != 'undefined') {
+ http_request = new XMLHttpRequest();
+ }
+ else if (typeof ActiveXObject != 'undefined') {
+ try {
+ http_request = new ActiveXObject('Msxml2.XMLHTTP');
+ } catch (e) {
+ try {
+ http_request = new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e) {}
+ }
+ }
+ if (!http_request)
+ throw 'Both getURL and XMLHttpRequest are undefined';
+ http_request.onreadystatechange = function() {
+ if (http_request.readyState == 4) {
+ callback( { success : true,
+ content : http_request.responseText,
+ contentType : http_request.getResponseHeader("Content-Type") } );
+ }
+ }
+ http_request.open('GET', url, true);
+ http_request.send(null);
+ }
+}
+
+function outputrule(req) {
+ alert(req.content);
+}
+function fetch_new_rules() {
+ if(isPaused)
+ return;
+ if(isBusy)
+ return;
+ isBusy = true;
+ getURL('diag_logs_filter_dynamic.php?lastsawtime=' + lastsawtime, fetch_new_rules_callback);
+}
+function fetch_new_rules_callback(callback_data) {
+ if(isPaused)
+ return;
+ var data_split;
+ var new_data_to_add = Array();
+ var data = callback_data.content;
+ data_split = data.split("\n");
+ for(var x=0; x<data_split.length-1; x++) {
+ /* loop through rows */
+ row_split = data_split[x].split("||");
+ var line = '';
+ line = '<div class="log-entry">';
+ line += ' <span class="log-action" nowrap>' + row_split[0] + '</span>';
+ line += ' <span class="log-time" nowrap>' + row_split[1] + '</span>';
+ line += ' <span class="log-interface" nowrap>' + row_split[2] + '</span>';
+ line += ' <span class="log-source" nowrap>' + row_split[3] + '</span>';
+ line += ' <span class="log-destination" nowrap>' + row_split[4] + '</span>';
+ line += ' <span class="log-protocol" nowrap>' + row_split[5] + '</span>';
+ line += '</div>';
+ lastsawtime = row_split[6];
+ new_data_to_add[new_data_to_add.length] = line;
+ }
+ update_div_rows(new_data_to_add);
+ isBusy = false;
+}
+function update_div_rows(data) {
+ if(isPaused)
+ return;
+ var isIE = navigator.appName.indexOf('Microsoft') != -1;
+ var isSafari = navigator.userAgent.indexOf('Safari') != -1;
+ var isOpera = navigator.userAgent.indexOf('Opera') != -1;
+ var rulestable = document.getElementById('log');
+ var rows = rulestable.getElementsByTagName('div');
+ var showanim = 1;
+ if (isIE) {
+ showanim = 0;
+ }
+ for(var x=1; x<data.length; x++) {
+ var numrows = rows.length;
+ /* if reverse logging is enabled we need to show the
+ * records in a reverse order with new items appearing
+ * on the top
+ */
+ if(isReverse == false) {
+ for (var i = numrows-1; i > 1; i--) {
+ rows[i].innerHTML = rows[i-1].innerHTML;
+ }
+ } else {
+ for (var i = 1; i < numrows+1; i++) {
+ rows[i].innerHTML = rows[i-1].innerHTML;
+ }
+ }
+ var item = document.getElementById('firstrow');
+ if (showanim) {
+ rows[1].style.display = 'none';
+ rows[1].innerHTML = data[x];
+ new Effect.Appear(item);
+ } else {
+ rows[1].innerHTML = data[x];
+ }
+ }
+ /* rechedule AJAX interval */
+ timer = setInterval('fetch_new_rules()', updateDelay);
+}
+function toggle_pause() {
+ if(isPaused) {
+ isPaused = false;
+ fetch_new_rules();
+ } else {
+ isPaused = true;
+ }
+}
+/* start local AJAX engine */
+lastsawtime = '<?php echo time(); ?>;';
+timer = setInterval('fetch_new_rules()', updateDelay);
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
+<?php
+
+/* AJAX specific handlers */
+function handle_ajax() {
+ if($_GET['getrulenum'] or $_POST['getrulenum']) {
+ if($_GET['getrulenum'])
+ $rulenum = $_GET['getrulenum'];
+ if($_POST['getrulenum'])
+ $rulenum = $_POST['getrulenum'];
+ $rule = `pfctl -vvsr | grep @{$rulenum}`;
+ echo "The rule that triggered this action is:\n\n{$rule}";
+ exit;
+ }
+
+ if($_GET['lastsawtime'] or $_POST['lastsawtime']) {
+ global $filter_logfile,$filterent;
+ if($_GET['lastsawtime'])
+ $lastsawtime = $_GET['lastsawtime'];
+ if($_POST['lastsawtime'])
+ $lastsawtime = $_POST['lastsawtime'];
+ /* compare lastsawrule's time stamp to filter logs.
+ * afterwards return the newer records so that client
+ * can update AJAX interface screen.
+ */
+ $new_rules = "";
+ $filterlog = conv_clog($filter_logfile, 50);
+ foreach($filterlog as $log_row) {
+ $time_regex = "";
+ preg_match("/.*([0-9][0-9]:[0-9][0-9]:[0-9][0-9])/", $log_row['time'], $time_regex);
+ $row_time = strtotime($time_regex[1]);
+ if (strstr(strtolower($log_row['act']), "p"))
+ $img = "<img border='0' src='/themes/metallic/images/icons/icon_pass.gif'>";
+ else if(strstr(strtolower($filterent['act']), "r"))
+ $img = "<img border='0' src='/themes/metallic/images/icons/icon_reject.gif'>";
+ else
+ $img = "<img border='0' src='/themes/metallic/images/icons/icon_block.gif'>";
+ //echo "{$time_regex[1]} - $row_time > $lastsawtime<p>";
+ if($row_time > $lastsawtime)
+ $new_rules .= "{$img}||{$log_row['time']}||{$log_row['interface']}||{$log_row['src']}||{$log_row['dst']}||{$log_row['proto']}||" . time() . "||\n";
+ }
+ echo $new_rules;
+ exit;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/usr/local/www/themes/metallic/all.css b/usr/local/www/themes/metallic/all.css
index ac439e7..558d0ed 100644
--- a/usr/local/www/themes/metallic/all.css
+++ b/usr/local/www/themes/metallic/all.css
@@ -4,6 +4,16 @@ html, body, td, th, input, select {
font-size: 0.9em;
}
+div.GraphLink {
+ position: relative;
+}
+
+span.GraphLinkLine {
+ position: absolute;
+ background-color: #990000;
+ width: 100%;
+}
+
body {
background-color: #333333;
margin: 5px auto;
@@ -34,7 +44,7 @@ iframe {
}
#header {
- background: url('images/header.gif') no-repeat;
+ background: url('/themes/metallic/images/header.gif') no-repeat;
background-position: 4px;
height: 102px;
width: 808px;
@@ -43,7 +53,7 @@ iframe {
}
#header-left {
position: relative;
- /* background: url('images/logo.gif') no-repeat; */
+ /* background: url('/themes/metallic/images/logo.gif') no-repeat; */
background-position: center;
height: 65px;
width: 145px;
@@ -57,7 +67,7 @@ iframe {
}
#header-right {
position: relative;
- /* background: url('images/header.gif') no-repeat; */
+ /* background: url('/themes/metallic/images/header.gif') no-repeat; */
height: 70px;
color: #fff;
left: 0px;
@@ -65,7 +75,7 @@ iframe {
}
#header-right .alert {
position: relative;
- /* background: url('images/alert.gif') no-repeat; */
+ /* background: url('/themes/metallic/images/alert.gif') no-repeat; */
background-position: 4px 2px;
color: #fff;
height: 17px;
@@ -89,34 +99,32 @@ iframe {
#header-right .container .right {
position: relative;
float: right;
- top: 22px;
+ top: 10px;
padding-right: 4px;
z-index: 1;
}
-#header-right .container .right #alerts {
+#header-right .container .right #marquee-text {
+ background: url('/themes/metallic/images/misc/status_alerter.gif') no-repeat;
+ margin: 0px;
+}
+#header-right .container .right #ajaxstatusbar {
position: relative;
- background: url('images/alert_bgr.gif') no-repeat;
- height: 39px;
+ height: 13px;
width: 431px;
z-index: 1;
- padding-top: 20px;
- padding-left: 5px;
margin: 0px;
+text-align: right;
}
#header-right .container .right #hostname {
position: relative;
- height: 39px;
- width: 431px;
+ height: 13px;
z-index: 1;
- padding-left: 5px;
margin: 0px;
- top: 25px;
- left: 230px;
+top: 25px;
+text-align: right;
}
-
-
table#marquee {
position: relative;
top: -6px;
@@ -164,7 +172,7 @@ table#marquee div#container div#scroller {
margin-left: 5px;
padding-top: 0px;
width: 800px;
- background: url('images/horizontal.gif') repeat-y;
+ background: url('/themes/metallic/images/horizontal.gif') repeat-y;
}
#left {
@@ -187,15 +195,15 @@ table#marquee div#container div#scroller {
#footer {
position: relative;
- background: url('images/footer.gif') no-repeat;
+ background: url('/themes/metallic/images/footer.gif') no-repeat;
top: -18px;
left: 7px;
width: 800px;
height: 75px;
color: #ffffff;
text-align: center;;
- font-size: 0.9em;
- padding-top: 17px;
+ font-size: 0.7em;
+ padding-top: 10px;
margin-bottom: 20px;
clear: both;
}
@@ -720,3 +728,69 @@ div.suggestions div.current {
.r4,.rl4,.rr4,.re4,.rel4,.rer4,.ra4,.rar4,.ral4,.rx4,.rxl4,.rxr4{height:2px}
.rer1,.rel1,.re1,.res1,.resl1,.resr1{border-width:1px 0 0;height:0px !important;height /**/:1px}
/* End Nifty Corners Crap */
+
+
+
+/* CSS for Dynamic Log Viewer */
+/* Author: Erik Kristensen */
+div#log div.log-entry {
+ clear: both;
+}
+
+div#log div.log-entry span,
+div#log div.log-header span {
+ padding: 3px 2px 3px 2px;
+ padding-left: 8px;
+}
+
+div#log div.log-entry span.log-action {
+ padding-bottom: 6px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+div#log div.log-header span {
+ border-top: 1px solid #999;
+ background-color: #bbb;
+ font-weight: bold;
+ text-align: left;
+}
+
+div#log span.log-action,
+div#log span.log-time,
+div#log span.log-interface,
+div#log span.log-source,
+div#log span.log-destination,
+div#log span.log-protocol {
+ float: left;
+ text-align: left;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+}
+
+div#log span.log-protocol {
+ border-right: 1px solid #999;
+}
+
+div#log span.log-action {
+ width: 2em;
+ text-align: center;
+}
+
+div#log span.log-time {
+ width: 12.5em;
+}
+
+div#log span.log-interface {
+ width: 5em;
+}
+
+div#log span.log-source,
+div#log span.log-destination {
+ width: 17.6em;
+}
+
+div#log span.log-protocol {
+ width: 5.5em;
+}
+/* END CSS FOR DYNAMIC LOG VIEWER */
OpenPOWER on IntegriCloud