mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-15 00:54:41 +00:00
(legacy) refactor diag_states_summary.php
This commit is contained in:
parent
4e890eb5a1
commit
56e6924bb6
108
src/opnsense/scripts/filter/list_states.py
Executable file
108
src/opnsense/scripts/filter/list_states.py
Executable file
@ -0,0 +1,108 @@
|
||||
#!/usr/local/bin/python2.7
|
||||
|
||||
"""
|
||||
Copyright (c) 2015 Ad Schellevis
|
||||
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.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
list pf states
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
def parse_address(addr):
|
||||
result = {'port':'0'}
|
||||
if addr.count(':') > 1:
|
||||
# parse IPv6 address
|
||||
result['addr'] = addr.split('[')[0]
|
||||
result['ipproto'] = 'ipv6'
|
||||
if addr.find('[') > -1:
|
||||
result['port'] = addr.split('[')[1].split(']')[0]
|
||||
else:
|
||||
# parse IPv4 address
|
||||
result['ipproto'] = 'ipv4'
|
||||
result['addr'] = addr.split(':')[0]
|
||||
if addr.find(':') > -1:
|
||||
result['port'] = addr.split(':')[1]
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == '__main__':
|
||||
result={'details':[]}
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl','-s', 'state'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
data = output_stream.read().strip()
|
||||
if (data.count('\n') > 2):
|
||||
for line in data.split('\n'):
|
||||
parts = line.split()
|
||||
if len(parts) >= 6:
|
||||
record = {}
|
||||
record['nat_addr'] = None
|
||||
record['nat_port'] = None
|
||||
record['iface'] = parts[0]
|
||||
record['proto'] = parts[1]
|
||||
record['src_addr'] = parse_address(parts[2])['addr']
|
||||
record['src_port'] = parse_address(parts[2])['port']
|
||||
record['ipproto'] = parse_address(parts[2])['ipproto']
|
||||
|
||||
if parts[3].find('(') > -1:
|
||||
# NAT enabled
|
||||
record['nat_addr'] = parts[3][1:].split(':')[0]
|
||||
record['nat_port'] = parts[3].split(':')[1][:-1]
|
||||
|
||||
record['dst_addr'] = parse_address(parts[-2])['addr']
|
||||
record['dst_port'] = parse_address(parts[-2])['port']
|
||||
|
||||
if parts[-3] == '->':
|
||||
record['direction'] = 'out'
|
||||
else:
|
||||
record['direction'] = 'in'
|
||||
|
||||
record['state'] = parts[-1]
|
||||
|
||||
result['details'].append(record)
|
||||
|
||||
result['total'] = len(result['details'])
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
print(ujson.dumps(result))
|
||||
else:
|
||||
# output plain
|
||||
print ('------------------------- STATES -------------------------')
|
||||
for state in result['details']:
|
||||
if state['ipproto'] == 'ipv4':
|
||||
if state['nat_addr'] is not None:
|
||||
print ('%(iface)s %(proto)s %(src_addr)s:%(src_port)s \
|
||||
(%(nat_addr)s:%(nat_port)s) %(direction)s %(dst_addr)s:%(dst_port)s %(state)s'%state)
|
||||
else:
|
||||
print ('%(iface)s %(proto)s %(src_addr)s:%(src_port)s \
|
||||
%(direction)s %(dst_addr)s:%(dst_port)s %(state)s'%state)
|
||||
else:
|
||||
print ('%(iface)s %(proto)s %(src_addr)s[%(src_port)s] \
|
||||
%(direction)s %(dst_addr)s[%(dst_port)s] %(state)s'%state)
|
||||
@ -34,6 +34,12 @@ parameters: %s %s
|
||||
type:script_output
|
||||
message:request content of pf %s table
|
||||
|
||||
[list.states]
|
||||
command:/usr/local/opnsense/scripts/filter/list_states.py
|
||||
parameters: %s
|
||||
type:script_output
|
||||
message:request pf states
|
||||
|
||||
[delete.table]
|
||||
command:/usr/local/opnsense/scripts/filter/delete_table.py
|
||||
parameters: %s %s
|
||||
|
||||
@ -1,205 +1,166 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (C) 2014 Deciso B.V.
|
||||
Copyright (C) 2010-2014 Jim Pingle
|
||||
Copyright (C) 2005-2009 Scott Ullrich
|
||||
Copyright (C) 2005 Colin Smith
|
||||
All rights reserved.
|
||||
Copyright (C) 2014 Deciso B.V.
|
||||
Copyright (C) 2010-2014 Jim Pingle
|
||||
Copyright (C) 2005-2009 Scott Ullrich
|
||||
Copyright (C) 2005 Colin Smith
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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_once("guiconfig.inc");
|
||||
|
||||
exec("/sbin/pfctl -s state", $states);
|
||||
function addipinfo(&$iparr, $ip, $proto, $srcport, $dstport) {
|
||||
if (!isset($iparr[$ip]['seen'])) {
|
||||
$iparr[$ip] = array("seen" => 0, "protos" => array());
|
||||
}
|
||||
if (!isset($iparr[$ip]['protos'][$proto])) {
|
||||
$iparr[$ip]['protos'][$proto] = array("seen" => 0, 'srcports' => array(), 'dstports' => array());
|
||||
}
|
||||
$iparr[$ip]['seen']++;
|
||||
$iparr[$ip]['protos'][$proto]['seen']++;
|
||||
if (!empty($srcport)) {
|
||||
if (!isset($iparr[$ip]['protos'][$proto]['srcports'][$srcport])) {
|
||||
$iparr[$ip]['protos'][$proto]['srcports'][$srcport] = 0;
|
||||
}
|
||||
$iparr[$ip]['protos'][$proto]['srcports'][$srcport]++;
|
||||
}
|
||||
if (!empty($dstport)) {
|
||||
$iparr[$ip]['protos'][$proto]['dstports'][$dstport]++;
|
||||
}
|
||||
}
|
||||
|
||||
function sort_by_ip($a, $b) {
|
||||
return ip2ulong($a) < ip2ulong($b) ? -1 : 1;
|
||||
}
|
||||
|
||||
function build_port_info($portarr, $proto) {
|
||||
if (empty($portarr)) {
|
||||
return '';
|
||||
}
|
||||
$ports = array();
|
||||
asort($portarr);
|
||||
foreach (array_reverse($portarr, TRUE) as $port => $count) {
|
||||
$str = "";
|
||||
$service = getservbyport($port, strtolower($proto));
|
||||
$port = "{$proto}/{$port}";
|
||||
if (!empty($service)) {
|
||||
$port = "{$port} ({$service})";
|
||||
}
|
||||
$ports[] = "{$port}: {$count}";
|
||||
}
|
||||
return implode($ports, ', ');
|
||||
}
|
||||
|
||||
$srcipinfo = array();
|
||||
$dstipinfo = array();
|
||||
$allipinfo = array();
|
||||
$pairipinfo = array();
|
||||
|
||||
function addipinfo(&$iparr, $ip, $proto, $srcport, $dstport) {
|
||||
$iparr[$ip]['seen']++;
|
||||
$iparr[$ip]['protos'][$proto]['seen']++;
|
||||
if (!empty($srcport)) {
|
||||
$iparr[$ip]['protos'][$proto]['srcports'][$srcport]++;
|
||||
}
|
||||
if (!empty($dstport)) {
|
||||
$iparr[$ip]['protos'][$proto]['dstports'][$dstport]++;
|
||||
}
|
||||
$states = json_decode(configd_run("filter list states json"), true);
|
||||
if(isset($states['details'])) {
|
||||
foreach($states['details'] as $state) {
|
||||
if (isset($state['nat_addr']) && $states['direction'] == 'out') {
|
||||
$srcip = $state['nat_addr'] ;
|
||||
$srcport = $state['nat_port'] ;
|
||||
} else {
|
||||
$srcip = $state['src_addr'] ;
|
||||
$srcport = $state['src_port'] ;
|
||||
}
|
||||
$dstip = $state['dst_addr'] ;
|
||||
$dstport = $state['dst_port'] ;
|
||||
$proto = $state['proto'];
|
||||
|
||||
addipinfo($srcipinfo, $srcip, $proto, $srcport, $dstport);
|
||||
addipinfo($dstipinfo, $dstip, $proto, $srcport, $dstport);
|
||||
addipinfo($pairipinfo, "{$srcip} -> {$dstip}", $proto, $srcport, $dstport);
|
||||
|
||||
addipinfo($allipinfo, $srcip, $proto, $srcport, $dstport);
|
||||
addipinfo($allipinfo, $dstip, $proto, $srcport, $dstport);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$row = 0;
|
||||
if(count($states) > 0) {
|
||||
foreach($states as $line) {
|
||||
$line_split = preg_split("/\s+/", $line);
|
||||
$iface = array_shift($line_split);
|
||||
$proto = array_shift($line_split);
|
||||
$state = array_pop($line_split);
|
||||
$info = implode(" ", $line_split);
|
||||
|
||||
/* Handle NAT cases
|
||||
Replaces an external IP + NAT by the internal IP */
|
||||
if (strpos($info, ') ->') !== FALSE) {
|
||||
/* Outbound NAT */
|
||||
$info = preg_replace('/(\S+) \((\S+)\)/U', "$2", $info);
|
||||
} elseif (strpos($info, ') <-') !== FALSE) {
|
||||
/* Inbound NAT/Port Forward */
|
||||
$info = preg_replace('/(\S+) \((\S+)\)/U', "$1", $info);
|
||||
}
|
||||
|
||||
/* break up info and extract $srcip and $dstip */
|
||||
$ends = preg_split("/\<?-\>?/", $info);
|
||||
|
||||
if (strpos($info, '->') === FALSE) {
|
||||
$srcinfo = $ends[count($ends) - 1];
|
||||
$dstinfo = $ends[0];
|
||||
} else {
|
||||
$srcinfo = $ends[0];
|
||||
$dstinfo = $ends[count($ends) - 1];
|
||||
}
|
||||
|
||||
/* Handle IPv6 */
|
||||
$parts = explode(":", $srcinfo);
|
||||
$partcount = count($parts);
|
||||
if ($partcount <= 2) {
|
||||
$srcip = trim($parts[0]);
|
||||
$srcport = trim($parts[1]);
|
||||
} else {
|
||||
preg_match("/([0-9a-f:]+)(\[([0-9]+)\])?/i", $srcinfo, $matches);
|
||||
$srcip = $matches[1];
|
||||
$srcport = trim($matches[3]);
|
||||
}
|
||||
|
||||
$parts = explode(":", $dstinfo);
|
||||
$partcount = count($parts);
|
||||
if ($partcount <= 2) {
|
||||
$dstip = trim($parts[0]);
|
||||
$dstport = trim($parts[1]);
|
||||
} else {
|
||||
preg_match("/([0-9a-f:]+)(\[([0-9]+)\])?/i", $dstinfo, $matches);
|
||||
$dstip = $matches[1];
|
||||
$dstport = trim($matches[3]);
|
||||
}
|
||||
|
||||
addipinfo($srcipinfo, $srcip, $proto, $srcport, $dstport);
|
||||
addipinfo($dstipinfo, $dstip, $proto, $srcport, $dstport);
|
||||
addipinfo($pairipinfo, "{$srcip} -> {$dstip}", $proto, $srcport, $dstport);
|
||||
|
||||
addipinfo($allipinfo, $srcip, $proto, $srcport, $dstport);
|
||||
addipinfo($allipinfo, $dstip, $proto, $srcport, $dstport);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function sort_by_ip($a, $b) {
|
||||
return ip2ulong($a) < ip2ulong($b) ? -1 : 1;
|
||||
}
|
||||
|
||||
function build_port_info($portarr, $proto) {
|
||||
if (!$portarr)
|
||||
return '';
|
||||
$ports = array();
|
||||
asort($portarr);
|
||||
foreach (array_reverse($portarr, TRUE) as $port => $count) {
|
||||
$str = "";
|
||||
$service = getservbyport($port, strtolower($proto));
|
||||
$port = "{$proto}/{$port}";
|
||||
if ($service)
|
||||
$port = "{$port} ({$service})";
|
||||
$ports[] = "{$port}: {$count}";
|
||||
}
|
||||
return implode($ports, ', ');
|
||||
}
|
||||
|
||||
function print_summary_table($label, $iparr, $sort = TRUE) { ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<header class="content-box-head container-fluid">
|
||||
<h3><?php echo $label; ?></h3>
|
||||
</header>
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
<table class="table table-striped table-sort sortable __nomb">
|
||||
<tr>
|
||||
<td class="listhdrr"><?=gettext("IP");?></td>
|
||||
<td class="listhdrr"># <?=gettext("States");?></td>
|
||||
<td class="listhdrr"><?=gettext("Proto");?></td>
|
||||
<td class="listhdrr"># <?=gettext("States");?></td>
|
||||
<td class="listhdrr"><?=gettext("Src Ports");?></td>
|
||||
<td class="listhdrr"><?=gettext("Dst Ports");?></td>
|
||||
</tr>
|
||||
<?php if ($sort)
|
||||
uksort($iparr, "sort_by_ip");
|
||||
foreach($iparr as $ip => $ipinfo) { ?>
|
||||
<tr>
|
||||
<td class="vncell"><?php echo $ip; ?></td>
|
||||
<td class="vncell"><?php echo $ipinfo['seen']; ?></td>
|
||||
<td class="vncell"> </td>
|
||||
<td class="vncell"> </td>
|
||||
<td class="vncell"> </td>
|
||||
<td class="vncell"> </td>
|
||||
</tr>
|
||||
<?php foreach($ipinfo['protos'] as $proto => $protoinfo) { ?>
|
||||
<tr>
|
||||
<td class="list"> </td>
|
||||
<td class="list"> </td>
|
||||
<td class="listlr"><?php echo $proto; ?></td>
|
||||
<td class="listr" align="center"><?php echo $protoinfo['seen']; ?></td>
|
||||
<td class="listr" align="center"><span title="<?php echo build_port_info($protoinfo['srcports'], $proto); ?>"><?php echo count($protoinfo['srcports']); ?></span></td>
|
||||
<td class="listr" align="center"><span title="<?php echo build_port_info($protoinfo['dstports'], $proto); ?>"><?php echo count($protoinfo['dstports']); ?></span></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
function print_summary_table($label, $iparr, $sort = TRUE) {
|
||||
if ($sort) {
|
||||
uksort($iparr, "sort_by_ip");
|
||||
}
|
||||
?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<header class="content-box-head container-fluid">
|
||||
<h3><?=$label; ?></h3>
|
||||
</header>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<td><?=gettext("IP");?></td>
|
||||
<td># <?=gettext("States");?></td>
|
||||
<td><?=gettext("Proto");?></td>
|
||||
<td># <?=gettext("States");?></td>
|
||||
<td><?=gettext("Src Ports");?></td>
|
||||
<td><?=gettext("Dst Ports");?></td>
|
||||
</tr>
|
||||
<?php
|
||||
foreach($iparr as $ip => $ipinfo) { ?>
|
||||
<tr>
|
||||
<td><?= $ip; ?></td>
|
||||
<td><?= $ipinfo['seen']; ?></td>
|
||||
<td colspan="4"> </td>
|
||||
</tr>
|
||||
<?php foreach($ipinfo['protos'] as $proto => $protoinfo) { ?>
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
<td><?=$proto; ?></td>
|
||||
<td ><?=$protoinfo['seen']; ?></td>
|
||||
<td ><span data-toggle="tooltip" title="<?=build_port_info($protoinfo['srcports'], $proto); ?>"><?=count($protoinfo['srcports']); ?></span></td>
|
||||
<td ><span data-toggle="tooltip" title="<?=build_port_info($protoinfo['dstports'], $proto); ?>"><?=count($protoinfo['dstports']); ?></span></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
}
|
||||
|
||||
$pgtitle = array(gettext("Diagnostics"),gettext("State Table Summary"));
|
||||
require_once("guiconfig.inc");
|
||||
include("head.inc");
|
||||
echo "<body>";
|
||||
include("fbegin.inc");
|
||||
?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?
|
||||
|
||||
print_summary_table(gettext("By Source IP"), $srcipinfo);
|
||||
print_summary_table(gettext("By Destination IP"), $dstipinfo);
|
||||
print_summary_table(gettext("Total per IP"), $allipinfo);
|
||||
print_summary_table(gettext("By IP Pair"), $pairipinfo, FALSE);
|
||||
?>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php include("foot.inc"); ?>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user