2011-12-21 16:28:01 +01:00
|
|
|
<?php
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
/**
|
|
|
|
* Netflow functions
|
|
|
|
*
|
|
|
|
* @package Functons.
|
|
|
|
* @subpackage Netflow functions.
|
|
|
|
*
|
|
|
|
* Pandora FMS - http://pandorafms.com
|
|
|
|
* ==================================================
|
|
|
|
* Copyright (c) 2005-2019 Artica Soluciones Tecnologicas
|
|
|
|
* Please see http://pandorafms.org for full contribution list
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; version 2
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
require_once $config['homedir'].'/include/functions_users.php';
|
|
|
|
require_once $config['homedir'].'/include/functions_io.php';
|
|
|
|
require_once $config['homedir'].'/include/functions_io.php';
|
2019-03-14 09:25:50 +01:00
|
|
|
require_once $config['homedir'].'/include/functions_network.php';
|
2019-03-15 14:24:49 +01:00
|
|
|
enterprise_include_once(
|
|
|
|
$config['homedir'].'/enterprise/include/pdf_translator.php'
|
|
|
|
);
|
|
|
|
enterprise_include_once(
|
|
|
|
$config['homedir'].'/enterprise/include/functions_metaconsole.php'
|
|
|
|
);
|
2012-01-11 19:12:33 +01:00
|
|
|
|
2019-03-13 18:55:16 +01:00
|
|
|
define('NETFLOW_RES_LOWD', 6);
|
|
|
|
define('NETFLOW_RES_MEDD', 12);
|
|
|
|
define('NETFLOW_RES_HID', 24);
|
|
|
|
define('NETFLOW_RES_ULTRAD', 30);
|
|
|
|
define('NETFLOW_RES_HOURLY', 'hourly');
|
|
|
|
define('NETFLOW_RES_DAILY', 'daily');
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Date format for nfdump.
|
2012-10-25 20:34:53 +02:00
|
|
|
global $nfdump_date_format;
|
2012-01-11 17:34:53 +01:00
|
|
|
$nfdump_date_format = 'Y/m/d.H:i:s';
|
2011-12-21 16:28:01 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Array to hold the hostnames.
|
2019-01-30 16:18:44 +01:00
|
|
|
$hostnames = [];
|
|
|
|
|
2014-04-23 11:34:00 +02:00
|
|
|
|
2011-12-21 16:28:01 +01:00
|
|
|
/**
|
|
|
|
* Selects all netflow filters (array (id_name => id_name)) or filters filtered
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param mixed $filter Array with filter conditions to retrieve filters or
|
|
|
|
* false.
|
2011-12-21 16:28:01 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array List of all filters.
|
2011-12-21 16:28:01 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_filters($filter=false)
|
|
|
|
{
|
|
|
|
if ($filter === false) {
|
|
|
|
$filters = db_get_all_rows_in_table('tnetflow_filter', 'id_name');
|
|
|
|
} else {
|
|
|
|
$filters = db_get_all_rows_filter('tnetflow_filter', $filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
$return = [];
|
|
|
|
if ($filters === false) {
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($filters as $filter) {
|
|
|
|
$return[$filter['id_name']] = $filter['id_name'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $return;
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Selects all netflow reports (array (id_name => id_name)) or filters filtered
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param mixed $filter Array with filter conditions to retrieve filters or
|
|
|
|
* false.
|
2011-12-21 16:28:01 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array List of all filters.
|
2011-12-21 16:28:01 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_reports($filter=false)
|
|
|
|
{
|
|
|
|
if ($filter === false) {
|
|
|
|
$filters = db_get_all_rows_in_table('tnetflow_report', 'id_name');
|
|
|
|
} else {
|
|
|
|
$filters = db_get_all_rows_filter('tnetflow_report', $filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
$return = [];
|
|
|
|
if ($filters === false) {
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($filters as $filter) {
|
|
|
|
$return[$filter['id_name']] = $filter['id_name'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $return;
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
/**
|
|
|
|
* Check if a filter owns to a certain group.
|
|
|
|
*
|
|
|
|
* @param integer $id_sg Id group to check.
|
|
|
|
*
|
|
|
|
* @return boolean True if user manages that group.
|
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_check_filter_group($id_sg)
|
|
|
|
{
|
|
|
|
global $config;
|
|
|
|
|
|
|
|
$id_group = db_get_value('id_group', 'tnetflow_filter', 'id_sg', $id_sg);
|
|
|
|
$own_info = get_user_info($config['id_user']);
|
2019-03-15 14:24:49 +01:00
|
|
|
// Get group list that user has access.
|
2019-01-30 16:18:44 +01:00
|
|
|
$groups_user = users_get_groups($config['id_user'], 'IW', $own_info['is_admin'], true);
|
|
|
|
$groups_id = [];
|
|
|
|
$has_permission = false;
|
|
|
|
|
|
|
|
foreach ($groups_user as $key => $groups) {
|
|
|
|
if ($groups['id_grupo'] == $id_group) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2012-01-11 19:12:33 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2011-12-21 16:28:01 +01:00
|
|
|
/**
|
|
|
|
* Get a filter.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param integer $id_sg Filter id to be fetched.
|
|
|
|
* @param mixed $filter Extra filter.
|
|
|
|
* @param mixed $fields Fields to be fetched.
|
2011-12-21 16:28:01 +01:00
|
|
|
*
|
|
|
|
* @return array A netflow filter matching id and filter.
|
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_filter_get_filter($id_sg, $filter=false, $fields=false)
|
|
|
|
{
|
|
|
|
if (! is_array($filter)) {
|
|
|
|
$filter = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter['id_sg'] = (int) $id_sg;
|
|
|
|
|
|
|
|
return db_get_row_filter('tnetflow_filter', $filter, $fields);
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Compare two flows according to the 'data' column.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $a First flow.
|
|
|
|
* @param array $b Second flow.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
|
|
|
* @return Result of the comparison.
|
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function compare_flows($a, $b)
|
|
|
|
{
|
|
|
|
return $a['data'] < $b['data'];
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Sort netflow data according to the 'data' column.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $netflow_data Netflow data array.
|
|
|
|
*
|
|
|
|
* @return void (Array passed by reference)
|
2012-01-11 17:34:53 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function sort_netflow_data(&$netflow_data)
|
|
|
|
{
|
|
|
|
usort($netflow_data, 'compare_flows');
|
2012-01-11 17:34:53 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-09-21 15:42:13 +02:00
|
|
|
/**
|
|
|
|
* Show a table with netflow statistics.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Statistic data.
|
|
|
|
* @param string $start_date Start date.
|
|
|
|
* @param string $end_date End date.
|
|
|
|
* @param string $aggregate Aggregate field.
|
2012-09-21 15:42:13 +02:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string HTML statistics table.
|
2012-09-21 15:42:13 +02:00
|
|
|
*/
|
2019-03-14 09:07:17 +01:00
|
|
|
function netflow_stat_table($data, $start_date, $end_date, $aggregate)
|
2019-01-30 16:18:44 +01:00
|
|
|
{
|
|
|
|
global $nfdump_date_format;
|
|
|
|
|
|
|
|
$start_date = date($nfdump_date_format, $start_date);
|
|
|
|
$end_date = date($nfdump_date_format, $end_date);
|
|
|
|
$values = [];
|
2019-03-18 16:44:16 +01:00
|
|
|
$table->width = '100%';
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->cellspacing = 0;
|
|
|
|
$table->class = 'databox';
|
|
|
|
$table->data = [];
|
|
|
|
$j = 0;
|
|
|
|
$x = 0;
|
|
|
|
|
|
|
|
$table->head = [];
|
|
|
|
$table->head[0] = '<b>'.netflow_format_aggregate($aggregate).'</b>';
|
2019-03-14 09:07:17 +01:00
|
|
|
$table->head[1] = '<b>'.__('Value').'</b>';
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->style[0] = 'padding: 6px;';
|
|
|
|
$table->style[1] = 'padding: 6px;';
|
|
|
|
|
|
|
|
while (isset($data[$j])) {
|
|
|
|
$agg = $data[$j]['agg'];
|
|
|
|
if (!isset($values[$agg])) {
|
|
|
|
$values[$agg] = $data[$j]['data'];
|
|
|
|
} else {
|
|
|
|
$values[$agg] += $data[$j]['data'];
|
|
|
|
}
|
|
|
|
|
2019-03-14 09:07:17 +01:00
|
|
|
$table->data[$x][0] = $agg;
|
2019-03-14 09:25:50 +01:00
|
|
|
$table->data[$x][1] = network_format_bytes($data[$j]['data']);
|
2019-03-14 09:07:17 +01:00
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
$j++;
|
|
|
|
$x++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return html_print_table($table, true);
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
2012-09-21 15:42:13 +02:00
|
|
|
* Show a table with netflow data.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Netflow data.
|
|
|
|
* @param string $start_date Start date.
|
|
|
|
* @param string $end_date End date.
|
|
|
|
* @param string $aggregate Aggregate field.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string HTML data table.
|
2012-01-11 17:34:53 +01:00
|
|
|
*/
|
2019-03-14 10:36:15 +01:00
|
|
|
function netflow_data_table($data, $start_date, $end_date, $aggregate)
|
2019-01-30 16:18:44 +01:00
|
|
|
{
|
|
|
|
global $nfdump_date_format;
|
|
|
|
|
|
|
|
$period = ($end_date - $start_date);
|
|
|
|
$start_date = date($nfdump_date_format, $start_date);
|
|
|
|
$end_date = date($nfdump_date_format, $end_date);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Set the format.
|
2019-01-30 16:18:44 +01:00
|
|
|
if ($period <= SECONDS_6HOURS) {
|
|
|
|
$time_format = 'H:i:s';
|
|
|
|
} else if ($period < SECONDS_1DAY) {
|
|
|
|
$time_format = 'H:i';
|
|
|
|
} else if ($period < SECONDS_15DAYS) {
|
|
|
|
$time_format = 'M d H:i';
|
|
|
|
} else if ($period < SECONDS_1MONTH) {
|
|
|
|
$time_format = 'M d H\h';
|
|
|
|
} else {
|
|
|
|
$time_format = 'M d H\h';
|
|
|
|
}
|
|
|
|
|
|
|
|
$values = [];
|
|
|
|
$table->size = ['100%'];
|
|
|
|
$table->class = 'databox';
|
|
|
|
$table->cellspacing = 0;
|
|
|
|
$table->data = [];
|
|
|
|
|
|
|
|
$table->head = [];
|
|
|
|
$table->head[0] = '<b>'.__('Timestamp').'</b>';
|
|
|
|
$table->style[0] = 'padding: 4px';
|
|
|
|
|
|
|
|
$j = 0;
|
|
|
|
$source_index = [];
|
|
|
|
$source_count = 0;
|
|
|
|
|
|
|
|
if (isset($data['sources'])) {
|
|
|
|
foreach ($data['sources'] as $source => $null) {
|
|
|
|
$table->style[($j + 1)] = 'padding: 4px';
|
|
|
|
$table->align[($j + 1)] = 'right';
|
|
|
|
$table->headstyle[($j + 1)] = 'text-align: right;';
|
|
|
|
$table->head[($j + 1)] = $source;
|
|
|
|
$source_index[$j] = $source;
|
|
|
|
$source_count++;
|
|
|
|
$j++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$table->style[1] = 'padding: 4px;';
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// No aggregates.
|
2019-01-30 16:18:44 +01:00
|
|
|
if ($source_count == 0) {
|
|
|
|
$table->head[1] = __('Data');
|
|
|
|
$table->align[1] = 'right';
|
|
|
|
$i = 0;
|
|
|
|
|
|
|
|
foreach ($data as $timestamp => $value) {
|
|
|
|
$table->data[$i][0] = date($time_format, $timestamp);
|
2019-03-14 10:36:15 +01:00
|
|
|
$table->data[$i][1] = network_format_bytes($value['data']);
|
2019-01-30 16:18:44 +01:00
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
}
|
2019-03-15 14:24:49 +01:00
|
|
|
|
|
|
|
// Aggregates.
|
2019-01-30 16:18:44 +01:00
|
|
|
else {
|
|
|
|
$i = 0;
|
|
|
|
foreach ($data['data'] as $timestamp => $values) {
|
|
|
|
$table->data[$i][0] = date($time_format, $timestamp);
|
|
|
|
for ($j = 0; $j < $source_count; $j++) {
|
2019-03-14 09:25:50 +01:00
|
|
|
$table->data[$i][($j + 1)] = network_format_bytes(
|
|
|
|
$values[$source_index[$j]]
|
2019-03-13 21:14:43 +01:00
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return html_print_table($table, true);
|
2012-01-11 17:34:53 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-09-21 15:42:13 +02:00
|
|
|
/**
|
|
|
|
* Show a table with a traffic summary.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Summary data.
|
2012-09-21 15:42:13 +02:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string HTML summary table.
|
2012-09-21 15:42:13 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_summary_table($data)
|
|
|
|
{
|
|
|
|
global $nfdump_date_format;
|
|
|
|
|
|
|
|
$values = [];
|
|
|
|
$table->size = ['50%'];
|
|
|
|
$table->cellspacing = 0;
|
|
|
|
$table->class = 'databox';
|
|
|
|
$table->data = [];
|
|
|
|
|
|
|
|
$table->style[0] = 'font-weight: bold; padding: 6px';
|
|
|
|
$table->style[1] = 'padding: 6px';
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Total flows');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = format_for_graph($data['totalflows'], 2);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Total bytes');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = network_format_bytes($data['totalbytes']);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Total packets');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = format_for_graph($data['totalpackets'], 2);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Average bits per second');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = network_format_bytes($data['avgbps']);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Average packets per second');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = format_for_graph($data['avgpps'], 2);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$row = [];
|
|
|
|
$row[] = __('Average bytes per packet');
|
2019-03-14 09:25:50 +01:00
|
|
|
$row[] = format_for_graph($data['avgbpp'], 2);
|
2019-01-30 16:18:44 +01:00
|
|
|
$table->data[] = $row;
|
|
|
|
|
|
|
|
$html = html_print_table($table, true);
|
|
|
|
|
|
|
|
return $html;
|
2012-09-21 15:42:13 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Returns 1 if the given address is a network address.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $address Host or network address.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
|
|
|
* @return 1 if the address is a network address, 0 otherwise.
|
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_is_net($address)
|
|
|
|
{
|
|
|
|
if (strpos($address, '/') !== false) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2012-01-11 17:34:53 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Returns netflow data for the given period in an array.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $start_date Period start date.
|
|
|
|
* @param string $end_date Period end date.
|
|
|
|
* @param mixed $interval_length Resolution points or hourly or daily.
|
|
|
|
* @param string $filter Netflow filter.
|
|
|
|
* @param string $aggregate Aggregate field.
|
|
|
|
* @param integer $max Maximum number of aggregates.
|
|
|
|
* @param boolean $absolute True to give the absolute data and false
|
|
|
|
* to get troughput.
|
|
|
|
* @param string $connection_name Node name when data is get in meta.
|
|
|
|
* @param boolean $address_resolution True to resolve ips to hostnames.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array An array with netflow stats.
|
2012-01-11 17:34:53 +01:00
|
|
|
*/
|
2019-03-15 14:24:49 +01:00
|
|
|
function netflow_get_data(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$interval_length,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max,
|
|
|
|
$absolute,
|
|
|
|
$connection_name='',
|
|
|
|
$address_resolution=false
|
|
|
|
) {
|
2019-01-30 16:18:44 +01:00
|
|
|
global $nfdump_date_format;
|
|
|
|
global $config;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Requesting remote data.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (defined('METACONSOLE') && $connection_name != '') {
|
2019-03-15 14:24:49 +01:00
|
|
|
$data = metaconsole_call_remote_api(
|
|
|
|
$connection_name,
|
|
|
|
'netflow_get_data',
|
|
|
|
"$start_date|$end_date|$interval_length|".base64_encode(json_encode($filter))."|$aggregate|$max|1".(int) $address_resolution
|
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
return json_decode($data, true);
|
|
|
|
}
|
|
|
|
|
2019-03-13 18:55:16 +01:00
|
|
|
if ($start_date > $end_date) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the number of intervals.
|
|
|
|
$multiplier_time = ($end_date - $start_date);
|
|
|
|
switch ($interval_length) {
|
|
|
|
case NETFLOW_RES_LOWD:
|
|
|
|
case NETFLOW_RES_MEDD:
|
|
|
|
case NETFLOW_RES_HID:
|
|
|
|
case NETFLOW_RES_ULTRAD:
|
|
|
|
$multiplier_time = ceil(($end_date - $start_date) / $interval_length);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NETFLOW_RES_HOURLY:
|
|
|
|
$multiplier_time = SECONDS_1HOUR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NETFLOW_RES_DAILY:
|
|
|
|
$multiplier_time = SECONDS_1DAY;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
$multiplier_time = ($end_date - $start_date);
|
|
|
|
break;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
2019-03-15 11:36:13 +01:00
|
|
|
// Recalculate to not pass of netflow_max_resolution.
|
|
|
|
if ($config['netflow_max_resolution'] > 0
|
|
|
|
&& (($end_date - $start_date) / $multiplier_time) > 50
|
|
|
|
) {
|
|
|
|
$multiplier_time = ceil(
|
|
|
|
(($end_date - $start_date) / $config['netflow_max_resolution'])
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-13 18:55:16 +01:00
|
|
|
// Put all points into an array.
|
|
|
|
$intervals = [($start_date - $multiplier_time)];
|
|
|
|
while ((end($intervals) < $end_date) === true) {
|
|
|
|
$intervals[] = (end($intervals) + $multiplier_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (end($intervals) != $end_date) {
|
|
|
|
$intervals[] = $end_date;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// If there is aggregation calculate the top n.
|
2019-03-13 19:16:21 +01:00
|
|
|
$values['data'] = [];
|
|
|
|
$values['sources'] = [];
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Get the command to call nfdump.
|
2019-03-13 19:16:21 +01:00
|
|
|
$command = netflow_get_command($filter);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Suppress the header line and the statistics at the bottom and configure
|
|
|
|
// piped output.
|
2019-03-13 19:16:21 +01:00
|
|
|
$command .= ' -q -o csv';
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Call nfdump.
|
2019-03-13 19:16:21 +01:00
|
|
|
$agg_command = $command." -n $max -s $aggregate/bytes -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date);
|
|
|
|
exec($agg_command, $string);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Remove the first line.
|
2019-03-13 19:16:21 +01:00
|
|
|
$string[0] = '';
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Parse aggregates.
|
2019-03-13 19:16:21 +01:00
|
|
|
foreach ($string as $line) {
|
|
|
|
if ($line == '') {
|
|
|
|
continue;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
$val = explode(',', $line);
|
2019-03-18 15:44:23 +01:00
|
|
|
$values['sources'][$val[4]] = 1;
|
2019-03-13 19:16:21 +01:00
|
|
|
}
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Update the filter.
|
2019-03-13 19:16:21 +01:00
|
|
|
switch ($aggregate) {
|
|
|
|
default:
|
|
|
|
case 'srcip':
|
|
|
|
$extra_filter = 'ip_src';
|
|
|
|
break;
|
|
|
|
case 'srcport':
|
|
|
|
$extra_filter = 'src_port';
|
|
|
|
break;
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
case 'dstip':
|
|
|
|
$extra_filter = 'ip_dst';
|
|
|
|
break;
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
case 'dstport':
|
|
|
|
$extra_filter = 'dst_port';
|
|
|
|
break;
|
|
|
|
}
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
if (isset($filter[$extra_filter]) && $filter[$extra_filter] != '') {
|
|
|
|
$filter[$extra_filter] .= ',';
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
$filter[$extra_filter] = implode(
|
|
|
|
',',
|
|
|
|
array_keys($values['sources'])
|
|
|
|
);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Address resolution start.
|
2019-01-30 16:18:44 +01:00
|
|
|
$get_hostnames = false;
|
|
|
|
if ($address_resolution && ($aggregate == 'srcip' || $aggregate == 'dstip')) {
|
|
|
|
$get_hostnames = true;
|
|
|
|
global $hostnames;
|
|
|
|
|
|
|
|
$sources = [];
|
|
|
|
foreach ($values['sources'] as $source => $value) {
|
|
|
|
if (!isset($hostnames[$source])) {
|
|
|
|
$hostname = gethostbyaddr($source);
|
|
|
|
if ($hostname !== false) {
|
|
|
|
$hostnames[$source] = $hostname;
|
|
|
|
$source = $hostname;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$source = $hostnames[$source];
|
|
|
|
}
|
|
|
|
|
|
|
|
$sources[$source] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
$values['sources'] = $sources;
|
|
|
|
}
|
|
|
|
|
2019-03-13 18:55:16 +01:00
|
|
|
// Address resolution end.
|
|
|
|
foreach ($intervals as $k => $time) {
|
|
|
|
$interval_start = $time;
|
|
|
|
if (!isset($intervals[($k + 1)])) {
|
|
|
|
continue;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
2019-03-13 18:55:16 +01:00
|
|
|
$interval_end = $intervals[($k + 1)];
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Set default values.
|
2019-03-13 19:16:21 +01:00
|
|
|
foreach ($values['sources'] as $source => $discard) {
|
|
|
|
$values['data'][$interval_end][$source] = 0;
|
|
|
|
}
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
$data = netflow_get_stats(
|
|
|
|
$interval_start,
|
|
|
|
$interval_end,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max,
|
2019-03-14 10:36:15 +01:00
|
|
|
$absolute,
|
2019-03-13 19:16:21 +01:00
|
|
|
$connection_name
|
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
foreach ($data as $line) {
|
2019-03-15 14:24:49 +01:00
|
|
|
// Address resolution start.
|
2019-03-13 19:16:21 +01:00
|
|
|
if ($get_hostnames) {
|
|
|
|
if (!isset($hostnames[$line['agg']])) {
|
|
|
|
$hostname = false;
|
2019-03-15 14:24:49 +01:00
|
|
|
// Trying to get something like an IP from the description.
|
2019-03-13 19:16:21 +01:00
|
|
|
if (preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $line['agg'], $matches)
|
|
|
|
|| preg_match(
|
|
|
|
"/(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:?)|\2))(?4){5}((?4){2}|(25[0-5]|
|
|
|
|
(2[0-4]|1\d|[1-9])?\d)(\.(?7)){3})/i",
|
|
|
|
$line['agg'],
|
|
|
|
$matches
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
if ($matches[0]) {
|
|
|
|
$hostname = gethostbyaddr($line['agg']);
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
if ($hostname !== false) {
|
|
|
|
$hostnames[$line['agg']] = $hostname;
|
|
|
|
$line['agg'] = $hostname;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$line['agg'] = $hostnames[$line['agg']];
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
2019-03-13 19:16:21 +01:00
|
|
|
}
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Address resolution end.
|
2019-03-13 19:16:21 +01:00
|
|
|
if (! isset($values['sources'][$line['agg']])) {
|
|
|
|
continue;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
2019-03-13 19:16:21 +01:00
|
|
|
|
|
|
|
$values['data'][$interval_end][$line['agg']] = $line['data'];
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-13 19:16:21 +01:00
|
|
|
if (empty($values['data'])) {
|
2019-01-30 16:18:44 +01:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $values;
|
2012-12-11 17:43:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Returns netflow stats for the given period in an array.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $start_date Period start date.
|
|
|
|
* @param string $end_date Period end date.
|
|
|
|
* @param string $filter Netflow filter.
|
|
|
|
* @param string $aggregate Aggregate field.
|
|
|
|
* @param integer $max Maximum number of aggregates.
|
|
|
|
* @param boolean $absolute True to give the absolute data and false to get
|
|
|
|
* troughput.
|
|
|
|
* @param string $connection_name Node name when data is get in meta.
|
|
|
|
* @param boolean $address_resolution True to resolve ips to hostnames.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array With netflow stats.
|
2012-01-11 17:34:53 +01:00
|
|
|
*/
|
2019-03-15 14:24:49 +01:00
|
|
|
function netflow_get_stats(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max,
|
|
|
|
$absolute=true,
|
|
|
|
$connection_name='',
|
|
|
|
$address_resolution=false
|
|
|
|
) {
|
2019-01-30 16:18:44 +01:00
|
|
|
global $config, $nfdump_date_format;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Requesting remote data.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (defined('METACONSOLE') && $connection_name != '') {
|
2019-03-13 21:14:43 +01:00
|
|
|
$data = metaconsole_call_remote_api($connection_name, 'netflow_get_stats', "$start_date|$end_date|".base64_encode(json_encode($filter))."|$aggregate|$max|$absolute|".(int) $address_resolution);
|
2019-01-30 16:18:44 +01:00
|
|
|
return json_decode($data, true);
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Get the command to call nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command = netflow_get_command($filter);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Execute nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command .= " -o csv -q -n $max -s $aggregate/bytes -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date);
|
|
|
|
exec($command, $string);
|
|
|
|
|
|
|
|
if (! is_array($string)) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Remove the first line.
|
2019-01-30 16:18:44 +01:00
|
|
|
$string[0] = '';
|
|
|
|
|
|
|
|
$i = 0;
|
|
|
|
$values = [];
|
|
|
|
$interval_length = ($end_date - $start_date);
|
|
|
|
foreach ($string as $line) {
|
|
|
|
if ($line == '') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$val = explode(',', $line);
|
|
|
|
|
|
|
|
$values[$i]['date'] = $val[0];
|
|
|
|
$values[$i]['time'] = $val[1];
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Create field to sort array.
|
2019-01-30 16:18:44 +01:00
|
|
|
$datetime = $val[0];
|
|
|
|
$end_date = strtotime($datetime);
|
|
|
|
$values[$i]['datetime'] = $end_date;
|
2019-03-18 15:44:23 +01:00
|
|
|
// Address resolution start.
|
|
|
|
if ($address_resolution && ($aggregate == 'srcip' || $aggregate == 'dstip')) {
|
|
|
|
global $hostnames;
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2019-03-18 15:44:23 +01:00
|
|
|
if (!isset($hostnames[$val[4]])) {
|
|
|
|
$hostname = gethostbyaddr($val[4]);
|
|
|
|
if ($hostname !== false) {
|
|
|
|
$hostnames[$val[4]] = $hostname;
|
|
|
|
$val[4] = $hostname;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
2019-03-18 15:44:23 +01:00
|
|
|
} else {
|
|
|
|
$val[4] = $hostnames[$val[4]];
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-18 15:44:23 +01:00
|
|
|
// Address resolution end.
|
|
|
|
$values[$i]['agg'] = $val[4];
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
if (! isset($val[9])) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2019-03-13 21:14:43 +01:00
|
|
|
$values[$i]['data'] = $val[9];
|
|
|
|
if (!$absolute) {
|
|
|
|
$values[$i]['data'] = ($values[$i]['data'] / $interval_length);
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
sort_netflow_data($values);
|
|
|
|
|
|
|
|
return $values;
|
2012-01-11 17:34:53 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-09-21 15:42:13 +02:00
|
|
|
/**
|
|
|
|
* Returns a traffic summary for the given period in an array.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $start_date Period start date.
|
|
|
|
* @param string $end_date Period end date.
|
|
|
|
* @param string $filter Netflow filter.
|
|
|
|
* @param string $connection_name Node name when data is get in meta.
|
2012-09-21 15:42:13 +02:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array With netflow summary data.
|
2012-09-21 15:42:13 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_summary($start_date, $end_date, $filter, $connection_name='')
|
|
|
|
{
|
|
|
|
global $nfdump_date_format;
|
|
|
|
global $config;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Requesting remote data.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (defined('METACONSOLE') && $connection_name != '') {
|
|
|
|
$data = metaconsole_call_remote_api($connection_name, 'netflow_get_summary', "$start_date|$end_date|".base64_encode(json_encode($filter)));
|
|
|
|
return json_decode($data, true);
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Get the command to call nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command = netflow_get_command($filter);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Execute nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command .= ' -o csv -n 1 -s srcip/bytes -t '.date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date);
|
|
|
|
exec($command, $string);
|
|
|
|
|
|
|
|
if (! is_array($string) || ! isset($string[5])) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Read the summary.
|
2019-01-30 16:18:44 +01:00
|
|
|
$summary = explode(',', $string[5]);
|
|
|
|
if (! isset($summary[5])) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$values['totalflows'] = $summary[0];
|
|
|
|
$values['totalbytes'] = $summary[1];
|
|
|
|
$values['totalpackets'] = $summary[2];
|
|
|
|
$values['avgbps'] = $summary[3];
|
|
|
|
$values['avgpps'] = $summary[4];
|
|
|
|
$values['avgbpp'] = $summary[5];
|
|
|
|
|
|
|
|
return $values;
|
2012-09-21 15:42:13 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2014-04-23 11:34:00 +02:00
|
|
|
/**
|
|
|
|
* Returns a traffic record for the given period in an array.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $start_date Period start date.
|
|
|
|
* @param string $end_date Period end date.
|
|
|
|
* @param string $filter Netflow filter.
|
|
|
|
* @param integer $max Maximum number of elements.
|
|
|
|
* @param boolean $address_resolution True to resolve ips to hostnames.
|
2014-04-23 11:34:00 +02:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return array With netflow record data.
|
2014-04-23 11:34:00 +02:00
|
|
|
*/
|
2019-03-15 14:24:49 +01:00
|
|
|
function netflow_get_record(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$max,
|
|
|
|
$address_resolution=false
|
|
|
|
) {
|
2019-01-30 16:18:44 +01:00
|
|
|
global $nfdump_date_format;
|
|
|
|
global $config;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Get the command to call nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command = netflow_get_command($filter);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Execute nfdump.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command .= " -q -o csv -n $max -s record/bytes -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date);
|
|
|
|
exec($command, $result);
|
|
|
|
|
|
|
|
if (! is_array($result)) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$values = [];
|
|
|
|
foreach ($result as $key => $line) {
|
|
|
|
$data = [];
|
|
|
|
|
|
|
|
$items = explode(',', $line);
|
|
|
|
|
|
|
|
$data['time_start'] = $items[0];
|
|
|
|
$data['time_end'] = $items[1];
|
|
|
|
$data['duration'] = ($items[2] / 1000);
|
|
|
|
$data['source_address'] = $items[3];
|
|
|
|
$data['destination_address'] = $items[4];
|
|
|
|
$data['source_port'] = $items[5];
|
|
|
|
$data['destination_port'] = $items[6];
|
|
|
|
$data['protocol'] = $items[7];
|
2019-03-14 10:05:21 +01:00
|
|
|
$data['data'] = $items[12];
|
2019-01-30 16:18:44 +01:00
|
|
|
|
|
|
|
$values[] = $data;
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Address resolution start.
|
2019-01-30 16:18:44 +01:00
|
|
|
if ($address_resolution) {
|
|
|
|
global $hostnames;
|
|
|
|
|
|
|
|
for ($i = 0; $i < count($values); $i++) {
|
|
|
|
if (!isset($hostnames[$values[$i]['source_address']])) {
|
|
|
|
$hostname = gethostbyaddr($values[$i]['source_address']);
|
|
|
|
if ($hostname !== false) {
|
|
|
|
$hostnames[$values[$i]['source_address']] = $hostname;
|
|
|
|
$values[$i]['source_address'] = $hostname;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$values[$i]['source_address'] = $hostnames[$values[$i]['source_address']];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isset($hostnames[$values[$i]['destination_address']])) {
|
|
|
|
$hostname = gethostbyaddr($values[$i]['destination_address']);
|
|
|
|
if ($hostname !== false) {
|
|
|
|
$hostnames[$values[$i]['destination_address']] = $hostname;
|
|
|
|
$values[$i]['destination_address'] = $hostname;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$values[$i]['destination_address'] = $hostnames[$values[$i]['destination_address']];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Address resolution end.
|
2019-01-30 16:18:44 +01:00
|
|
|
return $values;
|
2014-04-23 11:34:00 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-11 17:34:53 +01:00
|
|
|
/**
|
|
|
|
* Returns the command needed to run nfdump for the given filter.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $filter Netflow filter.
|
2012-01-11 17:34:53 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string Command to run.
|
2012-01-11 17:34:53 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_command($filter)
|
|
|
|
{
|
|
|
|
global $config;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Build command.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command = io_safe_output($config['netflow_nfdump']).' -N';
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Netflow data path.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (isset($config['netflow_path']) && $config['netflow_path'] != '') {
|
|
|
|
$command .= ' -R. -M '.$config['netflow_path'];
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Filter options.
|
2019-01-30 16:18:44 +01:00
|
|
|
$command .= netflow_get_filter_arguments($filter);
|
|
|
|
|
|
|
|
return $command;
|
2012-01-24 Ramon Novoa <rnovoa@artica.es>
* include/functions_config.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
extras/pandoradb_migrate_4.0.x_to_4.1.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.postgreSQL.sql,
godmode/agentes/module_manager_editor_prediction.php,
godmode/agentes/configurar_agente.php,
godmode/menu.php,
godmode/netflow/nf_edit_form.php: Added support for enterprise
netflow modules.
* godmode/netflow/nf_manage.php: Moved to
godmode/setup/setup_netflow.php.
* godmode/netflow/nf_option_form.php: Removed from repository. Not used.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@5416 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-01-24 18:11:12 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-24 Ramon Novoa <rnovoa@artica.es>
* include/functions_config.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
extras/pandoradb_migrate_4.0.x_to_4.1.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.postgreSQL.sql,
godmode/agentes/module_manager_editor_prediction.php,
godmode/agentes/configurar_agente.php,
godmode/menu.php,
godmode/netflow/nf_edit_form.php: Added support for enterprise
netflow modules.
* godmode/netflow/nf_manage.php: Moved to
godmode/setup/setup_netflow.php.
* godmode/netflow/nf_option_form.php: Removed from repository. Not used.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@5416 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-01-24 18:11:12 +01:00
|
|
|
/**
|
|
|
|
* Returns the nfdump command line arguments that match the given filter.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $filter Netflow filter.
|
2012-01-24 Ramon Novoa <rnovoa@artica.es>
* include/functions_config.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
extras/pandoradb_migrate_4.0.x_to_4.1.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.postgreSQL.sql,
godmode/agentes/module_manager_editor_prediction.php,
godmode/agentes/configurar_agente.php,
godmode/menu.php,
godmode/netflow/nf_edit_form.php: Added support for enterprise
netflow modules.
* godmode/netflow/nf_manage.php: Moved to
godmode/setup/setup_netflow.php.
* godmode/netflow/nf_option_form.php: Removed from repository. Not used.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@5416 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-01-24 18:11:12 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string Command line argument string.
|
2012-01-24 Ramon Novoa <rnovoa@artica.es>
* include/functions_config.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
extras/pandoradb_migrate_4.0.x_to_4.1.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_4.1.postgreSQL.sql,
godmode/agentes/module_manager_editor_prediction.php,
godmode/agentes/configurar_agente.php,
godmode/menu.php,
godmode/netflow/nf_edit_form.php: Added support for enterprise
netflow modules.
* godmode/netflow/nf_manage.php: Moved to
godmode/setup/setup_netflow.php.
* godmode/netflow/nf_option_form.php: Removed from repository. Not used.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@5416 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-01-24 18:11:12 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_filter_arguments($filter)
|
|
|
|
{
|
2019-03-15 14:24:49 +01:00
|
|
|
// Advanced filter.
|
2019-01-30 16:18:44 +01:00
|
|
|
$filter_args = '';
|
|
|
|
if ($filter['advanced_filter'] != '') {
|
|
|
|
$filter_args = preg_replace('/["\r\n]/', '', io_safe_output($filter['advanced_filter']));
|
|
|
|
return ' "('.$filter_args.')"';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filter['router_ip'] != '') {
|
|
|
|
$filter_args .= ' "(router ip '.$filter['router_ip'].')';
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Normal filter.
|
2019-01-30 16:18:44 +01:00
|
|
|
if ($filter['ip_dst'] != '') {
|
|
|
|
$filter_args .= ' "(';
|
|
|
|
$val_ipdst = explode(',', io_safe_output($filter['ip_dst']));
|
|
|
|
for ($i = 0; $i < count($val_ipdst); $i++) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$filter_args .= ' or ';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (netflow_is_net($val_ipdst[$i]) == 0) {
|
|
|
|
$filter_args .= 'dst ip '.$val_ipdst[$i];
|
|
|
|
} else {
|
|
|
|
$filter_args .= 'dst net '.$val_ipdst[$i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filter['ip_src'] != '') {
|
|
|
|
if ($filter_args == '') {
|
|
|
|
$filter_args .= ' "(';
|
|
|
|
} else {
|
|
|
|
$filter_args .= ' and (';
|
|
|
|
}
|
|
|
|
|
|
|
|
$val_ipsrc = explode(',', io_safe_output($filter['ip_src']));
|
|
|
|
for ($i = 0; $i < count($val_ipsrc); $i++) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$filter_args .= ' or ';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (netflow_is_net($val_ipsrc[$i]) == 0) {
|
|
|
|
$filter_args .= 'src ip '.$val_ipsrc[$i];
|
|
|
|
} else {
|
|
|
|
$filter_args .= 'src net '.$val_ipsrc[$i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filter['dst_port'] != '') {
|
|
|
|
if ($filter_args == '') {
|
|
|
|
$filter_args .= ' "(';
|
|
|
|
} else {
|
|
|
|
$filter_args .= ' and (';
|
|
|
|
}
|
|
|
|
|
|
|
|
$val_dstport = explode(',', io_safe_output($filter['dst_port']));
|
|
|
|
for ($i = 0; $i < count($val_dstport); $i++) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$filter_args .= ' or ';
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= 'dst port '.$val_dstport[$i];
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filter['src_port'] != '') {
|
|
|
|
if ($filter_args == '') {
|
|
|
|
$filter_args .= ' "(';
|
|
|
|
} else {
|
|
|
|
$filter_args .= ' and (';
|
|
|
|
}
|
|
|
|
|
|
|
|
$val_srcport = explode(',', io_safe_output($filter['src_port']));
|
|
|
|
for ($i = 0; $i < count($val_srcport); $i++) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$filter_args .= ' or ';
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= 'src port '.$val_srcport[$i];
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($filter['proto']) && $filter['proto'] != '') {
|
|
|
|
if ($filter_args == '') {
|
|
|
|
$filter_args .= ' "(';
|
|
|
|
} else {
|
|
|
|
$filter_args .= ' and (';
|
|
|
|
}
|
|
|
|
|
|
|
|
$val_proto = explode(',', io_safe_output($filter['proto']));
|
|
|
|
for ($i = 0; $i < count($val_proto); $i++) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$filter_args .= ' or ';
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= 'proto '.$val_proto[$i];
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter_args .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($filter_args != '') {
|
|
|
|
$filter_args .= '"';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $filter_args;
|
2011-12-21 16:28:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-20 14:14:09 +01:00
|
|
|
/**
|
|
|
|
* Get the types of netflow charts.
|
|
|
|
*
|
2019-01-30 16:18:44 +01:00
|
|
|
* @return array of types.
|
2012-01-20 14:14:09 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_get_chart_types()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'netflow_area' => __('Area graph'),
|
2019-03-18 16:44:16 +01:00
|
|
|
'netflow_pie_summatory' => __('Summary'),
|
2019-01-30 16:18:44 +01:00
|
|
|
'netflow_data' => __('Data table'),
|
|
|
|
'netflow_mesh' => __('Circular mesh'),
|
|
|
|
'netflow_host_treemap' => __('Host detailed traffic'),
|
|
|
|
];
|
2012-01-20 14:14:09 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-01-20 14:14:09 +01:00
|
|
|
/**
|
|
|
|
* Draw a netflow report item.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $start_date Period start date.
|
|
|
|
* @param string $end_date Period end date.
|
|
|
|
* @param mixed $interval_length Resolution points or hourly or daily.
|
|
|
|
* @param string $type Chart type.
|
|
|
|
* @param array $filter Netflow filter.
|
|
|
|
* @param integer $max_aggregates Maximum number of aggregates.
|
|
|
|
* @param string $connection_name Node name when data is get in meta.
|
|
|
|
* @param string $output Output format. Only HTML, PDF and XML
|
|
|
|
* are supported.
|
|
|
|
* @param boolean $address_resolution True to resolve ips to hostnames.
|
2012-01-20 14:14:09 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return string The netflow report in the appropriate format.
|
2012-01-20 14:14:09 +01:00
|
|
|
*/
|
2019-03-15 14:24:49 +01:00
|
|
|
function netflow_draw_item(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$interval_length,
|
|
|
|
$type,
|
|
|
|
$filter,
|
|
|
|
$max_aggregates,
|
|
|
|
$connection_name='',
|
|
|
|
$output='HTML',
|
|
|
|
$address_resolution=false
|
|
|
|
) {
|
2019-01-30 16:18:44 +01:00
|
|
|
$aggregate = $filter['aggregate'];
|
|
|
|
$interval = ($end_date - $start_date);
|
|
|
|
if (defined('METACONSOLE')) {
|
|
|
|
$width = 950;
|
|
|
|
} else {
|
|
|
|
$width = 850;
|
|
|
|
}
|
|
|
|
|
|
|
|
$height = 320;
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Process item.
|
2019-01-30 16:18:44 +01:00
|
|
|
switch ($type) {
|
|
|
|
case '0':
|
|
|
|
case 'netflow_area':
|
2019-03-15 14:24:49 +01:00
|
|
|
$data = netflow_get_data(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$interval_length,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max_aggregates,
|
|
|
|
false,
|
|
|
|
$connection_name,
|
|
|
|
$address_resolution
|
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
if (empty($data)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-03-13 21:14:43 +01:00
|
|
|
if ($output == 'HTML' || $output == 'PDF') {
|
2019-03-14 17:49:44 +01:00
|
|
|
$html .= graph_netflow_aggregate_area(
|
|
|
|
$data,
|
|
|
|
$interval,
|
|
|
|
$width,
|
|
|
|
$height,
|
|
|
|
($output === 'HTML') ? 1 : 2,
|
|
|
|
($output === 'HTML'),
|
|
|
|
$end_date
|
|
|
|
);
|
2019-03-13 19:16:21 +01:00
|
|
|
return $html;
|
|
|
|
} else if ($output == 'XML') {
|
2019-03-15 14:24:49 +01:00
|
|
|
$xml .= '<aggregate>'.$aggregate."</aggregate>\n";
|
|
|
|
$xml .= '<resolution>'.$interval_length."</resolution>\n";
|
2019-03-13 19:16:21 +01:00
|
|
|
$xml .= netflow_aggregate_area_xml($data);
|
|
|
|
return $xml;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '2':
|
|
|
|
case 'netflow_data':
|
2019-03-15 14:24:49 +01:00
|
|
|
$data = netflow_get_data(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$interval_length,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max_aggregates,
|
|
|
|
true,
|
|
|
|
$connection_name,
|
|
|
|
$address_resolution
|
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
if (empty($data)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($output == 'HTML' || $output == 'PDF') {
|
|
|
|
$html .= "<div style='width: 100%; overflow: auto;'>";
|
2019-03-14 10:36:15 +01:00
|
|
|
$html .= netflow_data_table($data, $start_date, $end_date, $aggregate);
|
2019-01-30 16:18:44 +01:00
|
|
|
$html .= '</div>';
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
} else if ($output == 'XML') {
|
2019-03-15 14:24:49 +01:00
|
|
|
$xml .= '<aggregate>'.$aggregate."</aggregate>\n";
|
|
|
|
$xml .= '<resolution>'.$interval_length."</resolution>\n";
|
|
|
|
// Same as netflow_aggregate_area_xml.
|
2019-01-30 16:18:44 +01:00
|
|
|
$xml .= netflow_aggregate_area_xml($data);
|
|
|
|
return $xml;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '3':
|
|
|
|
case 'netflow_statistics':
|
|
|
|
$data = netflow_get_stats(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max_aggregates,
|
2019-03-14 09:07:17 +01:00
|
|
|
true,
|
2019-01-30 16:18:44 +01:00
|
|
|
$connection_name,
|
|
|
|
$address_resolution
|
|
|
|
);
|
|
|
|
if (empty($data)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($output == 'HTML' || $output == 'PDF') {
|
2019-03-14 09:07:17 +01:00
|
|
|
$html = netflow_stat_table($data, $start_date, $end_date, $aggregate);
|
2019-01-30 16:18:44 +01:00
|
|
|
return $html;
|
|
|
|
} else if ($output == 'XML') {
|
|
|
|
return netflow_stat_xml($data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '4':
|
|
|
|
case 'netflow_summary':
|
|
|
|
$data_summary = netflow_get_summary(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$connection_name
|
|
|
|
);
|
|
|
|
if (empty($data_summary)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($output == 'HTML' || $output == 'PDF') {
|
|
|
|
return netflow_summary_table($data_summary);
|
|
|
|
} else if ($output == 'XML') {
|
|
|
|
return netflow_summary_xml($data_summary);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '1':
|
|
|
|
case 'netflow_pie':
|
|
|
|
$data_pie = netflow_get_stats(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max_aggregates,
|
2019-03-14 10:36:15 +01:00
|
|
|
true,
|
2019-01-30 16:18:44 +01:00
|
|
|
$connection_name,
|
|
|
|
$address_resolution
|
|
|
|
);
|
|
|
|
if (empty($data_pie)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($output == 'HTML') {
|
|
|
|
return $html;
|
|
|
|
} else if ($output == 'PDF') {
|
|
|
|
return $html;
|
|
|
|
} else if ($output == 'XML') {
|
|
|
|
return $xml;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'netflow_pie_summatory':
|
|
|
|
$data_summary = netflow_get_summary(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$connection_name
|
|
|
|
);
|
|
|
|
if (empty($data_summary)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data_pie = netflow_get_stats(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$aggregate,
|
|
|
|
$max_aggregates,
|
2019-03-14 10:36:15 +01:00
|
|
|
true,
|
2019-01-30 16:18:44 +01:00
|
|
|
$connection_name,
|
|
|
|
$address_resolution
|
|
|
|
);
|
|
|
|
if (empty($data_pie)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($output) {
|
|
|
|
case 'HTML':
|
|
|
|
$html = '<table>';
|
|
|
|
$html .= '<tr>';
|
|
|
|
$html .= '<td>';
|
|
|
|
$html .= netflow_summary_table($data_summary);
|
|
|
|
$html .= '</td>';
|
|
|
|
$html .= '<td>';
|
|
|
|
$html .= graph_netflow_aggregate_pie($data_pie, netflow_format_aggregate($aggregate));
|
|
|
|
$html .= '</td>';
|
|
|
|
$html .= '</tr>';
|
|
|
|
$html .= '</table>';
|
2019-03-18 16:44:16 +01:00
|
|
|
$html .= '</br>';
|
|
|
|
$html .= netflow_stat_table($data_pie, $start_date, $end_date, $aggregate);
|
2019-01-30 16:18:44 +01:00
|
|
|
return $html;
|
|
|
|
|
|
|
|
case 'XML':
|
|
|
|
return netflow_summary_xml($data_summary);
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
default:
|
|
|
|
// Nothing to do.
|
|
|
|
break;
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'netflow_mesh':
|
2019-03-15 14:24:49 +01:00
|
|
|
$netflow_data = netflow_get_record(
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
|
|
|
$filter,
|
|
|
|
$max_aggregates,
|
|
|
|
$address_resolution
|
|
|
|
);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
|
|
|
switch ($aggregate) {
|
|
|
|
case 'srcport':
|
|
|
|
case 'dstport':
|
|
|
|
$source_type = 'source_port';
|
|
|
|
$destination_type = 'destination_port';
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
case 'dstip':
|
|
|
|
case 'srcip':
|
|
|
|
$source_type = 'source_address';
|
|
|
|
$destination_type = 'destination_address';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data = [];
|
|
|
|
$data['elements'] = [];
|
|
|
|
$data['matrix'] = [];
|
|
|
|
foreach ($netflow_data as $record) {
|
|
|
|
if (!in_array($record[$source_type], $data['elements'])) {
|
|
|
|
$data['elements'][] = $record[$source_type];
|
|
|
|
$data['matrix'][] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in_array($record[$destination_type], $data['elements'])) {
|
|
|
|
$data['elements'][] = $record[$destination_type];
|
|
|
|
$data['matrix'][] = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ($i = 0; $i < count($data['matrix']); $i++) {
|
|
|
|
$data['matrix'][$i] = array_fill(0, count($data['matrix']), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($netflow_data as $record) {
|
|
|
|
$source_key = array_search($record[$source_type], $data['elements']);
|
|
|
|
$destination_key = array_search($record[$destination_type], $data['elements']);
|
|
|
|
if ($source_key !== false && $destination_key !== false) {
|
|
|
|
$data['matrix'][$source_key][$destination_key] += $record['data'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$html = '<div style="text-align:center;">';
|
2019-03-14 10:05:21 +01:00
|
|
|
$html .= graph_netflow_circular_mesh($data, 700);
|
2019-01-30 16:18:44 +01:00
|
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
|
|
|
|
|
|
case 'netflow_host_treemap':
|
2019-03-14 10:05:21 +01:00
|
|
|
$netflow_data = netflow_get_record($start_date, $end_date, $filter, $max_aggregates, $address_resolution);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
|
|
|
switch ($aggregate) {
|
|
|
|
case 'srcip':
|
|
|
|
case 'srcport':
|
|
|
|
$address_type = 'source_address';
|
|
|
|
$port_type = 'source_port';
|
|
|
|
$type = __('Sent');
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
case 'dstip':
|
|
|
|
case 'dstport':
|
|
|
|
$address_type = 'destination_address';
|
|
|
|
$port_type = 'destination_port';
|
|
|
|
$type = __('Received');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data_aux = [];
|
|
|
|
foreach ($netflow_data as $record) {
|
|
|
|
$address = $record[$address_type];
|
|
|
|
$port = $record[$port_type];
|
|
|
|
|
|
|
|
if (!isset($data_aux[$address])) {
|
|
|
|
$data_aux[$address] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isset($data_aux[$address][$port])) {
|
|
|
|
$data_aux[$address][$port] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data_aux[$address][$port] += $record['data'];
|
|
|
|
}
|
|
|
|
|
|
|
|
$id = -1;
|
|
|
|
|
|
|
|
$data = [];
|
|
|
|
|
|
|
|
if (! empty($netflow_data)) {
|
|
|
|
$data['name'] = __('Host detailed traffic').': '.$type;
|
|
|
|
$data['children'] = [];
|
|
|
|
|
|
|
|
foreach ($data_aux as $address => $ports) {
|
|
|
|
$children = [];
|
|
|
|
$children['id'] = $id++;
|
|
|
|
$children['name'] = $address;
|
|
|
|
$children['children'] = [];
|
|
|
|
foreach ($ports as $port => $value) {
|
|
|
|
$children_data = [];
|
|
|
|
$children_data['id'] = $id++;
|
|
|
|
$children_data['name'] = $port;
|
|
|
|
$children_data['value'] = $value;
|
2019-03-14 10:05:21 +01:00
|
|
|
$children_data['tooltip_content'] = $port.': <b>'.network_format_bytes($value).'</b>';
|
2019-01-30 16:18:44 +01:00
|
|
|
$children['children'][] = $children_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data['children'][] = $children;
|
|
|
|
}
|
|
|
|
}
|
2019-03-14 10:36:15 +01:00
|
|
|
return graph_netflow_host_traffic($data, 'auto', 400);
|
2019-01-30 16:18:44 +01:00
|
|
|
|
|
|
|
default:
|
2019-03-15 14:24:49 +01:00
|
|
|
// Nothing to do.
|
2019-01-30 16:18:44 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($output == 'HTML' || $output == 'PDF') {
|
|
|
|
return graph_nodata_image(300, 110, 'data');
|
|
|
|
}
|
2012-01-20 14:14:09 +01:00
|
|
|
}
|
2012-10-02 13:11:58 +02:00
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
/**
|
|
|
|
* Render an aggregated area chart as an XML.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Netflow data.
|
|
|
|
*
|
|
|
|
* @return void XML is echoed.
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_aggregate_area_xml($data)
|
|
|
|
{
|
2019-03-15 14:24:49 +01:00
|
|
|
// Print source information.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (isset($data['sources'])) {
|
|
|
|
echo "<aggregates>\n";
|
|
|
|
foreach ($data['sources'] as $source => $discard) {
|
2019-03-15 14:24:49 +01:00
|
|
|
echo '<aggregate>'.$source."</aggregate>\n";
|
2019-01-30 16:18:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
echo "</aggregates>\n";
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Print flow information.
|
2019-01-30 16:18:44 +01:00
|
|
|
echo "<flows>\n";
|
|
|
|
foreach ($data['data'] as $timestamp => $flow) {
|
|
|
|
echo "<flow>\n";
|
|
|
|
echo ' <timestamp>'.$timestamp."</timestamp>\n";
|
|
|
|
echo " <aggregates>\n";
|
|
|
|
foreach ($flow as $source => $data) {
|
|
|
|
echo " <aggregate>$source</aggregate>\n";
|
|
|
|
echo ' <data>'.$data."</data>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo " </aggregates>\n";
|
|
|
|
echo "</flow>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "</flows>\n";
|
|
|
|
} else {
|
|
|
|
echo "<flows>\n";
|
|
|
|
foreach ($data as $timestamp => $flow) {
|
|
|
|
echo "<flow>\n";
|
|
|
|
echo ' <timestamp>'.$timestamp."</timestamp>\n";
|
|
|
|
echo ' <data>'.$flow['data']."</data>\n";
|
|
|
|
echo "</flow>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "</flows>\n";
|
|
|
|
}
|
2012-10-02 13:11:58 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
/**
|
|
|
|
* Render a pie chart as an XML.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Netflow data.
|
|
|
|
*
|
|
|
|
* @return void XML is echoed.
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_aggregate_pie_xml($data)
|
|
|
|
{
|
2019-03-15 14:24:49 +01:00
|
|
|
// Calculate total.
|
2019-01-30 16:18:44 +01:00
|
|
|
$total = 0;
|
|
|
|
foreach ($data as $flow) {
|
|
|
|
$total += $flow['data'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($total == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Print percentages.
|
2019-01-30 16:18:44 +01:00
|
|
|
echo "<pie>\n";
|
|
|
|
foreach ($data as $flow) {
|
|
|
|
echo '<aggregate>'.$flow['agg']."</aggregate>\n";
|
|
|
|
echo '<data>'.format_numeric((100 * $flow['data'] / $total), 2)."%</data>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "</pie>\n";
|
2012-10-02 13:11:58 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
/**
|
|
|
|
* Render a stats table as an XML.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Netflow data.
|
|
|
|
*
|
|
|
|
* @return string Wiht XML data.
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_stat_xml($data)
|
|
|
|
{
|
2019-03-15 14:24:49 +01:00
|
|
|
// Print stats.
|
2019-01-30 16:18:44 +01:00
|
|
|
$xml .= "<stats>\n";
|
|
|
|
foreach ($data as $flow) {
|
|
|
|
$xml .= '<aggregate>'.$flow['agg']."</aggregate>\n";
|
|
|
|
$xml .= '<data>'.$flow['data']."</data>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
$xml .= "</stats>\n";
|
|
|
|
|
|
|
|
return $xml;
|
2012-10-02 13:11:58 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
/**
|
|
|
|
* Render a summary table as an XML.
|
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param array $data Netflow data.
|
|
|
|
*
|
|
|
|
* @return string Wiht XML data.
|
2012-10-04 Ramon Novoa <rnovoa@artica.es>
* include/functions_html.php,
include/functions_netflow.php,
pandoradb.sql,
pandoradb.postgreSQL.sql,
pandoradb.oracle.sql,
operation/netflow/nf_live_view.php,
operation/netflow/nf_reporting.php,
operation/netflow/nf_view.php,
extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.oracle.sql,
extras/pandoradb_migrate_4.0.x_to_5.0.postgreSQL.sql,
godmode/netflow/nf_edit_form.php,
godmode/netflow/nf_item_list.php,
godmode/netflow/nf_report_item.php,
godmode/netflow/nf_report_form.php,
godmode/netflow/nf_edit.php: Added metaconsole integration to netflow
reports.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7043 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2012-10-04 12:49:11 +02:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_summary_xml($data)
|
|
|
|
{
|
|
|
|
// Print summary
|
|
|
|
$xml = "<summary>\n";
|
|
|
|
$xml .= ' <total_flows>'.$data['totalflows']."</total_flows>\n";
|
|
|
|
$xml .= ' <total_bytes>'.$data['totalbytes']."</total_bytes>\n";
|
|
|
|
$xml .= ' <total_packets>'.$data['totalbytes']."</total_packets>\n";
|
|
|
|
$xml .= ' <average_bps>'.$data['avgbps']."</average_bps>\n";
|
|
|
|
$xml .= ' <average_pps>'.$data['avgpps']."</average_pps>\n";
|
|
|
|
$xml .= ' <average_bpp>'.$data['avgpps']."</average_bpp>\n";
|
|
|
|
$xml .= "</summary>\n";
|
|
|
|
|
|
|
|
return $xml;
|
2012-10-02 13:11:58 +02:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2012-12-07 15:03:00 +01:00
|
|
|
/**
|
|
|
|
* Return a string describing the given aggregate.
|
2019-01-30 16:18:44 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $aggregate Netflow aggregate.
|
|
|
|
*
|
|
|
|
* @return string With formatted aggregate.
|
2012-12-07 15:03:00 +01:00
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_format_aggregate($aggregate)
|
|
|
|
{
|
|
|
|
switch ($aggregate) {
|
|
|
|
case 'dstport':
|
|
|
|
return __('Dst port');
|
|
|
|
|
|
|
|
case 'dstip':
|
|
|
|
return __('Dst IP');
|
|
|
|
|
|
|
|
case 'srcip':
|
|
|
|
return __('Src IP');
|
|
|
|
|
|
|
|
case 'srcport':
|
|
|
|
return __('Src port');
|
|
|
|
|
|
|
|
default:
|
|
|
|
return '';
|
|
|
|
}
|
2012-12-07 15:03:00 +01:00
|
|
|
}
|
|
|
|
|
2019-01-30 16:18:44 +01:00
|
|
|
|
2013-09-27 13:18:04 +02:00
|
|
|
/**
|
|
|
|
* Check the nfdump binary for compatibility.
|
2019-01-30 16:18:44 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @param string $nfdump_binary Nfdump binary full path.
|
2019-01-30 16:18:44 +01:00
|
|
|
*
|
2019-03-15 14:24:49 +01:00
|
|
|
* @return integer 1 if the binary does not exist or is not executable, 2 if a
|
2013-09-27 13:18:04 +02:00
|
|
|
* version older than 1.6.8 is installed or the version cannot be
|
|
|
|
* determined, 0 otherwise.
|
|
|
|
*/
|
2019-01-30 16:18:44 +01:00
|
|
|
function netflow_check_nfdump_binary($nfdump_binary)
|
|
|
|
{
|
2019-03-15 14:24:49 +01:00
|
|
|
// Check that the binary exists and is executable.
|
2019-01-30 16:18:44 +01:00
|
|
|
if (! is_executable($nfdump_binary)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:24:49 +01:00
|
|
|
// Check at least version 1.6.8.
|
2019-01-30 16:18:44 +01:00
|
|
|
$output = '';
|
|
|
|
$rc = -1;
|
|
|
|
exec($nfdump_binary.' -V', $output, $rc);
|
|
|
|
if ($rc != 0) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
$matches = [];
|
|
|
|
foreach ($output as $line) {
|
|
|
|
if (preg_match('/Version:[^\d]+(\d+)\.(\d+)\.(\d+)/', $line, $matches) === 1) {
|
|
|
|
if ($matches[1] < 1) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($matches[2] < 6) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($matches[3] < 8) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 2;
|
2013-09-27 13:18:04 +02:00
|
|
|
}
|
2019-03-06 13:31:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the netflow datas to build a netflow explorer data structure.
|
|
|
|
*
|
|
|
|
* @param integer $max Number of result displayed.
|
|
|
|
* @param string $top_action Action to do (listeners,talkers,tcp or udp).
|
|
|
|
* @param integer $start_date In utimestamp.
|
|
|
|
* @param integer $end_date In utimestamp.
|
|
|
|
* @param string $filter Ip to filter.
|
2019-03-08 11:57:32 +01:00
|
|
|
* @param string $order Select one of bytes,pkts,flow.
|
2019-03-06 13:31:55 +01:00
|
|
|
*
|
|
|
|
* @return array With data (host, sum_bytes, sum_pkts and sum_flows).
|
|
|
|
*/
|
|
|
|
function netflow_get_top_summary(
|
|
|
|
$max,
|
|
|
|
$top_action,
|
|
|
|
$start_date,
|
|
|
|
$end_date,
|
2019-03-08 11:57:32 +01:00
|
|
|
$filter='',
|
|
|
|
$order='bytes'
|
2019-03-06 13:31:55 +01:00
|
|
|
) {
|
|
|
|
global $nfdump_date_format;
|
|
|
|
$netflow_filter = [];
|
|
|
|
$sort = '';
|
|
|
|
switch ($top_action) {
|
|
|
|
case 'listeners':
|
|
|
|
if (empty(!$filter)) {
|
|
|
|
$netflow_filter['ip_src'] = $filter;
|
|
|
|
}
|
|
|
|
|
|
|
|
$sort = 'dstip';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'talkers':
|
|
|
|
if (empty(!$filter)) {
|
|
|
|
$netflow_filter['ip_dst'] = $filter;
|
|
|
|
}
|
|
|
|
|
|
|
|
$sort = 'srcip';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'tcp':
|
|
|
|
case 'udp':
|
2019-03-07 13:38:03 +01:00
|
|
|
$netflow_filter['proto'] = $top_action;
|
|
|
|
$sort = 'port';
|
|
|
|
if (empty(!$filter)) {
|
|
|
|
$netflow_filter['advanced_filter'] = sprintf(
|
|
|
|
'((dst port %s) or (src port %s)) and (proto %s)',
|
|
|
|
$filter,
|
|
|
|
$filter,
|
|
|
|
$top_action
|
|
|
|
);
|
|
|
|
// Display ips when filter is set in port.
|
|
|
|
$sort = 'ip';
|
|
|
|
}
|
2019-03-06 13:31:55 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$command = netflow_get_command($netflow_filter);
|
|
|
|
|
|
|
|
// Execute nfdump.
|
2019-03-08 11:57:32 +01:00
|
|
|
$order_text = '';
|
|
|
|
switch ($order) {
|
|
|
|
case 'flows':
|
|
|
|
$order_text = 'flows';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'pkts':
|
|
|
|
$order_text = 'packets';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'bytes':
|
|
|
|
default:
|
|
|
|
$order_text = 'bytes';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-03-11 13:19:17 +01:00
|
|
|
$command .= " -q -o csv -n $max -s $sort/$order_text -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date);
|
2019-03-06 13:31:55 +01:00
|
|
|
exec($command, $result);
|
|
|
|
|
|
|
|
if (! is_array($result)) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove first line (avoiding slow array_shift).
|
|
|
|
$result = array_reverse($result);
|
|
|
|
array_pop($result);
|
|
|
|
$result = array_reverse($result);
|
|
|
|
|
|
|
|
$top_info = [];
|
|
|
|
foreach ($result as $line) {
|
|
|
|
if (empty($line)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data = explode(',', $line);
|
|
|
|
if (!isset($data[9])) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-03-07 19:11:30 +01:00
|
|
|
$top_info[(string) $data[4]] = [
|
2019-03-06 13:31:55 +01:00
|
|
|
'host' => $data[4],
|
|
|
|
'sum_bytes' => $data[9],
|
|
|
|
'sum_pkts' => $data[7],
|
|
|
|
'sum_flows' => $data[5],
|
2019-03-07 19:11:30 +01:00
|
|
|
'pct_bytes' => $data[10],
|
|
|
|
'pct_pkts' => $data[8],
|
|
|
|
'pct_flows' => $data[6],
|
2019-03-06 13:31:55 +01:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $top_info;
|
|
|
|
}
|
2019-03-07 14:01:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check the netflow version and print an error message if there is not correct.
|
|
|
|
*
|
|
|
|
* @return boolean True if version check is correct.
|
|
|
|
*/
|
|
|
|
function netflow_print_check_version_error()
|
|
|
|
{
|
|
|
|
global $config;
|
|
|
|
|
|
|
|
switch (netflow_check_nfdump_binary($config['netflow_nfdump'])) {
|
|
|
|
case 0:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
ui_print_error_message(
|
|
|
|
__('nfdump binary (%s) not found!', $config['netflow_nfdump'])
|
|
|
|
);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
ui_print_error_message(
|
|
|
|
__('Make sure nfdump version 1.6.8 or newer is installed!')
|
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2019-03-13 20:15:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the array for netflow resolution select.
|
|
|
|
*
|
|
|
|
* @return array With all values.
|
|
|
|
*/
|
|
|
|
function netflow_resolution_select_params()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
NETFLOW_RES_LOWD => __('Low'),
|
|
|
|
NETFLOW_RES_MEDD => __('Medium'),
|
|
|
|
NETFLOW_RES_HID => __('High'),
|
|
|
|
NETFLOW_RES_ULTRAD => __('Ultra High'),
|
|
|
|
NETFLOW_RES_HOURLY => __('Hourly'),
|
|
|
|
NETFLOW_RES_DAILY => __('Daily'),
|
|
|
|
];
|
|
|
|
}
|
2019-03-13 21:14:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the resolution name.
|
|
|
|
*
|
|
|
|
* @param mixed $value Type.
|
|
|
|
*
|
|
|
|
* @return string Translated name. Unknown for unrecognized resolution names.
|
|
|
|
*/
|
|
|
|
function netflow_get_resolution_name($value)
|
|
|
|
{
|
|
|
|
$resolutions = netflow_resolution_select_params();
|
|
|
|
return (isset($resolutions[$value])) ? $resolutions[$value] : __('Unknown');
|
|
|
|
}
|
2019-03-18 10:54:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Report formatted subtitle.
|
|
|
|
*
|
|
|
|
* @param string $aggreagate Aggregate by param.
|
|
|
|
* @param string $resolution Netfow live view resolution.
|
|
|
|
* @param string $type Type of view.
|
|
|
|
*
|
|
|
|
* @return string HTML with formatted subtitle.
|
|
|
|
*/
|
|
|
|
function netflow_generate_subtitle_report($aggregate, $resolution, $type)
|
|
|
|
{
|
|
|
|
$subt = __(
|
|
|
|
'Agregate by %s',
|
|
|
|
netflow_format_aggregate($aggregate)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Display the resolution only in required reports.
|
|
|
|
if (in_array($type, ['netflow_area', 'netflow_data']) === true) {
|
|
|
|
$subt .= ' - ';
|
|
|
|
$subt .= __(
|
|
|
|
'Resolution %s',
|
|
|
|
netflow_get_resolution_name($resolution)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $subt;
|
|
|
|
}
|