diff --git a/extras/build_rpm_rhel7.sh b/extras/build_rpm_rhel7.sh new file mode 100755 index 0000000000..6bb65d816d --- /dev/null +++ b/extras/build_rpm_rhel7.sh @@ -0,0 +1,26 @@ +#!/bin/bash +source build_vars.sh + +if [ ! -d $RPMHOME/RPMS ]; then + mkdir -p $RPMHOME/RPMS || exit 1 +fi + +echo "Creating RPM packages in $RPMHOME/RPMS" + +# Console +rpmbuild -ba $CODEHOME/pandora_console/pandora_console.rhel7.spec || exit 1 + +# Server +rpmbuild -ba $CODEHOME/pandora_server/pandora_server.rhel7.spec || exit 1 + +# Unix agent +rpmbuild -ba $CODEHOME/pandora_agents/unix/pandora_agent.rhel7.spec || exit 1 + +# Enterprise console +rpmbuild -ba $PANDHOME_ENT/pandora_console/enterprise/pandora_console_enterprise.rhel7.spec || exit 1 + +# Enterprise server +rpmbuild -ba $PANDHOME_ENT/pandora_server/PandoraFMS-Enterprise/pandora_server_enterprise.rhel7.spec || exit 1 + +exit 0 + diff --git a/extras/pandora_update_version.sh b/extras/pandora_update_version.sh index 7d143f0f03..33e0c891f7 100755 --- a/extras/pandora_update_version.sh +++ b/extras/pandora_update_version.sh @@ -26,6 +26,7 @@ $CODEHOME/pandora_server/pandora_server.spec \ $PANDHOME_ENT/pandora_console/enterprise/pandora_console_enterprise.spec \ $PANDHOME_ENT/pandora_server/PandoraFMS-Enterprise/pandora_server_enterprise.spec \ $CODEHOME/pandora_console/pandora_console.redhat.spec \ +$CODEHOME/pandora_console/pandora_console.rhel7.spec \ $CODEHOME/pandora_agents/unix/pandora_agent.redhat.spec \ $CODEHOME/pandora_server/pandora_server.redhat.spec \ $PANDHOME_ENT/pandora_console/enterprise/pandora_console_enterprise.redhat.spec \ diff --git a/pandora_agents/pc/AIX/pandora_agent.conf b/pandora_agents/pc/AIX/pandora_agent.conf index 07054ee2e1..c5a79a38b5 100644 --- a/pandora_agents/pc/AIX/pandora_agent.conf +++ b/pandora_agents/pc/AIX/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, AIX version +# Version 7.0NG.733, AIX version # Licensed under GPL license v2, # Copyright (c) 2003-2010 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/FreeBSD/pandora_agent.conf b/pandora_agents/pc/FreeBSD/pandora_agent.conf index 9d8a49bb99..da15c864ea 100644 --- a/pandora_agents/pc/FreeBSD/pandora_agent.conf +++ b/pandora_agents/pc/FreeBSD/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, FreeBSD Version +# Version 7.0NG.733, FreeBSD Version # Licensed under GPL license v2, # Copyright (c) 2003-2010 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/HP-UX/pandora_agent.conf b/pandora_agents/pc/HP-UX/pandora_agent.conf index c02e4647e1..cb8075b7ac 100644 --- a/pandora_agents/pc/HP-UX/pandora_agent.conf +++ b/pandora_agents/pc/HP-UX/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, HP-UX Version +# Version 7.0NG.733, HP-UX Version # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/Linux/pandora_agent.conf b/pandora_agents/pc/Linux/pandora_agent.conf index 153113e070..170e9c6ccf 100644 --- a/pandora_agents/pc/Linux/pandora_agent.conf +++ b/pandora_agents/pc/Linux/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, GNU/Linux +# Version 7.0NG.733, GNU/Linux # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/NT4/pandora_agent.conf b/pandora_agents/pc/NT4/pandora_agent.conf index 6ddeba7edc..42257021fa 100644 --- a/pandora_agents/pc/NT4/pandora_agent.conf +++ b/pandora_agents/pc/NT4/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, GNU/Linux +# Version 7.0NG.733, GNU/Linux # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/SunOS/pandora_agent.conf b/pandora_agents/pc/SunOS/pandora_agent.conf index 502317f893..ebad34a0ab 100644 --- a/pandora_agents/pc/SunOS/pandora_agent.conf +++ b/pandora_agents/pc/SunOS/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, Solaris Version +# Version 7.0NG.733, Solaris Version # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/pc/Win32/pandora_agent.conf b/pandora_agents/pc/Win32/pandora_agent.conf index 96b20ea7e3..972f6d8aa1 100644 --- a/pandora_agents/pc/Win32/pandora_agent.conf +++ b/pandora_agents/pc/Win32/pandora_agent.conf @@ -1,6 +1,6 @@ # Base config file for Pandora FMS Windows Agent # (c) 2006-2010 Artica Soluciones Tecnologicas -# Version 7.0NG.732 +# Version 7.0NG.733 # This program is Free Software, you can redistribute it and/or modify it # under the terms of the GNU General Public Licence as published by the Free Software diff --git a/pandora_agents/shellscript/aix/pandora_agent.conf b/pandora_agents/shellscript/aix/pandora_agent.conf index 200ff9db97..6a80829c29 100644 --- a/pandora_agents/shellscript/aix/pandora_agent.conf +++ b/pandora_agents/shellscript/aix/pandora_agent.conf @@ -1,6 +1,6 @@ # Fichero de configuracion base de agentes de Pandora # Base config file for Pandora agents -# Version 7.0NG.732, AIX version +# Version 7.0NG.733, AIX version # General Parameters # ================== diff --git a/pandora_agents/shellscript/bsd-ipso/pandora_agent.conf b/pandora_agents/shellscript/bsd-ipso/pandora_agent.conf index 2002f4db65..6555df787c 100644 --- a/pandora_agents/shellscript/bsd-ipso/pandora_agent.conf +++ b/pandora_agents/shellscript/bsd-ipso/pandora_agent.conf @@ -1,6 +1,6 @@ # Fichero de configuracion base de agentes de Pandora # Base config file for Pandora agents -# Version 7.0NG.732 +# Version 7.0NG.733 # FreeBSD/IPSO version # Licenced under GPL licence, 2003-2007 Sancho Lerena diff --git a/pandora_agents/shellscript/hp-ux/pandora_agent.conf b/pandora_agents/shellscript/hp-ux/pandora_agent.conf index f9c19dbd06..ba29482633 100644 --- a/pandora_agents/shellscript/hp-ux/pandora_agent.conf +++ b/pandora_agents/shellscript/hp-ux/pandora_agent.conf @@ -1,6 +1,6 @@ # Fichero de configuracion base de agentes de Pandora # Base config file for Pandora agents -# Version 7.0NG.732, HPUX Version +# Version 7.0NG.733, HPUX Version # General Parameters # ================== diff --git a/pandora_agents/shellscript/linux/pandora_agent.conf b/pandora_agents/shellscript/linux/pandora_agent.conf index dc272a7a71..7bd41ad039 100644 --- a/pandora_agents/shellscript/linux/pandora_agent.conf +++ b/pandora_agents/shellscript/linux/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732 +# Version 7.0NG.733 # Licensed under GPL license v2, # (c) 2003-2010 Artica Soluciones Tecnologicas # please visit http://pandora.sourceforge.net diff --git a/pandora_agents/shellscript/mac_osx/pandora_agent.conf b/pandora_agents/shellscript/mac_osx/pandora_agent.conf index 5a466677d2..525f70c2af 100644 --- a/pandora_agents/shellscript/mac_osx/pandora_agent.conf +++ b/pandora_agents/shellscript/mac_osx/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732 +# Version 7.0NG.733 # Licensed under GPL license v2, # (c) 2003-2009 Artica Soluciones Tecnologicas # please visit http://pandora.sourceforge.net diff --git a/pandora_agents/shellscript/openWRT/pandora_agent.conf b/pandora_agents/shellscript/openWRT/pandora_agent.conf index 170188cc6f..d3cf26efa2 100644 --- a/pandora_agents/shellscript/openWRT/pandora_agent.conf +++ b/pandora_agents/shellscript/openWRT/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732 +# Version 7.0NG.733 # Licensed under GPL license v2, # please visit http://pandora.sourceforge.net diff --git a/pandora_agents/shellscript/solaris/pandora_agent.conf b/pandora_agents/shellscript/solaris/pandora_agent.conf index aad04ca60d..5a94defce2 100644 --- a/pandora_agents/shellscript/solaris/pandora_agent.conf +++ b/pandora_agents/shellscript/solaris/pandora_agent.conf @@ -1,6 +1,6 @@ # Fichero de configuracion base de agentes de Pandora # Base config file for Pandora agents -# Version 7.0NG.732, Solaris version +# Version 7.0NG.733, Solaris version # General Parameters # ================== diff --git a/pandora_agents/unix/AIX/pandora_agent.conf b/pandora_agents/unix/AIX/pandora_agent.conf index 3ce7da3c7e..ac43dfdabb 100644 --- a/pandora_agents/unix/AIX/pandora_agent.conf +++ b/pandora_agents/unix/AIX/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, AIX version +# Version 7.0NG.733, AIX version # Licensed under GPL license v2, # Copyright (c) 2003-2010 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index e31162e56a..ccc4c495a3 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.732-190321 +Version: 7.0NG.733-190405 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 37bc1d1b45..8780e8a466 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.732-190321" +pandora_version="7.0NG.733-190405" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/Darwin/pandora_agent.conf b/pandora_agents/unix/Darwin/pandora_agent.conf index 35202fcbe5..3b87b2bdbf 100644 --- a/pandora_agents/unix/Darwin/pandora_agent.conf +++ b/pandora_agents/unix/Darwin/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, GNU/Linux +# Version 7.0NG.733, GNU/Linux # Licensed under GPL license v2, # Copyright (c) 2003-2012 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/FreeBSD/pandora_agent.conf b/pandora_agents/unix/FreeBSD/pandora_agent.conf index c505d5f75e..55e5ab3dd0 100644 --- a/pandora_agents/unix/FreeBSD/pandora_agent.conf +++ b/pandora_agents/unix/FreeBSD/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, FreeBSD Version +# Version 7.0NG.733, FreeBSD Version # Licensed under GPL license v2, # Copyright (c) 2003-2016 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/HP-UX/pandora_agent.conf b/pandora_agents/unix/HP-UX/pandora_agent.conf index 237bffb291..3c9891fdce 100644 --- a/pandora_agents/unix/HP-UX/pandora_agent.conf +++ b/pandora_agents/unix/HP-UX/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, HP-UX Version +# Version 7.0NG.733, HP-UX Version # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index 5a65e0e095..0f6cbfc83a 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, GNU/Linux +# Version 7.0NG.733, GNU/Linux # Licensed under GPL license v2, # Copyright (c) 2003-2014 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/NT4/pandora_agent.conf b/pandora_agents/unix/NT4/pandora_agent.conf index 1394067390..11e8c8e6c0 100644 --- a/pandora_agents/unix/NT4/pandora_agent.conf +++ b/pandora_agents/unix/NT4/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, GNU/Linux +# Version 7.0NG.733, GNU/Linux # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/NetBSD/pandora_agent.conf b/pandora_agents/unix/NetBSD/pandora_agent.conf index 677615a47c..d0e7f040e2 100644 --- a/pandora_agents/unix/NetBSD/pandora_agent.conf +++ b/pandora_agents/unix/NetBSD/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, NetBSD Version +# Version 7.0NG.733, NetBSD Version # Licensed under GPL license v2, # Copyright (c) 2003-2010 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/SunOS/pandora_agent.conf b/pandora_agents/unix/SunOS/pandora_agent.conf index 89d5b46100..bb270634a5 100644 --- a/pandora_agents/unix/SunOS/pandora_agent.conf +++ b/pandora_agents/unix/SunOS/pandora_agent.conf @@ -1,5 +1,5 @@ # Base config file for Pandora FMS agents -# Version 7.0NG.732, Solaris Version +# Version 7.0NG.733, Solaris Version # Licensed under GPL license v2, # Copyright (c) 2003-2009 Artica Soluciones Tecnologicas # http://www.pandorafms.com diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 0b8fe1b267..5674b70177 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -41,8 +41,8 @@ my $Sem = undef; # Semaphore used to control the number of threads my $ThreadSem = undef; -use constant AGENT_VERSION => '7.0NG.732'; -use constant AGENT_BUILD => '190321'; +use constant AGENT_VERSION => '7.0NG.733'; +use constant AGENT_BUILD => '190405'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 7fdb0693cc..eaf92c3ca5 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -2,8 +2,8 @@ #Pandora FMS Linux Agent # %define name pandorafms_agent_unix -%define version 7.0NG.732 -%define release 190321 +%define version 7.0NG.733 +%define release 190405 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index e16822b5ba..a12a113b92 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -2,8 +2,8 @@ #Pandora FMS Linux Agent # %define name pandorafms_agent_unix -%define version 7.0NG.732 -%define release 190321 +%define version 7.0NG.733 +%define release 190405 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 4660a502c5..2b6ba8babf 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -9,8 +9,8 @@ # Please see http://www.pandorafms.org. This code is licensed under GPL 2.0 license. # ********************************************************************** -PI_VERSION="7.0NG.732" -PI_BUILD="190321" +PI_VERSION="7.0NG.733" +PI_BUILD="190405" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/bin/pandora_agent.conf b/pandora_agents/win32/bin/pandora_agent.conf index 3d1e208de8..3ec2bf3880 100644 --- a/pandora_agents/win32/bin/pandora_agent.conf +++ b/pandora_agents/win32/bin/pandora_agent.conf @@ -1,6 +1,6 @@ # Base config file for Pandora FMS Windows Agent # (c) 2006-2017 Artica Soluciones Tecnologicas -# Version 7.0NG.732 +# Version 7.0NG.733 # This program is Free Software, you can redistribute it and/or modify it # under the terms of the GNU General Public Licence as published by the Free Software @@ -44,6 +44,8 @@ remote_config 0 #agent_name_cmd cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\agentname.vbs" agent_name_cmd __rand__ +# Agent alias. Name should be unique rather than alias. Hostname by default +# agent_alias $Alias$ #Parent agent_name #parent_agent_name caprica diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index c1cebe236b..9dadbf90fd 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -3,7 +3,7 @@ AllowLanguageSelection {Yes} AppName -{Pandora FMS Windows Agent v7.0NG.732} +{Pandora FMS Windows Agent v7.0NG.733} ApplicationID {17E3D2CF-CA02-406B-8A80-9D31C17BD08F} @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{190321} +{190405} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 7a6d0e2a7c..f4f3ddac52 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.732(Build 190321)") +#define PANDORA_VERSION ("7.0NG.733(Build 190405)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 3d4ee130e6..4bdc9a4096 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.732(Build 190321))" + VALUE "ProductVersion", "(7.0NG.733(Build 190405))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index a987df1cc3..9a41b31fe5 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.732-190321 +Version: 7.0NG.733-190405 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 470eb8d328..3907e8f72c 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.732-190321" +pandora_version="7.0NG.733-190405" package_pear=0 package_pandora=1 diff --git a/pandora_console/extensions/agents_modules.php b/pandora_console/extensions/agents_modules.php index 798f4e140e..8c0eaa7dae 100644 --- a/pandora_console/extensions/agents_modules.php +++ b/pandora_console/extensions/agents_modules.php @@ -661,7 +661,7 @@ $ignored_params['refresh'] = ''; else { var agentes_id = $("#id_agents2").val(); - var id_agentes = $.get("full_agents_id"); + var id_agentes = getQueryParam("full_agents_id"); if (agentes_id === null && id_agentes !== null) { id_agentes = id_agentes.split(";") id_agentes.forEach(function(element) { @@ -799,7 +799,7 @@ $ignored_params['refresh'] = ''; $("#module").append (option); }); - var id_modules = $.get("full_modules_selected"); + var id_modules = getQueryParam("full_modules_selected"); if(id_modules !== null) { id_modules = id_modules.split(";"); id_modules.forEach(function(element) { @@ -812,20 +812,18 @@ $ignored_params['refresh'] = ''; ); } - (function($) { - $.get = function(key) { - key = key.replace(/[[]/, '['); - key = key.replace(/[]]/, ']'); - var pattern = "[?&]" + key + "=([^&#]*)"; - var regex = new RegExp(pattern); - var url = unescape(window.location.href); - var results = regex.exec(url); - if (results === null) { - return null; - } else { - return results[1]; - } - } - })(jQuery); + function getQueryParam (key) { + key = key.replace(/[[]/, '['); + key = key.replace(/[]]/, ']'); + var pattern = "[?&]" + key + "=([^&#]*)"; + var regex = new RegExp(pattern); + var url = unescape(window.location.href); + var results = regex.exec(url); + if (results === null) { + return null; + } else { + return results[1]; + } + } \ No newline at end of file diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 7ddcdae14e..00eb4021d0 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1,3 +1,3 @@ -/godmode/servers/recorn_script.php +/godmode/servers/recon_script.php /godmode/servers/manage_recontask_form.php /godmode/servers/manage_recontask.php \ No newline at end of file diff --git a/pandora_console/extras/mr/26.sql b/pandora_console/extras/mr/26.sql index f9c904a0a3..591edd6499 100644 --- a/pandora_console/extras/mr/26.sql +++ b/pandora_console/extras/mr/26.sql @@ -1,8 +1,24 @@ START TRANSACTION; --- ---------------------------------------------------------------------- --- Add column in table `tagent_custom_fields` --- ---------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tnetwork_matrix` ( + `id` int(10) unsigned NOT NULL auto_increment, + `source` varchar(60) default '', + `destination` varchar(60) default '', + `utimestamp` bigint(20) default 0, + `bytes` int(18) unsigned default 0, + `pkts` int(18) unsigned default 0, + PRIMARY KEY (`id`), + UNIQUE (`source`, `destination`, `utimestamp`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +ALTER TABLE `treport_content` ADD COLUMN `show_extended_events` tinyint(1) default '0'; + +UPDATE `treport_content` SET type="netflow_summary" WHERE type="netflow_pie" OR type="netflow_statistics"; + +UPDATE `tnetflow_filter` SET aggregate="dstip" WHERE aggregate NOT IN ("dstip", "srcip", "dstport", "srcport"); + ALTER TABLE tagent_custom_fields ADD COLUMN `combo_values` VARCHAR(255) DEFAULT ''; +ALTER TABLE `trecon_task` ADD COLUMN `summary` text; + COMMIT; diff --git a/pandora_console/extras/mr/27.sql b/pandora_console/extras/mr/27.sql new file mode 100644 index 0000000000..f85064c9eb --- /dev/null +++ b/pandora_console/extras/mr/27.sql @@ -0,0 +1,6 @@ +START TRANSACTION; + +UPDATE tuser_task SET parameters = 'a:5:{i:0;a:6:{s:11:\"description\";s:28:\"Report pending to be created\";s:5:\"table\";s:7:\"treport\";s:8:\"field_id\";s:9:\"id_report\";s:10:\"field_name\";s:4:\"name\";s:4:\"type\";s:3:\"int\";s:9:\"acl_group\";s:8:\"id_group\";}i:1;a:2:{s:11:\"description\";s:46:\"Send to email addresses (separated by a comma)\";s:4:\"type\";s:4:\"text\";}i:2;a:2:{s:11:\"description\";s:7:\"Subject\";s:8:\"optional\";i:1;}i:3;a:3:{s:11:\"description\";s:7:\"Message\";s:4:\"type\";s:4:\"text\";s:8:\"optional\";i:1;}i:4;a:2:{s:11:\"description\";s:11:\"Report Type\";s:4:\"type\";s:11:\"report_type\";}}' where function_name = "cron_task_generate_report"; + + +COMMIT; \ No newline at end of file diff --git a/pandora_console/extras/pandora_diag.php b/pandora_console/extras/pandora_diag.php index d6cd017087..10e9fbfd42 100644 --- a/pandora_console/extras/pandora_diag.php +++ b/pandora_console/extras/pandora_diag.php @@ -139,7 +139,7 @@ function get_logs_size($file) function get_status_logs($path) { $status_server_log = ''; - $size_server_log = number_format(get_logs_size($path)); + $size_server_log = get_logs_size($path); if ($size_server_log <= 1048576) { $status_server_log = "Normal Status   You have less than 10 MB of logs"; } else { @@ -157,9 +157,9 @@ function percentage_modules_per_agent() $total_modules = db_get_value_sql('SELECT count(*) FROM tagente_modulo'); $average_modules_per_agent = ($total_modules / $total_agents); if ($average_modules_per_agent <= 40) { - $status_average_modules = "Normal Status   The average of modules per agent is less than 40 percent"; + $status_average_modules = "Normal Status   The average of modules per agent is less than 40"; } else { - $status_average_modules = "Warning Status  The average of modules per agent is more than 40 percent. You can have performance problems"; + $status_average_modules = "Warning Status  The average of modules per agent is more than 40. You can have performance problems"; } return $status_average_modules; @@ -202,9 +202,9 @@ function interval_average_of_network_modules() $average_time = ((int) $total_module_interval_time / $total_network_modules); if ($average_time < 180) { - $status_average_modules = "Warning Status   The system has a lot of load and a very fine configuration is required"; + $status_average_modules = "Warning Status   The system has a lot of load (average time $average_time) and a very fine configuration is required"; } else { - $status_average_modules = "Normal Status   The system has an acceptable charge"; + $status_average_modules = "Normal Status   The system has an acceptable charge (average time $average_time) "; } if ($average_time == 0) { @@ -274,6 +274,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { } $path_server_logs = '/log/pandora/pandora_server.log'; +$path_err_logs = '/log/pandora/pandora_server.error'; $path_console_logs = '/www/html/pandora_console/pandora_console.log'; $innodb_log_file_size_min_rec_value = '64M'; $innodb_log_buffer_size_min_rec_value = '16M'; @@ -710,6 +711,8 @@ render_info_data( render_row(number_format((get_logs_size($path_server_logs) / 1048576), 3).'M', 'Size server logs (current value)'); render_row(get_status_logs($path_server_logs), 'Status server logs'); + render_row(number_format((get_logs_size($path_err_logs) / 1048576), 3).'M', 'Size error logs (current value)'); + render_row(get_status_logs($path_err_logs), 'Status error logs'); render_row(number_format((get_logs_size($path_console_logs) / 1048576), 3).'M', 'Size console logs (current value)'); render_row(get_status_logs($path_console_logs), 'Status console logs'); diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index e7cedb62f5..323e7ee0d8 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -1199,13 +1199,13 @@ ALTER TABLE titem MODIFY `source_data` int(10) unsigned; INSERT INTO `tconfig` (`token`, `value`) VALUES ('big_operation_step_datos_purge', '100'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('small_operation_step_datos_purge', '1000'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('days_autodisable_deletion', '30'); -INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 26); +INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 27); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_docs_logo', 'default_docs.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_support_logo', 'default_support.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_logo_white_bg_preview', 'pandora_logo_head_white_bg.png'); UPDATE tconfig SET value = 'https://licensing.artica.es/pandoraupdate7/server.php' WHERE token='url_update_manager'; DELETE FROM `tconfig` WHERE `token` = 'current_package_enterprise'; -INSERT INTO `tconfig` (`token`, `value`) VALUES ('current_package_enterprise', '733'); +INSERT INTO `tconfig` (`token`, `value`) VALUES ('current_package_enterprise', '734'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('status_monitor_fields', 'policy,agent,data_type,module_name,server_type,interval,status,graph,warn,data,timestamp'); -- --------------------------------------------------------------------- @@ -1355,6 +1355,7 @@ ALTER TABLE tgraph ADD COLUMN `fullscale` tinyint(1) UNSIGNED NOT NULL default ' -- Table `tnetflow_filter` -- --------------------------------------------------------------------- ALTER TABLE tnetflow_filter ADD COLUMN `router_ip` TEXT NOT NULL DEFAULT ""; +UPDATE `tnetflow_filter` SET aggregate="dstip" WHERE aggregate NOT IN ("dstip", "srcip", "dstport", "srcport"); -- --------------------------------------------------------------------- -- Table `treport_custom_sql` @@ -1376,6 +1377,8 @@ ALTER TABLE treport_content ADD COLUMN `lapse` int(11) default '300'; ALTER TABLE treport_content ADD COLUMN `visual_format` tinyint(1) default '0'; ALTER TABLE treport_content ADD COLUMN `hide_no_data` tinyint(1) default '0'; ALTER TABLE treport_content ADD COLUMN `recursion` tinyint(1) default NULL; +ALTER TABLE treport_content ADD COLUMN `show_extended_events` tinyint(1) default '0'; +UPDATE `treport_content` SET type="netflow_summary" WHERE type="netflow_pie" OR type="netflow_statistics"; -- --------------------------------------------------------------------- -- Table `tmodule_relationship` @@ -1410,6 +1413,7 @@ ALTER TABLE trecon_task ADD `vlan_enabled` int(2) unsigned default '0'; ALTER TABLE trecon_task ADD `wmi_enabled` tinyint(1) unsigned DEFAULT '0'; ALTER TABLE trecon_task ADD `auth_strings` text; ALTER TABLE trecon_task ADD `autoconfiguration_enabled` tinyint(1) unsigned default '0'; +ALTER TABLE trecon_task ADD `summary` text; -- --------------------------------------------------------------------- -- Table `twidget` AND Table `twidget_dashboard` @@ -1912,6 +1916,20 @@ CREATE TABLE `tgis_map_layer_groups` ( CONSTRAINT `tgis_map_layer_groups_ibfk_3` FOREIGN KEY (`agent_id`) REFERENCES `tagente` (`id_agente`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- ----------------------------------------------------- +-- Table `tnetwork_matrix` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tnetwork_matrix` ( + `id` int(10) unsigned NOT NULL auto_increment, + `source` varchar(60) default '', + `destination` varchar(60) default '', + `utimestamp` bigint(20) default 0, + `bytes` int(18) unsigned default 0, + `pkts` int(18) unsigned default 0, + PRIMARY KEY (`id`), + UNIQUE (`source`, `destination`, `utimestamp`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + -- ----------------------------------------------------- -- Table `tnotification_source` -- ----------------------------------------------------- @@ -2040,3 +2058,8 @@ INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Di -- Add column in table `tagent_custom_fields` -- ---------------------------------------------------------------------- ALTER TABLE tagent_custom_fields ADD COLUMN `combo_values` VARCHAR(255) DEFAULT ''; + +-- ---------------------------------------------------------------------- +-- Update table `tuser_task` +-- ---------------------------------------------------------------------- +UPDATE tuser_task set parameters = 'a:5:{i:0;a:6:{s:11:\"description\";s:28:\"Report pending to be created\";s:5:\"table\";s:7:\"treport\";s:8:\"field_id\";s:9:\"id_report\";s:10:\"field_name\";s:4:\"name\";s:4:\"type\";s:3:\"int\";s:9:\"acl_group\";s:8:\"id_group\";}i:1;a:2:{s:11:\"description\";s:46:\"Send to email addresses (separated by a comma)\";s:4:\"type\";s:4:\"text\";}i:2;a:2:{s:11:\"description\";s:7:\"Subject\";s:8:\"optional\";i:1;}i:3;a:3:{s:11:\"description\";s:7:\"Message\";s:4:\"type\";s:4:\"text\";s:8:\"optional\";i:1;}i:4;a:2:{s:11:\"description\";s:11:\"Report Type\";s:4:\"type\";s:11:\"report_type\";}}' where function_name = "cron_task_generate_report"; diff --git a/pandora_console/general/firts_task/collections.php b/pandora_console/general/firts_task/collections.php index 269de3ba12..8e27ce6ee3 100755 --- a/pandora_console/general/firts_task/collections.php +++ b/pandora_console/general/firts_task/collections.php @@ -22,7 +22,7 @@ ui_require_css_file('firts_task'); __('Collections')]); ?>
-

+

true, 'message' => __('There are no custom __('Custom Fields')]); ?>

-

+

true, 'message' => __('There are no custom __('Custom Graphs')]); ?>

-

+

__('Fields Manager')]); ?>

-

+

__('Incidents')]); ?>

-

+

__('Visual Console')]); ?>

-

+

__('Network Map')]); ?>

-

+

__('Planned Downtime')]); ?>

-

+

__('Discovery server')]); ?>

-

+

__('Services')]); ?>

-

+

__('SNMP Filter')]); ?>

-

+

__('Tags')]); ?>

-

+

__('Transactions')]); ?>

-

+

'; -echo ''.__('Page generated at').' '.date($config['date_format']); -echo '
® '.get_copyright_notice().''; if (isset($config['debug'])) { $cache_info = []; diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 7addef057f..d3bf94ddc1 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -18,10 +18,14 @@ require_once 'include/functions_notifications.php'; // Global errors/warnings checking. config_check(); -?> -

-
+if ($config['menu_type'] == 'classic') { + echo '
'; +} else { + echo '
'; +} +?> +
'; - // Search + // Search. $acl_head_search = true; if ($config['acl_enterprise'] == 1 && !users_is_admin()) { $acl_head_search = db_get_sql( @@ -94,7 +98,7 @@ require_once 'include/functions_notifications.php'; } if ($acl_head_search) { - // Search bar + // Search bar. $search_bar = '
'; if (!isset($config['search_keywords'])) { $search_bar .= ''; @@ -116,15 +120,13 @@ require_once 'include/functions_notifications.php'; } $search_bar .= 'onfocus="javascript: if (fieldKeyWordEmpty) $(\'#keywords\').val(\'\');" - onkeyup="javascript: fieldKeyWordEmpty = false;" - style="margin-top:5px;" class="search_input" />'; + onkeyup="javascript: fieldKeyWordEmpty = false;" class="search_input" />'; // $search_bar .= 'onClick="javascript: document.quicksearch.submit()"'; $search_bar .= ""; $search_bar .= '
'; - $header_searchbar = ''; + $header_searchbar = ''; } @@ -145,10 +147,19 @@ require_once 'include/functions_notifications.php'; $_GET['refr'] = null; } - $select = db_process_sql("SELECT autorefresh_white_list,time_autorefresh FROM tusuario WHERE id_user = '".$config['id_user']."'"); - $autorefresh_list = json_decode($select[0]['autorefresh_white_list']); + $select = db_process_sql( + "SELECT autorefresh_white_list,time_autorefresh + FROM tusuario + WHERE id_user = '".$config['id_user']."'" + ); - if ($autorefresh_list !== null && array_search($_GET['sec2'], $autorefresh_list) !== false) { + $autorefresh_list = json_decode( + $select[0]['autorefresh_white_list'] + ); + + if ($autorefresh_list !== null + && array_search($_GET['sec2'], $autorefresh_list) !== false + ) { $do_refresh = true; if ($_GET['sec2'] == 'operation/agentes/pandora_networkmap') { if ((!isset($_GET['tab'])) || ($_GET['tab'] != 'view')) { @@ -157,22 +168,57 @@ require_once 'include/functions_notifications.php'; } if ($do_refresh) { - $autorefresh_img = html_print_image('images/header_refresh_gray.png', true, ['class' => 'bot', 'alt' => 'lightning', 'title' => __('Configure autorefresh')]); + $autorefresh_img = html_print_image( + 'images/header_refresh_gray.png', + true, + [ + 'class' => 'bot', + 'alt' => 'lightning', + 'title' => __('Configure autorefresh'), + ] + ); - if ($_GET['refr']) { - $autorefresh_txt .= ' ('.date('i:s', $config['refr']).')'; + if ((isset($select[0]['time_autorefresh']) === true) + && $select[0]['time_autorefresh'] !== 0 + && $config['refr'] === null + ) { + $config['refr'] = $select[0]['time_autorefresh']; + $autorefresh_txt .= ' ('; + $autorefresh_txt .= date( + 'i:s', + $config['refr'] + ); + $autorefresh_txt .= ')'; + } else if ($_GET['refr']) { + $autorefresh_txt .= ' ('; + $autorefresh_txt .= date('i:s', $config['refr']); + $autorefresh_txt .= ')'; } $ignored_params['refr'] = ''; $values = get_refresh_time_array(); + $autorefresh_additional = ''; unset($values); $autorefresh_link_open_img = ''; - if ($_GET['refr']) { + if ($_GET['refr'] + || ((isset($select[0]['time_autorefresh']) === true) + && $select[0]['time_autorefresh'] !== 0) + ) { $autorefresh_link_open_txt = ''; } else { $autorefresh_link_open_txt = ''; @@ -192,7 +238,15 @@ require_once 'include/functions_notifications.php'; $display_counter = 'display:none'; } } else { - $autorefresh_img = html_print_image('images/header_refresh_disabled_gray.png', true, ['class' => 'bot autorefresh_disabled', 'alt' => 'lightning', 'title' => __('Disabled autorefresh')]); + $autorefresh_img = html_print_image( + 'images/header_refresh_disabled_gray.png', + true, + [ + 'class' => 'bot autorefresh_disabled', + 'alt' => 'lightning', + 'title' => __('Disabled autorefresh'), + ] + ); $ignored_params['refr'] = false; @@ -203,56 +257,80 @@ require_once 'include/functions_notifications.php'; $display_counter = 'display:none'; } - $header_autorefresh = '
'.$autorefresh_link_open_img.$autorefresh_img.$autorefresh_link_close.'
'; - $header_autorefresh_counter = '
'.$autorefresh_link_open_txt.$autorefresh_txt.$autorefresh_link_close.$autorefresh_additional.'
'; + $header_autorefresh = '
'; + $header_autorefresh .= $autorefresh_link_open_img; + $header_autorefresh .= $autorefresh_img; + $header_autorefresh .= $autorefresh_link_close; + $header_autorefresh .= '
'; + + $header_autorefresh_counter = '
'; + $header_autorefresh_counter .= $autorefresh_link_open_txt; + $header_autorefresh_counter .= $autorefresh_txt; + $header_autorefresh_counter .= $autorefresh_link_close; + $header_autorefresh_counter .= $autorefresh_additional; + $header_autorefresh_counter .= '
'; - // Qr. - if ($config['show_qr_code_header'] == 0) { - $show_qr_code_header = 'display: none;'; + // Support. + if (defined('PANDORA_ENTERPRISE')) { + $header_support_link = 'https://support.artica.es/'; } else { - $show_qr_code_header = 'display: inline;'; + $header_support_link = 'https://pandorafms.com/forums/'; } - $header_qr = '
'; + $header_support = ''; + + // Documentation. + $header_docu = ''; + - echo "'; - ?> - - __('Edit my user'), 'class' => 'bot', 'alt' => 'user']); + $header_user = html_print_image( + 'images/header_user_admin_green.png', + true, + [ + 'title' => __('Edit my user'), + 'class' => 'bot', + 'alt' => 'user', + ] + ); } else { - $header_user = html_print_image('images/header_user_green.png', true, ['title' => __('Edit my user'), 'class' => 'bot', 'alt' => 'user']); + $header_user = html_print_image( + 'images/header_user_green.png', + true, + [ + 'title' => __('Edit my user'), + 'class' => 'bot', + 'alt' => 'user', + ] + ); } $header_user = ''; // Logout. $header_logout = ''; - echo '
'.$header_autorefresh, $header_autorefresh_counter, $header_qr, $header_chat.'
-
'.$header_searchbar, $header_discovery, $servers_list.'
-
'.$header_user, $header_logout.'
'; + echo '
'.$config['custom_title_header'].''.$config['custom_subtitle_header'].'
+
'.$header_searchbar.'
+
'.$header_chat, $header_autorefresh, $header_autorefresh_counter, $header_discovery, $servers_list, $header_support, $header_docu, $header_user, $header_logout.'
'; ?>
@@ -490,7 +568,12 @@ require_once 'include/functions_notifications.php'; ); - $("a.autorefresh_txt").toggle (); - $("#combo_refr").toggle (); - href = $("a.autorefresh").attr ("href"); - - var refresh = ''; - $(document).attr ("location", href + refresh); - - - if (fixed_header) { $('div#head').addClass('fixed_header'); - $('div#page') - .css('padding-top', $('div#head').innerHeight() + 'px') - .css('position', 'relative'); + $('div#main').css('padding-top', $('div#head').innerHeight() + 'px'); } check_new_chats_icon('icon_new_messages_chat'); @@ -547,14 +611,14 @@ require_once 'include/functions_notifications.php'; blinkpubli(); $("#header_autorefresh").css('padding-right', '5px'); var refr_time = ; var t = new Date(); - t.setTime (t.getTime () + - parseInt()); - $("#refrcounter").countdown ({until: t, + t.setTime (t.getTime () + parseInt()); + $("#refrcounter").countdown ({ + until: t, layout: '%M%nn%M:%S%nn%S', labels: ['', '', '', '', '', '', ''], onExpiry: function () { diff --git a/pandora_console/general/login_page.php b/pandora_console/general/login_page.php index ea73318e2a..d8e28223c6 100755 --- a/pandora_console/general/login_page.php +++ b/pandora_console/general/login_page.php @@ -305,12 +305,12 @@ if (file_exists(ENTERPRISE_DIR.'/load_enterprise.php')) { echo ''; diff --git a/pandora_console/general/logon_ok.php b/pandora_console/general/logon_ok.php index 21c9713a48..a267e36b4d 100644 --- a/pandora_console/general/logon_ok.php +++ b/pandora_console/general/logon_ok.php @@ -1,26 +1,39 @@ @@ -88,7 +113,7 @@ if (!empty($all_data)) { class = 'databox'; @@ -101,12 +126,12 @@ if (!empty($all_data)) { $table->head[0] = ''.__('%s Overview', get_product_name()).''; $table->head_colspan[0] = 4; - // Indicators + // Indicators. $tdata = []; $stats = reporting_get_stats_indicators($data, 120, 10, false); $status = '
'; foreach ($stats as $stat) { - $status .= ''; + $status .= ''; } $status .= '
'.$stat['title'].''.''.$stat['graph'].'
'.$stat['title'].''.$stat['graph'].'
'; @@ -115,25 +140,25 @@ if (!empty($all_data)) { $table->data[] = $tdata; - // Alerts + // Alerts. $tdata = []; $tdata[0] = reporting_get_stats_alerts($data); $table->rowclass[] = ''; $table->data[] = $tdata; - // Modules by status + // Modules by status. $tdata = []; $tdata[0] = reporting_get_stats_modules_status($data, 180, 100); $table->rowclass[] = ''; $table->data[] = $tdata; - // Total agents and modules + // Total agents and modules. $tdata = []; $tdata[0] = reporting_get_stats_agents_monitors($data); $table->rowclass[] = ''; $table->data[] = $tdata; - // Users + // Users. if (users_is_admin()) { $tdata = []; $tdata[0] = reporting_get_stats_users($data); @@ -160,7 +185,7 @@ if (!empty($all_data)) { if (!empty($news)) { - // NEWS BOARD///////////////////////////// + // NEWS BOARD. echo '
'; echo ''; @@ -184,20 +209,72 @@ if (!empty($all_data)) { echo '
'; echo '
'; - // News board + // News board. echo '

'; - // END OF NEWS BOARD///////////////////////////// + // END OF NEWS BOARD. } - // LAST ACTIVITY///////////////////////////// - // Show last activity from this user + $nots = messages_get_overview('utimestamp', 'DESC', false); + if (!empty($nots)) { + // Notifications board. + echo '
'; + + echo ''; + echo ''; + if ($config['prominent_time'] == 'timestamp') { + $comparation_suffix = ''; + } else { + $comparation_suffix = __('ago'); + } + + foreach ($nots as $msg) { + $conversation = io_safe_output( + messages_get_conversation($msg) + ); + + if (is_array($conversation)) { + $text = array_pop($conversation)['message']; + } else { + // Skip empty message. + continue; + } + + $url = ui_get_full_url( + 'index.php?sec=message_list&sec2=operation/messages/message_edit&read_message=1&id_message='.$msg['id_mensaje'] + ); + if ($msg['url'] != '') { + $url = $msg['url']; + } + + echo ''; + echo ''; + echo ''; + } + + echo '
'.__('Pending notifications').'
'.$msg['subject'].'
'; + if ($msg['id_usuario_origen'] != '') { + echo ''.get_user_fullname($msg['id_usuario_origen']).' '; + } + + echo ''.ui_print_timestamp($msg['timestamp'], true).' '.$comparation_suffix.'
'; + echo nl2br($text); + echo '
'; + echo '
'; + + echo '

'; + + // EO Notifications board. + } + + // LAST ACTIVITY. + // Show last activity from this user. echo '
'; $table = new stdClass(); $table->class = 'databox data'; $table->width = '100%'; - // Don't specify px + // Don't specify px. $table->data = []; $table->size = []; $table->size[0] = '5%'; @@ -212,38 +289,14 @@ if (!empty($all_data)) { $table->head[3] = __('Source IP'); $table->head[4] = __('Comments'); $table->title = ''.__('This is your last activity performed on the %s console', get_product_name()).''; - - switch ($config['dbtype']) { - case 'mysql': - $sql = sprintf( - 'SELECT id_usuario,accion, ip_origen,descripcion,utimestamp + $sql = sprintf( + 'SELECT id_usuario,accion, ip_origen,descripcion,utimestamp FROM tsesion WHERE (`utimestamp` > UNIX_TIMESTAMP(NOW()) - '.SECONDS_1WEEK.") AND `id_usuario` = '%s' ORDER BY `utimestamp` DESC LIMIT 10", - $config['id_user'] - ); - break; + $config['id_user'] + ); - case 'postgresql': - $sql = sprintf( - "SELECT \"id_usuario\", accion, \"ip_origen\", descripcion, utimestamp - FROM tsesion - WHERE (\"utimestamp\" > ceil(date_part('epoch', CURRENT_TIMESTAMP)) - ".SECONDS_1WEEK.") - AND \"id_usuario\" = '%s' ORDER BY \"utimestamp\" DESC LIMIT 10", - $config['id_user'] - ); - break; - - case 'oracle': - $sql = sprintf( - "SELECT id_usuario, accion, ip_origen, descripcion, utimestamp - FROM tsesion - WHERE ((utimestamp > ceil((sysdate - to_date('19700101000000','YYYYMMDDHH24MISS')) * (".SECONDS_1DAY.')) - '.SECONDS_1WEEK.") - AND id_usuario = '%s') AND rownum <= 10 ORDER BY utimestamp DESC", - $config['id_user'] - ); - break; - } $sessions = db_get_all_rows_sql($sql); @@ -253,24 +306,17 @@ if (!empty($all_data)) { foreach ($sessions as $session) { $data = []; + $session_id_usuario = $session['id_usuario']; + $session_ip_origen = $session['ip_origen']; - switch ($config['dbtype']) { - case 'mysql': - case 'oracle': - $session_id_usuario = $session['id_usuario']; - $session_ip_origen = $session['ip_origen']; - break; - - case 'postgresql': - $session_id_usuario = $session['id_usuario']; - $session_ip_origen = $session['ip_origen']; - break; - } $data[0] = ''.$session_id_usuario.''; $data[1] = ui_print_session_action_icon($session['accion'], true).' '.$session['accion']; - $data[2] = ui_print_help_tip(date($config['date_format'], $session['utimestamp']), true).human_time_comparation($session['utimestamp'], 'tiny'); + $data[2] = ui_print_help_tip( + date($config['date_format'], $session['utimestamp']), + true + ).human_time_comparation($session['utimestamp'], 'tiny'); $data[3] = $session_ip_origen; $description = str_replace([',', ', '], ', ', $session['descripcion']); if (strlen($description) > 100) { @@ -287,8 +333,7 @@ if (!empty($all_data)) { unset($table); echo '
'; echo '
'; - // activity - // END OF LAST ACTIVIYY///////////////////////////// + // END OF LAST ACTIVIYY. ?> diff --git a/pandora_console/general/main_menu.php b/pandora_console/general/main_menu.php index cb5126b621..877f171090 100644 --- a/pandora_console/general/main_menu.php +++ b/pandora_console/general/main_menu.php @@ -20,31 +20,13 @@ if (! isset($config['id_user'])) { diff --git a/pandora_console/godmode/servers/recon_script.php b/pandora_console/godmode/servers/recon_script.php index b24c2a59e2..a77f465395 100644 --- a/pandora_console/godmode/servers/recon_script.php +++ b/pandora_console/godmode/servers/recon_script.php @@ -1,401 +1,27 @@ $id_reconscript] - ); - - echo htmlentities(io_safe_output($description), ENT_QUOTES, 'UTF-8', true); - return; -} - -// Load global vars -global $config; - -check_login(); - -if (! check_acl($config['id_user'], 0, 'LM')) { - db_pandora_audit( - 'ACL Violation', - 'Trying to access recon script Management' - ); - include 'general/noaccess.php'; - return; -} - -/* - * Disabled at the moment. - if (!check_referer()) { - require ("general/noaccess.php"); - - return; - } +/** + * Deprectated. + * + * @category Deprectated + * @package Pandora FMS + * @subpackage recon script + * @version 1.0.0 + * @license See below + * + * ______ ___ _______ _______ ________ + * | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __| + * | __/| _ | | _ || _ | _| _ | | ___| |__ | + * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| + * + * ============================================================================ + * 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 for 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. + * ============================================================================ */ - -$view = get_parameter('view', ''); -$create = get_parameter('create', ''); - -if ($view != '') { - $form_id = $view; - $reconscript = db_get_row('trecon_script', 'id_recon_script', $form_id); - $form_name = $reconscript['name']; - $form_description = $reconscript['description']; - $form_script = $reconscript['script']; - $macros = $reconscript['macros']; -} - -if ($create != '') { - $form_name = ''; - $form_description = ''; - $form_script = ''; - $macros = ''; -} - -// SHOW THE FORM -// ================================================================= -if (($create != '') or ($view != '')) { - if ($create != '') { - ui_print_page_header(__('Recon script creation'), 'images/gm_servers.png', false, 'reconscript_definition', true); - } else { - ui_print_page_header(__('Recon script update'), 'images/gm_servers.png', false, 'reconscript_definition', true); - $id_recon_script = get_parameter('view', ''); - } - - - if ($create == '') { - echo "
"; - } else { - echo ""; - } - - $table = new stdClass(); - $table->width = '100%'; - $table->id = 'table-form'; - $table->class = 'databox filters'; - $table->style = []; - $table->style[0] = 'font-weight: bold'; - $table->style[2] = 'font-weight: bold'; - $table->data = []; - - $data = []; - $data[0] = __('Name'); - $data[1] = ''; - $table->data['recon_name'] = $data; - $table->colspan['recon_name'][1] = 3; - - $data = []; - $data[0] = __('Script fullpath'); - $data[1] = ''; - $table->data['recon_fullpath'] = $data; - $table->colspan['recon_fullpath'][1] = 3; - - $data = []; - $data[0] = __('Description'); - $data[1] = ''; - $table->data['recon_description'] = $data; - $table->colspan['recon_description'][1] = 3; - - $macros = json_decode($macros, true); - - // This code is ready to add locked feature as plugins - $locked = false; - - // The next row number is recon_3 - $next_name_number = 3; - $i = 1; - while (1) { - // Always print at least one macro - if ((!isset($macros[$i]) || $macros[$i]['desc'] == '') && $i > 1) { - break; - } - - $macro_desc_name = 'field'.$i.'_desc'; - $macro_desc_value = ''; - $macro_help_name = 'field'.$i.'_help'; - $macro_help_value = ''; - $macro_value_name = 'field'.$i.'_value'; - $macro_value_value = ''; - $macro_name_name = 'field'.$i.'_macro'; - $macro_name = '_field'.$i.'_'; - $macro_hide_value_name = 'field'.$i.'_hide'; - $macro_hide_value_value = 0; - - if (isset($macros[$i]['desc'])) { - $macro_desc_value = $macros[$i]['desc']; - } - - if (isset($macros[$i]['help'])) { - $macro_help_value = $macros[$i]['help']; - } - - if (isset($macros[$i]['value'])) { - $macro_value_value = $macros[$i]['value']; - } - - if (isset($macros[$i]['hide'])) { - $macro_hide_value_value = $macros[$i]['hide']; - } - - $datam = []; - $datam[0] = __('Description')." ($macro_name)"; - $datam[0] .= html_print_input_hidden($macro_name_name, $macro_name, true); - $datam[1] = html_print_input_text_extended($macro_desc_name, $macro_desc_value, 'text-'.$macro_desc_name, '', 30, 255, $locked, '', "class='command_advanced_conf'", true); - if ($locked) { - $datam[1] .= html_print_image('images/lock.png', true, ['class' => 'command_advanced_conf']); - } - - $datam[2] = __('Default value')." ($macro_name)"; - $datam[3] = html_print_input_text_extended($macro_value_name, $macro_value_value, 'text-'.$macro_value_name, '', 30, 255, $locked, '', "class='command_component command_advanced_conf'", true); - if ($locked) { - $datam[3] .= html_print_image('images/lock.png', true, ['class' => 'command_advanced_conf']); - } - - $table->data['recon_'.$next_name_number] = $datam; - - $next_name_number++; - - $table->colspan['recon_'.$next_name_number][1] = 3; - - $datam = []; - $datam[0] = __('Hide value').ui_print_help_tip(__('This field will show up as dots like a password'), true); - $datam[1] = html_print_checkbox_extended($macro_hide_value_name, 1, $macro_hide_value_value, 0, '', ['class' => 'command_advanced_conf'], true, 'checkbox-'.$macro_hide_value_name); - - $table->data['recon_'.$next_name_number] = $datam; - $next_name_number++; - - $table->colspan['recon_'.$next_name_number][1] = 3; - - $datam = []; - $datam[0] = __('Help')." ($macro_name)


"; - $tadisabled = $locked === true ? ' disabled' : ''; - $datam[1] = html_print_textarea($macro_help_name, 6, 100, $macro_help_value, 'class="command_advanced_conf" style="width: 97%;"'.$tadisabled, true); - - if ($locked) { - $datam[1] .= html_print_image('images/lock.png', true, ['class' => 'command_advanced_conf']); - } - - $datam[1] .= '


'; - - $table->data['recon_'.$next_name_number] = $datam; - $next_name_number++; - $i++; - } - - if (!$locked) { - $datam = []; - $datam[0] = ''.__('Add macro').' '.html_print_image('images/add.png', true).''; - $datam[0] .= ''; - $datam[0] .= ''; - $delete_macro_style = ''; - if ($i <= 2) { - $delete_macro_style = 'display:none;'; - } - - $datam[2] = ''; - - $table->colspan['recon_action'][0] = 2; - $table->rowstyle['recon_action'] = 'text-align:center'; - $table->colspan['recon_action'][2] = 2; - $table->data['recon_action'] = $datam; - } - - html_print_table($table); - - echo ''; - echo '
'; - - if ($create != '') { - echo ""; - } else { - echo ""; - } - - echo '
'; -} else { - ui_print_page_header(__('Recon scripts registered on %s', get_product_name()), 'images/gm_servers.png', false, '', true); - - // Update reconscript - if (isset($_GET['update_reconscript'])) { - // if modified any parameter - $id_recon_script = get_parameter('update_reconscript', 0); - $reconscript_name = get_parameter('form_name', ''); - $reconscript_description = get_parameter('form_description', ''); - $reconscript_script = get_parameter('form_script', ''); - - // Get macros - $i = 1; - $macros = []; - while (1) { - $macro = (string) get_parameter('field'.$i.'_macro'); - if ($macro == '') { - break; - } - - $desc = (string) get_parameter('field'.$i.'_desc'); - $help = (string) get_parameter('field'.$i.'_help'); - $value = (string) get_parameter('field'.$i.'_value'); - $hide = get_parameter('field'.$i.'_hide'); - - $macros[$i]['macro'] = $macro; - $macros[$i]['desc'] = $desc; - $macros[$i]['help'] = $help; - $macros[$i]['value'] = $value; - $macros[$i]['hide'] = $hide; - $i++; - } - - $macros = io_json_mb_encode($macros); - - $sql_update = "UPDATE trecon_script SET - name = '$reconscript_name', - description = '$reconscript_description', - script = '$reconscript_script', - macros = '$macros' - WHERE id_recon_script = $id_recon_script"; - $result = false; - if ($reconscript_name != '' && $reconscript_script != '') { - $result = db_process_sql($sql_update); - } - - if (! $result) { - ui_print_error_message(__('Problem updating')); - } else { - ui_print_success_message(__('Updated successfully')); - } - } - - // Create reconscript - if (isset($_GET['create_reconscript'])) { - $reconscript_name = get_parameter('form_name', ''); - $reconscript_description = get_parameter('form_description', ''); - $reconscript_script = get_parameter('form_script', ''); - - // Get macros - $i = 1; - $macros = []; - while (1) { - $macro = (string) get_parameter('field'.$i.'_macro'); - if ($macro == '') { - break; - } - - $desc = (string) get_parameter('field'.$i.'_desc'); - $help = (string) get_parameter('field'.$i.'_help'); - $value = (string) get_parameter('field'.$i.'_value'); - $hide = get_parameter('field'.$i.'_hide'); - - $macros[$i]['macro'] = $macro; - $macros[$i]['desc'] = $desc; - $macros[$i]['help'] = $help; - $macros[$i]['value'] = $value; - $macros[$i]['hide'] = $hide; - $i++; - } - - $macros = io_json_mb_encode($macros); - - $values = [ - 'name' => $reconscript_name, - 'description' => $reconscript_description, - 'script' => $reconscript_script, - 'macros' => $macros, - ]; - $result = false; - if ($values['name'] != '' && $values['script'] != '') { - $result = db_process_sql_insert('trecon_script', $values); - } - - if (! $result) { - ui_print_error_message(__('Problem creating')); - } else { - ui_print_success_message(__('Created successfully')); - } - } - - if (isset($_GET['kill_reconscript'])) { - // if delete alert - $reconscript_id = get_parameter('kill_reconscript', 0); - - $result = db_process_sql_delete( - 'trecon_script', - ['id_recon_script' => $reconscript_id] - ); - - if (! $result) { - ui_print_error_message(__('Problem deleting reconscript')); - } else { - ui_print_success_message(__('reconscript deleted successfully')); - } - - if ($reconscript_id != 0) { - $result = db_process_sql_delete( - 'trecon_task', - ['id_recon_script' => $reconscript_id] - ); - } - } - - // If not edition or insert, then list available reconscripts - $rows = db_get_all_rows_in_table('trecon_script'); - - if ($rows !== false) { - echo ''; - echo ''; - echo ''; - echo ''; - $color = 0; - foreach ($rows as $row) { - if ($color == 1) { - $tdcolor = 'datos'; - $color = 0; - } else { - $tdcolor = 'datos2'; - $color = 1; - } - - echo ''; - echo "'; - echo "'; - } - - echo '
'.__('Name').''.__('Description').''.__('Delete').'
"; - echo ""; - echo $row['name']; - echo '"; - $desc = io_safe_output($row['description']); - $desc = str_replace("\n", '
', $desc); - echo $desc.'

'; - echo ''.__('Command').': '.$row['script'].''; - echo "
"; - echo "".html_print_image('images/cross.png', true, ['border' => '0']).''; - echo '
'; - } else { - ui_print_info_message(['no_close' => true, 'message' => __('There are no recon scripts in the system') ]); - } - - echo ''; - echo '
'; - echo "
"; - echo ""; - echo '
'; -} - -ui_require_javascript_file('pandora_modules'); diff --git a/pandora_console/godmode/setup/performance.php b/pandora_console/godmode/setup/performance.php index 666dd0b21c..4d4281eec5 100644 --- a/pandora_console/godmode/setup/performance.php +++ b/pandora_console/godmode/setup/performance.php @@ -536,6 +536,19 @@ $table->data[] = [ ), ]; + +$table->data[] = [ + __('Max. days before delete old network matrix data'), + html_print_input_text( + 'delete_old_network_matrix', + $config['delete_old_network_matrix'], + '', + 5, + 5, + true + ), +]; + $table_other = new stdClass(); $table_other->width = '100%'; $table_other->class = 'databox filters'; diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 370df5d808..4f2679fcf9 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -131,6 +131,14 @@ if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { $table->data[19][1] = html_print_checkbox_switch_extended('activate_netflow', 1, $config['activate_netflow'], $rbt_disabled, '', '', true); +$table->data[21][0] = __('Enable Network Traffic Analyzer'); +$table->data[21][1] = html_print_switch( + [ + 'name' => 'activate_nta', + 'value' => $config['activate_nta'], + ] +); + $zone_name = [ 'Africa' => __('Africa'), diff --git a/pandora_console/godmode/setup/setup_visuals.php b/pandora_console/godmode/setup/setup_visuals.php index a1ffc9008a..283afc5565 100755 --- a/pandora_console/godmode/setup/setup_visuals.php +++ b/pandora_console/godmode/setup/setup_visuals.php @@ -243,7 +243,7 @@ function logo_custom_enterprise($name, $logo) false, true, '', - $open, + false, 'width:240px' ); return $select; @@ -259,7 +259,7 @@ function logo_custom_enterprise($name, $logo) false, true, '', - $open, + true, 'width:240px' ); return $select; @@ -462,6 +462,20 @@ if (enterprise_installed()) { $row++; } +// Title Header +if (enterprise_installed()) { + $table_styles->data[$row][0] = __('Title (header)'); + $table_styles->data[$row][1] = html_print_input_text('custom_title_header', $config['custom_title_header'], '', 50, 40, true); + $row++; +} + +// Subtitle Header +if (enterprise_installed()) { + $table_styles->data[$row][0] = __('Subtitle (header)'); + $table_styles->data[$row][1] = html_print_input_text('custom_subtitle_header', $config['custom_subtitle_header'], '', 50, 40, true); + $row++; +} + // login title1 if (enterprise_installed()) { $table_styles->data[$row][0] = __('Title 1 (login)'); diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 9796646fce..610353ebb7 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -30,7 +30,10 @@ require_once __DIR__.'/Wizard.main.php'; require_once $config['homedir'].'/include/functions_users.php'; require_once $config['homedir'].'/include/functions_reports.php'; require_once $config['homedir'].'/include/functions_cron.php'; -enterprise_include('include/functions_tasklist.php'); +enterprise_include_once('include/functions_tasklist.php'); +enterprise_include_once('include/functions_cron.php'); + +ui_require_css_file('task_list'); /** * Defined as wizard to guide user to explore running tasks. @@ -93,7 +96,8 @@ class DiscoveryTaskList extends Wizard ] ); - $this->printHeader(); + // Header + ui_print_page_header(__('Task list'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); // Show redirected messages from discovery.php. if ($status === 0) { @@ -237,7 +241,7 @@ class DiscoveryTaskList extends Wizard $id_console_task = (int) get_parameter('id_console_task'); if ($id_console_task !== null) { - enterprise_include('cron_task_run', $id_console_task, true); + enterprise_hook('cron_task_run', [$id_console_task, true]); // Trick to avoid double execution. header('Location: '.$this->url); } @@ -345,6 +349,8 @@ class DiscoveryTaskList extends Wizard $recon_tasks = []; } + $url_ajax = $config['homeurl'].'ajax.php'; + $table = new StdClass(); $table->cellpadding = 4; $table->cellspacing = 4; @@ -424,7 +430,16 @@ class DiscoveryTaskList extends Wizard $data[0] = ''; } - $data[1] = ''.$task['name'].''; + // Name task. + $data[1] = ''; + if ($task['disabled'] != 2) { + $data[1] .= ''; + } + + $data[1] .= ''.$task['name'].''; + if ($task['disabled'] != 2) { + $data[1] .= ''; + } $data[2] = $server_name; @@ -488,6 +503,24 @@ class DiscoveryTaskList extends Wizard $data[8] = __('Not executed yet'); } + if ($task['disabled'] != 2) { + $data[9] = ''; + $data[9] .= html_print_image( + 'images/eye.png', + true + ); + $data[9] .= ''; + } + + if ($task['disabled'] != 2 && $task['utimestamp'] > 0) { + $data[9] .= ''; + $data[9] .= html_print_image( + 'images/dynamic_network_icon.png', + true + ); + $data[9] .= ''; + } + if (check_acl( $config['id_user'], $task['id_group'], @@ -495,7 +528,7 @@ class DiscoveryTaskList extends Wizard ) ) { if ($ipam === true) { - $data[9] = ''; } else { // Check if is a H&D, Cloud or Application or IPAM. - $data[9] = 'getTargetWiz($task), @@ -533,6 +566,9 @@ class DiscoveryTaskList extends Wizard $data[9] = ''; } + // Div neccesary for modal progress task. + echo ''; + array_push($table->data, $data); } @@ -544,7 +580,12 @@ class DiscoveryTaskList extends Wizard html_print_table($table); } - unset($table); + // Div neccesary for modal map task. + echo ''; + + unset($table); + + ui_require_javascript_file('pandora_taskList'); } return true; @@ -583,7 +624,12 @@ class DiscoveryTaskList extends Wizard return 'wiz=ctask'; default: - return 'wiz=hd&mode=netscan'; + if ($task['id_recon_script'] === null) { + return 'wiz=hd&mode=netscan'; + } else { + return 'wiz=hd&mode=customnetscan'; + } + break; } } diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php index f405641fde..e4e0e97fdc 100755 --- a/pandora_console/godmode/wizards/HostDevices.class.php +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -28,7 +28,10 @@ require_once __DIR__.'/Wizard.main.php'; require_once $config['homedir'].'/include/functions_users.php'; -enterprise_include('include/class/CSVImportAgents.class.php'); +require_once $config['homedir'].'/include/class/CustomNetScan.class.php'; +require_once $config['homedir'].'/include/class/ManageNetScanScripts.class.php'; + +enterprise_include_once('include/class/CSVImportAgents.class.php'); enterprise_include_once('include/functions_hostdevices.php'); /** @@ -117,6 +120,7 @@ class HostDevices extends Wizard 'icon' => 'images/wizard/netscan.png', 'label' => __('Net Scan'), ]; + if (enterprise_installed()) { $buttons[] = [ 'url' => $this->url.'&mode=importcsv', @@ -125,6 +129,18 @@ class HostDevices extends Wizard ]; } + $buttons[] = [ + 'url' => $this->url.'&mode=customnetscan', + 'icon' => '/images/wizard/customnetscan.png', + 'label' => __('Custom NetScan'), + ]; + + $buttons[] = [ + 'url' => $this->url.'&mode=managenetscanscripts', + 'icon' => '/images/wizard/managenetscanscripts.png', + 'label' => __('Manage NetScan scripts'), + ]; + $this->prepareBreadcrum( [ [ @@ -136,19 +152,38 @@ class HostDevices extends Wizard ] ); - $this->printHeader(); + ui_print_page_header(__('Host & devices'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); $this->printBigButtonsList($buttons); return; } if (enterprise_installed()) { - if ($mode == 'importcsv') { - $csv_importer = new CSVImportAgents($this->page, $this->breadcrum); + if ($mode === 'importcsv') { + $csv_importer = new CSVImportAgents( + $this->page, + $this->breadcrum + ); return $csv_importer->runCSV(); } } + if ($mode === 'customnetscan') { + $customnetscan_importer = new CustomNetScan( + $this->page, + $this->breadcrum + ); + return $customnetscan_importer->runCustomNetScan(); + } + + if ($mode === 'managenetscanscripts') { + $managenetscanscript_importer = new ManageNetScanScripts( + $this->page, + $this->breadcrum + ); + return $managenetscanscript_importer->runManageNetScanScript(); + } + if ($mode == 'netscan') { return $this->runNetScan(); } @@ -477,9 +512,15 @@ class HostDevices extends Wizard $task_url = '&task='.$this->task['id_rt']; } - $breadcrum[] = [ - 'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd', - 'label' => __($this->label), + $breadcrum = [ + [ + 'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery', + 'label' => 'Discovery', + ], + [ + 'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd', + 'label' => __($this->label), + ], ]; for ($i = 0; $i < $this->maxPagesNetScan; $i++) { $breadcrum[] = [ @@ -492,7 +533,7 @@ class HostDevices extends Wizard if ($this->page < $this->maxPagesNetScan) { // Avoid to print header out of wizard. $this->prepareBreadcrum($breadcrum); - $this->printHeader(); + ui_print_page_header(__('NetScan'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); } if (isset($this->page) === true diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index c763e0ff29..022402a8d1 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -26,14 +26,15 @@ * ============================================================================ */ -define('CLOUDWIZARD_AWS_DESCRIPTION', 'Discovery.Cloud.AWS.EC2'); +// Begin. -/** - * Global Wizard generic class. Needs to be inherited. - * - * Used in Hostdevices class, Applications class and others, is the core of - * Discovery proyect. - */ + + /** + * Global Wizard generic class. Needs to be inherited. + * + * Used in Hostdevices class, Applications class and others, is the core of + * Discovery proyect. + */ class Wizard { @@ -195,20 +196,38 @@ class Wizard * * @return void */ - public function prepareBreadcrum(array $urls, bool $add=false) + public function prepareBreadcrum(array $urls, bool $add=false, bool $separator_beginning=false) { $bc = []; $i = 0; + $count = 0; + $array_size = count($urls); + foreach ($urls as $url) { + $count++; + if ($url['selected'] == 1) { $class = 'selected'; } else { $class = ''; } - $bc[$i] = ''; - $bc[$i] .= '
'.$url['label']; - $bc[$i++] .= '
'; + $bc[$i] = ''; + + if ($separator_beginning === true) { + $bc[$i] .= ' / '; + } + + $bc[$i] .= ''; + $bc[$i] .= $url['label']; + $bc[$i] .= ''; + if ($count < $array_size) { + $bc[$i] .= ' / '; + } + + $bc[$i] .= ''; + + $i++; } if ($add === true) { @@ -256,7 +275,7 @@ class Wizard */ public function printBreadcrum() { - return '

'.implode('', $this->breadcrum).'

'; + return implode('', $this->breadcrum); } @@ -572,14 +591,18 @@ class Wizard { $output = ''; if ($input['hidden'] == 1) { - $class = ' class="hidden"'; + $class = ' hidden'; } else { $class = ''; } + if (isset($input['class']) === true) { + $class = $input['class'].$class; + } + if (is_array($input['block_content']) === true) { // Print independent block of inputs. - $output .= '
  • '; + $output .= '
  • '; $output .= '
      '; foreach ($input['block_content'] as $input) { $output .= $this->printBlock($input, $return); @@ -588,7 +611,7 @@ class Wizard $output .= '
  • '; } else { if ($input['arguments']['type'] != 'hidden') { - $output .= '
  • '; + $output .= '
  • '; $output .= ''; $output .= $this->printInput($input['arguments']); // Allow dynamic content. diff --git a/pandora_console/images/custom_logo/pandora_logo_head_3.png b/pandora_console/images/custom_logo/pandora_logo_head_3.png index 5bce825279..c39d604af8 100644 Binary files a/pandora_console/images/custom_logo/pandora_logo_head_3.png and b/pandora_console/images/custom_logo/pandora_logo_head_3.png differ diff --git a/pandora_console/images/custom_logo/pandora_logo_head_4.png b/pandora_console/images/custom_logo/pandora_logo_head_4.png index 275871dca6..8bf5fbb1d3 100644 Binary files a/pandora_console/images/custom_logo/pandora_logo_head_4.png and b/pandora_console/images/custom_logo/pandora_logo_head_4.png differ diff --git a/pandora_console/images/custom_logo/pandora_logo_head_5.png b/pandora_console/images/custom_logo/pandora_logo_head_5.png new file mode 100644 index 0000000000..275871dca6 Binary files /dev/null and b/pandora_console/images/custom_logo/pandora_logo_head_5.png differ diff --git a/pandora_console/images/custom_logo/pandora_logo_head_6.png b/pandora_console/images/custom_logo/pandora_logo_head_6.png new file mode 100644 index 0000000000..5bce825279 Binary files /dev/null and b/pandora_console/images/custom_logo/pandora_logo_head_6.png differ diff --git a/pandora_console/images/custom_logo/pandora_logo_head_green.png b/pandora_console/images/custom_logo/pandora_logo_head_green.png deleted file mode 100644 index 8bf5fbb1d3..0000000000 Binary files a/pandora_console/images/custom_logo/pandora_logo_head_green.png and /dev/null differ diff --git a/pandora_console/images/darrowleft_green.png b/pandora_console/images/darrowleft_green.png new file mode 100644 index 0000000000..6262dd7e2d Binary files /dev/null and b/pandora_console/images/darrowleft_green.png differ diff --git a/pandora_console/images/darrowright_green.png b/pandora_console/images/darrowright_green.png new file mode 100644 index 0000000000..ccac0d6690 Binary files /dev/null and b/pandora_console/images/darrowright_green.png differ diff --git a/pandora_console/images/edit_user_map_not_available.jpg b/pandora_console/images/edit_user_map_not_available.jpg new file mode 100644 index 0000000000..ec633d8411 Binary files /dev/null and b/pandora_console/images/edit_user_map_not_available.jpg differ diff --git a/pandora_console/images/firts_task/icono_aws.png b/pandora_console/images/firts_task/icono_aws.png new file mode 100644 index 0000000000..c5f0c3a547 Binary files /dev/null and b/pandora_console/images/firts_task/icono_aws.png differ diff --git a/pandora_console/images/gm_discovery.menu.png b/pandora_console/images/gm_discovery.menu.png index b33975dcec..5c0296b562 100644 Binary files a/pandora_console/images/gm_discovery.menu.png and b/pandora_console/images/gm_discovery.menu.png differ diff --git a/pandora_console/images/gm_discovery.menu_white.png b/pandora_console/images/gm_discovery.menu_white.png index d05d5e7616..80d0913c90 100644 Binary files a/pandora_console/images/gm_discovery.menu_white.png and b/pandora_console/images/gm_discovery.menu_white.png differ diff --git a/pandora_console/images/header_docu.png b/pandora_console/images/header_docu.png new file mode 100644 index 0000000000..2a1c193bed Binary files /dev/null and b/pandora_console/images/header_docu.png differ diff --git a/pandora_console/images/header_down_gray.png b/pandora_console/images/header_down_gray.png index 0cfebc477a..68b302c3ea 100644 Binary files a/pandora_console/images/header_down_gray.png and b/pandora_console/images/header_down_gray.png differ diff --git a/pandora_console/images/header_ready_gray.png b/pandora_console/images/header_ready_gray.png index 9aadb340d5..a1fd9adfb3 100644 Binary files a/pandora_console/images/header_ready_gray.png and b/pandora_console/images/header_ready_gray.png differ diff --git a/pandora_console/images/header_support.png b/pandora_console/images/header_support.png new file mode 100644 index 0000000000..75823214b6 Binary files /dev/null and b/pandora_console/images/header_support.png differ diff --git a/pandora_console/images/header_warning_gray.png b/pandora_console/images/header_warning_gray.png index ca9954d54f..c09319fef4 100644 Binary files a/pandora_console/images/header_warning_gray.png and b/pandora_console/images/header_warning_gray.png differ diff --git a/pandora_console/images/help_g.png b/pandora_console/images/help_g.png new file mode 100644 index 0000000000..60aae95a80 Binary files /dev/null and b/pandora_console/images/help_g.png differ diff --git a/pandora_console/images/help_green.png b/pandora_console/images/help_green.png new file mode 100644 index 0000000000..0d02332988 Binary files /dev/null and b/pandora_console/images/help_green.png differ diff --git a/pandora_console/images/people_1.png b/pandora_console/images/people_1.png old mode 100755 new mode 100644 index 19ad0f4e6a..aa1dd32f32 Binary files a/pandora_console/images/people_1.png and b/pandora_console/images/people_1.png differ diff --git a/pandora_console/images/people_1_old.png b/pandora_console/images/people_1_old.png new file mode 100755 index 0000000000..19ad0f4e6a Binary files /dev/null and b/pandora_console/images/people_1_old.png differ diff --git a/pandora_console/images/people_2.png b/pandora_console/images/people_2.png old mode 100755 new mode 100644 index dd38b8d758..14ba3aaaeb Binary files a/pandora_console/images/people_2.png and b/pandora_console/images/people_2.png differ diff --git a/pandora_console/images/people_2_old.png b/pandora_console/images/people_2_old.png new file mode 100755 index 0000000000..dd38b8d758 Binary files /dev/null and b/pandora_console/images/people_2_old.png differ diff --git a/pandora_console/images/tip_help.png b/pandora_console/images/tip_help.png new file mode 100644 index 0000000000..f2704b34ac Binary files /dev/null and b/pandora_console/images/tip_help.png differ diff --git a/pandora_console/images/user_email.png b/pandora_console/images/user_email.png new file mode 100644 index 0000000000..095b012a5c Binary files /dev/null and b/pandora_console/images/user_email.png differ diff --git a/pandora_console/images/user_name.png b/pandora_console/images/user_name.png new file mode 100644 index 0000000000..20f823f40e Binary files /dev/null and b/pandora_console/images/user_name.png differ diff --git a/pandora_console/images/user_password.png b/pandora_console/images/user_password.png new file mode 100644 index 0000000000..8e81afd75e Binary files /dev/null and b/pandora_console/images/user_password.png differ diff --git a/pandora_console/images/user_phone.png b/pandora_console/images/user_phone.png new file mode 100644 index 0000000000..050559ed8d Binary files /dev/null and b/pandora_console/images/user_phone.png differ diff --git a/pandora_console/images/wizard/customnetscan.png b/pandora_console/images/wizard/customnetscan.png new file mode 100644 index 0000000000..edc036fa39 Binary files /dev/null and b/pandora_console/images/wizard/customnetscan.png differ diff --git a/pandora_console/images/wizard/managenetscanscripts.png b/pandora_console/images/wizard/managenetscanscripts.png new file mode 100644 index 0000000000..4694ec1e7a Binary files /dev/null and b/pandora_console/images/wizard/managenetscanscripts.png differ diff --git a/pandora_console/include/ajax/task_list.ajax.php b/pandora_console/include/ajax/task_list.ajax.php new file mode 100644 index 0000000000..4f69ecaed0 --- /dev/null +++ b/pandora_console/include/ajax/task_list.ajax.php @@ -0,0 +1,174 @@ + true]); + return; + } + + $task = db_get_row('trecon_task', 'id_rt', $id_task); + $global_progress = $task['status']; + $summary = json_decode($task['summary'], true); + + $result = '
    '; + if ($task['utimestamp']) { + $result .= '
      '; + $result .= '
    • '._('Overall Progress').'

    • '; + $result .= '
    • '; + $result .= d3_progress_bar( + $id_task, + ($global_progress < 0) ? 100 : $global_progress, + 460, + 30, + '#EA5434', + '%', + '', + '#FFFFFF', + 0, + 0, + 0 + ); + + if ($global_progress > 0) { + switch ($summary['step']) { + case STEP_SCANNING: + $str = __('Scanning network'); + break; + + case STEP_AFT: + $str = __('Finding AFT connectivity'); + break; + + case STEP_TRACEROUTE: + $str = __('Finding traceroute connectivity'); + break; + + case STEP_GATEWAY: + $str = __('Finding gateway connectivity'); + break; + + default: + $str = __('Searching for devices...'); + break; + } + + $result .= '
    • '; + $result .= '
    • '.$str.' '; + $result .= $summary['c_network_name']; + $result .= '

    • '; + $result .= '
    • '; + $result .= d3_progress_bar( + $id_task.'_detail', + $summary['c_network_percent'], + 460, + 30, + '#2751E1', + '%', + '', + '#FFFFFF', + 0, + 0, + 0 + ); + $result .= '
    • '; + } + + $result .= '
    '; + + $i = 0; + $table = new StdClasS(); + $table->class = 'databox data'; + $table->width = '75%'; + $table->styleTable = 'margin: 2em auto 0;border: 1px solid #ddd;background: white;'; + $table->rowid = []; + $table->data = []; + + // Content. + $table->data[$i][0] = ''.__('Hosts discovered').''; + $table->data[$i][1] = ''; + $table->data[$i][1] .= $summary['summary']['discovered']; + $table->data[$i++][1] .= ''; + + $table->data[$i][0] = ''.__('Alive').''; + $table->data[$i][1] = ''; + $table->data[$i][1] .= $summary['summary']['alive']; + $table->data[$i++][1] .= ''; + + $table->data[$i][0] = ''.__('Not alive').''; + $table->data[$i][1] = ''; + $table->data[$i][1] .= $summary['summary']['not_alive']; + $table->data[$i++][1] .= ''; + + $table->data[$i][0] = ''.__('Responding SNMP').''; + $table->data[$i][1] = ''; + $table->data[$i][1] .= $summary['summary']['SNMP']; + $table->data[$i++][1] .= ''; + + $table->data[$i][0] = ''.__('Responding WMI').''; + $table->data[$i][1] = ''; + $table->data[$i][1] .= $summary['summary']['WMI']; + $table->data[$i++][1] .= ''; + + $result .= html_print_table($table, true).'
    '; + } else { + $global_progress = -1; + $result .= ui_print_error_message( + __('No data to show'), + '', + true + ).'
  • '; + } + + $result_array['status'] = $global_progress; + $result_array['html'] = $result; + + echo json_encode($result_array); + return; +} + +if ($showmap) { + include_once $config['homedir'].'/include/class/NetworkMap.class.php'; + $id_task = get_parameter('id', 0); + + $map = new NetworkMap( + [ + 'id_task' => $id_task, + 'pure' => 1, + 'widget' => true, + ] + ); + $map->printMap(); +} diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index 64643b4c58..7259287d68 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -36,7 +36,7 @@ require_once $config['homedir'].'/include/functions_servers.php'; // Enterprise includes. enterprise_include_once('include/functions_metaconsole.php'); enterprise_include_once('include/functions_license.php'); -enterprise_include_once('extensions/cron/functions.php'); +enterprise_include_once('include/functions_cron.php'); /** * Base class to run scheduled tasks in cron extension @@ -234,6 +234,7 @@ class ConsoleSupervisor /* * Check license. * NOTIF.LICENSE.EXPIRATION + * NOTIF.LICENSE.LIMITED */ $this->checkLicense(); @@ -537,6 +538,10 @@ class ConsoleSupervisor } switch ($data['type']) { + case 'NOTIF.LICENSE.LIMITED': + $max_age = 0; + break; + case 'NOTIF.LICENSE.EXPIRATION': case 'NOTIF.FILES.ATTACHMENT': case 'NOTIF.FILES.DATAIN': @@ -684,14 +689,30 @@ class ConsoleSupervisor $days_to_expiry = ((strtotime($license['expiry_date']) - time()) / (60 * 60 * 24)); + // Limited mode. + if (isset($config['limited_mode'])) { + // Warn user if license is going to expire in 15 days or less. + $this->notify( + [ + 'type' => 'NOTIF.LICENSE.LIMITED', + 'title' => __('Limited mode.'), + 'message' => io_safe_output($config['limited_mode']), + 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/license', + ] + ); + } else { + $this->cleanNotifications('NOTIF.LICENSE.LIMITED'); + } + + // Expiry. if (($days_to_expiry <= 15) && ($days_to_expiry > 0)) { // Warn user if license is going to expire in 15 days or less. $this->notify( [ - 'type' => 'NOTIF.LICENSE_EXPIRATION', - 'title' => __('License is going to expire.'), + 'type' => 'NOTIF.LICENSE.EXPIRATION', + 'title' => __('License is about to expire'), 'message' => __( - 'Your license is going to expire in %d days. Please contact sales.', + 'Your license will expire in %d days. Please, contact our sales department.', $days_to_expiry ), 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/license', @@ -702,8 +723,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.LICENSE.EXPIRATION', - 'title' => __('License is expired.'), - 'message' => __('Your license has expired. Please contact sales.'), + 'title' => __('Expired license'), + 'message' => __('Your license has expired. Please, contact our sales department.'), 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/license', ] ); @@ -776,9 +797,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.WRITABLE.ATTACHMENT', - 'title' => __('Attachment directory is not writable.'), + 'title' => __('Attachment directory is not writable'), 'message' => __( - 'Directory %s is not writable. Please configure proper permissions.', + 'Directory %s is not writable. Please, configure corresponding permissions.', $config['attachment_store'] ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', @@ -798,9 +819,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.FILES.ATTACHMENT', - 'title' => __('There are too much files in attachment directory.'), + 'title' => __('There are too many files in attachment directory'), 'message' => __( - 'There are more than %d files in attachment, you should consider cleaning up your attachment directory manually.', + 'There are more than %d files in attachment, consider cleaning up attachment directory manually.', $config['num_files_attachment'] ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', @@ -830,9 +851,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG', - 'title' => __('Remote configuration directory is not readable.'), + 'title' => __('Remote configuration directory is not readable'), 'message' => __( - 'Remote configuration directory %s is not readable. Please configure it.', + 'Remote configuration directory %s is not readable. Please, adjust configuration.', $config['remote_config'] ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', @@ -849,9 +870,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.CONF', - 'title' => __('Remote configuration directory is not writable.'), + 'title' => __('Remote configuration directory is not writable'), 'message' => __( - 'Remote configuration directory %s is not writable. Please configure it.', + 'Remote configuration directory %s is not writable. Please, adjust configuration.', $config['remote_config'].'/conf' ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', @@ -867,9 +888,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.COLLECTIONS', - 'title' => __('Remote collections directory is not writable.'), + 'title' => __('Remote collections directory is not writable'), 'message' => __( - 'Collections directory %s is not writable. Please configure it.', + 'Collections directory %s is not writable. Please, adjust configuration.', $config['remote_config'].'/collections' ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', @@ -885,9 +906,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PERMISSIONS.REMOTE_CONFIG.MD5', - 'title' => __('Remote md5 directory is not writable.'), + 'title' => __('Remote md5 directory is not writable'), 'message' => __( - 'MD5 directory %s is not writable. Please configure it.', + 'MD5 directory %s is not writable. Please, adjust configuration.', $config['remote_config'].'/md5' ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=general', @@ -917,7 +938,7 @@ class ConsoleSupervisor 'type' => 'NOTIF.FILES.DATAIN', 'title' => __('There are too much files in spool').'.', 'message' => __( - 'There are more than %d files in %s, you should consider checking DataServer performance', + 'There are more than %d files in %s. Consider checking DataServer performance', $MAX_FILES_DATA_IN, $config['remote_config'] ), @@ -938,9 +959,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.FILES.DATAIN.BADXML', - 'title' => __('There are too much BADXML files in spool.'), + 'title' => __('There are too many BADXML files in spool'), 'message' => __( - 'There are more than %d files in %s, you should consider checking software agents.', + 'There are more than %d files in %s. Consider checking software agents.', $MAX_BADXML_FILES_DATA_IN, $config['remote_config'] ), @@ -962,10 +983,12 @@ class ConsoleSupervisor { global $config; + include_once $config['homedir'].'/include/functions_servers.php'; + $idx_file = $config['attachment_store'].'/.cron.supervisor.servers.idx'; $MAX_QUEUE = 1500; - $MAX_GROWN = 50; + $total_modules = servers_get_total_modules(); $queue_state = []; $previous = []; @@ -988,6 +1011,13 @@ class ConsoleSupervisor $key = $queue['id_server']; $type = $queue['server_type']; $new_data[$key] = $queue['queued_modules']; + $max_grown = 0; + + if (is_array($total_modules) + && isset($total_modules[$queue['server_type']]) + ) { + $max_grown = ($total_modules[$queue['server_type']] * 0.40); + } // Compare queue increments in a not over 900 seconds. if (empty($previous[$key]['modules']) @@ -998,9 +1028,9 @@ class ConsoleSupervisor $modules_queued = ($queue['queued_modules'] - $previous[$key]['modules']); - // 50 Modules queued since last check. Or more than 1500 queued. - if ($modules_queued > $MAX_GROWN - || $queue['queued_modules'] > $MAX_QUEUE + // 40% Modules queued since last check. If any. + if ($max_grown > 0 + && $modules_queued > $max_grown ) { $msg = 'Queue has grown %d modules. Total %d'; if ($modules_queued <= 0) { @@ -1012,7 +1042,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.SERVER.QUEUE.'.$key, 'title' => __( - '%s (%s) performance is being lacked.', + '%s (%s) is lacking performance.', servers_get_server_string_name($type), $queue['name'] ), @@ -1056,6 +1086,7 @@ class ConsoleSupervisor id_server, name, server_type, + server_keepalive, status, unix_timestamp() - unix_timestamp(keepalive) as downtime FROM tserver @@ -1079,7 +1110,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.SERVER.STATUS', 'title' => __('No servers available.'), - 'message' => __('There are no servers registered in this console, please check installation guide.'), + 'message' => __('There are no servers registered in this console. Please, check installation guide.'), 'url' => $url, ] ); @@ -1091,28 +1122,35 @@ class ConsoleSupervisor } foreach ($servers as $server) { + if ($server['server_type'] == SERVER_TYPE_ENTERPRISE_SATELLITE) { + if ($server['downtime'] < ($server['server_keepalive'] * 2)) { + // Satellite uses different keepalive mode. + continue; + } + } + if ($server['status'] == 1) { // Fatal error. Component has die. $msg = __( - '%s (%s) crashed.', + '%s (%s) has crashed.', servers_get_server_string_name($server['server_type']), $server['name'] ); $description = __( - '%s (%s) has died, please check log files', + '%s (%s) has crashed, please check log files.', servers_get_server_string_name($server['server_type']), $server['name'] ); } else { // Non-fatal error. Controlated exit. Component is not running. $msg = __( - '%s (%s) is stopped.', + '%s (%s) is not running.', servers_get_server_string_name($server['server_type']), $server['name'] ); $description = __( - '%s (%s) is stopped, please check configuration file or remove this server from server list.', + '%s (%s) is not running. Please, check configuration file or remove this server from server list.', servers_get_server_string_name($server['server_type']), $server['name'] ); @@ -1163,7 +1201,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.SERVER.MASTER', 'title' => __('No master servers found.'), - 'message' => __('You should define at last one server to run as master, please check documentation.'), + 'message' => __('At least one server must be defined to run as master. Please, check documentation.'), 'url' => $url, ] ); @@ -1204,12 +1242,17 @@ class ConsoleSupervisor $php_version_array = explode('.', $php_version); if ($PHPsafe_mode === '1') { + $url = 'http://php.net/manual/en/features.safe-mode.php'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/features.safe-mode.php'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.SAFE_MODE', - 'title' => __('PHP safe mode is enabled. Some features may not properly work.'), - 'message' => __('To disable, change it on your PHP configuration file (php.ini) and put safe_mode = Off (Dont forget restart apache process after changes)'), - 'url' => 'index.php', + 'title' => __('PHP safe mode is enabled. Some features may not work properly'), + 'message' => __('To disable it, go to your PHP configuration file (php.ini) and put safe_mode = Off (Do not forget to restart apache process after changes)'), + 'url' => $url, ] ); } else { @@ -1217,18 +1260,23 @@ class ConsoleSupervisor } if ($PHPmax_input_time !== '-1') { + $url = 'http://php.net/manual/en/info.configuration.php#ini.max-input-time'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/info.configuration.php#ini.max-input-time'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.INPUT_TIME', 'title' => sprintf( - __("Not recommended '%s' value in PHP configuration"), + __("'%s' value in PHP configuration is not recommended"), 'max_input_time' ), 'message' => sprintf( __('Recommended value is %s'), '-1 ('.__('Unlimited').')' - ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - 'url' => 'index.php', + ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Do not forget to restart Apache process after)'), + 'url' => $url, ] ); } else { @@ -1236,6 +1284,11 @@ class ConsoleSupervisor } if ($PHPmax_execution_time !== '0') { + $url = 'http://php.net/manual/en/info.configuration.php#ini.max-execution-time'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/info.configuration.php#ini.max-execution-time'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.EXECUTION_TIME', @@ -1247,7 +1300,7 @@ class ConsoleSupervisor __('Recommended value is: %s'), '0 ('.__('Unlimited').')' ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - 'url' => 'index.php', + 'url' => $url, ] ); } else { @@ -1255,6 +1308,11 @@ class ConsoleSupervisor } if ($PHPupload_max_filesize < $PHPupload_max_filesize_min) { + $url = 'http://php.net/manual/en/ini.core.php#ini.upload-max-filesize'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/ini.core.php#ini.upload-max-filesize'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.UPLOAD_MAX_FILESIZE', @@ -1266,7 +1324,7 @@ class ConsoleSupervisor __('Recommended value is: %s'), sprintf(__('%s or greater'), '800M') ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - 'url' => 'index.php', + 'url' => $url, ] ); } else { @@ -1274,6 +1332,11 @@ class ConsoleSupervisor } if ($PHPmemory_limit < $PHPmemory_limit_min && $PHPmemory_limit !== '-1') { + $url = 'http://php.net/manual/en/ini.core.php#ini.memory-limit'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/ini.core.php#ini.memory-limit'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.MEMORY_LIMIT', @@ -1285,7 +1348,7 @@ class ConsoleSupervisor __('Recommended value is: %s'), sprintf(__('%s or greater'), '500M') ).'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator'), - 'url' => 'index.php', + 'url' => $url, ] ); } else { @@ -1293,12 +1356,17 @@ class ConsoleSupervisor } if (preg_match('/system/', $PHPdisable_functions) || preg_match('/exec/', $PHPdisable_functions)) { + $url = 'http://php.net/manual/en/ini.core.php#ini.disable-functions'; + if ($config['language'] == 'es') { + $url = 'http://php.net/manual/es/ini.core.php#ini.disable-functions'; + } + $this->notify( [ 'type' => 'NOTIF.PHP.DISABLE_FUNCTIONS', - 'title' => __('Problems with disable functions in PHP.INI'), - 'message' => __('Variable disable_functions containts functions system() or exec(), in PHP configuration file (php.ini)').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), - 'url' => 'index.php', + 'title' => __('Problems with disable_functions in php.ini'), + 'message' => __('The variable disable_functions contains functions system() or exec() in PHP configuration file (php.ini)').'

    '.__('Please, change it on your PHP configuration file (php.ini) or contact with administrator (Dont forget restart apache process after changes)'), + 'url' => $url, ] ); } else { @@ -1314,8 +1382,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PHP.PHANTOMJS', - 'title' => __('phantomjs is not installed'), - 'message' => __('To be able to create images of the graphs for PDFs, please install the phantom.js extension. For that, it is necessary to follow these steps:'), + 'title' => __('PhantomJS is not installed'), + 'message' => __('To be able to create images of the graphs for PDFs, please install the PhantomJS extension. For that, it is necessary to follow these steps:'), 'url' => $url, ] ); @@ -1375,7 +1443,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.HISTORYDB', 'title' => __('Historical database not available'), - 'message' => __('Historical database is enabled. But not available using given configuration. Please check it.'), + 'message' => __('Historical database is enabled, though not accessible with the current configuration.'), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=hist_db', ] ); @@ -1418,9 +1486,9 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.PANDORADB', - 'title' => __('Database maintance problem'), + 'title' => __('Database maintenance problem'), 'message' => __( - 'Your database is not maintained correctly. It seems that more than 48hrs have passed without proper maintenance. Please review documents of %s on how to perform this maintenance process (DB Tool) and enable it as soon as possible.', + 'Your database hasn\'t been through maintenance for 48hrs. Please, check documentation on how to perform this maintenance process on %s and enable it as soon as possible.', io_safe_output(get_product_name()) ), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', @@ -1480,9 +1548,9 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.PANDORADB.HISTORY', 'title' => __( - 'Historical database maintance problem.' + 'Historical database maintenance problem.' ), - 'message' => __('Your historical database is not being maintained correctly. It seems that more than 48hrs have passed without proper maintenance. Please review documents of %s on how to perform this maintenance process (DB Tool) and enable it as soon as possible.', get_product_name()), + 'message' => __('Your historical database hasn\'t been through maintenance for 48hrs. Please, check documentation on how to perform this maintenance process on %s and enable it as soon as possible.', get_product_name()), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=perf', ] ); @@ -1520,8 +1588,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.HISTORYDB.MR', - 'title' => __('Historical database MR missmatch'), - 'message' => __('Your historical database is not using the same schema of main DB. This could produce anomalyes while storing historical data.'), + 'title' => __('Historical database MR mismatch'), + 'message' => __('Your historical database is not using the same schema as the main DB. This could produce anomalies while storing historical data.'), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=hist_db', ] ); @@ -1563,7 +1631,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.EXT.ELASTICSEARCH', 'title' => __('Log collector cannot connect to ElasticSearch'), - 'message' => __('ElasticSearch is not available using current configuration. Please check it.'), + 'message' => __('ElasticSearch is not available using current configuration.'), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=log', ] ); @@ -1633,7 +1701,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.METACONSOLE.DB_CONNECTION', 'title' => __('Metaconsole DB is not available.'), - 'message' => __('Cannot connect with Metaconsole DB using stored configuration. Please check it.'), + 'message' => __('Cannot connect with Metaconsole DB using current configuration.'), 'url' => 'index.php?sec=general&sec2=godmode/setup/setup§ion=enterprise', ] ); @@ -1662,7 +1730,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.DOWNTIME', 'title' => __('Scheduled downtime running.'), - 'message' => __('A scheduled downtime is running. Some monitorization data won\'t be available while downtime is taking place.'), + 'message' => __('A scheduled downtime is running. Some monitoring data won\'t be available while downtime is taking place.'), 'url' => 'index.php?sec=gagente&sec2=godmode/agentes/planned_downtime.list', ] ); @@ -1820,7 +1888,7 @@ class ConsoleSupervisor 'type' => 'NOTIF.DOWNTIME', 'title' => __('Downtime scheduled soon.'), 'message' => __( - 'A scheduled downtime is going to be executed from %s to %s. Some monitorization data won\'t be available while downtime is taking place.', + 'A scheduled downtime is going to be executed from %s to %s. Some monitoring data won\'t be available while downtime is taking place.', date('M j, G:i:s ', $next_downtime_begin), date('M j, G:i:s ', $next_downtime_end) ), @@ -1856,7 +1924,7 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.UPDATEMANAGER.REGISTRATION', - 'title' => __('This instance is not registered in the Update manager'), + 'title' => __('This instance is not registered in the Update manager section'), 'message' => __('Click here to start the registration process'), 'url' => 'javascript: force_run_register();', ] @@ -1895,7 +1963,7 @@ class ConsoleSupervisor [ 'type' => 'NOTIF.NEWSLETTER.SUBSCRIPTION', 'title' => __('Not subscribed to the newsletter'), - 'message' => __('Click here to start the newsletter subscription process'), + 'message' => __('Click here to subscribe to the newsletter'), 'url' => 'javascript: force_run_newsletter();', ] ); @@ -1927,8 +1995,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.SECURITY.DEFAULT_PASSWORD', - 'title' => __('Default password for "Admin" user has not been changed.'), - 'message' => __('Please change the default password because is a common vulnerability reported.'), + 'title' => __('Default password for "Admin" user has not been changed'), + 'message' => __('Please, change the default password since it is a commonly reported vulnerability.'), 'url' => 'index.php?sec=gusuarios&sec2=godmode/users/user_list', ] ); @@ -1953,8 +2021,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.MISC.FONTPATH', - 'title' => __('Default font doesnt exist'), - 'message' => __('Your defined font doesnt exist or is not defined. Please check font parameters in your config'), + 'title' => __('Default font doesn\'t exist'), + 'message' => __('Your defined font doesn\'t exist or is not defined. Please, check font parameters in your config'), 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=vis', ] ); @@ -1979,7 +2047,7 @@ class ConsoleSupervisor 'type' => 'NOTIF.MISC.DEVELOPBYPASS', 'title' => __('Developer mode is enabled'), 'message' => __( - 'Your %s has the "develop_bypass" mode enabled. This is a developer mode and should be disabled in a production system. This value is written in the main index.php file', + 'Your %s has the "develop_bypass" mode enabled. This is a developer mode and should be disabled in a production environment. This value is located in the main index.php file', get_product_name() ), 'url' => 'index.php', @@ -2003,8 +2071,8 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.MISC.EVENTSTORMPROTECTION', - 'title' => __('Event storm protection is activated.'), - 'message' => __('You need to restart server after altering this configuration setting. No events will be generated during this mode.'), + 'title' => __('Event storm protection is enabled.'), + 'message' => __('Some events may get lost while this mode is enabled. The server must be restarted after altering this setting.'), 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=general', ] ); @@ -2030,7 +2098,7 @@ class ConsoleSupervisor $this->notify( [ 'type' => 'NOTIF.UPDATEMANAGER.OPENSETUP', - 'title' => __('Error, first setup "Open update".'), + 'title' => __('Failed to retrieve updates, please configure utility'), 'message' => $message, 'url' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=general', ] @@ -2087,10 +2155,10 @@ class ConsoleSupervisor 'type' => 'NOTIF.UPDATEMANAGER.MINOR', 'title' => __('Minor release/s available'), 'message' => __( - 'There are one or more minor releases waiting for update. .About minor release update.', + 'There is one or more minor releases available. .About minor release update.', $url ), - 'url' => $url, + 'url' => 'index.php?sec=messages&sec2=godmode/update_manager/update_manager&tab=online', ] ); } else { @@ -2115,7 +2183,7 @@ class ConsoleSupervisor ) { $message_conf_cron = __('DiscoveryConsoleTasks is not running properly'); if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { - $message_conf_cron .= __('Discovery relies on a proper setup of cron, the time-based scheduling service'); + $message_conf_cron .= __('Discovery relies on an appropriate cron setup.'); $message_conf_cron .= '. '.__('Please, add the following line to your crontab file:'); $message_conf_cron .= '
    * * * * * <user> wget -q -O - --no-check-certificate ';
                     $message_conf_cron .= str_replace(
    @@ -2131,7 +2199,7 @@ class ConsoleSupervisor
                 if (isset($config['cron_last_run']) === true) {
                     $message_conf_cron .= __('Last execution').': ';
                     $message_conf_cron .= date('Y/m/d H:i:s', $config['cron_last_run']);
    -                $message_conf_cron .= __('Please check process is no locked.');
    +                $message_conf_cron .= __('Please, make sure process is not locked.');
                 }
     
                 $this->notify(
    @@ -2139,7 +2207,7 @@ class ConsoleSupervisor
                         'type'    => 'NOTIF.CRON.CONFIGURED',
                         'title'   => __('DiscoveryConsoleTasks is not configured.'),
                         'message' => __($message_conf_cron),
    -                    'url'     => 'index.php?extension_in_menu=gservers&sec=extensions&sec2=enterprise/extensions/cron',
    +                    'url'     => 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist',
                     ]
                 );
             } else {
    diff --git a/pandora_console/include/class/CustomNetScan.class.php b/pandora_console/include/class/CustomNetScan.class.php
    new file mode 100644
    index 0000000000..7477594637
    --- /dev/null
    +++ b/pandora_console/include/class/CustomNetScan.class.php
    @@ -0,0 +1,768 @@
    +url = ui_get_full_url(
    +            'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd'
    +        );
    +        $this->page = $page;
    +        $this->breadcrum = $breadcrum;
    +    }
    +
    +
    +    /**
    +     * Retrieves and validates information given by user in NetScan wizard.
    +     *
    +     * @return boolean Data OK or not.
    +     */
    +    public function parseNetScan()
    +    {
    +        if (isset($this->page) === true && $this->page === 0) {
    +            // Check if we're updating a task.
    +            $task_id = get_parameter('task', null);
    +
    +            if (isset($task_id) === true) {
    +                // We're updating this task.
    +                $task = db_get_row(
    +                    'trecon_task',
    +                    'id_rt',
    +                    $task_id
    +                );
    +
    +                if ($task !== false) {
    +                    $this->task = $task;
    +                }
    +            }
    +
    +            return true;
    +        }
    +
    +        // Validate response from page 0. No, not a bug, we're always 1 page
    +        // from 'validation' page.
    +        if (isset($this->page) === true && $this->page === 1) {
    +            $task_id = get_parameter('task', null);
    +            $taskname = get_parameter('taskname', '');
    +            $comment = get_parameter('comment', '');
    +            $server_id = get_parameter('id_recon_server', '');
    +            $id_group = get_parameter('id_group', '');
    +            $interval = get_parameter('interval', 0);
    +
    +            if (isset($task_id) === true) {
    +                // We're updating this task.
    +                $task = db_get_row(
    +                    'trecon_task',
    +                    'id_rt',
    +                    $task_id
    +                );
    +
    +                if ($task !== false) {
    +                    $this->task = $task;
    +                }
    +            } else if (isset($taskname) === true) {
    +                // Avoid double creation.
    +                $task = db_get_row_filter(
    +                    'trecon_task',
    +                    ['name' => $taskname]
    +                );
    +
    +                if ($task !== false) {
    +                    $this->task = $task;
    +                    $this->msg = __('This task has been already defined. Please edit it or create a new one.');
    +                    return false;
    +                }
    +            }
    +
    +            if ($task_id !== null
    +                && $taskname == null
    +                && $server_id == null
    +                && $id_group == null
    +                && $server == null
    +                && $datacenter == ''
    +                && $user == ''
    +                && $pass == ''
    +                && $encrypt == null
    +                && $interval == 0
    +            ) {
    +                // Default values, no data received.
    +                // User is accesing directly to this page.
    +                if (users_is_admin() !== true && check_acl(
    +                    $config['id_usuario'],
    +                    $this->task['id_group'],
    +                    'PM'
    +                ) !== true
    +                ) {
    +                    $this->msg = __('You have no access to edit this task.');
    +                    return false;
    +                }
    +            } else {
    +                if (isset($this->task['id_rt']) === false) {
    +                    // Disabled 2 Implies wizard non finished.
    +                    $this->task['disabled'] = 2;
    +                }
    +
    +                if ($taskname == '') {
    +                    $this->msg = __('You must provide a task name.');
    +                    return false;
    +                }
    +
    +                if ($server_id == '') {
    +                    $this->msg = __('You must select a Discovery Server.');
    +                    return false;
    +                }
    +
    +                if ($id_group == '') {
    +                    $this->msg = __('You must select a valid group.');
    +                    return false;
    +                }
    +
    +                // Assign fields.
    +                $this->task['name'] = $taskname;
    +                $this->task['description'] = $comment;
    +                $this->task['id_recon_server'] = $server_id;
    +                $this->task['id_group'] = $id_group;
    +                $this->task['interval_sweep'] = $interval;
    +
    +                if (isset($this->task['id_rt']) === false) {
    +                    // Create.
    +                    $this->task['id_rt'] = db_process_sql_insert(
    +                        'trecon_task',
    +                        $this->task
    +                    );
    +                } else {
    +                    // Update.
    +                    db_process_sql_update(
    +                        'trecon_task',
    +                        $this->task,
    +                        ['id_rt' => $this->task['id_rt']]
    +                    );
    +                }
    +            }
    +
    +            return true;
    +        }
    +
    +        // Validate response from page 1.
    +        if ($this->page == 2) {
    +            $id_rt = get_parameter('task', -1);
    +
    +            $task = db_get_row(
    +                'trecon_task',
    +                'id_rt',
    +                $id_rt
    +            );
    +
    +            if ($task !== false) {
    +                $this->task = $task;
    +            } else {
    +                $this->msg = __('Failed to find network scan task.');
    +                return false;
    +            }
    +
    +            $id_recon_script = get_parameter('id_recon_script', null);
    +            $field1 = get_parameter('_field1_', '');
    +            $field2 = get_parameter('_field2_', '');
    +            $field3 = get_parameter('_field3_', '');
    +            $field4 = get_parameter('_field4_', '');
    +
    +            // Get macros.
    +            $macros = get_parameter('macros', null);
    +
    +            if (empty($macros) === false) {
    +                $macros = json_decode(
    +                    base64_decode($macros),
    +                    true
    +                );
    +
    +                foreach ($macros as $k => $m) {
    +                    $macros[$k]['value'] = get_parameter($m['macro'], '');
    +                }
    +            }
    +
    +            $this->task['id_recon_script'] = $id_recon_script;
    +            $this->task['macros'] = io_json_mb_encode($macros);
    +            $this->task['field1'] = $field1;
    +            $this->task['field2'] = $field2;
    +            $this->task['field3'] = $field3;
    +            $this->task['field4'] = $field4;
    +
    +            if ($this->task['disabled'] == 2) {
    +                // Wizard finished.
    +                $this->task['disabled'] = 0;
    +            }
    +
    +            // Update.
    +            $res = db_process_sql_update(
    +                'trecon_task',
    +                $this->task,
    +                ['id_rt' => $this->task['id_rt']]
    +            );
    +
    +            return true;
    +        }
    +
    +        return false;
    +    }
    +
    +
    +    /**
    +     * Run function. It will be call into HostsDevices class.
    +     *      Page 0: Upload form.
    +     *      Page 1: Task resume.
    +     *
    +     * @return void
    +     */
    +    public function runCustomNetScan()
    +    {
    +        global $config;
    +
    +        if (!check_acl($config['id_user'], 0, 'PM')) {
    +            db_pandora_audit(
    +                'ACL Violation',
    +                'Trying to access Custom Net Scan.'
    +            );
    +            include 'general/noaccess.php';
    +            return;
    +        }
    +
    +        if ($this->parseNetScan() === false) {
    +            // Error.
    +            ui_print_error_message(
    +                $this->msg
    +            );
    +
    +            $form = [
    +                'form'   => [
    +                    'method' => 'POST',
    +                    'action' => $this->url.'&mode=customnetscan&page='.($this->page - 1).'&task='.$this->task['id_rt'],
    +                ],
    +                'inputs' => [
    +                    [
    +                        'arguments' => [
    +                            'type'  => 'hidden',
    +                            'name'  => 'task',
    +                            'value' => $this->task['id_rt'],
    +                        ],
    +                    ],
    +                    [
    +                        'arguments' => [
    +                            'name'       => 'submit',
    +                            'label'      => __('Go back'),
    +                            'type'       => 'submit',
    +                            'attributes' => 'class="sub cancel"',
    +                            'return'     => true,
    +                        ],
    +                    ],
    +                ],
    +            ];
    +
    +            // Check ACL. If user is not able to manage target task,
    +            // redirect him to main page.
    +            if (users_is_admin() !== true && check_acl(
    +                $config['id_usuario'],
    +                $this->task['id_group'],
    +                'PM'
    +            ) !== true
    +            ) {
    +                $form['form']['action'] = $this->url.'&mode=customnetscan&page='.($this->page - 1);
    +            }
    +
    +            $this->printForm($form);
    +            return null;
    +        }
    +
    +        $run_url = 'index.php?sec=gservers&sec2=godmode/servers/discovery';
    +
    +        $task_url = '';
    +        if (isset($this->task['id_rt']) === true) {
    +            $task_url = '&task='.$this->task['id_rt'];
    +        }
    +
    +        $breadcrum = [
    +            [
    +                'link'  => 'index.php?sec=gservers&sec2=godmode/servers/discovery',
    +                'label' => 'Discovery',
    +            ],
    +            [
    +                'link'  => $run_url.'&wiz=hd',
    +                'label' => __('Host & Devices'),
    +            ],
    +        ];
    +
    +        for ($i = 0; $i < $this->MAXPAGES; $i++) {
    +            $breadcrum[] = [
    +                'link'     => $run_url.'&wiz=hd&mode=customnetscan&page='.$i.$task_url,
    +                'label'    => __($this->pageLabels[$i]),
    +                'selected' => (($i == $this->page) ? 1 : 0),
    +            ];
    +        }
    +
    +        if ($this->page < $this->MAXPAGES) {
    +            // Avoid to print header out of wizard.
    +            $this->prepareBreadcrum($breadcrum);
    +
    +            // Header
    +            ui_print_page_header(__('NetScan Custom'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true));
    +        }
    +
    +        $task_url = '';
    +        if (isset($this->task['id_rt'])) {
    +            $task_url = '&task='.$this->task['id_rt'];
    +        }
    +
    +        $breadcrum[] = [
    +            'link'  => $run_url.'&wiz=hd',
    +            'label' => __($this->label),
    +        ];
    +        for ($i = 0; $i < $this->maxPagesNetScan; $i++) {
    +            $breadcrum[] = [
    +                'link'     => $run_url.'&wiz=hd&mode=customnetscan&page='.$i.$task_url,
    +                'label'    => $this->pageLabelsNetScan[$i],
    +                'selected' => (($i == $this->page) ? 1 : 0),
    +            ];
    +        }
    +
    +        if ($this->page < $this->maxPagesNetScan) {
    +            // Avoid to print header out of wizard.
    +            $this->prepareBreadcrum($breadcrum);
    +
    +            // Header
    +            ui_print_page_header(__('NetScan Custom'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true));
    +        }
    +
    +        if (isset($this->page) === true
    +            && $this->page !== 0
    +            && isset($this->task['id_rt']) === false
    +        ) {
    +            // Error.
    +            ui_print_error_message(
    +                __('Internal error, please re-run this wizard.')
    +            );
    +
    +            $form = [
    +                'form'   => [
    +                    'method' => 'POST',
    +                    'action' => $this->url.'&mode=customnetscan&page=0',
    +                ],
    +                'inputs' => [
    +                    [
    +                        'arguments' => [
    +                            'type'  => 'hidden',
    +                            'name'  => 'page',
    +                            'value' => 0,
    +                        ],
    +                    ],
    +                    [
    +                        'arguments' => [
    +                            'name'       => 'submit',
    +                            'label'      => __('Go back'),
    +                            'type'       => 'submit',
    +                            'attributes' => 'class="sub cancel"',
    +                            'return'     => true,
    +                        ],
    +                    ],
    +                ],
    +            ];
    +
    +            $this->printForm($form);
    +            return null;
    +        }
    +
    +        // -------------------------------.
    +        // Page 0. wizard starts HERE.
    +        // -------------------------------.
    +        if (isset($this->page) === true || $this->page == 0) {
    +            if (isset($this->page) === false
    +                || $this->page == 0
    +            ) {
    +                $form = [];
    +
    +                // Input task name.
    +                $form['inputs'][] = [
    +                    'label'     => ''.__('Task name').'',
    +                    'arguments' => [
    +                        'name'  => 'taskname',
    +                        'value' => $this->task['name'],
    +                        'type'  => 'text',
    +                        'size'  => 25,
    +                    ],
    +                ];
    +
    +                if (isset($this->task['id_rt']) === true) {
    +                    // Propagate id.
    +                    $form['inputs'][] = [
    +                        'arguments' => [
    +                            'name'  => 'task',
    +                            'value' => $this->task['id_rt'],
    +                            'type'  => 'hidden',
    +                        ],
    +                    ];
    +                }
    +
    +                // Input task description.
    +                $form['inputs'][] = [
    +                    'label'     => ''.__('Comment').'',
    +                    'arguments' => [
    +                        'name'  => 'comment',
    +                        'value' => $this->task['description'],
    +                        'type'  => 'text',
    +                        'size'  => 25,
    +                    ],
    +                ];
    +
    +                // Input Discovery Server.
    +                $form['inputs'][] = [
    +                    'label'     => ''.__('Discovery server').''.ui_print_help_tip(
    +                        __('You must select a Discovery Server to run the Task, otherwise the Recon Task will never run'),
    +                        true
    +                    ),
    +                    'arguments' => [
    +                        'type'     => 'select_from_sql',
    +                        'sql'      => sprintf(
    +                            'SELECT id_server, name
    +                                    FROM tserver
    +                                    WHERE server_type = %d
    +                                    ORDER BY name',
    +                            SERVER_TYPE_DISCOVERY
    +                        ),
    +                        'name'     => 'id_recon_server',
    +                        'selected' => $this->task['id_recon_server'],
    +                        'return'   => true,
    +                    ],
    +                ];
    +
    +                // Input Group.
    +                $form['inputs'][] = [
    +                    'label'     => ''.__('Group').'',
    +                    'arguments' => [
    +                        'name'           => 'id_group',
    +                        'returnAllGroup' => false,
    +                        'privilege'      => 'PM',
    +                        'type'           => 'select_groups',
    +                        'selected'       => $this->task['id_group'],
    +                        'return'         => true,
    +                    ],
    +                ];
    +
    +                // Interval and schedules.
    +                $interv_manual = 0;
    +                if ((int) $this->task['interval_sweep'] == 0) {
    +                    $interv_manual = 1;
    +                }
    +
    +                // Schedule.
    +                $form['inputs'][] = [
    +                    'label'     => ''.__('Interval').''.ui_print_help_tip(
    +                        __('Manual interval means that it will be executed only On-demand'),
    +                        true
    +                    ),
    +                    'arguments' => [
    +                        'type'     => 'select',
    +                        'selected' => $interv_manual,
    +                        'fields'   => [
    +                            0 => __('Defined'),
    +                            1 => __('Manual'),
    +                        ],
    +                        'name'     => 'interval_manual_defined',
    +                        'return'   => true,
    +                    ],
    +                    'extra'     => ''.html_print_extended_select_for_time(
    +                        'interval',
    +                        $this->task['interval_sweep'],
    +                        '',
    +                        '',
    +                        '0',
    +                        false,
    +                        true,
    +                        false,
    +                        false
    +                    ).ui_print_help_tip(
    +                        __('The minimum recomended interval for Recon Task is 5 minutes'),
    +                        true
    +                    ).'',
    +                ];
    +
    +                $str = __('Next');
    +
    +                if (isset($this->task['id_rt']) === true) {
    +                    $str = __('Update and continue');
    +                }
    +
    +                // Submit button.
    +                $form['inputs'][] = [
    +                    'arguments' => [
    +                        'name'       => 'submit',
    +                        'label'      => $str,
    +                        'type'       => 'submit',
    +                        'attributes' => 'class="sub next"',
    +                        'return'     => true,
    +                    ],
    +                ];
    +
    +                $task_url = '';
    +                if (isset($this->task['id_rt'])) {
    +                    $task_url = '&task='.$this->task['id_rt'];
    +                }
    +
    +                $form['form'] = [
    +                    'method' => 'POST',
    +                    'action' => $this->url.'&mode=customnetscan&page='.($this->page + 1).$task_url,
    +                ];
    +
    +                // Default.
    +                $interval = 600;
    +                $unit = 60;
    +                if (isset($this->task['interval_sweep']) === true) {
    +                    $interval = $this->task['interval_sweep'];
    +                    $unit = $this->getTimeUnit($interval);
    +                }
    +
    +                $form['js'] = '
    +                    $("select#interval_manual_defined").change(function() {
    +                        if ($("#interval_manual_defined").val() == 1) {
    +                            $("#interval_manual_container").hide();
    +                            $("#text-interval_text").val(0);
    +                            $("#hidden-interval").val(0);
    +                        }
    +                        else {
    +                            $("#interval_manual_container").show();
    +                            $("#text-interval_text").val(10);
    +                            $("#hidden-interval").val('.$interval.');
    +                            $("#interval_units").val('.$unit.');
    +                        }
    +                    }).change();
    +                ';
    +
    +                // XXX: Could be improved validating inputs before continue (JS)
    +                // Print NetScan page 0.
    +                $this->printForm($form);
    +            }
    +        }
    +
    +        if (isset($this->page) === true && $this->page === 1) {
    +            $name_ipam = 'IPAM Recon';
    +            // Recon script.
    +            $form['inputs'][] = [
    +                'label'     => ''.__('Recon script').'',
    +                'arguments' => [
    +                    'type'     => 'select_from_sql',
    +                    'sql'      => sprintf(
    +                        'SELECT id_recon_script, name FROM trecon_script WHERE name <> "%s" ORDER BY name',
    +                        $name_ipam
    +                    ),
    +                    'name'     => 'id_recon_script',
    +                    'selected' => $this->task['id_recon_script'],
    +                    'return'   => true,
    +                ],
    +            ];
    +
    +            $form['inputs'][] = [
    +                'hidden'    => 1,
    +                'arguments' => [
    +                    'type'  => 'hidden',
    +                    'name'  => 'task',
    +                    'value' => $this->task['id_rt'],
    +                ],
    +            ];
    +
    +            $form['inputs'][] = [
    +                'hidden'    => 1,
    +                'arguments' => [
    +                    'type'   => 'hidden_extended',
    +                    'name'   => 'macros',
    +                    'value'  => base64_encode($this->task['macros']),
    +                    'return' => true,
    +                ],
    +            ];
    +
    +            // Explanation.
    +            $explanation = db_get_value(
    +                'description',
    +                'trecon_script',
    +                'id_recon_script',
    +                $this->task['id_recon_script']
    +            );
    +
    +            $form['inputs'][] = [
    +                'label'     => ''.__('Explanation').'',
    +                'arguments' => [
    +                    'type'       => 'textarea',
    +                    'rows'       => 4,
    +                    'columns'    => 60,
    +                    'name'       => 'explanation',
    +                    'value'      => $explanation,
    +                    'return'     => true,
    +                    'attributes' => 'style="width: 388px;"',
    +                ],
    +            ];
    +
    +            $form['inputs'][] = [
    +                'hidden'    => 1,
    +                'id'        => 'table_recon-macro_field',
    +                'label'     => ''.__('macro_desc').''.ui_print_help_tip('macro_help', true),
    +                'arguments' => [
    +                    'name'   => 'macro_name',
    +                    'value'  => 'macro_value',
    +                    'type'   => 'text',
    +                    'size'   => 100,
    +                    'return' => true,
    +                ],
    +            ];
    +
    +            if (empty($this->task['macros']) === false) {
    +                $macros = json_decode($this->task['macros'], true);
    +                foreach ($macros as $k => $m) {
    +                    $label_macro = '';
    +                    $label_macro .= ''.$m['desc'].'';
    +                    if (!empty($m['help'])) {
    +                        $label_macro .= ui_print_help_tip(
    +                            $m['help'],
    +                            true
    +                        );
    +                    }
    +
    +                    if ($m['hide']) {
    +                        $form['inputs'][] = [
    +                            'label'     => $label_macro,
    +                            'id'        => 'table_recon-macro'.$m['macro'],
    +                            'class'     => 'macro_field',
    +                            'arguments' => [
    +                                'name'   => $m['macro'],
    +                                'value'  => $m['value'],
    +                                'type'   => 'password',
    +                                'size'   => 100,
    +                                'return' => true,
    +                            ],
    +                        ];
    +                    } else {
    +                        $form['inputs'][] = [
    +                            'label'     => $label_macro,
    +                            'id'        => 'table_recon-macro'.$m['macro'],
    +                            'class'     => 'macro_field',
    +                            'arguments' => [
    +                                'name'   => $m['macro'],
    +                                'value'  => $m['value'],
    +                                'type'   => 'text',
    +                                'size'   => 100,
    +                                'return' => true,
    +                            ],
    +                        ];
    +                    }
    +                }
    +            }
    +
    +            // Submit button.
    +            $form['inputs'][] = [
    +                'arguments' => [
    +                    'name'       => 'submit',
    +                    'label'      => __('Finish'),
    +                    'type'       => 'submit',
    +                    'attributes' => 'class="sub next"',
    +                    'return'     => true,
    +                ],
    +            ];
    +
    +            $form['form'] = [
    +                'method' => 'POST',
    +                'action' => $this->url.'&mode=customnetscan&page='.($this->page + 1).'&task='.$this->task['id_rt'],
    +            ];
    +
    +            $id_task = (isset($this->task['id_rt']) === true) ? $this->task['id_rt'] : 0;
    +
    +            $url_ajax = $config['homeurl'].'ajax.php';
    +
    +            $change = '';
    +            if (empty($this->task['macros']) !== false) {
    +                $change = '.change();';
    +            }
    +
    +            $form['js'] = '
    +                $("select#id_recon_script").change(function() {
    +                    get_explanation_recon_script($(this).val(), "'.$id_task.'", "'.$url_ajax.'");
    +                })'.$change;
    +
    +            $this->printForm($form);
    +        }
    +
    +        if (isset($this->page) === true && $this->page === 2) {
    +            if ($this->task['id_rt']) {
    +                // 0 - Is OK.
    +                $this->result = 0;
    +                $this->msg = __('Task configured.');
    +            } else {
    +                // 1 - Is NOT OK.
    +                $this->result = 1;
    +                $this->msg = __('Wizard failed. Cannot configure task.');
    +            }
    +
    +            return [
    +                'result' => $this->result,
    +                'id'     => $this->task['id_rt'],
    +                'msg'    => $this->msg,
    +            ];
    +        }
    +
    +        ui_require_javascript_file('pandora_modules');
    +    }
    +
    +
    +}
    diff --git a/pandora_console/include/class/ManageNetScanScripts.class.php b/pandora_console/include/class/ManageNetScanScripts.class.php
    new file mode 100644
    index 0000000000..f3ca4c92b5
    --- /dev/null
    +++ b/pandora_console/include/class/ManageNetScanScripts.class.php
    @@ -0,0 +1,767 @@
    +url = ui_get_full_url(
    +            'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=hd'
    +        );
    +        $this->page = $page;
    +        $this->breadcrum = $breadcrum;
    +    }
    +
    +
    +    /**
    +     * Run function. It will be call into HostsDevices class.
    +     *      Page 0: Upload form.
    +     *      Page 1: Task resume.
    +     *
    +     * @return void
    +     */
    +    public function runManageNetScanScript()
    +    {
    +        global $config;
    +
    +        if (check_acl($config['id_user'], 0, 'AW') === 0) {
    +            db_pandora_audit(
    +                'ACL Violation',
    +                'Trying to access Net Scan Script.'
    +            );
    +            include 'general/noaccess.php';
    +            return;
    +        }
    +
    +        $run_url = 'index.php?sec=gservers&sec2=godmode/servers/discovery';
    +
    +        $breadcrum = [
    +            [
    +                'link'  => 'index.php?sec=gservers&sec2=godmode/servers/discovery',
    +                'label' => 'Discovery',
    +            ],
    +            [
    +                'link'  => $run_url.'&wiz=hd',
    +                'label' => __('Host & Devices'),
    +            ],
    +        ];
    +
    +        for ($i = 0; $i < $this->MAXPAGES; $i++) {
    +            $breadcrum[] = [
    +                'link'     => $run_url.'&wiz=hd&mode=managenetscanscripts&page='.$i,
    +                'label'    => __($this->pageLabels[$i]),
    +                'selected' => (($i == $this->page) ? 1 : 0),
    +            ];
    +        }
    +
    +        if ($this->page < $this->MAXPAGES) {
    +            // Avoid to print header out of wizard.
    +            $this->prepareBreadcrum($breadcrum);
    +
    +            // Header
    +            ui_print_page_header(__('Net scan scripts'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true));
    +        }
    +
    +        $id_script = get_parameter('id_script', 0);
    +
    +        // Initialize msg.
    +        $msg = [];
    +
    +        // Operations.
    +        $operation_scp = get_parameter('operation_scp', '');
    +        if ($operation_scp !== '') {
    +            switch ($operation_scp) {
    +                case 'update_scp':
    +                    $msg = $this->updateScanScripts($id_script);
    +                break;
    +
    +                case 'delete_scp':
    +                    $msg = $this->deleteScanScripts($id_script);
    +                break;
    +
    +                case 'create_scp':
    +                    $msg = $this->createScanScripts($id_script);
    +                break;
    +
    +                default:
    +                    // Nothing for doing. Never exist other operation.
    +                break;
    +            }
    +        }
    +
    +        if (!isset($this->page) || $this->page === 0) {
    +            $this->printListNetScanScripts($msg);
    +        }
    +
    +        if (!isset($this->page) || $this->page === 1) {
    +            $this->printFormScanScripts($id_script);
    +        }
    +    }
    +
    +
    +    /**
    +     * Create net scan script.
    +     *
    +     * @return array Check msg successfully or problem
    +     */
    +    private function createScanScripts()
    +    {
    +        $result = [];
    +
    +        $reconscript_name = get_parameter('form_name', '');
    +        $reconscript_description = get_parameter('form_description', '');
    +        $reconscript_script = get_parameter('form_script', '');
    +
    +        // Get macros.
    +        $i = 1;
    +        $macros = [];
    +        while (1) {
    +            $macro = (string) get_parameter('field'.$i.'_macro');
    +            if ($macro == '') {
    +                break;
    +            }
    +
    +            $desc = (string) get_parameter('field'.$i.'_desc');
    +            $help = (string) get_parameter('field'.$i.'_help');
    +            $value = (string) get_parameter('field'.$i.'_value');
    +            $hide = get_parameter('field'.$i.'_hide');
    +
    +            $macros[$i]['macro'] = $macro;
    +            $macros[$i]['desc'] = $desc;
    +            $macros[$i]['help'] = $help;
    +            $macros[$i]['value'] = $value;
    +            $macros[$i]['hide'] = $hide;
    +            $i++;
    +        }
    +
    +        $macros = io_json_mb_encode($macros);
    +
    +        $values = [
    +            'name'        => $reconscript_name,
    +            'description' => $reconscript_description,
    +            'script'      => $reconscript_script,
    +            'macros'      => $macros,
    +        ];
    +
    +        $result_crt = false;
    +        if ($values['name'] !== '' && $values['script'] !== '') {
    +            $result_crt = db_process_sql_insert('trecon_script', $values);
    +            if (!$result_crt) {
    +                $result = [
    +                    'error' => 1,
    +                    'msg'   => __('Problem creating'),
    +                ];
    +            } else {
    +                $result = [
    +                    'error' => 0,
    +                    'msg'   => __('Created successfully'),
    +                ];
    +            }
    +        } else {
    +            $result = [
    +                'error' => 1,
    +                'msg'   => __('Name or Script fullpath they can not be empty'),
    +            ];
    +        }
    +
    +        return $result;
    +    }
    +
    +
    +    /**
    +     * Update net scan script.
    +     *
    +     * @param integer $id_script Id script.
    +     *
    +     * @return array Check msg successfully or problem
    +     */
    +    private function updateScanScripts(int $id_script)
    +    {
    +        $result = [];
    +        if (isset($id_script) === false || $id_script === 0) {
    +            $result = [
    +                'error' => 1,
    +                'msg'   => __('Problem deleting Net scan Scripts, Not selected script'),
    +            ];
    +
    +            return $result;
    +        }
    +
    +        // If modified any parameter.
    +        $reconscript_name = get_parameter('form_name', '');
    +        $reconscript_description = get_parameter('form_description', '');
    +        $reconscript_script = get_parameter('form_script', '');
    +
    +        // Get macros.
    +        $i = 1;
    +        $macros = [];
    +        while (1) {
    +            $macro = (string) get_parameter('field'.$i.'_macro');
    +            if ($macro == '') {
    +                break;
    +            }
    +
    +            $desc = (string) get_parameter('field'.$i.'_desc');
    +            $help = (string) get_parameter('field'.$i.'_help');
    +            $value = (string) get_parameter('field'.$i.'_value');
    +            $hide = get_parameter('field'.$i.'_hide');
    +
    +            $macros[$i]['macro'] = $macro;
    +            $macros[$i]['desc'] = $desc;
    +            $macros[$i]['help'] = $help;
    +            $macros[$i]['value'] = $value;
    +            $macros[$i]['hide'] = $hide;
    +            $i++;
    +        }
    +
    +        $macros = io_json_mb_encode($macros);
    +
    +        $sql_update = sprintf(
    +            "UPDATE trecon_script SET
    +		        name = '%s',
    +		        description = '%s',
    +		        script = '%s',
    +		        macros = '%s'
    +            WHERE id_recon_script = %d",
    +            $reconscript_name,
    +            $reconscript_description,
    +            $reconscript_script,
    +            $macros,
    +            $id_script
    +        );
    +
    +        $result_upd = false;
    +        if ($reconscript_name !== '' && $reconscript_script !== '') {
    +            $result_upd = db_process_sql($sql_update);
    +            if (!$result_upd) {
    +                $result = [
    +                    'error' => 1,
    +                    'msg'   => __('Problem updating'),
    +                ];
    +            } else {
    +                $result = [
    +                    'error' => 0,
    +                    'msg'   => __('Updated successfully'),
    +                ];
    +            }
    +        } else {
    +            $result = [
    +                'error' => 1,
    +                'msg'   => __('Name or Script fullpath they can not be empty'),
    +            ];
    +        }
    +
    +        return $result;
    +    }
    +
    +
    +    /**
    +     * Delete net scan script.
    +     *
    +     * @param integer $id_script Id script.
    +     *
    +     * @return array Check msg successfully or problem
    +     */
    +    private function deleteScanScripts(int $id_script)
    +    {
    +        $result = [];
    +        if (isset($id_script) === false || $id_script === 0) {
    +            $result = [
    +                'error' => 1,
    +                'msg'   => __('Problem deleting Net scan Scripts, Not selected script'),
    +            ];
    +
    +            return $result;
    +        }
    +
    +        $result_dlt = db_process_sql_delete(
    +            'trecon_script',
    +            ['id_recon_script' => $id_script]
    +        );
    +
    +        if (!$result_dlt) {
    +            $result = [
    +                'error' => 1,
    +                'msg'   => __('Problem deleting Net scan Scripts'),
    +            ];
    +        } else {
    +            $result_dlt2 = db_process_sql_delete(
    +                'trecon_task',
    +                ['id_recon_script' => $id_script]
    +            );
    +
    +            if (!$result_dlt2) {
    +                $result = [
    +                    'error' => 1,
    +                    'msg'   => __('Problem deleting Net scan Scripts'),
    +                ];
    +            } else {
    +                $result = [
    +                    'error' => 0,
    +                    'msg'   => __('Deleted successfully'),
    +                ];
    +            }
    +        }
    +
    +        return $result;
    +
    +    }
    +
    +
    +    /**
    +     * Print list Net scan scripts and messages operations.
    +     *
    +     * @param array $msg Print msg if necessary.
    +     *
    +     * @return void
    +     */
    +    private function printListNetScanScripts(array $msg)
    +    {
    +        if (count($msg) > 0) {
    +            if ($msg['error'] === 1) {
    +                ui_print_error_message($msg['msg']);
    +            } else {
    +                ui_print_success_message($msg['msg']);
    +            }
    +        }
    +
    +        $url = 'index.php?sec=gservers&sec2=godmode/servers/discovery';
    +        $url .= '&wiz=hd&mode=managenetscanscripts';
    +
    +        // List available Net scan scripts.
    +        $rows = db_get_all_rows_in_table('trecon_script');
    +
    +        if ($rows !== false) {
    +            echo '';
    +            echo '';
    +            echo '';
    +            echo '';
    +            $color = 0;
    +            foreach ($rows as $row) {
    +                if ($color == 1) {
    +                    $tdcolor = 'datos';
    +                    $color = 0;
    +                } else {
    +                    $tdcolor = 'datos2';
    +                    $color = 1;
    +                }
    +
    +                echo '';
    +                echo "';
    +                echo "';
    +            }
    +
    +            echo '
    '.__('Name').''.__('Description').''.__('Delete').'
    "; + echo ''; + echo $row['name']; + echo '"; + $desc = io_safe_output( + $row['description'] + ); + + $desc = str_replace( + "\n", + '
    ', + $desc + ); + + echo $desc.'

    '; + echo ''.__('Command').': '.$row['script'].''; + echo "
    "; + // Delete. + echo ''; + echo html_print_input_hidden('page', 0, true); + echo html_print_input_hidden( + 'operation_scp', + 'delete_scp', + true + ); + echo html_print_input_hidden( + 'id_script', + $row['id_recon_script'], + true + ); + echo html_print_input_image( + 'delete', + 'images/cross.png', + 1, + '', + true, + [ + 'title' => __('Delete Script'), + ] + ); + echo ''; + echo '
    '; + + echo "
    "; + echo html_print_input_hidden('page', 1, true); + echo ""; + echo '
    '; + } else { + ui_print_info_message( + [ + 'no_close' => true, + 'message' => __( + 'There are no net scan scripts in the system' + ), + ] + ); + } + } + + + /** + * Print form net scan scripts. + * + * @param integer $id_script Id script. + * + * @return void + */ + private function printFormScanScripts(int $id_script) + { + // Initialize vars. + if ($id_script !== 0) { + $form_id = $id_script; + $reconscript = db_get_row( + 'trecon_script', + 'id_recon_script', + $form_id + ); + $form_name = $reconscript['name']; + $form_description = $reconscript['description']; + $form_script = $reconscript['script']; + $macros = $reconscript['macros']; + } else { + $form_name = ''; + $form_description = ''; + $form_script = ''; + $macros = ''; + } + + $url = 'index.php?sec=gservers&sec2=godmode/servers/discovery'; + $url .= '&wiz=hd&mode=managenetscanscripts'; + + if ($id_script !== 0) { + echo '
    '; + echo html_print_input_hidden('page', 0, true); + echo html_print_input_hidden( + 'operation_scp', + 'update_scp', + true + ); + } else { + echo ''; + echo html_print_input_hidden('page', 0, true); + echo html_print_input_hidden( + 'operation_scp', + 'create_scp', + true + ); + } + + $table = new stdClass(); + $table->width = '100%'; + $table->id = 'table-form'; + $table->class = 'databox filters'; + $table->style = []; + $table->style[0] = 'font-weight: bold'; + $table->style[2] = 'font-weight: bold'; + $table->data = []; + + $data = []; + $data[0] = __('Name'); + $data[0] .= ui_print_help_icon( + 'reconscript_definition', + true, + '', + 'images/help_w.png' + ); + + $data[1] = ''; + $table->data['recon_name'] = $data; + $table->colspan['recon_name'][1] = 3; + + $data = []; + $data[0] = __('Script fullpath'); + $data[1] = ''; + $table->data['recon_fullpath'] = $data; + $table->colspan['recon_fullpath'][1] = 3; + + $data = []; + $data[0] = __('Description'); + $data[1] = ''; + $table->data['recon_description'] = $data; + $table->colspan['recon_description'][1] = 3; + + $macros = json_decode($macros, true); + + // This code is ready to add locked feature as plugins. + $locked = false; + + // The next row number is recon_3. + $next_name_number = 3; + $i = 1; + while (1) { + // Always print at least one macro. + if ((!isset($macros[$i]) || $macros[$i]['desc'] == '') && $i > 1) { + break; + } + + $macro_desc_name = 'field'.$i.'_desc'; + $macro_desc_value = ''; + $macro_help_name = 'field'.$i.'_help'; + $macro_help_value = ''; + $macro_value_name = 'field'.$i.'_value'; + $macro_value_value = ''; + $macro_name_name = 'field'.$i.'_macro'; + $macro_name = '_field'.$i.'_'; + $macro_hide_value_name = 'field'.$i.'_hide'; + $macro_hide_value_value = 0; + + if (isset($macros[$i]['desc'])) { + $macro_desc_value = $macros[$i]['desc']; + } + + if (isset($macros[$i]['help'])) { + $macro_help_value = $macros[$i]['help']; + } + + if (isset($macros[$i]['value'])) { + $macro_value_value = $macros[$i]['value']; + } + + if (isset($macros[$i]['hide'])) { + $macro_hide_value_value = $macros[$i]['hide']; + } + + $datam = []; + $datam[0] = __('Description'); + $datam[0] .= " ( "; + $datam[0] .= $macro_name; + $datam[0] .= ' )'; + $datam[0] .= html_print_input_hidden( + $macro_name_name, + $macro_name, + true + ); + $datam[1] = html_print_input_text_extended( + $macro_desc_name, + $macro_desc_value, + 'text-'.$macro_desc_name, + '', + 30, + 255, + $locked, + '', + "class='command_advanced_conf'", + true + ); + if ($locked) { + $datam[1] .= html_print_image( + 'images/lock.png', + true, + ['class' => 'command_advanced_conf'] + ); + } + + $datam[2] = __('Default value'); + $datam[2] .= " ( "; + $datam[2] .= $macro_name; + $datam[2] .= ' ) '; + $datam[3] = html_print_input_text_extended( + $macro_value_name, + $macro_value_value, + 'text-'.$macro_value_name, + '', + 30, + 255, + $locked, + '', + "class='command_component command_advanced_conf'", + true + ); + if ($locked) { + $datam[3] .= html_print_image( + 'images/lock.png', + true, + ['class' => 'command_advanced_conf'] + ); + } + + $table->data['recon_'.$next_name_number] = $datam; + + $next_name_number++; + + $table->colspan['recon_'.$next_name_number][1] = 3; + + $datam = []; + $datam[0] = __('Hide value'); + $datam[0] .= ui_print_help_tip( + __('This field will show up as dots like a password'), + true + ); + + $datam[1] = html_print_checkbox_extended( + $macro_hide_value_name, + 1, + $macro_hide_value_value, + 0, + '', + ['class' => 'command_advanced_conf'], + true, + 'checkbox-'.$macro_hide_value_name + ); + + $table->data['recon_'.$next_name_number] = $datam; + $next_name_number++; + + $table->colspan['recon_'.$next_name_number][1] = 3; + + $datam = []; + $datam[0] = __('Help'); + $datam[0] .= " ( "; + $datam[0] .= $macro_name; + $datam[0] .= ' )


    '; + + $tadisabled = ($locked === true) ? ' disabled' : ''; + + $datam[1] = html_print_textarea( + $macro_help_name, + 6, + 100, + $macro_help_value, + 'class="command_advanced_conf" style="width: 97%;"'.$tadisabled, + true + ); + + if ($locked) { + $datam[1] .= html_print_image( + 'images/lock.png', + true, + ['class' => 'command_advanced_conf'] + ); + } + + $datam[1] .= '


    '; + + $table->data['recon_'.$next_name_number] = $datam; + $next_name_number++; + $i++; + } + + if (!$locked) { + $datam = []; + $datam[0] = ''; + $datam[0] .= __('Add macro').''; + $datam[0] .= ''; + $datam[0] .= html_print_image( + 'images/add.png', + true + ); + $datam[0] .= ''; + $datam[0] .= ''; + $datam[0] .= ''; + + $delete_macro_style = ''; + if ($i <= 2) { + $delete_macro_style = 'display:none;'; + } + + $datam[2] = ''; + + $table->colspan['recon_action'][0] = 2; + $table->rowstyle['recon_action'] = 'text-align:center'; + $table->colspan['recon_action'][2] = 2; + $table->data['recon_action'] = $datam; + } + + html_print_table($table); + + echo ''; + echo '
    '; + + if ($id_script === 0) { + echo ""; + } else { + echo ""; + } + + echo '
    '; + + ui_require_javascript_file('pandora_modules'); + } + + +} diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php new file mode 100644 index 0000000000..17133d4d65 --- /dev/null +++ b/pandora_console/include/class/NetworkMap.class.php @@ -0,0 +1,3493 @@ + is really 'rawNodes' here you put an array like follows: + * nodes => [ + * 'some_id' => [ + * 'type' => NODE_GENERIC/NODE_PANDORA/NODE_MODULE/NODE_AGENT, + * behaviour and fields to be used are different depending + * on the type. + * 'id_agente' => 'some_id', + * 'status' => 'agent status', + * 'id_parent' => 'target parent to match in map, its no need to use the + * real parent but must match some_id' + * 'id_node' => incremental id (0,1,2,3...), + * 'image' => relative path to image to use, + * 'label' => label to use (in NODE_GENERIC) + * ] + * ] + * + * Tooltipster support: Keep in mind, using tooltipster behaviour + * of map changes. + * + * Sample usage: + * + * + * + * $map_manager = new NetworkMap( + * [ + * 'nodes' => vmware_get_nodes($show_vms, $show_ds, $show_esx), + * 'pure' => 1, + * 'use_tooltipster' => 1, + * 'tooltip_params' => [ + * 'page' => 'operation/agentes/ver_agente', + * 'get_agent_json' => 1, + * ], + * ] + * ); + * + * $map_manager->printMap(); + * + * + */ +class NetworkMap +{ + + /** + * Target map Id, from tmap. If the maps is being simulated + * then the idMap value will be uniqid. + * + * @var integer + */ + public $idMap; + + /** + * Content of tmap. Map definition. If the map is being simulated + * then defaults to constructor received parameters. + * + * @var array + */ + public $map; + + /** + * Data origin, network. + * + * @var string + */ + public $network; + + /** + * Data origin, group id. + * + * @var integer + */ + public $idGroup; + + /** + * Data origin, Discovery task. + * + * @var integer + */ + public $idTask; + + /** + * Graph definition. Previously was 'nodes_and_relationships' + * Is the data format before be translated to JS variables. + * + * @var array + */ + public $graph; + + /** + * Dot string with graph definition. + * Its contents will be send to graphviz to calculate node positions. + * + * @var string + */ + public $dotGraph; + + /** + * Node list processed by NetworkMap class. + * + * @var array + */ + public $nodes; + + /** + * Node list RAW. + * A simple list of nodes, could content information of agents, modules... + * Is the 'raw' information. + * + * @var array + */ + public $rawNodes; + + /** + * Useful to translate id_node to id_agent or id_module. + * Maps built nodes to original node information (agents, modules). + * + * @var array + */ + public $nodeMapping; + + /** + * Relationship map. + * Each element contents: + * id_parent + * id_child + * parent_type + * child_type + * id_parent_source_data (from $this->nodes) + * id_child_source_data (from $this->nodes) + * + * @var array + */ + public $relations; + + /** + * Include a Pandora (or vendor) node or not. + * + * @var integer + */ + public $noPandoraNode; + + /** + * Use tooltipster interface instead of standard. + * + * @var boolean + */ + public $useTooltipster; + + /** + * Options used in AJAX call while using tooltipster. + * + * @var array + */ + public $tooltipParams; + + /** + * Shows the map using 100% of height and width if is a widget. + * + * @var boolean + */ + public $fullSize; + + /** + * Defines a custom method to parse Graphviz output and generate Graph. + * Function pointer. + * + * @var string + */ + public $customParser; + + /** + * Defines arguments to be passed to $customParser. + * If is not defined, default arguments will be used. + * + * @var array + */ + public $customParserArgs; + + /** + * If using a custom parser, fallback to default parser while + * found exceptions. + * + * @var boolean + */ + public $fallbackDefaultParser; + + /** + * Array of map options. Because how is built, the structure matches + * with tmap definition, where map_filter is the json-extracted data. + * Duplicate options appears since tmap stores information in different + * ways (simplifies process). + * If an idMap is defined, map is loaded into this structure and used along + * the class. + * generation_method + * simple + * font_size + * nooverlap + * z_dash + * ranksep + * center + * regen + * pure + * show_snmp_modules + * cut_names + * relative + * text_filter + * dont_show_subgroups + * strict_user + * size_canvas + * old_mode + * map_filter (array) + * dont_show_subgroups + * node_radius + * x_offs + * y_offs + * z_dash + * node_sep + * rank_sep + * mindist + * kval + * + * @var array + */ + public $mapOptions; + + /** + * Filter (command) to use to calculate node positions. + * + * @var string + */ + private $filter; + + /** + * Do not show the popup window. + * + * @var integer + */ + private $noPopUp; + + + /** + * Base constructor. + * + * @param mixed $options Could define in array as: + * id_map => target discovery task id. + * id_group => target group. + * network => target CIDR. + * graph => target graph (already built). + * nodes => target agents or nodes. + * relations => target array of relationships. + * mode => simple (0) or advanced (1). + * map_options => Map options. + * + * @return object New networkmap manager. + */ + public function __construct($options=false) + { + global $config; + + // Default mapOptions values. + // Defines the command to generate positions. + $this->mapOptions['generation_method'] = LAYOUT_SPRING1; + $this->mapOptions['width'] = $config['networkmap_max_width']; + $this->mapOptions['height'] = $config['networkmap_max_width']; + $this->mapOptions['simple'] = 0; + $this->mapOptions['font_size'] = 20; + $this->mapOptions['nooverlap'] = 1; + $this->mapOptions['z_dash'] = 0.5; + $this->mapOptions['center'] = 0; + $this->mapOptions['regen'] = 0; + $this->mapOptions['pure'] = 0; + $this->mapOptions['show_snmp_modules'] = false; + $this->mapOptions['cut_names'] = false; + $this->mapOptions['relative'] = true; + $this->mapOptions['text_filter'] = ''; + $this->mapOptions['dont_show_subgroups'] = false; + $this->mapOptions['strict_user'] = false; + $this->mapOptions['size_canvas'] = 0; + $this->mapOptions['old_mode'] = false; + $this->mapOptions['map_filter'] = [ + 'dont_show_subgroups' => 0, + 'node_radius' => 40, + 'x_offs' => 0, + 'y_offs' => 0, + 'z_dash' => 0.5, + 'node_sep' => 5, + 'rank_sep' => 5, + 'mindist' => 1, + 'kval' => 0.1, + ]; + + if (is_array($options)) { + // Previously nodes_and_relations. + if (isset($options['graph'])) { + $this->graph = $options['graph']; + } + + // String dotmap. + if (isset($options['dot_graph'])) { + $this->dotGraph = $options['dot_graph']; + } + + // Array of nodes, agents, virtual, etc. + if (isset($options['nodes'])) { + $this->rawNodes = $options['nodes']; + } + + // Array of relations. + if (isset($options['relations'])) { + $this->relations = $options['relations']; + } + + // User interface type. Simple or advanced. + if (isset($options['mode'])) { + $this->mode = $options['mode']; + } + + // Show interface elements or dashboard style. + if (isset($options['pure'])) { + $this->mapOptions['pure'] = $options['pure']; + } + + if (isset($options['no_pandora_node'])) { + $this->noPandoraNode = $options['no_pandora_node']; + } + + if (isset($options['no_popup'])) { + $this->noPopUp = $options['no_popup']; + } + + // Initialize as widget? + if (isset($options['widget'])) { + $this->fullSize = (bool) $options['widget']; + } else { + $this->fullSize = true; + } + + // Use a custom parser. + if (isset($options['custom_parser'])) { + $this->customParser = $options['custom_parser']; + } + + // Custom parser arguments. + if (isset($options['custom_parser_args'])) { + if (is_array($options['custom_parser_args'])) { + foreach ($options['custom_parser_args'] as $k) { + $this->customParserArgs[] = $k; + } + } else { + $this->customParserArgs = $options['custom_parser_args']; + } + } + + // Fallback to default parser. + if (isset($options['fallback_to_default_parser'])) { + $this->fallbackDefaultParser = $options['fallback_to_default_parser']; + } + + if (isset($options['use_tooltipster'])) { + $this->useTooltipster = $options['use_tooltipster']; + } + + if (is_array($options['tooltip_params'])) { + foreach ($options['tooltip_params'] as $k => $v) { + $this->tooltipParams[$k] = $v; + } + } + + // Map options, check default values above. + // This is only used while generating new maps using + // (generateDotGraph). + if (isset($options['map_options']) + && is_array($options['map_options']) + ) { + foreach ($options['map_options'] as $k => $v) { + if ($k == 'map_filter' && is_array($v)) { + foreach ($v as $kc => $vc) { + $this->mapOptions['map_filter'][$kc] = $vc; + } + } else { + $this->mapOptions[$k] = $v; + } + } + } + + // Load from tmap. + if ($options['id_map']) { + $this->idMap = $options['id_map']; + // Update nodes and relations. + $this->loadMap(); + + if (empty($this->nodes) + && empty($this->relations) + ) { + $this->createMap(); + } + } else { + // Generate from group, task or network. + if ($options['id_group']) { + $this->idGroup = $options['id_group']; + } + + if ($options['id_task']) { + $this->idTask = $options['id_task']; + } + + if ($options['network']) { + $this->network = $options['network']; + } + + $this->createMap(); + } + } + + return $this; + + } + + + /** + * Creates a new map based on a target. + * + * Target is specified from constructor arguments. + * options: + * - id_task => create a map from task. + * - id_group => create a map from group. + * - network => create a map from network. + * + * @return void + */ + public function createMap() + { + // If exists, load from DB. + if ($this->idMap) { + $this->loadMap(); + + return; + } + + // Simulated map. + $this->idMap = uniqid(); + // No tmap definition. Paint data. + if ($this->idTask) { + $recon_task = db_get_row_filter( + 'trecon_task', + ['id_rt' => $this->idTask] + ); + $this->network = $recon_task['subnet']; + } + + // Simulate map entry. + $this->map = [ + 'id' => $this->idMap, + '__simulated' => 1, + 'background' => '', + 'background_options' => 0, + 'source_period' => 60, + 'filter' => $this->mapOptions['map_filter'], + 'width' => $config['networkmap_max_width'], + 'height' => $config['networkmap_max_width'], + 'center_x' => 0, + 'center_y' => 0, + ]; + + if (isset($this->mapOptions['generation_method']) === false) { + $this->mapOptions['generation_method'] = LAYOUT_SPRING1; + } + + // Load filter. + $this->loadFilter(); + + // Will be stored in $this->graph. + $this->generateNetworkMap(); + + } + + + /** + * Update filter and layout based on generation_method selected. + * + * @return boolean True or false. + */ + private function loadFilter() + { + if (is_array($this->mapOptions) === false) { + return false; + } + + switch ($this->mapOptions['generation_method']) { + case LAYOUT_CIRCULAR: + $this->filter = 'circo'; + $this->mapOptions['layout'] = 'circular'; + break; + + case LAYOUT_FLAT: + $this->filter = 'dot'; + $this->mapOptions['layout'] = 'flat'; + break; + + case LAYOUT_RADIAL: + $this->filter = 'twopi'; + $this->mapOptions['layout'] = 'radial'; + break; + + case LAYOUT_SPRING1: + default: + $this->filter = 'neato'; + $this->mapOptions['layout'] = 'spring1'; + break; + + case LAYOUT_SPRING2: + $this->filter = 'fdp'; + $this->mapOptions['layout'] = 'spring2'; + break; + } + + return true; + } + + + /** + * Loads a map from a target map ID. + * + * @return void. + */ + public function loadMap() + { + if ($this->map) { + // Already loaded. + return; + } + + if ($this->idMap) { + $this->map = db_get_row('tmap', 'id', $this->idMap); + + $this->mapOptions['map_filter'] = json_decode( + $this->map['filter'], + true + ); + + foreach ($this->map as $k => $v) { + $this->mapOptions[$k] = $v; + } + + // Load filter. + $this->loadFilter(); + + // Retrieve data origin. + $this->network = null; + $this->idTask = null; + $this->idGroup = $this->map['id_group']; + + switch ($this->map['source']) { + case SOURCE_TASK: + $this->idTask = $this->map['source_data']; + break; + + case SOURCE_NETWORK: + $this->network = $this->map['source_data']; + break; + + case SOURCE_GROUP: + // Already load. + default: + // Ignore. + break; + } + + if ($this->idTask) { + $recon_task = db_get_row_filter( + 'trecon_task', + ['id_rt' => $this->idTask] + ); + $this->network = $recon_task['subnet']; + } + + // Retrieve or update nodes and relations. + $this->getNodes(); + $this->getRelations(); + + // Nodes and relations will be stored in $this->graph. + $this->loadGraph(); + } + } + + + /** + * Retrieves node information using id_node as mapping instead element id. + * + * @param integer $id_node Target node. + * @param string $field Field to retrieve, if null, all are return. + * + * @return mixed Array (node data) or null if error. + */ + public function getNodeData(int $id_node, $field=null) + { + if (is_array($this->nodes) === false + || is_array($this->nodeMapping) === false + ) { + return null; + } + + if (is_array($this->nodes[$this->nodeMapping[$id_node]]) === true) { + if (isset($field) === false) { + return $this->nodes[$this->nodeMapping[$id_node]]; + } else { + return $this->nodes[$this->nodeMapping[$id_node]][$field]; + } + } else { + return null; + } + } + + + /** + * Set nodes. + * + * @param array $nodes Nodes definition. + * + * @return void + */ + public function setNodes($nodes) + { + $this->nodes = $nodes; + } + + + /** + * Return nodes of current map. + * + * @return array Nodes. + */ + public function getNodes() + { + if ($this->nodes) { + return $this->nodes; + } + + if ($this->idMap !== false) { + if (enterprise_installed()) { + // Enterprise environment: LOAD. + $this->nodes = enterprise_hook( + 'get_nodes_from_db', + [$this->idMap] + ); + } + } + + return $this->nodes; + + } + + + /** + * Set relations. + * + * @param array $relations Relations definition. + * + * @return void + */ + public function setRelations($relations) + { + $this->relations = $relations; + } + + + /** + * Return relations of current map. + * + * @return array Relations. + */ + public function getRelations() + { + if ($this->relations) { + return $this->relations; + } + + if ($this->idMap !== false) { + if (enterprise_installed()) { + $this->relations = enterprise_hook( + 'get_relations_from_db', + [$this->idMap] + ); + } + } + + return $this->relations; + + } + + + /** + * Search for nodes in current map definition. + * + * @return array Nodes detected, internal variable NOT updated. + */ + public function calculateNodes() + { + global $config; + + // Calculate. + // Search. + if (enterprise_installed() && $this->idTask) { + // Network map, based on discovery task. + return enterprise_hook( + 'get_discovery_agents', + [$this->idTask] + ); + } + + if ($this->network) { + // Network map, based on direct network. + $nodes = networkmap_get_nodes_from_ip_mask( + $this->network + ); + } else if ($this->mapOptions['map_filter']['empty_map']) { + // Empty map returns no data. + $nodes = []; + } else { + if ($this->mapOptions['map_filter']['dont_show_subgroups'] === 'true' + || $this->mapOptions['map_filter']['dont_show_subgroups'] == 1 + ) { + // Show only current selected group. + $filter['id_grupo'] = $this->idGroup; + } else { + // Show current group and children. + $childrens = groups_get_childrens($this->idGroup, null, true); + if (!empty($childrens)) { + $childrens = array_keys($childrens); + + $filter['id_grupo'] = $childrens; + $filter['id_grupo'][] = $this->idGroup; + } else { + $filter['id_grupo'] = $this->idGroup; + } + } + + // Group map. + $nodes = agents_get_agents( + $filter, + ['*'], + 'AR', + [ + 'field' => 'id_parent', + 'order' => 'ASC', + ] + ); + + if (is_array($nodes)) { + // Remap ids. + $nodes = array_reduce( + $nodes, + function ($carry, $item) { + $carry[$item['id_agente']] = $item; + return $carry; + } + ); + } else { + $nodes = []; + } + } + + return $nodes; + } + + + /** + * Search for relations for a given node in current map definition. + * Use id_parent in custom node definition to create an edge between + * two nodes. + * + * Representation is to => from because from could be equal in multiple + * edges but no to (1 origin, multiple targets). + * + * @param array $id_source Id for source data, agent, module or custom. + * + * @return array Relations found for given node. + */ + public function calculateRelations( + $id_source + ) { + // Calculate. + $node = $this->nodes[$id_source]; + if (is_array($node) === false) { + return false; + } + + $relations = []; + $i = 0; + $from_type = NODE_AGENT; + $to_type = NODE_AGENT; + switch ($node['node_type']) { + case NODE_AGENT: + // Search for agent parent and module relationships. + $module_relations = modules_get_relations( + ['id_agent' => $node['id_agente']] + ); + + if ($module_relations !== false) { + // Module relation exist. + foreach ($module_relations as $mod_rel) { + // Check if target referenced agent is defined in + // current map. + $agent_a = modules_get_agentmodule_agent( + $mod_rel['module_a'] + ); + $module_a = $mod_rel['module_a']; + $agent_b = modules_get_agentmodule_agent( + $mod_rel['module_b'] + ); + $module_b = $mod_rel['module_b']; + + // Calculate target. + $module_to = $module_a; + $agent_to = $agent_a; + $module_from = $module_b; + $agent_from = $agent_b; + + // Module relations does not have from and to, + // If current agent_a is current node, reverse relation. + if ($agent_a == $node['id_agente']) { + $module_to = $module_b; + $agent_to = $agent_b; + $module_from = $module_a; + $agent_from = $agent_a; + } + + $target_node = $this->nodes[NODE_AGENT.'_'.$agent_to]; + + if (isset($target_node) === false) { + // Agent is not present in this map. + continue; + } + + $rel = []; + // Node reference (child). + $rel['id_child'] = $node['id_node']; + $rel['child_type'] = NODE_MODULE; + $rel['id_child_source_data'] = $module_from; + $rel['id_child_agent'] = $agent_from; + + // Node reference (parent). + $rel['id_parent'] = $target_node['id_node']; + $rel['parent_type'] = NODE_MODULE; + $rel['id_parent_source_data'] = $module_to; + $rel['id_parent_agent'] = $agent_to; + + // Store relation. + $relations[] = $rel; + } + } + + // Add also parent relationship. + $parent_id = NODE_AGENT.'_'.$node['id_parent']; + + if ((int) $node['id_parent'] > 0) { + $parent_node = $this->nodes[$parent_id]['id_node']; + } + + // Store relationship. + if (is_integer($parent_node) && $node['id_parent'] > 0) { + $rel = []; + + // Node reference (parent). + $rel['id_parent'] = $parent_node; + $rel['parent_type'] = NODE_AGENT; + $rel['id_parent_source_data'] = $node['id_parent']; + + // Node reference (child). + $rel['id_child'] = $node['id_node']; + $rel['child_type'] = NODE_AGENT; + $rel['id_child_source_data'] = $node['id_agente']; + + // Store relation. + $relations[] = $rel; + } + break; + + case NODE_MODULE: + // Search for module relationships. + $module_relations = modules_get_relations( + ['id_module' => $node['id_agente_modulo']] + ); + + if ($module_relations !== false) { + // Module relation exist. + foreach ($module_relations as $mod_rel) { + // Check if target referenced agent is defined in + // current map. + $agent_a = modules_get_agentmodule_agent( + $mod_rel['module_a'] + ); + $module_a = $mod_rel['module_a']; + $agent_b = modules_get_agentmodule_agent( + $mod_rel['module_b'] + ); + $module_b = $mod_rel['module_b']; + + // Calculate target. + $module_to = $module_a; + $agent_to = $agent_a; + $module_from = $module_b; + $agent_from = $agent_b; + + // Module relations does not have from and to, + // If current agent_a is current node, reverse relation. + if ($agent_a == $node['id_agente']) { + $module_to = $module_b; + $agent_to = $agent_b; + $module_from = $module_a; + $agent_from = $agent_a; + } + + $target_node = $this->nodes[NODE_AGENT.'_'.$agent_to]; + + if (isset($target_node) === false) { + // Agent is not present in this map. + continue; + } + + $rel = []; + // Node reference (child). + $rel['id_child'] = $node['id_node']; + $rel['child_type'] = NODE_MODULE; + $rel['id_child_source_data'] = $module_from; + $rel['id_child_agent'] = $agent_from; + + // Node reference (parent). + $rel['id_parent'] = $target_node['id_node']; + $rel['parent_type'] = NODE_MODULE; + $rel['id_parent_source_data'] = $module_to; + $rel['id_parent_agent'] = $agent_to; + + // Store relation. + $relations[] = $rel; + } + } + break; + + case NODE_GENERIC: + // Handmade ones. + // Add also parent relationship. + $parent_id = $node['id_parent']; + + if ((int) $parent_id > 0) { + $parent_node = $this->getNodeData( + (int) $parent_id, + 'id_node' + ); + } + + // Store relationship. + if ($parent_node) { + $relations[] = [ + 'id_parent' => $parent_node, + 'parent_type' => NODE_GENERIC, + 'id_child' => $node['id_node'], + 'child_type' => NODE_GENERIC, + ]; + } + break; + + case NODE_PANDORA: + default: + // Ignore. + break; + } + + // Others. + return $relations; + } + + + /** + * Generates or loads nodes&relations array from DB. + * Load, calculates statuses and leave the structure in $this->graph. + * + * * Structure generated: + * Nodes: + * id_map. + * id. + * id_agent. + * id_module. + * type. + * x. + * y. + * width. + * height. + * text. + * source_data. + * style (json). + * + * Relations: + * id_map. + * id_parent. + * parent_type. + * id_parent_source_data. + * id_child. + * child_type. + * id_child_source_data. + * id_parent_agent. + * id_child_agent. + * + * @return void + */ + public function loadGraph() + { + $nodes = $this->nodes; + $relations = $this->relations; + + // Generate if there's no data in DB about nodes or relations. + if (empty($nodes) && empty($relations)) { + $this->generateNetworkMap(); + return; + } + + $graph = enterprise_hook( + 'networkmap_load_map', + [$this] + ); + + if ($graph === ENTERPRISE_NOT_HOOK) { + // Method not available, regenerate. + $this->generateNetworkMap(); + return; + } + + $this->graph = $graph; + + } + + + /** + * Generates a graph definition (header only) for dot graph. + * + * @return string Dot graph header. + */ + public function openDotFile() + { + global $config; + + $overlap = 'compress'; + + $map_filter = $this->mapOptions['map_filter']; + $nooverlap = $this->mapOptions['nooverlap']; + $zoom = $this->mapOptions['zoom']; + + if (isset($this->mapOptions['width']) + && isset($this->mapOptions['height']) + ) { + $size_x = ($this->mapOptions['width'] / 100); + $size_y = ($this->mapOptions['height'] / 100); + } else if (isset($config['networkmap_max_width'])) { + $size_x = ($config['networkmap_max_width'] / 100); + $size_y = ($size_x * 0.8); + } else { + $size_x = 8; + $size_y = 5.4; + $size = ''; + } + + if ($zoom > 0) { + $size_x *= $zoom; + $size_y *= $zoom; + } + + $size = $size_x.','.$size_y; + + if ($size_canvas === null) { + $size = ($this->mapOptions['size_canvas']['x'] / 100); + $size .= ','.($this->mapOptions['size_canvas']['y'] / 100); + } + + // Graphviz custom values. + if (isset($map_filter['node_sep'])) { + $node_sep = $map_filter['node_sep']; + } else { + $node_sep = 0.1; + } + + if (isset($map_filter['rank_sep'])) { + $rank_sep = $map_filter['rank_sep']; + } else { + if ($layout == 'radial') { + $rank_sep = 1.0; + } else { + $rank_sep = 0.5; + } + } + + if (isset($map_filter['mindist'])) { + $mindist = $map_filter['mindist']; + } else { + $mindist = 1.0; + } + + if (isset($map_filter['kval'])) { + $kval = $map_filter['kval']; + } else { + $kval = 0.1; + } + + // BEWARE: graphwiz DONT use single ('), you need double ("). + $head = 'graph networkmap { dpi=100; bgcolor="transparent"; labeljust=l; margin=0; pad="0.75,0.75";'; + if ($nooverlap != '') { + $head .= 'overlap=scale;'; + $head .= 'outputorder=first;'; + } + + if ($layout == 'flat' + || $layout == 'spring1' + || $layout == 'spring2' + ) { + if ($nooverlap != '') { + $head .= 'overlap="scalexy";'; + } + + if ($layout == 'flat') { + $head .= 'ranksep="'.$rank_sep.'";'; + } + + if ($layout == 'spring2') { + $head .= 'K="'.$kval.'";'; + } + } + + if ($layout == 'radial') { + $head .= 'ranksep="'.$rank_sep.'";'; + } + + if ($layout == 'circular') { + $head .= 'mindist="'.$mindist.'";'; + } + + $head .= 'ratio="fill";'; + $head .= 'root=0;'; + $head .= 'nodesep="'.$node_sep.'";'; + $head .= 'size="'.$size.'";'; + + $head .= "\n"; + + return $head; + } + + + /** + * Creates a node in dot format. + * Requirements: + * id_node + * id_source + * status => defines 'color' + * label + * image + * url + * + * @param array $data Node definition. + * + * @return string Dot node. + */ + public function createDotNode($data) + { + global $config; + + if (is_array($data) === false) { + return ''; + } + + $dot_str = ''; + + // Color is being printed by D3, not graphviz. + // Used only for positioning. + $color = COL_NORMAL; + $label = $data['label']; + $url = 'none'; + $parent = $data['parent']; + $font_size = $this->mapOptions['font_size']; + $radius = $this->mapOptions['map_filter']['node_radius']; + $radius /= GRAPHVIZ_RADIUS_CONVERSION_FACTOR; + + if (strlen($label) > 16) { + $label = ui_print_truncate_text($label, 16, false, true, false); + } + + // If radius is 0, set to 1 instead. + if ($radius <= 0) { + $radius = 1; + } + + // Simple node always. This kind of node is used only to + // retrieve X,Y positions from graphviz no for personalization. + $dot_str = $data['id_node'].' [ parent="'.$data['id_parent'].'"'; + $dot_str .= ', color="'.$color.'", fontsize='.$font_size; + $dot_str .= ', shape="doublecircle"'.$url_node_link; + $dot_str .= ', style="filled", fixedsize=true, width='.$radius; + $dot_str .= ', height='.$radius.', label="'.$label.'"]'."\n"; + + return $dot_str; + } + + + /** + * Avoid multiple connections between two nodes if any of them does not + * add more information. Prioritize. + * + * For instance, if we have module - module relationship and agent - agent + * discard agent - agent relationship (module - module apports more + * information). + * + * @return void + */ + public function cleanGraphRelations() + { + global $config; + + $relations = $this->graph['relations']; + + $cleaned = []; + $rel_map = []; + + /* + * Relation map: + * id_child.'_'.id_parent => [ + * 'priority' (0,1) + * 'relation_index' + * ] + */ + + if (is_array($relations)) { + foreach ($relations as $index => $rel) { + /* + * AA, AM and MM links management + * Priority: + * 1 -> MM (module - module) + * 1 -> AM (agent - module) + * 0 -> AA (agent - agent) + */ + + $id_parent = $rel['id_parent']; + $id_child = $rel['id_child']; + $rel_type = $rel['child_type'].'_'.$rel['parent_type']; + + $valid = 0; + $key = -1; + if ($rel['parent_type'] == NODE_MODULE + && $rel['child_type'] == NODE_MODULE + ) { + // Module information available. + $priority = 1; + $valid = 1; + + if (is_array($rel_map[$id_child.'_'.$id_parent])) { + // Already defined. + $key = $id_child.'_'.$id_parent; + $data = $rel_map[$id_child.'_'.$id_parent]; + if ($priority > $data['priority']) { + unset($rel[$data['index']]); + } else { + $valid = 0; + } + } + + if (is_array($rel_map[$id_parent.'_'.$id_child])) { + // Already defined. + $key = $id_parent.'_'.$id_child; + $data = $rel_map[$id_parent.'_'.$id_child]; + if ($priority > $data['priority']) { + unset($rel[$data['index']]); + } else { + $valid = 0; + } + } + + if ($valid == 1) { + $rel_map[$id_parent.'_'.$id_child] = [ + 'index' => $index, + 'priority' => $priority, + ]; + } + } else if ($rel['parent_type'] == NODE_AGENT + && $rel['child_type'] == NODE_AGENT + ) { + // Module information not available. + $priority = 0; + $valid = 1; + + if (is_array($rel_map[$id_child.'_'.$id_parent])) { + // Already defined. + $key = $id_child.'_'.$id_parent; + $data = $rel_map[$id_child.'_'.$id_parent]; + if ($priority > $data['priority']) { + unset($rel[$data['index']]); + } else { + $valid = 0; + } + } + + if (is_array($rel_map[$id_parent.'_'.$id_child])) { + // Already defined. + $key = $id_parent.'_'.$id_child; + $data = $rel_map[$id_parent.'_'.$id_child]; + if ($priority > $data['priority']) { + unset($rel[$data['index']]); + } else { + $valid = 0; + } + } + + if ($valid == 1) { + $rel_map[$id_parent.'_'.$id_child] = [ + 'index' => $index, + 'priority' => $priority, + ]; + } + } else if ($rel['parent_type'] == NODE_MODULE + && $rel['child_type'] == NODE_AGENT + ) { + // Module information not available. + $priority = 1; + + $valid = 1; + } else if ($rel['parent_type'] == NODE_AGENT + && $rel['child_type'] == NODE_MODULE + ) { + // Module information not available. + $priority = 1; + + $valid = 1; + } else { + // Pandora & generic links are always accepted. + $valid = 1; + } + + if ($valid === 1) { + if ($rel['id_parent'] != $rel['id_child']) { + $cleaned[] = $rel; + } + } + } + } else { + return; + } + + $this->graph['relations'] = $cleaned; + } + + + /** + * Internal method to allow developer to compare status from + * different origins by checking a value. + * + * Greater value implies more critical. + * + * @param integer $status Status. + * + * @return integer Criticity value. + */ + private static function getStatusNumeric($status) + { + if (isset($status) === false) { + return NO_CRIT; + } + + switch ($status) { + case AGENT_MODULE_STATUS_NORMAL: + case AGENT_STATUS_NORMAL: + return CRIT_1; + + case AGENT_MODULE_STATUS_NOT_INIT: + case AGENT_STATUS_NOT_INIT: + return CRIT_0; + + case AGENT_MODULE_STATUS_CRITICAL_BAD: + case AGENT_STATUS_CRITICAL: + return CRIT_4; + + case AGENT_MODULE_STATUS_WARNING: + case AGENT_STATUS_WARNING: + return CRIT_3; + + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case AGENT_MODULE_STATUS_WARNING_ALERT: + case AGENT_STATUS_ALERT_FIRED: + return CRIT_5; + + case AGENT_MODULE_STATUS_UNKNOWN: + case AGENT_STATUS_UNKNOWN: + return CRIT_2; + + default: + // Ignored. + break; + } + + return NO_CRIT; + } + + + /** + * Returns worst status from two received. + * Agent and module statuses should be identical, unless little differences. + * + * @param integer $status_a Status A. + * @param integer $status_b Status B. + * + * @return integer Status A or status B, the worstest one. + */ + public static function getWorstStatus($status_a, $status_b) + { + // Case agent statuses. + $a = self::getStatusNumeric($status_a); + $b = self::getStatusNumeric($status_b); + + return ($a > $b) ? $status_a : $status_b; + } + + + /** + * Returns target color to be used based on the status received. + * + * @param integer $status Source information. + * + * @return string HTML tag for color. + */ + public static function getColorByStatus($status) + { + if (isset($status) === false) { + return COL_UNKNOWN; + } + + switch ($status) { + case AGENT_MODULE_STATUS_NORMAL: + case AGENT_STATUS_NORMAL: + return COL_NORMAL; + + case AGENT_MODULE_STATUS_NOT_INIT: + case AGENT_STATUS_NOT_INIT: + return COL_NOTINIT; + + case AGENT_MODULE_STATUS_CRITICAL_BAD: + case AGENT_STATUS_CRITICAL: + return COL_CRITICAL; + + case AGENT_MODULE_STATUS_WARNING: + case AGENT_STATUS_WARNING: + return COL_WARNING; + + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case AGENT_MODULE_STATUS_WARNING_ALERT: + case AGENT_STATUS_ALERT_FIRED: + return COL_ALERTFIRED; + + case AGENT_MODULE_STATUS_UNKNOWN: + case AGENT_STATUS_UNKNOWN: + return COL_UNKNOWN; + + default: + // Ignored. + break; + } + + return COL_IGNORED; + + } + + + /** + * Translates a standard node into a JS node with following attributes: + * + * @param array $nodes Input array (standard nodes structure). + * id_map. + * id_db. + * type. + * source_data. + * x. + * y. + * z. + * state. + * deleted. + * style. + * shape. + * image. + * label. + * id_agent. + * id_networkmap. + * + * @return array Object ready to be dump to JS. + * * Output array (translated): + * id. + * id_db. + * type. + * id_agent. + * id_module. + * fixed. + * x. + * y. + * px. + * py. + * z. + * state. + * deleted. + * image_url. + * image_width. + * image_height. + * raw_text. + * text. + * shape. + * color. + * map_id. + * networkmap_id. + */ + public function nodesToJS($nodes) + { + global $config; + + $return = []; + foreach ($nodes as $node) { + $item = []; + $item['id'] = $node['id']; + + if ($node['deleted']) { + // Skip deleted nodes. + continue; + } + + // Id titem. + if (isset($this->map['__simulated']) === false) { + $item['id_db'] = $node['id_db']; + } else { + $item['id_db'] = (int) $node['id']; + } + + // Get source data. + $source_data = $this->getNodeData($node['id']); + + if (is_array($node['style']) === false) { + $node['style'] = json_decode($node['style'], true); + } + + $item['type'] = $node['type']; + $item['fixed'] = true; + $item['x'] = (int) $node['x']; + $item['y'] = (int) $node['y']; + $item['z'] = (int) $node['z']; + + // X,Y aliases for D3. + $item['px'] = $item['x']; + $item['py'] = $item['y']; + + // Status represents the status of the node (critical, warning...). + // State represents state of node in map (in holding_area or not). + $item['state'] = $node['state']; + $item['deleted'] = $node['deleted']; + + // Node color. + $item['color'] = self::getColorByStatus($source_data['status']); + switch ($node['type']) { + case NODE_AGENT: + $item['id_agent'] = $node['source_data']; + break; + + case NODE_MODULE: + $item['id_module'] = $node['source_data']; + break; + + case NODE_PANDORA: + $item['color'] = COL_IGNORED; + $node['style']['image'] = ui_get_logo_to_center_networkmap(); + break; + + case NODE_GENERIC: + default: + foreach ($source_data as $k => $v) { + $node[$k] = $v; + } + + $node['style']['label'] = $node['name']; + $node['style']['shape'] = 'circle'; + $item['color'] = self::getColorByStatus($node['status']); + break; + } + + // Calculate values. + // 40 => DEFAULT NODE RADIUS. + // 30 => alignment factor. + $holding_area_max_y = ($this->mapOptions['height'] + 30 + $this->mapOptions['map_filter']['node_radius'] * 2 - $this->mapOptions['map_filter']['holding_area'][1] + 10 * $this->mapOptions['map_filter']['node_radius']); + + // Update position if node must be stored in holding_area. + if ($item['state'] == 'holding_area') { + $holding_area_x = ($this->mapOptions['width'] + 30 + $this->mapOptions['map_filter']['node_radius'] * 2 - $this->mapOptions['map_filter']['holding_area'][0] + ($count_item_holding_area % 11) * $this->mapOptions['map_filter']['node_radius']); + $holding_area_y = ($this->mapOptions['height'] + 30 + $this->mapOptions['map_filter']['node_radius'] * 2 - $this->mapOptions['map_filter']['holding_area'][1] + (int) (($count_item_holding_area / 11)) * $this->mapOptions['map_filter']['node_radius']); + + // Keep holding area nodes in holding area. + if ($holding_area_max_y <= $holding_area_y) { + $holding_area_y = $holding_area_max_y; + } + + $item['x'] = $holding_area_x; + $item['y'] = $holding_area_y; + + // Increment for the next node in holding area. + $count_item_holding_area++; + } + + // Node image. + $item['image_url'] = ''; + $item['image_width'] = 0; + $item['image_height'] = 0; + if (empty($node['style']['image']) === false) { + $item['image_url'] = ui_get_full_url( + $node['style']['image'] + ); + $image_size = getimagesize( + $config['homedir'].'/'.$node['style']['image'] + ); + $item['image_width'] = (int) $image_size[0]; + $item['image_height'] = (int) $image_size[1]; + } + + $item['raw_text'] = $node['style']['label']; + $item['text'] = io_safe_output($node['style']['label']); + $item['shape'] = $node['style']['shape']; + $item['map_id'] = $node['id_map']; + if (!isset($node['style']['id_networkmap']) + || $node['style']['id_networkmap'] == '' + || $node['style']['id_networkmap'] == 0 + ) { + $item['networkmap_id'] = 0; + } else { + $item['networkmap_id'] = $node['style']['id_networkmap']; + } + + // XXX: Compatibility with Tooltipster - Simple map controller. + if ($this->useTooltipster) { + $item['label'] = $item['text']; + $item['image'] = $item['image_url']; + $item['image_height'] = 52; + $item['image_width'] = 52; + $item['width'] = $this->mapOptions['map_filter']['node_radius']; + $item['height'] = $this->mapOptions['map_filter']['node_radius']; + } + + $return[] = $item; + } + + return $return; + } + + + /** + * Transforms an edge relationship into a JS array to be dumped. + * Sets fields like status, link color and updates some internal identifiers + * used by JS frontend. + * + * @param array $edges Edges information in array of following items. + * + * * Input structure: + * id_map. + * id_parent. + * parent_type. + * id_parent_source_data. + * id_child. + * child_type. + * id_child_source_data. + * id_parent_agent. + * id_child_agent. + * + * @return array Edge translated to JS object. + * + * * Output structure: + * arrow_start. + * arrow_end. + * status_start. + * status_end. + * id_module_start. + * id_agent_start. + * id_module_end. + * id_agent_end. + * link_color. + * target. + * source. + * deleted. + * target_id_db. + * source_id_db. + * text_start. + * text_end. + */ + public function edgeToJS($edges) + { + $return = []; + // JS edge pseudo identificator. + $i = 0; + foreach ($edges as $rel) { + $item = []; + + // Simulated index. + $item['id_db'] = $i; + $item['deleted'] = 0; + + // Else load. + if (isset($this->map['__simulated']) === false) { + $item['id_db'] = $rel['id_db']; + $item['deleted'] = $rel['deleted']; + $item['target_id_db'] = $this->getNodeData( + $rel['id_parent'], + 'id_db' + ); + $item['source_id_db'] = $this->getNodeData( + $rel['id_child'], + 'id_db' + ); + } + + if ($item['deleted']) { + // Relation is deleted. Avoid. + continue; + } + + // Set relationship as 'agent' by default. + // Generic and Pandora nodes simulates agent relationships. + $item['arrow_start'] = 'agent'; + $item['arrow_end'] = 'agent'; + $item['source'] = $rel['id_parent']; + $item['target'] = $rel['id_child']; + $item['id_agent_start'] = $rel['id_child_agent']; + $item['id_agent_end'] = $rel['id_parent_agent']; + + if ($rel['parent_type'] == NODE_MODULE) { + $item['arrow_start'] = 'module'; + $item['id_module_start'] = $rel['id_parent_source_data']; + $item['status_start'] = modules_get_agentmodule_status( + $item['id_module_start'] + ); + + // Extract interface name to be placed on edge. + $text = modules_get_agentmodule_name( + (int) $item['id_module_start'] + ); + if (preg_match( + '/(.+)_ifOperStatus$/', + (string) $text, + $matches + ) + ) { + if ($matches[1]) { + $item['text_start'] = io_safe_output($matches[1]); + } + } + } + + if ($rel['child_type'] == NODE_MODULE) { + $item['arrow_end'] = 'module'; + $item['id_module_end'] = $rel['id_child_source_data']; + $item['status_end'] = modules_get_agentmodule_status( + $item['id_module_end'] + ); + + // Extract interface name to be placed on edge. + $text = modules_get_agentmodule_name( + (int) $item['id_module_end'] + ); + if (preg_match( + '/(.+)_ifOperStatus$/', + (string) $text, + $matches + ) + ) { + if ($matches[1]) { + $item['text_end'] = io_safe_output($matches[1]); + } + } + } + + if (isset($rel['text_start']) && !empty($rel['text_start'])) { + // Direct text_start definition. + $item['text_start'] = $rel['text_start']; + } + + if (isset($rel['text_end']) && !empty($rel['text_end'])) { + // Direct text_end definition. + $item['text_end'] = $rel['text_end']; + } + + if (isset($rel['link_color']) && !empty($rel['link_color'])) { + // Direct color definition. + $item['link_color'] = $rel['link_color']; + } else { + // Use worst case to set link color. + $item['link_color'] = self::getColorByStatus( + self::getWorstStatus( + $item['status_start'], + $item['status_end'] + ) + ); + } + + // XXX: Compatibility with Tooltipster - Simple map controller. + if ($this->useTooltipster) { + $item['orig'] = $rel['id_parent']; + $item['dest'] = $rel['id_child']; + } + + // Set direct values. + $item['id'] = $i++; + + $return[] = $item; + } + + return $return; + } + + + /** + * Creates an edge in dot format. + * Requirements: + * from + * to + * + * @param array $data Edge content. + * + * @return string Dot code for given edge. + */ + public function createDotEdge($data) + { + if (is_array($data) === false) { + return ''; + } + + if (!isset($data['from']) || !isset($data['to'])) { + return ''; + } + + $edge = "\n".$data['from'].' -- '.$data['to']; + $edge .= '[len='.$this->mapOptions['map_filter']['node_sep']; + $edge .= ', color="#BDBDBD", headclip=false, tailclip=false,'; + $edge .= ' edgeURL=""];'."\n"; + + return $edge; + } + + + /** + * Returns dot file end string. + * + * @return string Dot file end string. + */ + public function closeDotFile() + { + return '}'; + } + + + /** + * Generate a graphviz string structure to be used later. + * + * Usage: + * To create a new handmade graph: + * Define node struture + * key => node source data (agent/module row or custom) + * + * Minimum required fields in array: + * label + * status + * id + * + * @param array $nodes Generate dotgraph using defined nodes. + * + * @return void + */ + public function generateDotGraph($nodes=false) + { + if (!isset($this->dotGraph)) { + // Generate dot file. + $this->nodes = []; + $edges = []; + $graph = ''; + + if ($nodes === false) { + if (isset($this->rawNodes)) { + $nodes = $this->rawNodes; + } else { + // Search for nodes. + $nodes = $this->calculateNodes(); + } + } + + // Search for relations. + // Build dot structure. + // Open Graph. + $graph = $this->openDotFile(); + + if (!$this->noPandoraNode) { + // Create empty pandora node to link orphans. + $this->nodes[0] = [ + 'label' => get_product_name(), + 'id_node' => 0, + 'id_agente' => 0, + 'id_agente_modulo' => 0, + 'node_type' => NODE_PANDORA, + ]; + + $this->nodeMapping[0] = 0; + + $graph .= $this->createDotNode( + $this->nodes[0] + ); + $i = 1; + } else { + $i = 0; + } + + // Create dot nodes. + $orphans = []; + foreach ($nodes as $k => $node) { + if ((isset($node['type']) && $node['type'] == NODE_AGENT + || isset($node['type']) && $node['type'] == NODE_MODULE) + || (isset($node['type']) === false + && isset($node['id_agente']) === true + && $node['id_agente'] > 0) + ) { + // Origin is agent or module. + if (isset($node['type']) && $node['type'] == NODE_MODULE + || (isset($node['type']) === false + && isset($node['id_agente_modulo']) === true + && $node['id_agente_modulo'] > 0) + ) { + $k = NODE_MODULE.'_'.$k; + // Origin is module. + $id_source = $node['id_agente_modulo']; + $label = io_safe_output($node['nombre']); + $status = modules_get_agentmodule_status($node); + $this->nodes[$k]['node_type'] = NODE_MODULE; + + $url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$node['id_agente']; + $url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_agentmodule_status_tooltip=1&id_module='.$node['id_agente_modulo']; + } else { + // Origin is agent. + $k = NODE_AGENT.'_'.$k; + $id_source = $node['id_agente']; + $label = io_safe_output($node['alias']); + $status = agents_get_status_from_counts($node); + $this->nodes[$k]['node_type'] = NODE_AGENT; + + $url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$node['id_agente']; + $url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_agent_status_tooltip=1&id_agent='.$node['id_agente']; + } + } else { + // Handmade node. + // Store user node definitions. + $k = NODE_GENERIC.'_'.$k; + $id_source = $node['id']; + $label = $node['label']; + $status = $node['status']; + $this->nodes[$k]['node_type'] = NODE_GENERIC; + // In handmade nodes, edges are defined by using id_parent + // Referencing target parent 'id'. + $this->nodes[$k]['id_parent'] = $node['id_parent']; + $this->nodes[$k]['width'] = $node['width']; + $this->nodes[$k]['height'] = $node['height']; + $this->nodes[$k]['id_source'] = $node['id_source']; + $this->nodes[$k]['shape'] = $node['shape']; + $url = $this->node['url']; + $url_tooltip = $this->node['url_tooltip']; + } + + $this->nodes[$k]['url'] = $url; + $this->nodes[$k]['url_tooltip'] = $url_tooltip; + + // Fullfill data. + // If url is defined in node will be overwritten. + foreach ($node as $key => $value) { + $this->nodes[$k][$key] = $value; + } + + $graph .= $this->createDotNode( + [ + 'id_node' => $i, + 'id_source' => $id_source, + 'label' => $label, + 'image' => null, + ] + ); + + // Keep reverse reference. + $this->nodeMapping[$i] = $k; + $this->nodes[$k]['id_source_data'] = $id_source; + $this->nodes[$k]['id_node'] = $i; + $this->nodes[$k]['status'] = $status; + + // Increase for next node. + $i++; + } + + if (!$this->relations) { + // Search for relations. + foreach ($this->nodes as $k => $item) { + $target = $this->calculateRelations($k); + + // Adopt all orphan nodes but pandora one. + if (empty($target)) { + if (isset($this->noPandoraNode) === false + || $this->noPandoraNode == false + ) { + if ($item['id_node'] != 0) { + $rel = []; + $rel['id_parent'] = 0; + $rel['id_child'] = $item['id_node']; + $rel['parent_type'] = NODE_PANDORA; + $rel['child_type'] = $item['node_type']; + $rel['id_child_source_data'] = $item['id_source_data']; + + $orphans[] = $rel; + } + } + } else { + // Flattern edges. + foreach ($target as $rel) { + $edges[] = $rel; + } + } + } + } else { + $edges = $this->relations; + } + + if (is_array($edges)) { + foreach ($edges as $rel) { + $graph .= $this->createDotEdge( + [ + 'to' => $rel['id_child'], + 'from' => $rel['id_parent'], + ] + ); + } + } else { + $edges = []; + } + + if (isset($this->noPandoraNode) === false + || $this->noPandoraNode == false + ) { + // Add missed edges. + foreach ($orphans as $rel) { + $graph .= $this->createDotEdge( + [ + 'from' => $rel['id_child'], + 'to' => $rel['id_parent'], + ] + ); + } + + // Store relationships. + $this->relations = array_merge($edges, $orphans); + } else { + $this->relations = $edges; + } + + // Close dot file. + $graph .= $this->closeDotFile(); + $this->dotGraph = $graph; + } + } + + + /** + * Extracts node coordinates and relationships built by graphviz. + * + * @param string $graphviz_file Graphviz output file path. + * + * @return mixed Nodes and relations if success. False if not. + */ + private function parseGraphvizMapFile($graphviz_file) + { + global $config; + + if (isset($graphviz_file) === false + || is_file($graphviz_file) === false + ) { + return false; + } + + $content = file($graphviz_file); + + $nodes = []; + $relations = []; + foreach ($content as $key => $line) { + // Reduce blank spaces. + $line = preg_replace('/\ +/', ' ', $line); + + if (preg_match('/^graph.*$/', $line) != 0) { + // Graph definition. + $fields = explode(' ', $line); + $this->map['width'] = ($fields[2] * 10 * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + $this->map['height'] = ($fields[3] * 10 * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + + if ($this->map['width'] > $config['networkmap_max_width']) { + $this->map['width'] = $config['networkmap_max_width']; + } + + if ($this->map['height'] > $config['networkmap_max_width']) { + $this->map['height'] = $config['networkmap_max_width']; + } + } else if (preg_match('/^node.*$/', $line) != 0) { + // Node. + $fields = explode(' ', $line); + $id = $fields[1]; + $nodes[$id]['x'] = (($fields[2] * $this->mapOptions['map_filter']['node_radius']) - $this->mapOptions['map_filter']['rank_sep'] * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + $nodes[$id]['y'] = (($fields[3] * $this->mapOptions['map_filter']['node_radius']) - $this->mapOptions['map_filter']['rank_sep'] * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + } else if (preg_match('/^edge.*$/', $line) != 0 + && empty($this->relations) === true + ) { + // Edge. + // This is really not needed, because is already defined + // in $this->relations. Only for debug purposes. + $fields = explode(' ', $line); + + if (strpos($fields[1], 'transp_') !== false + || strpos($fields[2], 'transp_') !== false + ) { + // Skip transparent nodes relationships. + continue; + } + + $relations[] = [ + 'id_parent' => $target_node['id_node'], + 'parent_type' => NODE_GENERIC, + 'id_parent_source_data' => $mod_rel['module_b'], + 'id_child' => $node['id_node'], + 'child_type' => NODE_GENERIC, + 'id_child_source_data' => $mod_rel['module_a'], + ]; + } + } + + // Use current relationship definitions (if exists). + if (empty($this->relations) === false) { + $relations = $this->relations; + } + + return [ + 'nodes' => $nodes, + 'relations' => $relations, + ]; + + } + + + /** + * Calculates X,Y positions foreach element defined in dotGraph. + * + * @return array Structure parsed. + */ + public function calculateCoords() + { + global $config; + + switch (PHP_OS) { + case 'WIN32': + case 'WINNT': + case 'Windows': + $filename_dot = sys_get_temp_dir()."\\networkmap_".$filter; + break; + + default: + $filename_dot = sys_get_temp_dir().'/networkmap_'.$filter; + break; + } + + if ($this->mapOptions['simple']) { + $filename_dot .= '_simple'; + } + + if ($this->mapOptions['nooverlap']) { + $filename_dot .= '_nooverlap'; + } + + $filename_dot .= uniqid().'_'.$this->idMap.'.dot'; + + file_put_contents($filename_dot, $this->dotGraph); + + $plain_file = 'plain'.uniqid().'.txt'; + switch (PHP_OS) { + case 'WIN32': + case 'WINNT': + case 'Windows': + $filename_plain = sys_get_temp_dir().'\\'.$plain_file; + + $cmd = io_safe_output( + $config['graphviz_bin_dir'].'\\'.$this->filter.'.exe -Tplain -o '.$filename_plain.' '.$filename_dot + ); + break; + + default: + $filename_plain = sys_get_temp_dir().'/'.$plain_file; + + $cmd = $this->filter.' -Tplain -o '.$filename_plain.' '.$filename_dot; + break; + } + + $retval = 0; + $r = system($cmd, $retval); + + if ($retval != 0) { + ui_print_error_message( + __('Failed to generate dotmap, please select different layout schema') + ); + return []; + } + + unlink($filename_dot); + + if (function_exists($this->customParser)) { + try { + if (empty($this->customParserArgs)) { + $graph = call_user_func( + $this->customParser, + $filename_plain, + $this->dotGraph + ); + } else { + $graph = call_user_func( + $this->customParser, + $filename_plain, + $this->dotGraph, + $this->customParserArgs + ); + } + } catch (Exception $e) { + // If developer is using a custom method to parse graphviz + // results, but want to handle using default parser + // or custom based on data, it is possible to launch + // exceptions to control internal flow. + if ($this->fallbackDefaultParser === true) { + $graph = $this->parseGraphvizMapFile( + $filename_plain + ); + } else { + ui_print_error_message($e->getMessage()); + $graph = []; + } + } + } else { + $graph = $this->parseGraphvizMapFile( + $filename_plain + ); + } + + unlink($filename_plain); + + /* + * Graphviz section ends here. + */ + + return $graph; + } + + + /** + * Creates an empty dot graph (with only base node) + * + * @return void + */ + public function generateEmptyDotGraph() + { + // Create an empty map dot structure. + $graph = $this->openDotFile(); + + $this->nodes[0] = [ + 'label' => get_product_name(), + 'id_node' => 0, + 'id_agente' => 0, + 'id_agente_modulo' => 0, + 'node_type' => NODE_PANDORA, + ]; + + $this->nodeMapping[0] = 0; + + $graph .= $this->createDotNode( + $this->nodes[0] + ); + + $graph .= $this->closeDotFile(); + + $this->dotGraph = $graph; + } + + + /** + * Returns the most representative ID based on the tipe of node received. + * + * @param array $node Source data. + * + * @return integer Source id. + */ + private function auxGetIdByType($node) + { + if (!is_array($node)) { + return 0; + } + + switch ($to_source['node_type']) { + case NODE_MODULE: + return $node['id_agente_modulo']; + + case NODE_AGENT: + return $node['id_agente']; + + case NODE_GENERIC: + return $node['id_node']; + + case NODE_PANDORA: + default: + return 0; + } + } + + + /** + * Generates a nodes - relationships array using graphviz dot + * schema and stores nodes&relations into $this->graph. + * + * @return void + */ + public function generateNetworkMap() + { + global $config; + + include_once 'include/functions_os.php'; + + $map_filter = $this->mapOptions['map_filter']; + + /* + * Let graphviz place the nodes. + */ + + if ($map_filter['empty_map']) { + $this->generateEmptyDotGraph(); + } else if (!isset($this->dotGraph)) { + $this->generateDotGraph(); + } + + /* + * Calculate X,Y positions. + */ + + $graph = $this->calculateCoords(); + + if (is_array($graph) === true) { + $nodes = $graph['nodes']; + $relations = $graph['relations']; + } else { + ui_print_error_message( + __('Failed to retrieve graph data.') + ); + return; + } + + /* + * Calculate references. + */ + + $index = 0; + $node_center = []; + + $graph = []; + $graph['nodes'] = []; + + // Prepare graph nodes. + foreach ($nodes as $id => $coords) { + $node_tmp['id_map'] = $this->idMap; + $node_tmp['id'] = $id; + + $source = $this->getNodeData($id); + + $node_tmp['id_agent'] = $source['id_agente']; + $node_tmp['id_module'] = $source['id_agente_modulo']; + $node_tmp['type'] = $source['node_type']; + $node_tmp['x'] = $coords['x']; + $node_tmp['y'] = $coords['y']; + + $node_tmp['width'] = $this->mapOptions['map_filter']['node_radius']; + $node_tmp['height'] = $this->mapOptions['map_filter']['node_radius']; + + if (isset($source['width'])) { + $node_tmp['width'] = $source['width']; + } + + if (isset($source['height'])) { + $node_tmp['height'] = $source['height']; + } + + switch ($node_tmp['type']) { + case NODE_AGENT: + $node_tmp['source_data'] = $source['id_agente']; + $node_tmp['text'] = $source['alias']; + $node_tmp['image'] = ui_print_os_icon( + $source['id_os'], + false, + true, + true, + true, + true, + true + ); + break; + + case NODE_MODULE: + $node_tmp['source_data'] = $source['id_agente_modulo']; + $node_tmp['text'] = $source['nombre']; + $node_tmp['image'] = ui_print_moduletype_icon( + $this->getNodeData($id, 'id_tipo_modulo'), + true, + true, + false, + true + ); + break; + + case NODE_PANDORA: + $node_tmp['text'] = $source['label']; + $node_tmp['id_agent'] = $source['id_agente']; + $node_tmp['id_module'] = $source['id_agente_modulo']; + $node_tmp['source_data'] = 0; + $node_center['x'] = ($coords['x'] - MAP_X_CORRECTION); + $node_center['y'] = ($coords['y'] - MAP_Y_CORRECTION); + break; + + case NODE_GENERIC: + default: + $node_tmp['text'] = $source['label']; + $node_tmp['id_agent'] = $source['id_agente']; + $node_tmp['id_module'] = $source['id_agente_modulo']; + $node_tmp['source_data'] = $source['id_source']; + break; + } + + $style = []; + $style['shape'] = $source['shape']; + if (isset($style['shape']) === false) { + $style['shape'] = 'circle'; + } + + $style['image'] = $node_tmp['image']; + $style['width'] = $node_tmp['width']; + $style['height'] = $node_tmp['height']; + $style['label'] = $node_tmp['text']; + + $node_tmp['style'] = json_encode($style); + + $graph['nodes'][$index] = $node_tmp; + $index++; + } + + // Prepare graph edges and clean double references. + $graph['relations'] = []; + $parents = []; + foreach ($relations as $rel) { + $tmp = [ + 'id_map' => $this->idMap, + 'id_parent' => $rel['id_parent'], + 'parent_type' => $rel['parent_type'], + 'id_parent_source_data' => $rel['id_parent_source_data'], + 'id_child' => $rel['id_child'], + 'child_type' => $rel['child_type'], + 'id_child_source_data' => $rel['id_child_source_data'], + 'id_parent_agent' => $rel['id_parent_agent'], + 'id_child_agent' => $rel['id_child_agent'], + 'link_color' => $rel['link_color'], + 'text_start' => $rel['text_start'], + 'text_end' => $rel['text_end'], + ]; + + $found = 0; + if (isset($tmp['id_parent_source_data'])) { + // Avoid [child - parent] : [parent - child] relation duplicates. + if (is_array($parents[$tmp['id_parent_source_data']])) { + foreach ($parents[$tmp['id_parent_source_data']] as $k) { + if ($k === $tmp['id_child_source_data']) { + $found = 1; + break; + } + } + } else { + $parents[$tmp['id_parent_source_data']] = []; + } + } + + if ($found == 0) { + $parents[$tmp['id_child_source_data']][] = $tmp['id_parent_source_data']; + $graph['relations'][] = $tmp; + } + } + + // Prioritize relations between same nodes. + $this->cleanGraphRelations(); + + // Save data. + if ($this->idMap > 0 && (isset($this->map['__simulated']) === false)) { + if (enterprise_installed()) { + $graph = enterprise_hook( + 'save_generate_nodes', + [ + $this->idMap, + $graph, + ] + ); + } + + db_process_sql_update( + 'tmap', + [ + 'width' => $this->map['width'], + 'height' => $this->map['height'], + 'center_x' => $this->map['center_x'], + 'center_y' => $this->map['center_y'], + ], + ['id' => $this->idMap] + ); + } else { + $this->map['center_x'] = $node_center['x']; + $this->map['center_y'] = $node_center['y']; + + if (!isset($this->map['center_x']) + && !isset($this->map['center_y']) + ) { + $this->map['center_x'] = ($nodes[0]['x'] - MAP_X_CORRECTION); + $this->map['center_y'] = ($nodes[0]['y'] - MAP_Y_CORRECTION); + } + } + + $this->graph = $graph; + } + + + /** + * Transform node information into JS data. + * + * @return string HTML code with JS data. + */ + public function loadMapData() + { + $networkmap = $this->map; + + $simulate = false; + if (isset($networkmap['__simulated']) === false) { + $networkmap['filter'] = json_decode( + $networkmap['filter'], + true + ); + $networkmap['filter']['holding_area'] = [ + 500, + 500, + ]; + $holding_area_title = __('Holding Area'); + } else { + $simulate = true; + $holding_area_title = ''; + $networkmap['filter']['holding_area'] = [ + 0, + 0, + ]; + } + + // Prioritize relations between same nodes. + $this->cleanGraphRelations(); + + // Print some params to handle it in js. + html_print_input_hidden('product_name', get_product_name()); + html_print_input_hidden('center_logo', ui_get_full_url(ui_get_logo_to_center_networkmap())); + + $output .= ''; + + return $output; + } + + + /** + * Generates a simple interface to interact with nodes. + * + * @return string HTML code for simple interface. + */ + public function loadSimpleInterface() + { + $output = ''; + + $output .= ''; + + return $output; + } + + + /** + * Show an advanced interface to manage dialogs. + * + * @return string HTML code with dialogs. + */ + public function loadAdvancedInterface() + { + $list_networkmaps = get_networkmaps($this->idMap); + if (empty($list_networkmaps)) { + $list_networkmaps = []; + } + + $output .= ''; + + $output .= ''; + + $output .= ''; + + $output .= ''; + + return $output; + } + + + /** + * Loads advanced map controller (JS). + * + * @return string HTML code for advanced controller. + */ + public function loadController() + { + $output = ''; + + if (enterprise_installed() + && $this->useTooltipster + ) { + $output .= ''; + } else { + // Generate JS for advanced controller. + $output .= ' + +'; + } + + if ($return === false) { + echo $output; + } + + return $output; + + } + + + /** + * Load networkmap HTML skel and JS requires. + * + * @return string HTML code for skel. + */ + public function loadMapSkel() + { + global $config; + + if (enterprise_installed() + && isset($this->useTooltipster) + && $this->useTooltipster == true + ) { + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''."\n"; + + $output .= '
    mapOptions['width']; + $output .= ' ;height:'.$this->mapOptions['height'].'">'; + $output .= ''; + $output .= ''; + $output .= '
    '; + } else { + // Load default interface. + ui_require_css_file('networkmap'); + ui_require_css_file('jquery.contextMenu', 'include/styles/js/'); + + $output = ''; + $minimap_display = ''; + if ($this->mapOptions['pure']) { + $minimap_display = 'none'; + } + + $networkmap = $this->map; + if (is_array($networkmap['filter']) === false) { + $networkmap['filter'] = json_decode($networkmap['filter'], true); + } + + $networkmap['filter']['l2_network_interfaces'] = 1; + + $output .= ''; + if (isset($this->map['__simulated']) === false) { + // Load context menu if manageable networkmap. + $output .= ''; + } + + $output .= ''; + + // Open networkconsole_id div. + $output .= '
    fullSize) { + $output .= ' style="width: 100%; height: 100%;position: relative; overflow: hidden; background: #FAFAFA">'; + } else { + $output .= ' style="width: '.$this->mapOptions['width'].'px; height: '.$this->mapOptions['height'].'px;position: relative; overflow: hidden; background: #FAFAFA">'; + } + + $output .= '
    '; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= '
    '; + + $output .= '
    idMap) + && isset($this->map['__simulated']) === false + ) { + $output .= $this->loadMapSkel(); + $output .= $this->loadMapData(); + $output .= $this->loadController(); + if (!$this->noPopUp) { + $output .= $this->loadAdvancedInterface(); + } + } else { + // Simulated, no tmap entries. + $output .= $this->loadMapSkel(); + $output .= $this->loadMapData(); + $output .= $this->loadController(); + if (!$this->noPopUp) { + $output .= $this->loadSimpleInterface(); + } + } + + $output .= ' + + +'; + if ($return === false) { + echo $output; + } + + return $output; + } + + +} diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 875a4d8535..a72e7ee8ab 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,8 +20,8 @@ /** * Pandora build version and version */ -$build_version = 'PC190321'; -$pandora_version = 'v7.0NG.732'; +$build_version = 'PC190405'; +$pandora_version = 'v7.0NG.733'; // Do not overwrite default timezone set if defined. $script_tz = @date_default_timezone_get(); @@ -306,3 +306,9 @@ switch ($config['dbtype']) { } // ====================================================================== +// Menu display mode. +if ($_SESSION['menu_type']) { + $config['menu_type'] = $_SESSION['menu_type']; +} else { + $config['menu_type'] = 'classic'; +} diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index b472f98ad8..ea18c90d3f 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -195,6 +195,14 @@ define('AGENT_STATUS_UNKNOWN', 3); define('AGENT_STATUS_ALERT_FIRED', 4); define('AGENT_STATUS_WARNING', 2); +// Pseudo criticity analysis. +define('NO_CRIT', -1); +define('CRIT_0', 0); +define('CRIT_1', 1); +define('CRIT_2', 2); +define('CRIT_3', 3); +define('CRIT_4', 4); +define('CRIT_5', 5); // Visual maps contants. // The items kind. @@ -506,6 +514,18 @@ define('OPTION_COLOR_PICKER', 11); define('NODE_TYPE', 0); define('ARROW_TYPE', 1); +// Discovery task steps. +define('STEP_SCANNING', 1); +define('STEP_AFT', 2); +define('STEP_TRACEROUTE', 3); +define('STEP_GATEWAY', 4); + +// Networkmap node types. +define('NODE_AGENT', 0); +define('NODE_MODULE', 1); +define('NODE_PANDORA', 2); +define('NODE_GENERIC', 3); + // SAML attributes constants. define('SAML_ROLE_AND_TAG', 'eduPersonEntitlement'); define('SAML_USER_DESC', 'commonName'); @@ -535,12 +555,41 @@ define('MAP_GENERATION_RADIAL', 2); define('MAP_GENERATION_SPRING1', 3); define('MAP_GENERATION_SPRING2', 4); +// Algorithm: Circo. +define('LAYOUT_CIRCULAR', 0); +// Algorithm: Dot. +define('LAYOUT_FLAT', 1); +// Algorithm: Twopi. +define('LAYOUT_RADIAL', 2); +// Algorithm: Neato. +define('LAYOUT_SPRING1', 3); +// Algorithm: Fdp. +define('LAYOUT_SPRING2', 4); +// Extra: radial dynamic. +define('LAYOUT_RADIAL_DYNAMIC', 6); + +// Map sources. +define('SOURCE_GROUP', 0); +define('SOURCE_TASK', 1); +define('SOURCE_NETWORK', 2); + +// Backward compatibility ~ Migration. define('MAP_SOURCE_GROUP', 0); define('MAP_SOURCE_IP_MASK', 1); define('NETWORKMAP_DEFAULT_WIDTH', 800); define('NETWORKMAP_DEFAULT_HEIGHT', 800); +// Discovery task types. +define('DISCOVERY_HOSTDEVICES', 0); +define('DISCOVERY_HOSTDEVICES_CUSTOM', 1); +define('DISCOVERY_CLOUD_AWS', 10); +define('DISCOVERY_APP_VMWARE', 100); + +// Discovery task descriptions. +define('CLOUDWIZARD_AWS_DESCRIPTION', 'Discovery.Cloud.AWS.EC2'); +define('CLOUDWIZARD_VMWARE_DESCRIPTION', 'Discovery.App.VMware'); + // Background options. define('CENTER', 0); define('MOSAIC', 1); diff --git a/pandora_console/include/fonts/mem8YaGs126MiZpBA-UFW50bbck.woff2 b/pandora_console/include/fonts/mem8YaGs126MiZpBA-UFW50bbck.woff2 new file mode 100755 index 0000000000..2312604864 Binary files /dev/null and b/pandora_console/include/fonts/mem8YaGs126MiZpBA-UFW50bbck.woff2 differ diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index e1861e70a3..0b9f71221b 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -243,19 +243,25 @@ function format_numeric($number, $decimals=1) /** * Render numeric data for a graph. It adds magnitude suffix to the number - * (M for millions, K for thousands...) base-10 + * (M for millions, K for thousands...). Base can be modified with divider. * - * TODO: base-2 multiplication - * - * @param float $number Number to be rendered - * @param integer $decimals Numbers after comma. Default value: 1 - * @param dec_point Decimal separator character. Default value: . - * @param thousands_sep Thousands separator character. Default value: , + * @param float $number Number to be rendered. + * @param integer $decimals Numbers after comma (default 1). + * @param string $dec_point Decimal separator character (default .). + * @param string $thousands_sep Thousands separator character (default ,). + * @param integer $divider Number to divide the rendered number. + * @param string $sufix Units of the multiple. * * @return string A string with the number and the multiplier */ -function format_for_graph($number, $decimals=1, $dec_point='.', $thousands_sep=',') -{ +function format_for_graph( + $number, + $decimals=1, + $dec_point='.', + $thousands_sep=',', + $divider=1000, + $sufix='' +) { $shorts = [ '', 'K', @@ -268,15 +274,15 @@ function format_for_graph($number, $decimals=1, $dec_point='.', $thousands_sep=' 'Y', ]; $pos = 0; - while ($number >= 1000) { - // as long as the number can be divided by 1000 + while ($number >= $divider) { + // As long as the number can be divided by divider. $pos++; - // Position in array starting with 0 - $number = ($number / 1000); + // Position in array starting with 0. + $number = ($number / $divider); } - return remove_right_zeros(format_numeric($number, $decimals)).$shorts[$pos]; - // This will actually do the rounding and the decimals + // This will actually do the rounding and the decimals. + return remove_right_zeros(format_numeric($number, $decimals)).$shorts[$pos].$sufix; } @@ -1438,7 +1444,13 @@ function enterprise_include($filename) global $config; // Load enterprise extensions - $filepath = realpath($config['homedir'].'/'.ENTERPRISE_DIR.'/'.$filename); + if (defined('DESTDIR')) { + $destdir = DESTDIR; + } else { + $destdir = ''; + } + + $filepath = realpath($destdir.$config['homedir'].'/'.ENTERPRISE_DIR.'/'.$filename); if ($filepath === false) { return ENTERPRISE_NOT_HOOK; diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 0ac9bb876f..67ad7b949c 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -578,6 +578,7 @@ function agents_get_agents( } $sql = sprintf('%s %s', $sql, $limit_sql); + if ($return) { return $sql; } else { @@ -2202,7 +2203,7 @@ function agents_delete_agent($id_agents, $disableACL=false) // Delete agent in networkmap enterprise if (enterprise_installed()) { - enterprise_include_once('include/functions_pandora_networkmap.php'); + enterprise_include_once('include/functions_networkmap.php'); networkmap_delete_nodes_by_agent([$id_agent]); } diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index e57dd31013..b2ac851e8f 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -8794,7 +8794,14 @@ function api_set_alert_actions($id, $id2, $other, $trash1) } $firesMin = $other['data'][2]; + if (!$firesMin) { + $firesMin = 0; + } + $firesMax = $other['data'][3]; + if (!$firesMax) { + $firesMax = 0; + } $values = [ 'id_alert_template_module' => $idAlertTemplateModule, diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 9ba9ace3ff..5435de5b8a 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -224,6 +224,10 @@ function config_update_config() $error_update[] = __('Enable Netflow'); } + if (!config_update_value('activate_nta', (bool) get_parameter_switch('activate_nta'))) { + $error_update[] = __('Enable Network Traffic Analyzer'); + } + $timezone = (string) get_parameter('timezone'); if ($timezone != '') { if (!config_update_value('timezone', $timezone)) { @@ -756,6 +760,10 @@ function config_update_config() $error_update[] = __('Max. days before delete old messages'); } + if (!config_update_value('delete_old_network_matrix', get_parameter('delete_old_network_matrix'))) { + $error_update[] = __('Max. days before delete old network matrix data'); + } + if (!config_update_value('max_graph_container', get_parameter('max_graph_container'))) { $error_update[] = __('Graph container - Max. Items'); } @@ -896,6 +904,14 @@ function config_update_config() $error_update[] = __('Custom networkmap center logo'); } + if (!config_update_value('custom_title_header', (string) get_parameter('custom_title_header'))) { + $error_update[] = __('Custom title header'); + } + + if (!config_update_value('custom_subtitle_header', (string) get_parameter('custom_subtitle_header'))) { + $error_update[] = __('Custom subtitle header'); + } + if (!config_update_value('custom_title1_login', (string) get_parameter('custom_title1_login'))) { $error_update[] = __('Custom title1 login'); } @@ -1547,6 +1563,10 @@ function config_process_config() config_update_value('delete_old_messages', 21); } + if (!isset($config['delete_old_network_matrix'])) { + config_update_value('delete_old_network_matrix', 10); + } + if (!isset($config['max_graph_container'])) { config_update_value('max_graph_container', 10); } @@ -1792,7 +1812,7 @@ function config_process_config() } if (!isset($config['custom_logo'])) { - config_update_value('custom_logo', 'pandora_logo_head_green.png'); + config_update_value('custom_logo', 'pandora_logo_head_4.png'); } if (!isset($config['custom_logo_collapsed'])) { @@ -1827,6 +1847,14 @@ function config_process_config() config_update_value('custom_mobile_console_logo', ''); } + if (!isset($config['custom_title_header'])) { + config_update_value('custom_title_header', __('Pandora FMS')); + } + + if (!isset($config['custom_subtitle_header'])) { + config_update_value('custom_subtitle_header', __('the Flexible Monitoring System')); + } + if (!isset($config['custom_title1_login'])) { config_update_value('custom_title1_login', __('PANDORA FMS')); } @@ -1975,6 +2003,10 @@ function config_process_config() config_update_value('activate_netflow', 0); } + if (!isset($config['activate_nta'])) { + config_update_value('activate_nta', 0); + } + if (!isset($config['netflow_path'])) { if ($is_windows) { $default = 'C:\\PandoraFMS\\Pandora_Server\\data_in\\netflow'; @@ -2684,9 +2716,7 @@ function config_check() if (enterprise_installed() === false) { $supervisor = new ConsoleSupervisor(false); $supervisor->run(); - } else if ($config['cron_last_run'] == 0 - || (get_system_time() - $config['cron_last_run']) > 3600 - ) { + } else { $supervisor = new ConsoleSupervisor(false); $supervisor->runBasic(); } diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index e56a3d4a52..4bb7f5c752 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -429,8 +429,10 @@ function cron_list_table() } $email = $args[1]; + $report_type = $args[4]; $data[2] .= '
    - '.__('Report').": "; $data[2] .= $report['name'].''; + $data[2] .= '
    - '.__('Report type').': '.$report_type; $data[2] .= '
    - '.__('Email').": "; $data[2] .= ui_print_truncate_text($email, 60, false).''; break; diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index dc69af7baf..0182c2141b 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -3167,8 +3167,7 @@ function events_page_general($event) $table_general->data[] = $data; - $event['owner_user'] = $event['id_usuario']; - + // $event['owner_user'] = $event['id_usuario']; $data = []; $data[0] = __('Owner'); if (empty($event['owner_user'])) { diff --git a/pandora_console/include/functions_extensions.php b/pandora_console/include/functions_extensions.php index 8efb4c8f36..66e7ff9c3d 100755 --- a/pandora_console/include/functions_extensions.php +++ b/pandora_console/include/functions_extensions.php @@ -380,7 +380,18 @@ function extensions_load_extensions($process_login) // ~ } // ~ } // ~ else { + try { include_once $path_extension; + } + + // PHP 7 + catch (Throwable $e) { + } + + // PHP 5 + catch (Exception $e) { + } + // ~ } } } diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index 71049d7804..de0a1bdd6f 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -533,7 +533,8 @@ function grafico_modulo_sparse_data( 'image_treshold' => false, 'graph_combined' => false, 'zoom' => 1, - 'server_id' => null + 'server_id' => null, + 'stacked' => 0, ); */ function grafico_modulo_sparse($params) @@ -710,6 +711,10 @@ function grafico_modulo_sparse($params) $agent_module_id = $params['agent_module_id']; } + if (!isset($params['stacked'])) { + $params['stacked'] = 0; + } + // XXXX Configurable $params['grid_color'] = '#C1C1C1'; $params['legend_color'] = '#636363'; @@ -4104,7 +4109,7 @@ function fullscale_data( /** * Print an area graph with netflow aggregated */ -function graph_netflow_aggregate_area($data, $period, $width, $height, $unit='', $ttl=1, $only_image=false) +function graph_netflow_aggregate_area($data, $period, $width, $height, $ttl=1, $only_image=false, $date=null) { global $config; global $graphic_type; @@ -4150,7 +4155,7 @@ function graph_netflow_aggregate_area($data, $period, $width, $height, $unit='', 'period' => $period, 'width' => '90%', 'height' => 450, - 'unit' => $unit, + 'unit' => 'bytes', 'only_image' => $only_image, 'homeurl' => $homeurl, 'menu' => true, @@ -4159,6 +4164,10 @@ function graph_netflow_aggregate_area($data, $period, $width, $height, $unit='', 'font' => $config['fontpath'], 'font_size' => $config['font_size'], 'array_data_create' => $chart, + 'stacked' => 1, + 'date' => $date, + 'show_export_csv' => false, + 'show_overview' => false, ]; return grafico_modulo_sparse($params); @@ -4280,9 +4289,16 @@ function graph_netflow_aggregate_pie($data, $aggregate, $ttl=1, $only_image=fals /** - * Print a circular graph with the data transmitted between IPs + * Print a circular mesh array. + * + * @param array $data Array with properly data structure. Array with two + * elements required: + * 'elements': Non-associative array with all the relationships. + * 'matrix': Array of arrays with value of the relationship. + * + * @return string HTML data. */ -function graph_netflow_circular_mesh($data, $unit, $radius=700) +function graph_netflow_circular_mesh($data) { global $config; @@ -4292,14 +4308,14 @@ function graph_netflow_circular_mesh($data, $unit, $radius=700) include_once $config['homedir'].'/include/graphs/functions_d3.php'; - return d3_relationship_graph($data['elements'], $data['matrix'], $unit, $radius, true); + return d3_relationship_graph($data['elements'], $data['matrix'], 700, true); } /** * Print a rectangular graph with the traffic of the ports for each IP */ -function graph_netflow_host_traffic($data, $unit, $width=700, $height=700) +function graph_netflow_host_traffic($data, $width=700, $height=700) { global $config; diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 6d461350e9..4a24d5a964 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1060,7 +1060,7 @@ function html_print_extended_select_for_time( 'images/pencil.png', true, [ - 'class' => $uniq_name.'_toggler', + 'class' => $uniq_name.'_toggler '.$class, 'alt' => __('Custom'), 'title' => __('Custom'), 'style' => 'width: 18px;'.$style_icon, @@ -2392,12 +2392,21 @@ function html_print_checkbox_switch($name, $value, $checked=false, $return=false /** * Prints an image HTML element. * - * @param string $src Image source filename. - * @param boolean $return Whether to return or print - * @param array $options Array with optional HTML options to set. At this moment, the - * following options are supported: alt, style, title, width, height, class, pos_tree. - * @param boolean $return_src Whether to return src field of image ('images/*.*') or complete html img tag ('...'). - * @param boolean $relative Whether to use relative path to image or not (i.e. $relative= true : /pandora/). + * @param string $src Image source filename. + * @param boolean $return Whether to return or print. + * @param array $options Array with optional HTML options to set. + * At this moment, the following options are supported: + * align, border, hspace, ismap, vspace, style, title, height, + * longdesc, usemap, width, id, class, lang, xml:lang, onclick, + * ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, + * onmouseout, onkeypress, onkeydown, onkeyup, pos_tree, alt. + * @param boolean $return_src Whether to return src field of image + * ('images/*.*') or complete html img tag ('...'). + * @param boolean $relative Whether to use relative path to image or not + * (i.e. $relative= true : /pandora/). + * @param boolean $no_in_meta Do not show on metaconsole folder at first. Go + * directly to the node. + * @param boolean $isExternalLink Do not shearch for images in Pandora. * * @return string HTML code if return parameter is true. */ @@ -2412,9 +2421,9 @@ function html_print_image( ) { global $config; - // If metaconsole is in use then don't use skins + // If metaconsole is in use then don't use skins. if (!is_metaconsole()) { - // Checks if user's skin is available + // Checks if user's skin is available. $isFunctionSkins = enterprise_include_once('include/functions_skins.php'); if ($isFunctionSkins !== ENTERPRISE_NOT_HOOK) { @@ -2426,11 +2435,11 @@ function html_print_image( } } - // If metaconsole is activated and image doesn't exists try to search on normal console + // If metaconsole is activated and image doesn't exists try to search on normal console. if (is_metaconsole()) { if (!$relative) { $working_dir = str_replace('\\', '/', getcwd()); - // Windows compatibility + // Windows compatibility. if ($no_in_meta) { $src = '../../'.$src; } else if (strstr($working_dir, 'enterprise/meta') === false) { @@ -2468,22 +2477,22 @@ function html_print_image( } } - // Only return src field of image + // Only return src field of image. if ($return_src) { if (!$return) { echo io_safe_input($src); - return; + return null; } return io_safe_input($src); } $output = ' '(GMT-11:00) '.__('Midway Island'), - 'US/Samoa' => '(GMT-11:00) '.__('Samoa'), - 'US/Hawaii' => '(GMT-10:00) '.__('Hawaii'), - 'US/Alaska' => '(GMT-09:00) '.__('Alaska'), - 'US/Pacific' => '(GMT-08:00) '.__('Pacific Time (US & Canada)'), - 'America/Tijuana' => '(GMT-08:00) '.__('Tijuana'), - 'US/Arizona' => '(GMT-07:00) '.__('Arizona'), - 'US/Mountain' => '(GMT-07:00) '.__('Mountain Time (US & Canada)'), - 'America/Chihuahua' => '(GMT-07:00) '.__('Chihuahua'), - 'America/Mazatlan' => '(GMT-07:00) '.__('Mazatlan'), - 'America/Mexico_City' => '(GMT-06:00) '.__('Mexico City'), - 'America/Monterrey' => '(GMT-06:00) '.__('Monterrey'), - 'Canada/Saskatchewan' => '(GMT-06:00) '.__('Saskatchewan'), - 'US/Central' => '(GMT-06:00) '.__('Central Time (US & Canada)'), - 'US/Eastern' => '(GMT-05:00) '.__('Eastern Time (US & Canada)'), - 'US/East-Indiana' => '(GMT-05:00) '.__('Indiana (East)'), - 'America/Bogota' => '(GMT-05:00) '.__('Bogota'), - 'America/Lima' => '(GMT-05:00) '.__('Lima'), - 'America/Caracas' => '(GMT-04:30) '.__('Caracas'), - 'Canada/Atlantic' => '(GMT-04:00) '.__('Atlantic Time (Canada)'), - 'America/La_Paz' => '(GMT-04:00) '.__('La Paz'), - 'America/Santiago' => '(GMT-04:00) '.__('Santiago'), - 'Canada/Newfoundland' => '(GMT-03:30) '.__('Newfoundland'), - 'America/Buenos_Aires' => '(GMT-03:00) '.__('Buenos Aires'), - "Greenland'" => '(GMT-03:00) '.__('Greenland'), - 'Atlantic/Stanley' => '(GMT-02:00) '.__('Stanley'), - 'Atlantic/Azores' => '(GMT-01:00) '.__('Azores'), - 'Atlantic/Cape_Verde' => '(GMT-01:00) '.__('Cape Verde Is.'), - 'Africa/Casablanca' => '(GMT+00:00) '.__('Casablanca'), - 'Europe/Dublin' => '(GMT+00:00) '.__('Dublin'), - 'Europe/Lisbon' => '(GMT+00:00) '.__('Lisbon'), - 'Europe/London' => '(GMT+00:00) '.__('London'), - 'Africa/Monrovia' => '(GMT+00:00) '.__('Monrovia'), - 'Europe/Amsterdam' => '(GMT+01:00) '.__('Amsterdam'), - 'Europe/Belgrade' => '(GMT+01:00) '.__('Belgrade'), - 'Europe/Berlin' => '(GMT+01:00) '.__('Berlin'), - 'Europe/Bratislava' => '(GMT+01:00) '.__('Bratislava'), - 'Europe/Brussels' => '(GMT+01:00) '.__('Brussels'), - 'Europe/Budapest' => '(GMT+01:00) '.__('Budapest'), - 'Europe/Copenhagen' => '(GMT+01:00) '.__('Copenhagen'), - 'Europe/Ljubljana' => '(GMT+01:00) '.__('Ljubljana'), - 'Europe/Madrid' => '(GMT+01:00) '.__('Madrid'), - 'Europe/Paris' => '(GMT+01:00) '.__('Paris'), - 'Europe/Prague' => '(GMT+01:00) '.__('Prague'), - 'Europe/Rome' => '(GMT+01:00) '.__('Rome'), - 'Europe/Sarajevo' => '(GMT+01:00) '.__('Sarajevo'), - 'Europe/Skopje' => '(GMT+01:00) '.__('Skopje'), - 'Europe/Stockholm' => '(GMT+01:00) '.__('Stockholm'), - 'Europe/Vienna' => '(GMT+01:00) '.__('Vienna'), - 'Europe/Warsaw' => '(GMT+01:00) '.__('Warsaw'), - 'Europe/Zagreb' => '(GMT+01:00) '.__('Zagreb'), - 'Europe/Athens' => '(GMT+02:00) '.__('Athens'), - 'Europe/Bucharest' => '(GMT+02:00) '.__('Bucharest'), - 'Africa/Cairo' => '(GMT+02:00) '.__('Cairo'), - 'Africa/Harare' => '(GMT+02:00) '.__('Harare'), - 'Europe/Helsinki' => '(GMT+02:00) '.__('Helsinki'), - 'Europe/Istanbul' => '(GMT+02:00) '.__('Istanbul'), - 'Asia/Jerusalem' => '(GMT+02:00) '.__('Jerusalem'), - 'Europe/Kiev' => '(GMT+02:00) '.__('Kyiv'), - 'Europe/Minsk' => '(GMT+02:00) '.__('Minsk'), - 'Europe/Riga' => '(GMT+02:00) '.__('Riga'), - 'Europe/Sofia' => '(GMT+02:00) '.__('Sofia'), - 'Europe/Tallinn' => '(GMT+02:00) '.__('Tallinn'), - 'Europe/Vilnius' => '(GMT+02:00) '.__('Vilnius'), - 'Asia/Baghdad' => '(GMT+03:00) '.__('Baghdad'), - 'Asia/Kuwait' => '(GMT+03:00) '.__('Kuwait'), - 'Africa/Nairobi' => '(GMT+03:00) '.__('Nairobi'), - 'Asia/Riyadh' => '(GMT+03:00) '.__('Riyadh'), - 'Europe/Moscow' => '(GMT+03:00) '.__('Moscow'), - 'Asia/Tehran' => '(GMT+03:30) '.__('Tehran'), - 'Asia/Baku' => '(GMT+04:00) '.__('Baku'), - 'Europe/Volgograd' => '(GMT+04:00) '.__('Volgograd'), - 'Asia/Muscat' => '(GMT+04:00) '.__('Muscat'), - 'Asia/Tbilisi' => '(GMT+04:00) '.__('Tbilisi'), - 'Asia/Yerevan' => '(GMT+04:00) '.__('Yerevan'), - 'Asia/Kabul' => '(GMT+04:30) '.__('Kabul'), - 'Asia/Karachi' => '(GMT+05:00) '.__('Karachi'), - 'Asia/Tashkent' => '(GMT+05:00) '.__('Tashkent'), - 'Asia/Kolkata' => '(GMT+05:30) '.__('Kolkata'), - 'Asia/Kathmandu' => '(GMT+05:45) '.__('Kathmandu'), - 'Asia/Yekaterinburg' => '(GMT+06:00) '.__('Ekaterinburg'), - 'Asia/Almaty' => '(GMT+06:00) '.__('Almaty'), - 'Asia/Dhaka' => '(GMT+06:00) '.__('Dhaka'), - 'Asia/Novosibirsk' => '(GMT+07:00) '.__('Novosibirsk'), - 'Asia/Bangkok' => '(GMT+07:00) '.__('Bangkok'), - 'Asia/Jakarta' => '(GMT+07:00) '.__('Jakarta'), - 'Asia/Krasnoyarsk' => '(GMT+08:00) '.__('Krasnoyarsk'), - 'Asia/Chongqing' => '(GMT+08:00) '.__('Chongqing'), - 'Asia/Hong_Kong' => '(GMT+08:00) '.__('Hong Kong'), - 'Asia/Kuala_Lumpur' => '(GMT+08:00) '.__('Kuala Lumpur'), - 'Australia/Perth' => '(GMT+08:00) '.__('Perth'), - 'Asia/Singapore' => '(GMT+08:00) '.__('Singapore'), - 'Asia/Taipei' => '(GMT+08:00) '.__('Taipei'), - 'Asia/Ulaanbaatar' => '(GMT+08:00) '.__('Ulaan Bataar'), - 'Asia/Urumqi' => '(GMT+08:00) '.__('Urumqi'), - 'Asia/Irkutsk' => '(GMT+09:00) '.__('Irkutsk'), - 'Asia/Seoul' => '(GMT+09:00) '.__('Seoul'), - 'Asia/Tokyo' => '(GMT+09:00) '.__('Tokyo'), - 'Australia/Adelaide' => '(GMT+09:30) '.__('Adelaide'), - 'Australia/Darwin' => '(GMT+09:30) '.__('Darwin'), - 'Asia/Yakutsk' => '(GMT+10:00) '.__('Yakutsk'), - 'Australia/Brisbane' => '(GMT+10:00) '.__('Brisbane'), - 'Australia/Canberra' => '(GMT+10:00) '.__('Canberra'), - 'Pacific/Guam' => '(GMT+10:00) '.__('Guam'), - 'Australia/Hobart' => '(GMT+10:00) '.__('Hobart'), - 'Australia/Melbourne' => '(GMT+10:00) '.__('Melbourne'), - 'Pacific/Port_Moresby' => '(GMT+10:00) '.__('Port Moresby'), - 'Australia/Sydney' => '(GMT+10:00) '.__('Sydney'), - 'Asia/Vladivostok' => '(GMT+11:00) '.__('Vladivostok'), - 'Asia/Magadan' => '(GMT+12:00) '.__('Magadan'), - 'Pacific/Auckland' => '(GMT+12:00) '.__('Auckland'), - 'Pacific/Fiji' => '(GMT+12:00) '.__('Fiji'), - ]; - + $timezones_index = timezone_identifiers_list(); + $timezones = timezone_identifiers_list(); + $timezones = array_combine($timezones_index, $timezones); return html_print_select($timezones, $name, $selected, '', __('None'), '', true, false, false); } @@ -3114,3 +3011,48 @@ function html_print_switch($attributes=[]) "; } + + +/** + * Print a link with post params.The component is really a form with a button + * with some inputs hidden. + * + * @param string $text Text to show. + * @param array $params Params to be written like inputs hidden. + * @param string $text Text of image. + * @param string $style Additional style for the element. + * + * @return string With HTML code. + */ +function html_print_link_with_params($text, $params=[], $type='text', $style='') +{ + $html = '
    '; + switch ($type) { + case 'image': + $html .= html_print_input_image($text, $text, $text, $style, true); + break; + + case 'text': + default: + if (!empty($style)) { + $style = ' style="'.$style.'"'; + } + + $html .= html_print_submit_button( + $text, + $text, + false, + 'class="button-as-link"'.$style, + true + ); + break; + } + + foreach ($params as $param => $value) { + $html .= html_print_input_hidden($param, $value, true); + } + + $html .= '
    '; + + return $html; +} \ No newline at end of file diff --git a/pandora_console/include/functions_maps.php b/pandora_console/include/functions_maps.php index 9140c2ae6f..ed9b1bab06 100644 --- a/pandora_console/include/functions_maps.php +++ b/pandora_console/include/functions_maps.php @@ -188,3 +188,252 @@ function maps_add_node_relationship($values) $result_add_node_rel = db_process_sql_insert('trel_item', $values); return $result_add_node_rel; } + + +function run_graphviz($filename_map, $filename_dot, $layout, $graph) +{ + switch (PHP_OS) { + case 'WIN32': + case 'WINNT': + case 'Windows': + $filename_plain = sys_get_temp_dir().'\\plain.txt'; + break; + + default: + $filename_plain = sys_get_temp_dir().'/plain.txt'; + break; + } + + file_put_contents($filename_dot, $graph); + file_put_contents($filename_dot, $graph); + + $cmd = $layout.' -Tcmapx -o'.$filename_map.' -Tplain -o'.$filename_plain.' '.$filename_dot; + + system($cmd); + + if (file_exists($filename_map)) { + unlink($filename_map); + } + + if (file_exists($filename_dot)) { + unlink($filename_dot); + } + + return $filename_plain; +} + + +function open_graph($size_x=50, $size_y=25) +{ + $size = ''; + + $size = $size_x.','.$size_y; + + // BEWARE: graphwiz DONT use single ('), you need double ("). + $head = 'graph vmwaremap { labeljust=l; margin=0; '; + $head .= 'ratio=fill;'; + $head .= 'root=0;'; + $head .= 'rankdir=LR;'; + $head .= 'size="'.$size.'";'; + + return $head; +} + + +function create_node($node, $font_size=10) +{ + // Set node status. + if (isset($node['status'])) { + switch ($node['status']) { + case AGENT_MODULE_STATUS_NORMAL: + $status_color = COL_NORMAL; + // Normal monitor. + break; + + case AGENT_MODULE_STATUS_CRITICAL_BAD: + $status_color = COL_CRITICAL; + // Critical monitor. + break; + + case AGENT_MODULE_STATUS_WARNING: + $status_color = COL_WARNING; + // Warning monitor. + break; + + case AGENT_STATUS_ALERT_FIRED: + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case AGENT_MODULE_STATUS_WARNING_ALERT: + $status_color = COL_ALERTFIRED; + // Alert fired. + break; + + case AGENT_MODULE_STATUS_NOT_INIT: + $status_color = COL_NOTINIT; + // Not init. + break; + + default: + $status_color = COL_UNKNOWN; + // Unknown monitor. + break; + } + + $status_color = 'color="'.$status_color.'",'; + } else { + $status_color = ''; + } + + // Short name. + if (isset($node['nombre'])) { + $name = io_safe_output(strtolower($node['nombre'])); + if (strlen($name) > 16) { + $name = substr($name, 0, 16).'...'; + } + } + + // Set node icon. + if (isset($node['image'])) { + if (file_exists($node['image'])) { + $img_node = $node['image']; + } else { + $img_node = null; + } + } else { + $img_node = null; + } + + $result = $node['id_node'].' [ '.$status_color.' fontsize='.$font_size.', style="filled", fixedsize=true, width=0.40, height=0.40, label=< +
    '.html_print_image($img_node, true, false, false, true).'
    '.$name.'
    >, + shape="doublecircle", + tooltip="ajax.php?page=operation/agentes/ver_agente&get_agent_status_tooltip=1&id_agent='.$node['id'].'"];'; + + return $result; +} + + +/** + * Returns an edge definition. + * + * @param string $head Origin. + * @param string $tail Target. + * + * @return string Edge str. + */ +function create_edge($head, $tail) +{ + // Token edgeURL allows node navigation. + $edge = $head.' -- '.$tail.'[color="#BDBDBD", headclip=false, tailclip=false];'."\n"; + + return $edge; +} + + +// Closes a graph definition +function close_graph() +{ + return '}'; +} + + +function loadfile_map($file='', $graph) +{ + global $config; + + $networkmap_nodes = []; + + $relations = []; + + $other_file = file($file); + $graph = explode(']', $graph); + + $ids = []; + foreach ($graph as $node) { + $line = str_replace("\n", ' ', $node); + if (preg_match('/([0-9]+) \[.*tooltip.*id_agent=([0-9]+)/', $line, $match) != 0) { + $ids[$match[1]] = ['id_agent' => $match[2]]; + } + } + + foreach ($other_file as $key => $line) { + $line = preg_replace('/[ ]+/', ' ', $line); + + $data = []; + + if (preg_match('/^node.*$/', $line) != 0) { + $items = explode(' ', $line); + $node_id = $items[1]; + $node_x = ($items[2] * 100); + // 200 is for show more big + $node_y = ($height_map - $items[3] * 100); + // 200 is for show more big + $data['id'] = $node_id; + $data['image'] = ''; + $data['width'] = 10; + $data['height'] = 10; + $data['id_agent'] = 0; + + if (preg_match('/ $line_orig, + 'dest' => $line_dest, + ]; + } + } + + return $networkmap_nodes; +} diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 088f40168d..0dbe1049bc 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -1,22 +1,40 @@ = 18) ? 6 : 12; - $output .= ''; - // Add the notification ball if defined. + if ($config['menu_type'] == 'classic') { + $output .= ''; + } else { + $output .= ''; + } + + // Add the notification ball if defined if (isset($main['notification'])) { $output .= '
    '.$main['notification'].'
    '; } diff --git a/pandora_console/include/functions_messages.php b/pandora_console/include/functions_messages.php index 5374fb7b1e..35066129bc 100644 --- a/pandora_console/include/functions_messages.php +++ b/pandora_console/include/functions_messages.php @@ -582,6 +582,56 @@ function messages_get_overview_sent( } +/** + * Get a message interpreted as a conversation. + * + * @param mixed $data Complete message or message id. + * + * @return mixed False if fails. A string array with the conversation. + */ +function messages_get_conversation($data) +{ + if (is_array($data)) { + $message = $data; + } else { + $message = messages_get_message($data); + } + + if (!isset($message) || !is_array($message)) { + return []; + } + + $conversation = []; + $target_str = $message['mensaje']; + + while (preg_match_all( + '/(.*)On(.*)wrote:(.*)/', + $target_str, + $decoded, + PREG_PATTERN_ORDER + ) !== false && empty($target_str) !== true) { + if (empty($decoded[2]) !== true) { + array_push( + $conversation, + [ + 'message' => array_pop($decoded)[0], + 'date' => array_pop($decoded)[0], + ] + ); + } else { + array_push( + $conversation, + ['message' => $target_str] + ); + } + + $target_str = $decoded[1][0]; + } + + return $conversation; +} + + /** * Get the URL of a message. If field in db is null, it returs a link to * messages view. diff --git a/pandora_console/include/functions_netflow.php b/pandora_console/include/functions_netflow.php index 84f3c26169..69aa0a1608 100644 --- a/pandora_console/include/functions_netflow.php +++ b/pandora_console/include/functions_netflow.php @@ -1,36 +1,60 @@ id_name)) or filters filtered * - * @param mixed Array with filter conditions to retrieve filters or false. + * @param mixed $filter Array with filter conditions to retrieve filters or + * false. * - * @return array List of all filters + * @return array List of all filters. */ function netflow_get_filters($filter=false) { @@ -56,9 +80,10 @@ function netflow_get_filters($filter=false) /** * Selects all netflow reports (array (id_name => id_name)) or filters filtered * - * @param mixed Array with filter conditions to retrieve filters or false. + * @param mixed $filter Array with filter conditions to retrieve filters or + * false. * - * @return array List of all filters + * @return array List of all filters. */ function netflow_get_reports($filter=false) { @@ -81,14 +106,20 @@ function netflow_get_reports($filter=false) } -// permite validar si un filtro pertenece a un grupo permitido para el usuario +/** + * 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. + */ 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']); - // Get group list that user has access + // Get group list that user has access. $groups_user = users_get_groups($config['id_user'], 'IW', $own_info['is_admin'], true); $groups_id = []; $has_permission = false; @@ -103,44 +134,12 @@ function netflow_check_filter_group($id_sg) } -/* - Permite validar si un informe pertenece a un grupo permitido para el usuario. - * Si mode = false entonces es modo godmode y solo puede ver el grupo All el admin - * Si es modo operation (mode = true) entonces todos pueden ver el grupo All - */ - -function netflow_check_report_group($id_report, $mode=false) -{ - global $config; - - if (!$mode) { - $own_info = get_user_info($config['id_user']); - $mode = $own_info['is_admin']; - } - - $id_group = db_get_value('id_group', 'tnetflow_report', 'id_report', $id_report); - - // Get group list that user has access - $groups_user = users_get_groups($config['id_user'], 'IW', $mode, true); - $groups_id = []; - $has_permission = false; - - foreach ($groups_user as $key => $groups) { - if ($groups['id_grupo'] == $id_group) { - return true; - } - } - - return false; -} - - /** * Get a filter. * - * @param int filter id to be fetched. - * @param array Extra filter. - * @param array Fields to be fetched. + * @param integer $id_sg Filter id to be fetched. + * @param mixed $filter Extra filter. + * @param mixed $fields Fields to be fetched. * * @return array A netflow filter matching id and filter. */ @@ -156,52 +155,11 @@ function netflow_filter_get_filter($id_sg, $filter=false, $fields=false) } -/** - * Get options. - * - * @param int filter id to be fetched. - * @param array Extra filter. - * @param array Fields to be fetched. - * - * @return array A netflow filter matching id and filter. - */ -function netflow_reports_get_reports($id_report, $filter=false, $fields=false) -{ - if (empty($id_report)) { - return false; - } - - if (! is_array($filter)) { - $filter = []; - } - - $filter['id_report'] = (int) $id_report; - - return db_get_row_filter('tnetflow_report', $filter, $fields); -} - - -function netflow_reports_get_content($id_rc, $filter=false, $fields=false) -{ - if (empty($id_rc)) { - return false; - } - - if (! is_array($filter)) { - $filter = []; - } - - $filter['id_rc'] = (int) $id_rc; - - return db_get_row_filter('tnetflow_report_content', $filter, $fields); -} - - /** * Compare two flows according to the 'data' column. * - * @param array a First flow. - * @param array b Second flow. + * @param array $a First flow. + * @param array $b Second flow. * * @return Result of the comparison. */ @@ -214,7 +172,9 @@ function compare_flows($a, $b) /** * Sort netflow data according to the 'data' column. * - * @param array netflow_data Netflow data array. + * @param array $netflow_data Netflow data array. + * + * @return void (Array passed by reference) */ function sort_netflow_data(&$netflow_data) { @@ -225,22 +185,22 @@ function sort_netflow_data(&$netflow_data) /** * Show a table with netflow statistics. * - * @param array data Statistic data. - * @param string start_date Start date. - * @param string end_date End date. - * @param string aggregate Aggregate field. - * @param string unit Unit to show. + * @param array $data Statistic data. + * @param string $start_date Start date. + * @param string $end_date End date. + * @param string $aggregate Aggregate field. * - * @return The statistics table. + * @return string HTML statistics table. */ -function netflow_stat_table($data, $start_date, $end_date, $aggregate, $unit) +function netflow_stat_table($data, $start_date, $end_date, $aggregate) { global $nfdump_date_format; $start_date = date($nfdump_date_format, $start_date); $end_date = date($nfdump_date_format, $end_date); $values = []; - $table->width = '40%'; + $table = new stdClass(); + $table->width = '100%'; $table->cellspacing = 0; $table->class = 'databox'; $table->data = []; @@ -249,7 +209,7 @@ function netflow_stat_table($data, $start_date, $end_date, $aggregate, $unit) $table->head = []; $table->head[0] = ''.netflow_format_aggregate($aggregate).''; - $table->head[1] = ''.netflow_format_unit($unit).''; + $table->head[1] = ''.__('Value').''; $table->style[0] = 'padding: 6px;'; $table->style[1] = 'padding: 6px;'; @@ -257,14 +217,13 @@ function netflow_stat_table($data, $start_date, $end_date, $aggregate, $unit) $agg = $data[$j]['agg']; if (!isset($values[$agg])) { $values[$agg] = $data[$j]['data']; - $table->data[$x][0] = $agg; - $table->data[$x][1] = format_numeric($data[$j]['data']).' '.netflow_format_unit($unit); } else { $values[$agg] += $data[$j]['data']; - $table->data[$x][0] = $agg; - $table->data[$x][1] = format_numeric($data[$j]['data']).' '.netflow_format_unit($unit); } + $table->data[$x][0] = $agg; + $table->data[$x][1] = network_format_bytes($data[$j]['data']); + $j++; $x++; } @@ -276,14 +235,14 @@ function netflow_stat_table($data, $start_date, $end_date, $aggregate, $unit) /** * Show a table with netflow data. * - * @param array data Netflow data. - * @param string start_date Start date. - * @param string end_date End date. - * @param string aggregate Aggregate field. + * @param array $data Netflow data. + * @param string $start_date Start date. + * @param string $end_date End date. + * @param string $aggregate Aggregate field. * - * @return The statistics table. + * @return string HTML data table. */ -function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) +function netflow_data_table($data, $start_date, $end_date, $aggregate) { global $nfdump_date_format; @@ -291,7 +250,7 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) $start_date = date($nfdump_date_format, $start_date); $end_date = date($nfdump_date_format, $end_date); - // Set the format + // Set the format. if ($period <= SECONDS_6HOURS) { $time_format = 'H:i:s'; } else if ($period < SECONDS_1DAY) { @@ -305,6 +264,7 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) } $values = []; + $table = new stdClass(); $table->size = ['100%']; $table->class = 'databox'; $table->cellspacing = 0; @@ -332,7 +292,7 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) $table->style[1] = 'padding: 4px;'; } - // No aggregates + // No aggregates. if ($source_count == 0) { $table->head[1] = __('Data'); $table->align[1] = 'right'; @@ -340,21 +300,17 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) foreach ($data as $timestamp => $value) { $table->data[$i][0] = date($time_format, $timestamp); - $table->data[$i][1] = format_numeric($value['data']).' '.netflow_format_unit($unit); + $table->data[$i][1] = network_format_bytes($value['data']); $i++; } - } - // Aggregates - else { + } else { $i = 0; foreach ($data['data'] as $timestamp => $values) { $table->data[$i][0] = date($time_format, $timestamp); for ($j = 0; $j < $source_count; $j++) { - if (isset($values[$source_index[$j]])) { - $table->data[$i][($j + 1)] = format_numeric($values[$source_index[$j]]).' '.netflow_format_unit($unit); - } else { - $table->data[$i][($j + 1)] = (0).' '.netflow_format_unit($unit); - } + $table->data[$i][($j + 1)] = network_format_bytes( + $values[$source_index[$j]] + ); } $i++; @@ -368,18 +324,19 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate, $unit) /** * Show a table with a traffic summary. * - * @param array data Summary data. + * @param array $data Summary data. * - * @return The statistics table. + * @return string HTML summary table. */ function netflow_summary_table($data) { global $nfdump_date_format; $values = []; - $table->size = ['50%']; + $table = new stdClass(); $table->cellspacing = 0; $table->class = 'databox'; + $table->styleTable = 'width: 100%'; $table->data = []; $table->style[0] = 'font-weight: bold; padding: 6px'; @@ -387,32 +344,32 @@ function netflow_summary_table($data) $row = []; $row[] = __('Total flows'); - $row[] = format_numeric($data['totalflows']); + $row[] = format_for_graph($data['totalflows'], 2); $table->data[] = $row; $row = []; $row[] = __('Total bytes'); - $row[] = format_numeric($data['totalbytes']); + $row[] = network_format_bytes($data['totalbytes']); $table->data[] = $row; $row = []; $row[] = __('Total packets'); - $row[] = format_numeric($data['totalpackets']); + $row[] = format_for_graph($data['totalpackets'], 2); $table->data[] = $row; $row = []; $row[] = __('Average bits per second'); - $row[] = format_numeric($data['avgbps']); + $row[] = network_format_bytes($data['avgbps']); $table->data[] = $row; $row = []; $row[] = __('Average packets per second'); - $row[] = format_numeric($data['avgpps']); + $row[] = format_for_graph($data['avgpps'], 2); $table->data[] = $row; $row = []; $row[] = __('Average bytes per packet'); - $row[] = format_numeric($data['avgbpp']); + $row[] = format_for_graph($data['avgbpp'], 2); $table->data[] = $row; $html = html_print_table($table, true); @@ -424,7 +381,7 @@ function netflow_summary_table($data) /** * Returns 1 if the given address is a network address. * - * @param string address Host or network address. + * @param string $address Host or network address. * * @return 1 if the address is a network address, 0 otherwise. */ @@ -441,225 +398,173 @@ function netflow_is_net($address) /** * Returns netflow data for the given period in an array. * - * @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 int max Maximum number of aggregates. - * @param string unit Unit to show. + * @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. * - * @return An array with netflow stats. + * @return array An array with netflow stats. */ -function netflow_get_data($start_date, $end_date, $interval_length, $filter, $aggregate, $max, $unit, $connection_name='', $address_resolution=false) -{ +function netflow_get_data( + $start_date, + $end_date, + $interval_length, + $filter, + $aggregate, + $max, + $absolute, + $connection_name='', + $address_resolution=false +) { global $nfdump_date_format; global $config; - // Requesting remote data + // Requesting remote data. if (defined('METACONSOLE') && $connection_name != '') { - $data = metaconsole_call_remote_api($connection_name, 'netflow_get_data', "$start_date|$end_date|$interval_length|".base64_encode(json_encode($filter))."|$aggregate|$max|$unit".(int) $address_resolution); + $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 + ); return json_decode($data, true); } - // Calculate the number of intervals - if ($interval_length <= 0) { - // $num_intervals = $config['graph_res'] * 50; - $num_intervals = 250; - $period = ($end_date - $start_date); - $interval_length = (int) ($period / $num_intervals); - } else { - $period = ($end_date - $start_date); - $num_intervals = (int) ($period / $interval_length); + if ($start_date > $end_date) { + return []; } - // Set a max number of intervals - if ($num_intervals > $config['netflow_max_resolution']) { - $num_intervals = $config['netflow_max_resolution']; - $interval_length = (int) ($period / $num_intervals); + // 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; } - // If there is aggregation calculate the top n - if ($aggregate != 'none') { - $values['data'] = []; - $values['sources'] = []; - - // Get the command to call nfdump - $command = netflow_get_command($filter); - - // Suppress the header line and the statistics at the bottom and configure piped output - $command .= ' -q -o csv'; - - // Call nfdump - $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); - - // Remove the first line - $string[0] = ''; - - // Parse aggregates - foreach ($string as $line) { - if ($line == '') { - continue; - } - - $val = explode(',', $line); - if ($aggregate == 'proto') { - $values['sources'][$val[3]] = 1; - } else { - $values['sources'][$val[4]] = 1; - } - } - - // Update the filter - switch ($aggregate) { - case 'proto': - $extra_filter = 'proto'; - break; - - default: - case 'srcip': - $extra_filter = 'ip_src'; - break; - case 'srcport': - $extra_filter = 'src_port'; - break; - - case 'dstip': - $extra_filter = 'ip_dst'; - break; - - case 'dstport': - $extra_filter = 'dst_port'; - break; - } - - if (isset($filter[$extra_filter]) && $filter[$extra_filter] != '') { - $filter[$extra_filter] .= ','; - } - - $filter[$extra_filter] = implode( - ',', - array_keys($values['sources']) + // 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']) ); - } else { - $values = []; } - // Address resolution start - $get_hostnames = false; - if ($address_resolution && ($aggregate == 'srcip' || $aggregate == 'dstip')) { - $get_hostnames = true; - global $hostnames; + // Put all points into an array. + $intervals = [($start_date - $multiplier_time)]; + while ((end($intervals) < $end_date) === true) { + $intervals[] = (end($intervals) + $multiplier_time); + } - $sources = []; - foreach ($values['sources'] as $source => $value) { - if (!isset($hostnames[$source])) { - $hostname = gethostbyaddr($source); - if ($hostname !== false) { - $hostnames[$source] = $hostname; - $source = $hostname; + if (end($intervals) != $end_date) { + $intervals[] = $end_date; + } + + // Calculate the top values. + $values = netflow_get_top_data( + $start_date, + $end_date, + $filter, + $aggregate, + $max + ); + + // Update the filter to get properly next data. + netflow_update_second_level_filter( + $filter, + $aggregate, + array_keys($values['sources']) + ); + + // Resolve addresses if required. + $get_hostnames = false; + if ($address_resolution === true) { + global $hostnames; + netflow_address_resolution($values, $get_hostnames, $aggregate); + } + + foreach ($intervals as $k => $time) { + $interval_start = $time; + if (!isset($intervals[($k + 1)])) { + continue; + } + + $interval_end = $intervals[($k + 1)]; + + // Set default values. + foreach ($values['sources'] as $source => $discard) { + $values['data'][$interval_end][$source] = 0; + } + + $data = netflow_get_stats( + $interval_start, + $interval_end, + $filter, + $aggregate, + $max, + $absolute, + $connection_name + ); + + foreach ($data as $line) { + // Address resolution start. + if ($get_hostnames) { + if (!isset($hostnames[$line['agg']])) { + $hostname = false; + // Trying to get something like an IP from the description. + 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']); + } + } + + if ($hostname !== false) { + $hostnames[$line['agg']] = $hostname; + $line['agg'] = $hostname; + } + } else { + $line['agg'] = $hostnames[$line['agg']]; } - } else { - $source = $hostnames[$source]; } - $sources[$source] = $value; - } - - $values['sources'] = $sources; - } - - // Address resolution end - $interval_start = $start_date; - for ($i = 0; $i < $num_intervals; $i++, $interval_start += ($interval_length + 1)) { - $interval_end = ($interval_start + $interval_length); - if ($interval_end > $end_date) { - $interval_end = $end_date; - } - - if ($aggregate == 'none') { - $data = netflow_get_summary($interval_start, $interval_end, $filter, $connection_name); - if (! isset($data['totalbytes'])) { - $values[$interval_start]['data'] = 0; + // Address resolution end. + if (! isset($values['sources'][$line['agg']])) { continue; } - switch ($unit) { - case 'megabytes': - $values[$interval_start]['data'] = ($data['totalbytes'] / 1048576); - break; - - case 'megabytespersecond': - $values[$interval_start]['data'] = ($data['avgbps'] / 1048576 / 8); - break; - - case 'kilobytes': - $values[$interval_start]['data'] = ($data['totalbytes'] / 1024); - break; - - case 'kilobytespersecond': - $values[$interval_start]['data'] = ($data['avgbps'] / 1024 / 8); - break; - - default: - $values[$interval_start]['data'] = $data['totalbytes']; - break; - } - } else { - // Set default values - foreach ($values['sources'] as $source => $discard) { - $values['data'][$interval_start][$source] = 0; - } - - $data = netflow_get_stats( - $interval_start, - $interval_end, - $filter, - $aggregate, - $max, - $unit, - $connection_name - ); - - foreach ($data as $line) { - // Address resolution start - if ($get_hostnames) { - if (!isset($hostnames[$line['agg']])) { - $hostname = false; - // Trying to get something like an IP from the description - 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']); - } - } - - if ($hostname !== false) { - $hostnames[$line['agg']] = $hostname; - $line['agg'] = $hostname; - } - } else { - $line['agg'] = $hostnames[$line['agg']]; - } - } - - // Address resolution end - if (! isset($values['sources'][$line['agg']])) { - continue; - } - - $values['data'][$interval_start][$line['agg']] = $line['data']; - } + $values['data'][$interval_end][$line['agg']] = $line['data']; } } - if (($aggregate != 'none') && (empty($values['data']))) { + if (empty($values['data'])) { return []; } @@ -670,29 +575,40 @@ function netflow_get_data($start_date, $end_date, $interval_length, $filter, $ag /** * Returns netflow stats for the given period in an array. * - * @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 int max Maximum number of aggregates. - * @param string unit Unit to show. + * @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. * - * @return An array with netflow stats. + * @return array With netflow stats. */ -function netflow_get_stats($start_date, $end_date, $filter, $aggregate, $max, $unit, $connection_name='', $address_resolution=false) -{ +function netflow_get_stats( + $start_date, + $end_date, + $filter, + $aggregate, + $max, + $absolute=true, + $connection_name='', + $address_resolution=false +) { global $config, $nfdump_date_format; - // Requesting remote data + // Requesting remote data. if (defined('METACONSOLE') && $connection_name != '') { - $data = metaconsole_call_remote_api($connection_name, 'netflow_get_stats', "$start_date|$end_date|".base64_encode(json_encode($filter))."|$aggregate|$max|$unit|".(int) $address_resolution); + $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); return json_decode($data, true); } - // Get the command to call nfdump + // Get the command to call nfdump. $command = netflow_get_command($filter); - // Execute nfdump + // Execute nfdump. $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); @@ -700,7 +616,7 @@ function netflow_get_stats($start_date, $end_date, $filter, $aggregate, $max, $u return []; } - // Remove the first line + // Remove the first line. $string[0] = ''; $i = 0; @@ -716,60 +632,35 @@ function netflow_get_stats($start_date, $end_date, $filter, $aggregate, $max, $u $values[$i]['date'] = $val[0]; $values[$i]['time'] = $val[1]; - // create field to sort array + // Create field to sort array. $datetime = $val[0]; $end_date = strtotime($datetime); $values[$i]['datetime'] = $end_date; - if ($aggregate == 'proto') { - $values[$i]['agg'] = $val[3]; - } else { - // Address resolution start - if ($address_resolution && ($aggregate == 'srcip' || $aggregate == 'dstip')) { - global $hostnames; + // Address resolution start. + if ($address_resolution && ($aggregate == 'srcip' || $aggregate == 'dstip')) { + global $hostnames; - if (!isset($hostnames[$val[4]])) { - $hostname = gethostbyaddr($val[4]); - if ($hostname !== false) { - $hostnames[$val[4]] = $hostname; - $val[4] = $hostname; - } - } else { - $val[4] = $hostnames[$val[4]]; + if (!isset($hostnames[$val[4]])) { + $hostname = gethostbyaddr($val[4]); + if ($hostname !== false) { + $hostnames[$val[4]] = $hostname; + $val[4] = $hostname; } + } else { + $val[4] = $hostnames[$val[4]]; } - - // Address resolution end - $values[$i]['agg'] = $val[4]; } + // Address resolution end. + $values[$i]['agg'] = $val[4]; + if (! isset($val[9])) { return []; } - switch ($unit) { - case 'megabytes': - $values[$i]['data'] = ($val[9] / 1048576); - break; - - case 'megabytespersecond': - $values[$i]['data'] = ($val[9] / 1048576 / $interval_length); - break; - - case 'kilobytes': - $values[$i]['data'] = ($val[9] / 1024); - break; - - case 'kilobytespersecond': - $values[$i]['data'] = ($val[9] / 1024 / $interval_length); - break; - - default: - case 'bytes': - $values[$i]['data'] = $val[9]; - break; - case 'bytespersecond': - $values[$i]['data'] = ($val[9] / $interval_length); - break; + $values[$i]['data'] = $val[9]; + if (!$absolute) { + $values[$i]['data'] = ($values[$i]['data'] / $interval_length); } $i++; @@ -784,27 +675,28 @@ function netflow_get_stats($start_date, $end_date, $filter, $aggregate, $max, $u /** * Returns a traffic summary for the given period in an array. * - * @param string start_date Period start date. - * @param string end_date Period end date. - * @param string filter Netflow filter. + * @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. * - * @return An array with netflow stats. + * @return array With netflow summary data. */ function netflow_get_summary($start_date, $end_date, $filter, $connection_name='') { global $nfdump_date_format; global $config; - // Requesting remote data + // Requesting remote data. 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); } - // Get the command to call nfdump + // Get the command to call nfdump. $command = netflow_get_command($filter); - // Execute nfdump + // Execute nfdump. $command .= ' -o csv -n 1 -s srcip/bytes -t '.date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date); exec($command, $string); @@ -812,7 +704,7 @@ function netflow_get_summary($start_date, $end_date, $filter, $connection_name=' return []; } - // Read the summary + // Read the summary. $summary = explode(',', $string[5]); if (! isset($summary[5])) { return []; @@ -830,137 +722,174 @@ function netflow_get_summary($start_date, $end_date, $filter, $connection_name=' /** - * Returns a traffic record for the given period in an array. + * Returns a relationships data for the given period in an array. * - * @param string start_date Period start date. - * @param string end_date Period end date. - * @param string filter Netflow filter. - * @param int max Maximum number of elements. - * @param string unit to show. + * @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 string $aggregate One of srcip, srcport, dstip, dstport. * - * @return An array with netflow stats. + * @return array With raw relationship data. */ -function netflow_get_record($start_date, $end_date, $filter, $max, $unit, $address_resolution=false) -{ +function netflow_get_relationships_raw_data( + $start_date, + $end_date, + $filter, + $max, + $aggregate +) { global $nfdump_date_format; global $config; - // TIME_START = 0; - // TIME_END = 1; - // DURATION = 2; - // SOURCE_ADDRESS = 3; - // DESTINATION_ADDRESS = 4; - // SOURCE_PORT = 5; - // DESTINATION_PORT = 6; - // PROTOCOL = 7; - // INPUT_BYTES = 12; - // Get the command to call nfdump + $max_data = netflow_get_top_data( + $start_date, + $end_date, + $filter, + $aggregate, + $max + ); + + // Update src and dst filter (both). + $sources_array = array_keys($max_data['sources']); + $is_ip = netflow_aggregate_is_ip($aggregate); + netflow_update_second_level_filter( + $filter, + ($is_ip === true) ? 'dstip' : 'dstport', + $sources_array + ); + netflow_update_second_level_filter( + $filter, + ($is_ip === true) ? 'srcip' : 'srcport', + $sources_array + ); + + // Get the command to call nfdump. + $command = sprintf( + '%s -q -o csv -n %s -s %s/bytes -t %s-%s', + netflow_get_command($filter), + NETFLOW_MAX_DATA_CIRCULAR_MESH, + 'record', + date($nfdump_date_format, $start_date), + date($nfdump_date_format, $end_date) + ); + + // Get the command to call nfdump. $command = netflow_get_command($filter); - // Execute nfdump - $command .= " -q -o csv -n $max -s record/bytes -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date); + // Execute nfdump. + $command .= ' -q -o csv -n 10000 -s record/bytes -t '.date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date); exec($command, $result); if (! is_array($result)) { + return [ + 'lines' => [], + 'sources' => [], + ]; + } + + return [ + 'lines' => $result, + 'sources' => $sources_array, + ]; +} + + +/** + * Parse the raw relationships data to be painted by circular mesh chart. + * + * @param array $result Lines gotten from nfdump call. + * @param array $sources_array Array with sources involved in the chart. + * @param boolean $is_ip Is ip or port. + * + * @return array With data to be parsed on circular mesh chart. + */ +function netflow_parse_relationships_for_circular_mesh( + $result, + $sources_array, + $is_ip +) { + if (empty($result)) { return []; } - $values = []; - foreach ($result as $key => $line) { - $data = []; + // Initialize some data structures. + $data = [ + 'elements' => [], + 'matrix' => [], + ]; + $initial_data = []; + // This array has the ips or port like keys and the array position as value. + $inverse_sources_array = array_flip($sources_array); + foreach ($sources_array as $sdata) { + $data['elements'][$inverse_sources_array[$sdata]] = $sdata; + $initial_data[$inverse_sources_array[$sdata]] = 0; + } + foreach ($sources_array as $sdata) { + $data['matrix'][$inverse_sources_array[$sdata]] = $initial_data; + } + + // Port are situated in a different places from addreses. + $src_key = ($is_ip === true) ? 3 : 5; + $dst_key = ($is_ip === true) ? 4 : 6; + // Store a footprint of initial data to be compared at the end. + $freeze_data = md5(serialize($data)); + foreach ($result as $line) { + if (empty($line) === true) { + continue; + } + + // Parse the line. $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]; + // Get the required data. + $src_item = $inverse_sources_array[$items[$src_key]]; + $dst_item = $inverse_sources_array[$items[$dst_key]]; + $value = $items[12]; - switch ($unit) { - case 'megabytes': - $data['data'] = ($items[12] / 1048576); - break; - - case 'megabytespersecond': - $data['data'] = ($items[12] / 1048576 / $data['duration']); - break; - - case 'kilobytes': - $data['data'] = ($items[12] / 1024); - break; - - case 'kilobytespersecond': - $data['data'] = ($items[12] / 1024 / $data['duration']); - break; - - default: - case 'bytes': - $data['data'] = $items[12]; - break; - case 'bytespersecond': - $data['data'] = ($items[12] / $data['duration']); - break; + // Check if valid data. + if (!isset($value) + || !isset($data['matrix'][$dst_item][$src_item]) + || !isset($data['matrix'][$src_item][$dst_item]) + ) { + continue; } - $values[] = $data; + // Update the value. + $data['matrix'][$src_item][$dst_item] += (int) $value; } - // Address resolution start - 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']]; - } - } + // Comparte footprints. + if ($freeze_data === md5(serialize($data))) { + // Taht means that all relationships are 0. + return []; } - // Address resolution end - return $values; + return $data; } /** * Returns the command needed to run nfdump for the given filter. * - * @param array filter Netflow filter. + * @param array $filter Netflow filter. * - * @return Command to run. + * @return string Command to run. */ function netflow_get_command($filter) { global $config; - // Build command + // Build command. $command = io_safe_output($config['netflow_nfdump']).' -N'; - // Netflow data path + // Netflow data path. if (isset($config['netflow_path']) && $config['netflow_path'] != '') { $command .= ' -R. -M '.$config['netflow_path']; } - // Filter options + // Filter options. $command .= netflow_get_filter_arguments($filter); return $command; @@ -970,13 +899,13 @@ function netflow_get_command($filter) /** * Returns the nfdump command line arguments that match the given filter. * - * @param array filter Netflow filter. + * @param array $filter Netflow filter. * - * @return Command line argument string. + * @return string Command line argument string. */ function netflow_get_filter_arguments($filter) { - // Advanced filter + // Advanced filter. $filter_args = ''; if ($filter['advanced_filter'] != '') { $filter_args = preg_replace('/["\r\n]/', '', io_safe_output($filter['advanced_filter'])); @@ -987,7 +916,7 @@ function netflow_get_filter_arguments($filter) $filter_args .= ' "(router ip '.$filter['router_ip'].')'; } - // Normal filter + // Normal filter. if ($filter['ip_dst'] != '') { $filter_args .= ' "('; $val_ipdst = explode(',', io_safe_output($filter['ip_dst'])); @@ -1102,74 +1031,11 @@ function netflow_get_filter_arguments($filter) function netflow_get_chart_types() { return [ - 'netflow_area' => __('Area graph'), - 'netflow_pie_summatory' => __('Pie graph and Summary table'), - 'netflow_statistics' => __('Statistics table'), - 'netflow_data' => __('Data table'), - 'netflow_mesh' => __('Circular mesh'), - 'netflow_host_treemap' => __('Host detailed traffic'), - ]; -} - - -/** - * Gets valid intervals for a netflow chart in the format: - * - * interval_length => interval_description - * - * @return array of valid intervals. - */ -function netflow_get_valid_intervals() -{ - return [ - (string) SECONDS_10MINUTES => __('10 mins'), - (string) SECONDS_15MINUTES => __('15 mins'), - (string) SECONDS_30MINUTES => __('30 mins'), - (string) SECONDS_1HOUR => __('1 hour'), - (string) SECONDS_2HOUR => __('2 hours'), - (string) SECONDS_5HOUR => __('5 hours'), - (string) SECONDS_12HOURS => __('12 hours'), - (string) SECONDS_1DAY => __('1 day'), - (string) SECONDS_2DAY => __('2 days'), - (string) SECONDS_5DAY => __('5 days'), - (string) SECONDS_15DAYS => __('15 days'), - (string) SECONDS_1WEEK => __('Last week'), - (string) SECONDS_1MONTH => __('Last month'), - (string) SECONDS_2MONTHS => __('2 months'), - (string) SECONDS_3MONTHS => __('3 months'), - (string) SECONDS_6MONTHS => __('6 months'), - (string) SECONDS_1YEAR => __('Last year'), - (string) SECONDS_2YEARS => __('2 years'), - ]; -} - - -/** - * Gets valid intervals for a netflow chart in the format: - * - * interval_length => interval_description - * - * @return array of valid intervals. - */ -function netflow_get_valid_subintervals() -{ - return [ - (string) SECONDS_1MINUTE => __('1 min'), - (string) SECONDS_2MINUTES => __('2 mins'), - (string) SECONDS_5MINUTES => __('5 mins'), - (string) SECONDS_10MINUTES => __('10 mins'), - (string) SECONDS_15MINUTES => __('15 mins'), - (string) SECONDS_30MINUTES => __('30 mins'), - (string) SECONDS_1HOUR => __('1 hour'), - (string) SECONDS_2HOUR => __('2 hours'), - (string) SECONDS_5HOUR => __('5 hours'), - (string) SECONDS_12HOURS => __('12 hours'), - (string) SECONDS_1DAY => __('1 day'), - (string) SECONDS_2DAY => __('2 days'), - (string) SECONDS_5DAY => __('5 days'), - (string) SECONDS_15DAYS => __('15 days'), - (string) SECONDS_1WEEK => __('1 week'), - (string) SECONDS_1MONTH => __('1 month'), + 'netflow_area' => __('Area graph'), + 'netflow_summary' => __('Summary'), + 'netflow_data' => __('Data table'), + 'netflow_mesh' => __('Circular mesh'), + 'netflow_host_treemap' => __('Host detailed traffic'), ]; } @@ -1177,20 +1043,31 @@ function netflow_get_valid_subintervals() /** * Draw a netflow report item. * - * @param string start_date Period start date. - * @param string end_date Period end date. - * @param string interval_length Interval length in seconds (num_intervals * interval_length = start_date - end_date). - * @param string type Chart type. - * @param array filter Netflow filter. - * @param int max_aggregates Maximum number of aggregates. - * @param string output Output format. Only HTML and XML are supported. + * @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. * - * @return The netflow report in the appropriate format. + * @return string The netflow report in the appropriate format. */ -function netflow_draw_item($start_date, $end_date, $interval_length, $type, $filter, $max_aggregates, $connection_name='', $output='HTML', $address_resolution=false) -{ +function netflow_draw_item( + $start_date, + $end_date, + $interval_length, + $type, + $filter, + $max_aggregates, + $connection_name='', + $output='HTML', + $address_resolution=false +) { $aggregate = $filter['aggregate']; - $unit = $filter['output']; $interval = ($end_date - $start_date); if (defined('METACONSOLE')) { $width = 950; @@ -1200,106 +1077,17 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil $height = 320; - // Process item + // Process item. switch ($type) { - case '0': case 'netflow_area': - $data = netflow_get_data($start_date, $end_date, $interval_length, $filter, $aggregate, $max_aggregates, $unit, $connection_name, $address_resolution); - if (empty($data)) { - break; - } - - if ($aggregate != 'none') { - if ($output == 'HTML') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').': '.netflow_format_aggregate($aggregate); - if ($interval_length != 0) { - $html .= ' '._('Resolution').": $interval_length ".__('seconds'); - } - - $html .= graph_netflow_aggregate_area($data, $interval, $width, $height, netflow_format_unit($unit)); - return $html; - } else if ($output == 'PDF') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').': '.netflow_format_aggregate($aggregate); - if ($interval_length != 0) { - $html .= ' '._('Resolution').": $interval_length ".__('seconds'); - } - - $html .= graph_netflow_aggregate_area($data, $interval, $width, $height, netflow_format_unit($unit), 2, true); - return $html; - } else if ($output == 'XML') { - $xml = "$unit\n"; - $xml .= "$aggregate\n"; - $xml .= "$interval_length\n"; - $xml .= netflow_aggregate_area_xml($data); - return $xml; - } - } else { - if ($output == 'HTML') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - if ($interval_length != 0) { - $html .= ' '._('Resolution').": $interval_length ".__('seconds'); - } - - $html .= graph_netflow_total_area($data, $interval, 660, 320, netflow_format_unit($unit)); - return $html; - } else if ($output == 'PDF') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - if ($interval_length != 0) { - $html .= ' '._('Resolution').": $interval_length ".__('seconds'); - } - - $html .= graph_netflow_total_area($data, $interval, 660, 320, netflow_format_unit($unit), 2, true); - return $html; - } else if ($output == 'XML') { - $xml = "$unit\n"; - $xml .= "$interval_length\n"; - $xml .= netflow_total_area_xml($data); - return $xml; - } - } - break; - - case '2': - case 'netflow_data': - $data = netflow_get_data($start_date, $end_date, $interval_length, $filter, $aggregate, $max_aggregates, $unit, $connection_name, $address_resolution); - - if (empty($data)) { - break; - } - - if ($output == 'HTML' || $output == 'PDF') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').': '.netflow_format_aggregate($aggregate); - if ($interval_length != 0) { - $html .= ' '._('Resolution').": $interval_length ".__('seconds'); - } - - $html .= "
    "; - $html .= netflow_data_table($data, $start_date, $end_date, $aggregate, $unit); - $html .= '
    '; - - return $html; - } else if ($output == 'XML') { - $xml = "$unit\n"; - $xml .= "$aggregate\n"; - $xml .= "$interval_length\n"; - // Same as netflow_aggregate_area_xml - $xml .= netflow_aggregate_area_xml($data); - return $xml; - } - break; - - case '3': - case 'netflow_statistics': - $data = netflow_get_stats( + $data = netflow_get_data( $start_date, $end_date, + $interval_length, $filter, $aggregate, $max_aggregates, - $unit, + false, $connection_name, $address_resolution ); @@ -1308,14 +1096,55 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil } if ($output == 'HTML' || $output == 'PDF') { - $html = netflow_stat_table($data, $start_date, $end_date, $aggregate, $unit); + $html .= graph_netflow_aggregate_area( + $data, + $interval, + $width, + $height, + ($output === 'HTML') ? 1 : 2, + ($output === 'HTML'), + $end_date + ); return $html; } else if ($output == 'XML') { - return netflow_stat_xml($data); + $xml .= ''.$aggregate."\n"; + $xml .= ''.$interval_length."\n"; + $xml .= netflow_aggregate_area_xml($data); + return $xml; + } + break; + + case 'netflow_data': + $data = netflow_get_data( + $start_date, + $end_date, + $interval_length, + $filter, + $aggregate, + $max_aggregates, + true, + $connection_name, + $address_resolution + ); + if (empty($data)) { + break; + } + + if ($output == 'HTML' || $output == 'PDF') { + $html .= "
    "; + $html .= netflow_data_table($data, $start_date, $end_date, $aggregate); + $html .= '
    '; + + return $html; + } else if ($output == 'XML') { + $xml .= ''.$aggregate."\n"; + $xml .= ''.$interval_length."\n"; + // Same as netflow_aggregate_area_xml. + $xml .= netflow_aggregate_area_xml($data); + return $xml; } break; - case '4': case 'netflow_summary': $data_summary = netflow_get_summary( $start_date, @@ -1327,22 +1156,13 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil 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, - $unit, + true, $connection_name, $address_resolution ); @@ -1350,131 +1170,65 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil break; } - if ($output == 'HTML') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').': '.netflow_format_aggregate($aggregate); - $html .= graph_netflow_aggregate_pie($data_pie, netflow_format_aggregate($aggregate)); + if ($output === 'HTML' || $output === 'PDF') { + $html = ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= '
    '; + $html .= netflow_summary_table($data_summary); + $html .= ''; + $html .= graph_netflow_aggregate_pie( + $data_pie, + netflow_format_aggregate($aggregate), + ($output === 'HTML') ? 1 : 2, + ($output === 'HTML') + ); + $html .= '
    '; + $html .= netflow_stat_table( + $data_pie, + $start_date, + $end_date, + $aggregate + ); return $html; - } else if ($output == 'PDF') { - $html = ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').": $aggregate"; - $html .= graph_netflow_aggregate_pie($data_pie, netflow_format_aggregate($aggregate), 2, true); - return $html; - } else if ($output == 'XML') { - $xml = "$unit\n"; - $xml .= "$aggregate\n"; - $xml .= netflow_aggregate_pie_xml($data_pie); - 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, - $unit, - $connection_name, - $address_resolution - ); - if (empty($data_pie)) { - break; - } - - switch ($output) { - case 'HTML': - $html = ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= '
    '; - $html .= netflow_summary_table($data_summary); - $html .= ''.__('Unit').': '.netflow_format_unit($unit); - $html .= ' '.__('Aggregate').': '.netflow_format_aggregate($aggregate); - $html .= ''; - $html .= graph_netflow_aggregate_pie($data_pie, netflow_format_aggregate($aggregate)); - $html .= '
    '; - return $html; - - break; - case 'PDF': - break; - - case 'XML': - return netflow_summary_xml($data_summary); - - break; + } else if ($output === 'XML') { + return netflow_summary_xml($data_summary, $data_pie); } break; case 'netflow_mesh': - $netflow_data = netflow_get_record($start_date, $end_date, $filter, $max_aggregates, $unit, $address_resolution); - - 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']; - } - } + $data = netflow_get_relationships_raw_data( + $start_date, + $end_date, + $filter, + $max_aggregates, + $aggregate, + $address_resolution + ); + $data_circular = netflow_parse_relationships_for_circular_mesh( + $data['lines'], + $data['sources'], + netflow_aggregate_is_ip($aggregate) + ); $html = '
    '; - $html .= graph_netflow_circular_mesh($data, netflow_format_unit($unit), 700); + $html .= graph_netflow_circular_mesh($data_circular); $html .= '
    '; - return $html; - break; case 'netflow_host_treemap': - $netflow_data = netflow_get_record($start_date, $end_date, $filter, $max_aggregates, $unit, $address_resolution); - + $data_stats = netflow_get_stats( + $start_date, + $end_date, + $filter, + $aggregate, + $max_aggregates, + true, + $connection_name, + $address_resolution + ); switch ($aggregate) { case 'srcip': case 'srcport': @@ -1492,51 +1246,30 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil 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']; - } - + $data_graph = [ + 'name' => __('Host detailed traffic').': '.$type, + 'children' => [], + ]; $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; - $children_data['tooltip_content'] = "$port: ".format_numeric($value).' '.netflow_format_unit($unit).''; - $children['children'][] = $children_data; - } - - $data['children'][] = $children; - } + foreach ($data_stats as $sdata) { + $data_graph['children'][] = [ + 'id' => $i++, + 'name' => $sdata['agg'], + 'children' => [ + [ + 'id' => $i++, + 'name' => $sdata['agg'], + 'value' => $sdata['data'], + 'tooltip_content' => network_format_bytes($sdata['data']), + ], + ], + ]; } - return graph_netflow_host_traffic($data, netflow_format_unit($unit), 'auto', 400); + return graph_netflow_host_traffic($data_graph, 'auto', 400); - break; default: + // Nothing to do. break; } @@ -1546,107 +1279,32 @@ function netflow_draw_item($start_date, $end_date, $interval_length, $type, $fil } -/** - * Render a netflow report as an XML. - * - * @param int ID of the netflow report. - * @param string end_date Period start date. - * @param string end_date Period end date. - * @param string interval_length Interval length in seconds (num_intervals * interval_length = start_date - end_date). - */ -function netflow_xml_report($id, $start_date, $end_date, $interval_length=0) -{ - // Get report data - $report = db_get_row_sql('SELECT * FROM tnetflow_report WHERE id_report ='.(int) $id); - if ($report === false) { - echo ''.__('Error generating report')."\n"; - return; - } - - // Print report header - $time = get_system_time(); - echo ''; - echo "\n"; - echo " \n"; - echo ' '.$time."\n"; - echo ' '.date('r', $time)."\n"; - echo " \n"; - echo ' '.io_safe_output($report['id_name'])."\n"; - echo ' '.io_safe_output($report['description'])."\n"; - echo ' '.date('r', $start_date)."\n"; - echo ' '.date('r', $end_date)."\n"; - - // Get netflow item types - $item_types = netflow_get_chart_types(); - - // Print report items - $report_contents = db_get_all_rows_sql( - "SELECT * - FROM tnetflow_report_content - WHERE id_report='".$report['id_report']."' - ORDER BY `order`" - ); - foreach ($report_contents as $content) { - // Get item filters - $filter = db_get_row_sql( - "SELECT * - FROM tnetflow_filter - WHERE id_sg = '".io_safe_input($content['id_filter'])."'", - false, - true - ); - if ($filter === false) { - continue; - } - - echo " \n"; - echo ' '.io_safe_output($content['description'])."\n"; - echo ' '.io_safe_output($item_types[$content['show_graph']])."\n"; - echo ' '.$content['max']."\n"; - echo " \n"; - echo ' '.io_safe_output($filter['id_name'])."\n"; - echo ' '.io_safe_output($filter['ip_src'])."\n"; - echo ' '.io_safe_output($filter['ip_dst'])."\n"; - echo ' '.io_safe_output($filter['src_port'])."\n"; - echo ' '.io_safe_output($filter['src_port'])."\n"; - echo ' '.io_safe_output($filter['advanced_filter'])."\n"; - echo ' '.io_safe_output($filter['aggregate'])."\n"; - echo ' '.io_safe_output($filter['output'])."\n"; - echo " \n"; - - echo netflow_draw_item($start_date, $end_date, $interval_length, $content['show_graph'], $filter, $content['max'], $report['server_name'], 'XML'); - - echo " \n"; - } - - echo "\n"; -} - - /** * Render an aggregated area chart as an XML. * - * @param array Netflow data. + * @param array $data Netflow data. + * + * @return void XML is echoed. */ function netflow_aggregate_area_xml($data) { - // Print source information + // Print source information. if (isset($data['sources'])) { echo "\n"; foreach ($data['sources'] as $source => $discard) { - echo "$source\n"; + echo ''.$source."\n"; } echo "\n"; - // Print flow information + // Print flow information. echo "\n"; foreach ($data['data'] as $timestamp => $flow) { echo "\n"; echo ' '.$timestamp."\n"; echo " \n"; foreach ($flow as $source => $data) { - echo " $source\n"; + echo ' '.$source."\n"; echo ' '.$data."\n"; } @@ -1669,133 +1327,49 @@ function netflow_aggregate_area_xml($data) } -/** - * Render an area chart as an XML. - * - * @param array Netflow data. - */ -function netflow_total_area_xml($data) -{ - // Print flow information - $xml = "\n"; - foreach ($data as $timestamp => $flow) { - $xml .= "\n"; - $xml .= ' '.$timestamp."\n"; - $xml .= ' '.$flow['data']."\n"; - $xml .= "\n"; - } - - $xml .= "\n"; - - return $xml; -} - - -/** - * Render a pie chart as an XML. - * - * @param array Netflow data. - */ -function netflow_aggregate_pie_xml($data) -{ - // Calculate total - $total = 0; - foreach ($data as $flow) { - $total += $flow['data']; - } - - if ($total == 0) { - return; - } - - // Print percentages - echo "\n"; - foreach ($data as $flow) { - echo ''.$flow['agg']."\n"; - echo ''.format_numeric((100 * $flow['data'] / $total), 2)."%\n"; - } - - echo "\n"; -} - - -/** - * Render a stats table as an XML. - * - * @param array Netflow data. - */ -function netflow_stat_xml($data) -{ - // Print stats - $xml .= "\n"; - foreach ($data as $flow) { - $xml .= ''.$flow['agg']."\n"; - $xml .= ''.$flow['data']."\n"; - } - - $xml .= "\n"; - - return $xml; -} - - /** * Render a summary table as an XML. * - * @param array Netflow data. + * @param array $data Netflow data. + * @param array $rows_data Table info (top N hosts). + * + * @return string Wiht XML data. */ -function netflow_summary_xml($data) +function netflow_summary_xml($data, $rows_data) { - // Print summary + // Print summary. $xml = "\n"; - $xml .= ' '.$data['totalflows']."\n"; - $xml .= ' '.$data['totalbytes']."\n"; - $xml .= ' '.$data['totalbytes']."\n"; - $xml .= ' '.$data['avgbps']."\n"; - $xml .= ' '.$data['avgpps']."\n"; - $xml .= ' '.$data['avgpps']."\n"; + $xml = " \n"; + $xml .= ' '.$data['totalflows']."\n"; + $xml .= ' '.$data['totalbytes']."\n"; + $xml .= ' '.$data['totalbytes']."\n"; + $xml .= ' '.$data['avgbps']."\n"; + $xml .= ' '.$data['avgpps']."\n"; + $xml .= ' '.$data['avgpps']."\n"; + $xml .= " \n"; + + // Add the data table. + $xml .= " \n"; + foreach ($rows_data as $d) { + $xml .= "\n"; + $xml .= ''.$d['agg']."\n"; + $xml .= ''.$d['data']."\n"; + $xml .= "\n"; + } + + $xml .= " \n"; $xml .= "\n"; return $xml; } -/** - * Return a string describing the given unit. - * - * @param string Netflow unit. - */ -function netflow_format_unit($unit) -{ - switch ($unit) { - case 'megabytes': - return __('MB'); - - case 'megabytespersecond': - return __('MB/s'); - - case 'kilobytes': - return __('kB'); - - case 'kilobytespersecond': - return __('kB/s'); - - case 'bytes': - return __('Bytes'); - - case 'bytespersecond': - return __('B/s'); - - default: - return ''; - } -} - - /** * Return a string describing the given aggregate. * - * @param string Netflow aggregate. + * @param string $aggregate Netflow aggregate. + * + * @return string With formatted aggregate. */ function netflow_format_aggregate($aggregate) { @@ -1806,9 +1380,6 @@ function netflow_format_aggregate($aggregate) case 'dstip': return __('Dst IP'); - case 'proto': - return __('Protocol'); - case 'srcip': return __('Src IP'); @@ -1824,20 +1395,20 @@ function netflow_format_aggregate($aggregate) /** * Check the nfdump binary for compatibility. * - * @param string nfdump binary full path. + * @param string $nfdump_binary Nfdump binary full path. * - * @return 1 if the binary does not exist or is not executable, 2 if a + * @return integer 1 if the binary does not exist or is not executable, 2 if a * version older than 1.6.8 is installed or the version cannot be * determined, 0 otherwise. */ function netflow_check_nfdump_binary($nfdump_binary) { - // Check that the binary exists and is executable + // Check that the binary exists and is executable. if (! is_executable($nfdump_binary)) { return 1; } - // Check at least version 1.6.8 + // Check at least version 1.6.8. $output = ''; $rc = -1; exec($nfdump_binary.' -V', $output, $rc); @@ -1866,3 +1437,462 @@ function netflow_check_nfdump_binary($nfdump_binary) return 2; } + + +/** + * 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. + * @param string $order Select one of bytes,pkts,flow. + * + * @return array With data (host, sum_bytes, sum_pkts and sum_flows). + */ +function netflow_get_top_summary( + $max, + $top_action, + $start_date, + $end_date, + $filter='', + $order='bytes' +) { + 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': + $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'; + } + break; + + default: + return []; + } + + $command = netflow_get_command($netflow_filter); + + // Execute nfdump. + $order_text = ''; + switch ($order) { + case 'flows': + $order_text = 'flows'; + break; + + case 'pkts': + $order_text = 'packets'; + break; + + case 'bytes': + default: + $order_text = 'bytes'; + break; + } + + $command .= " -q -o csv -n $max -s $sort/$order_text -t ".date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date); + 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; + } + + $top_info[(string) $data[4]] = [ + 'host' => $data[4], + 'sum_bytes' => $data[9], + 'sum_pkts' => $data[7], + 'sum_flows' => $data[5], + 'pct_bytes' => $data[10], + 'pct_pkts' => $data[8], + 'pct_flows' => $data[6], + ]; + } + + return $top_info; +} + + +/** + * 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; + } +} + + +/** + * 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'), + ]; +} + + +/** + * 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'); +} + + +/** + * Report formatted subtitle. + * + * @param string $aggregate 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; +} + + +/** + * Returns netflow stats for the given period in an array. + * + * @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. + * + * @return array With netflow stats. + */ +function netflow_get_top_data( + $start_date, + $end_date, + $filter, + $aggregate, + $max +) { + global $nfdump_date_format; + + $values = [ + 'data' => [], + 'sources' => [], + ]; + + // Get the command to call nfdump. + $agg_command = sprintf( + '%s -q -o csv -n %s -s %s/bytes -t %s-%s', + netflow_get_command($filter), + $max, + $aggregate, + date($nfdump_date_format, $start_date), + date($nfdump_date_format, $end_date) + ); + + // Call nfdump. + exec($agg_command, $string); + + // Remove the first line. + $string[0] = ''; + + // Parse aggregates. + foreach ($string as $line) { + if (empty($line) === true) { + continue; + } + + $val = explode(',', $line); + $values['sources'][$val[4]] = 1; + } + + return $values; +} + + +/** + * Returns netflow stats for the given period in an array. + * + * @param string $filter Netflow filter (passed by reference). + * @param string $aggregate Aggregate field. + * @param array $sources Sources to aggregate to filter. + * + * @return void $filter is passed by reference. + */ +function netflow_update_second_level_filter(&$filter, $aggregate, $sources) +{ + // Update the filter. + switch ($aggregate) { + default: + case 'srcip': + $extra_filter = 'ip_src'; + break; + case 'srcport': + $extra_filter = 'src_port'; + break; + + case 'dstip': + $extra_filter = 'ip_dst'; + break; + + case 'dstport': + $extra_filter = 'dst_port'; + break; + } + + if (isset($filter[$extra_filter]) && $filter[$extra_filter] != '') { + $filter[$extra_filter] .= ','; + } + + $filter[$extra_filter] = implode(',', $sources); +} + + +/** + * Change some values on address resolve. + * + * @param array $values Where data will be overwritten (ref). + * @param boolean $get_hostnames Change it if address resolution es done (ref). + * @param string $aggregate One of srcip, srcport, dstip, dstport. + * + * @return void Referenced passed params will be changed. + */ +function netflow_address_resolution(&$values, &$get_hostnames, $aggregate) +{ + if ($aggregate !== 'srcip' && $aggregate !== 'dstip') { + return; + } + + $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; +} + + +/** + * Check if is aggregate by IP or by port + * + * @param string $aggregate Aggregate tag. + * + * @return boolean True if is IP. False for port. + */ +function netflow_aggregate_is_ip($aggregate) +{ + return in_array($aggregate, ['dstip', 'srcip']); +} + + +/** + * Build netflow data structure to network map. + * + * @param integer $start_date Time in timestamp format. + * @param integer $end_date Time in timestamp format. + * @param integer $top Max data to show. + * @param integer $aggregate One of dstip or srcip. + * + * @return array With map structure. + */ +function netflow_build_map_data($start_date, $end_date, $top, $aggregate) +{ + // Pass an empty filter data structure. + $data = netflow_get_relationships_raw_data( + $start_date, + $end_date, + [ + 'id_name' => '', + 'id_group' => 0, + 'aggregate' => $aggregate, + 'id_dst' => '', + 'ip_src' => '', + 'dst_port' => '', + 'src_port' => '', + 'advanced_filter' => '', + 'router_ip' => '', + ], + $top, + $aggregate + ); + + $nodes = array_map( + function ($elem) { + return network_init_node_map($elem); + }, + array_merge($data['sources'], [__('Others')]) + ); + + $relations = []; + $inverse_nodes = array_flip($data['sources']); + + // Port are situated in a different places from addreses. + $is_ip = true; + $src_key = ($is_ip === true) ? 3 : 5; + $dst_key = ($is_ip === true) ? 4 : 6; + $retrieved_data = array_fill_keys($inverse_nodes, false); + + foreach ($data['lines'] as $line) { + if (empty($line) === true) { + continue; + } + + // Parse the line. + $items = explode(',', $line); + + // Get the required data. + $src_item = $inverse_nodes[$items[$src_key]]; + $dst_item = $inverse_nodes[$items[$dst_key]]; + $value = $items[12]; + $index_rel = $src_item.'-'.$dst_item; + + // Check if valid data. + if (!isset($value) || (!isset($src_item) && !isset($dst_item))) { + continue; + } + + // Mark as connected source and destination. + $retrieved_data[$src_item] = true; + $retrieved_data[$dst_item] = true; + + if (isset($relations[$index_rel])) { + $relations[$index_rel]['text_start'] += $value; + } else { + // Update the value. + network_init_relation_map($relations, $src_item, $dst_item, $value); + } + } + + // Format the data in edges. + array_walk( + $relations, + function (&$elem) { + $elem['text_start'] = network_format_bytes($elem['text_start']); + } + ); + + // Search for orphan nodes. + $orphan_hosts = []; + $orphan_index = (end($inverse_nodes) + 1); + foreach ($retrieved_data as $position => $rd) { + if ($rd === true) { + continue; + } + + network_init_relation_map($orphan_hosts, $position, $orphan_index); + } + + // If there is not any orphan node, delete it. + if (empty($orphan_hosts)) { + array_pop($nodes); + } + + return network_general_map_configuration( + $nodes, + array_merge($relations, $orphan_hosts) + ); +} diff --git a/pandora_console/include/functions_network.php b/pandora_console/include/functions_network.php new file mode 100644 index 0000000000..9c9e1456b4 --- /dev/null +++ b/pandora_console/include/functions_network.php @@ -0,0 +1,320 @@ + %d AND utimestamp < %d + %s + %s + GROUP BY %s + ORDER BY %s DESC + LIMIT %d', + $field_to_group, + $start, + $end, + $filter_sql, + $host_filter_sql, + $field_to_group, + $field_to_order, + $top + ); + + $data = db_get_all_rows_sql($sql); + + return ($data !== false) ? $data : []; +} + + +/** + * Get the possible actions on networking. + * + * @param boolean $network True if network. False if netflow. + * + * @return array With the actions to print in a select. + */ +function network_get_report_actions($network=true) +{ + $common_actions = [ + 'listeners' => __('Top listeners'), + 'talkers' => __('Top talkers'), + ]; + + if ($network) { + return $common_actions; + } + + return array_merge( + $common_actions, + [ + 'tcp' => __('Top TCP protocols'), + 'udp' => __('Top UDP protocols'), + ] + ); +} + + +/** + * Print the header of the network + * + * @param string $title Title of header. + * @param string $order Current ordering. + * @param string $selected Selected order. + * @param array $hidden_data All the data to hide into the button. + * + * @return string With HTML data. + */ +function network_print_explorer_header( + $title, + $order, + $selected, + $hidden_data +) { + $cell = '
    '; + $cell .= $title; + $cell .= html_print_link_with_params( + 'images/arrow-down-white.png', + array_merge($hidden_data, ['order_by' => $order]), + 'image', + ($selected === $order) ? 'opacity: 0.5' : '' + ); + $cell .= '
    '; + + return $cell; +} + + +/** + * Alias for format_for_graph to print bytes. + * + * @param integer $value Value to parse like bytes. + * + * @return string Number parsed. + */ +function network_format_bytes($value) +{ + if (!isset($value)) { + $value = 0; + } + + $value = (int) $value; + + return format_for_graph( + $value, + 2, + '.', + ',', + 1024, + 'B' + ); +} + + +/** + * Build netflow data structure to network map. + * + * @param integer $start Time in timestamp format. + * @param integer $end Time in timestamp format. + * @param integer $top Max data to show. + * @param boolean $talker True to get top tolkers. False for listeners. + * + * @return array With map structure. + */ +function network_build_map_data($start, $end, $top, $talker) +{ + $data = network_matrix_get_top($top, $talker, $start, $end); + + $hosts = array_map( + function ($elem) { + return $elem['host']; + }, + $data + ); + $inverse_hosts = array_flip($hosts); + + $nodes = array_map( + function ($elem) { + return network_init_node_map($elem); + }, + $hosts + ); + + $relations = []; + $orphan_relations = []; + foreach ($hosts as $host) { + $host_top = network_matrix_get_top( + $top, + !$talker, + $start, + $end, + $host, + true, + $hosts + ); + foreach ($host_top as $sd) { + $src_index = $inverse_hosts[$host]; + $dst_index = $inverse_hosts[$sd['host']]; + if (isset($src_index) === false || isset($dst_index) === false) { + continue; + } + + network_init_relation_map( + $relations, + $src_index, + $dst_index, + network_format_bytes($sd['sum_bytes']) + ); + } + + // Put the orphans on Other node. + if (empty($host_top)) { + $other_id = (end($inverse_hosts) + 1); + // TODOS: Add the data. + network_init_relation_map( + $orphan_relations, + $other_id, + $inverse_hosts[$host] + ); + } + } + + // Put the Others node and their relations. + if (empty($orphan_relations) === false) { + $nodes[] = network_init_node_map(__('Others')); + $relations = array_merge($relations, $orphan_relations); + } + + return network_general_map_configuration($nodes, $relations); +} + + +/** + * Return the array to pass to constructor to NetworkMap. + * + * @param array $nodes Nodes data structure. + * @param array $relations Relations data structure. + * + * @return array To be passed to NetworMap class. + */ +function network_general_map_configuration($nodes, $relations) +{ + return [ + 'nodes' => $nodes, + 'relations' => $relations, + 'pure' => 1, + 'no_pandora_node' => 1, + 'no_popup' => 1, + 'map_options' => [ + 'generation_method' => LAYOUT_SPRING1, + 'map_filter' => [ + 'node_radius' => 40, + 'node_sep' => 7, + ], + ], + ]; +} + + +/** + * Added a relation to relations array + * + * @param array $relations Relations array (passed by reference). + * @param integer $parent Parent id (numeric). + * @param integer $child Child id (numeric). + * @param string $text Text to show at the end of edge (optional). + * + * @return void Relations will be modified (passed by reference). + */ +function network_init_relation_map(&$relations, $parent, $child, $text='') +{ + $index = $parent.'-'.$child; + $relations[$index] = [ + 'id_parent' => $parent, + 'parent_type' => NODE_GENERIC, + 'child_type' => NODE_GENERIC, + 'id_child' => $child, + 'link_color' => '#82B92E', + ]; + + if (empty($text) === false) { + $relations[$index]['text_start'] = $text; + } +} + + +/** + * Initialize a node structure to NetworkMap class. + * + * @param string $name Node name. + * + * @return array Node data structure. + */ +function network_init_node_map($name) +{ + return [ + 'name' => $name, + 'type' => NODE_GENERIC, + 'width' => 20, + 'height' => 20, + 'status' => '#82B92E', + ]; +} diff --git a/pandora_console/include/functions_networkmap.php b/pandora_console/include/functions_networkmap.php index adbaa00922..af11deb541 100644 --- a/pandora_console/include/functions_networkmap.php +++ b/pandora_console/include/functions_networkmap.php @@ -1,32 +1,36 @@ = 1) { + /* + * Select data origin. + * group + * discovery task + * - Cloud + * - Application + * - Standar or custom + * network/mask + */ + + if ($group >= 0 && empty($ip_mask)) { if ($dont_show_subgroups) { $filter['id_grupo'] = $group; } else { @@ -372,22 +358,8 @@ function networkmap_generate_dot( } else if ($group == -666) { $agents = false; } else if (!empty($ip_mask)) { - $agents = networkmap_get_new_nodes_from_ip_mask( - $ip_mask, - [ - 'id_grupo', - 'nombre', - 'id_os', - 'id_parent', - 'id_agente', - 'normal_count', - 'warning_count', - 'critical_count', - 'unknown_count', - 'total_count', - 'notinit_count', - ], - $strict_user + $agents = networkmap_get_nodes_from_ip_mask( + $ip_mask ); } else { $agents = agents_get_agents( @@ -455,7 +427,6 @@ function networkmap_generate_dot( // Get agent modules data $modules = agents_get_modules($agent['id_agente'], '*', $filter, true, true); - if ($modules === false) { $modules = []; } @@ -518,11 +489,11 @@ function networkmap_generate_dot( // Create void statistics array $stats = []; - - $count = 0; - $group_nodes = 10; - $graph .= networkmap_create_transparent_node($count); - foreach (array_keys($orphans) as $node) { + /* + $count = 0; + $group_nodes = 10; + $graph .= networkmap_create_transparent_node($count); + foreach (array_keys($orphans) as $node) { if ($group_nodes == 0) { $count++; $graph .= networkmap_create_transparent_node($count); @@ -536,7 +507,8 @@ function networkmap_generate_dot( ); $group_nodes--; - } + } + */ // Create nodes foreach ($nodes as $node_id => $node) { @@ -694,17 +666,57 @@ function networkmap_generate_dot( } -// Returns an edge definition -function networkmap_create_edge($head, $tail, $layout, $nooverlap, $pure, $zoom, $ranksep, $simple, $regen, $font_size, $group, $sec2='operation/agentes/networkmap', $tab='topology', $id_networkmap=0) -{ +/** + * Returns an edge definition. + * + * @param mixed $head Head. + * @param mixed $tail Tail. + * @param string $layout Layout. + * @param string $nooverlap Nooverlap. + * @param integer $pure Pure. + * @param float $zoom Zoom. + * @param float $ranksep Ranksep. + * @param integer $simple Simple. + * @param integer $regen Regen. + * @param integer $font_size Font_size. + * @param integer $group Group. + * @param string $sec2 Sec2. + * @param string $tab Tab. + * @param integer $id_networkmap Id_networkmap. + * + * @return string Dot string. + */ +function networkmap_create_edge( + $head, + $tail, + $layout, + $nooverlap, + $pure, + $zoom, + $ranksep, + $simple, + $regen, + $font_size, + $group, + $sec2='operation/agentes/networkmap', + $tab='topology', + $id_networkmap=0 +) { if (defined('METACONSOLE')) { $url = ''; } else { - $url = 'index.php?sec=estado&'.'sec2='.$sec2.'&'.'tab='.$tab.'&'.'recenter_networkmap=1&'.'center='.$head.'&'.'layout='.$layout.'&'.'nooverlap='.$nooverlap.'&'.'pure='.$pure.'&'.'zoom='.$zoom.'&'.'ranksep='.$ranksep.'&'.'simple='.$simple.'&'.'regen=1'.'&'.'font_size='.$font_size.'&'.'group='.$group.'&'.'id_networkmap='.$id_networkmap; + $url = 'index.php?sec=estado&sec2='.$sec2.'&tab='.$tab.'&'; + $url .= 'recenter_networkmap=1¢er='.$head.'&'; + $url .= 'layout='.$layout.'&nooverlap='.$nooverlap.'&'; + $url .= 'pure='.$pure.'&zoom='.$zoom.'&ranksep='.$ranksep.'&'; + $url .= 'simple='.$simple.'®en=1&font_size='.$font_size.'&'; + $url .= 'group='.$group.'&id_networkmap='.$id_networkmap; } - // edgeURL allows node navigation - $edge = "\n".$head.' -- '.$tail.'[color="#BDBDBD", headclip=false, tailclip=false, edgeURL=""];'."\n"; + // Option edgeURL allows node navigation. + $edge = "\n".$head.' -- '.$tail; + $edge .= '[len='.$ranksep.', color="#BDBDBD", headclip=false, tailclip=false, edgeURL=""];'; + $edge .= "\n"; return $edge; } @@ -719,96 +731,6 @@ function networkmap_create_transparent_edge($head, $tail) } -// Returns a group node definition -function networkmap_create_group_node($group, $simple=0, $font_size=10, $metaconsole=false, $id_server=null, $strict_user=false) -{ - global $config; - global $hack_networkmap_mobile; - - $status = groups_get_status($group['id_grupo'], $strict_user); - - // Set node status - switch ($status) { - case 0: - $status_color = COL_NORMAL; - // Normal monitor - break; - - case 1: - $status_color = COL_CRITICAL; - // Critical monitor - break; - - case 2: - $status_color = COL_WARNING; - // Warning monitor - break; - - case 4: - $status_color = COL_ALERTFIRED; - // Alert fired - break; - - default: - $status_color = COL_UNKNOWN; - // Unknown monitor - break; - } - - $icon = groups_get_icon($group['id_grupo']); - - if ($simple == 0) { - // Set node icon - if ($hack_networkmap_mobile) { - $img_node = $config['homedir'].'/images/groups_small/'.$icon.'.png'; - - if (!file_exists($img_node)) { - $img_node = '-'; - } - - $img_node = ''; - } else if (file_exists(html_print_image('images/groups_small/'.$icon.'.png', true, false, true, true))) { - $img_node = html_print_image('images/groups_small/'.$icon.'.png', true, false, false, true); - } else { - $img_node = '-'; - } - - if (strlen(groups_get_name($group['id_grupo'])) > 40) { - $name = substr(groups_get_name($group['id_grupo']), 0, 40).'...'; - } else { - $name = groups_get_name($group['id_grupo']); - } - - if (defined('METACONSOLE')) { - $url = ''; - $url_tooltip = ''; - } else { - $url = 'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60&group_id='.$group['id_grupo']; - $url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_group_status_tooltip=1&id_group='.$group['id_grupo']; - } - - $node = "\n".$group['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', style="filled", fixedsize=true, width=0.30, height=0.30, '.'label=< -
    '.$img_node.'
    '.io_safe_output($name).'
    >, - shape="invtrapezium", URL="'.$url.'", - tooltip="'.$url_tooltip.'"];'."\n"; - } else { - if (defined('METACONSOLE')) { - $url = ''; - $url_tooltip = ''; - } else { - $url = 'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60&group_id='.$group['id_grupo']; - $url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_group_status_tooltip=1&id_group='.$group['id_grupo']; - } - - $node = "\n".$group['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', shape="invtrapezium", - URL="'.$url.'", style="filled", fixedsize=true, width=0.20, height=0.20, label="", - tooltip="'.$url_tooltip.'"];'."\n"; - } - - return $node; -} - - // Returns a node definition function networkmap_create_agent_node($agent, $simple=0, $font_size=10, $cut_names=true, $relative=false, $metaconsole=false, $id_server=null, $strict_user=false) { @@ -952,76 +874,6 @@ function networkmap_create_agent_node($agent, $simple=0, $font_size=10, $cut_nam } -function networkmap_create_module_group_node($module_group, $simple=0, $font_size=10, $metaconsole=false, $id_server=null) -{ - global $config; - global $hack_networkmap_mobile; - - // Set node status - switch ($module_group['status']) { - case 0: - $status_color = COL_NORMAL; - // Normal monitor - break; - - case 1: - $status_color = COL_CRITICAL; - // Critical monitor - break; - - case 2: - $status_color = COL_WARNING; - // Warning monitor - break; - - case 4: - $status_color = COL_ALERTFIRED; - // Alert fired - break; - - default: - $status_color = COL_UNKNOWN; - // Unknown monitor - break; - } - - if ($simple == 0) { - if (defined('METACONSOLE')) { - $url = ''; - $url_tooltip = ''; - } else { - $url = ''; - $url_tooltip = ''; - } - - $node = $module_group['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', style="filled", '.'fixedsize=true, width=0.30, height=0.30, '.'label=<
    '.io_safe_output($module_group['name']).'
    >, - shape="square", URL="'.$url.'", - tooltip="'.$url_tooltip.'"];'; - } else { - if ($hack_networkmap_mobile) { - $img_node = ui_print_moduletype_icon($module['id_tipo_modulo'], true, true, false, true); - - $img_node = $config['homedir'].'/'.$img_node; - $img_node = ''; - } else { - $img_node = ui_print_moduletype_icon($module['id_tipo_modulo'], true, true, false); - } - - if (defined('METACONSOLE')) { - $url = ''; - $url_tooltip = ''; - } else { - $url = ''; - $url_tooltip = ''; - } - - $node = $module_group['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', shape="square", URL="'.$url.'", '.'style="filled", fixedsize=true, width=0.20, '.'height=0.20, label="", tooltip="'.$url_tooltip.'"];'; - } - - return $node; -} - - // Returns a module node definition function networkmap_create_module_node($module, $simple=0, $font_size=10, $metaconsole=false, $id_server=null) { @@ -1175,35 +1027,13 @@ function networkmap_create_transparent_node($count=0) } -// Opens a group definition -function networkmap_open_group($id) -{ - $img = 'images/'.groups_get_icon($id).'.png'; - $name = groups_get_name($id); - - $group = 'subgraph cluster_'.$id.' { style=filled; color=darkolivegreen3; label=< - -
    '.html_print_image($img, true).''.$name.'
    >; tooltip="'.$name.'"; - URL="index.php?sec=estado&sec2=operation/agentes/estado_agente&group_id='.$id.'";'; - - return $group; -} - - -// Closes a group definition -function networkmap_close_group() -{ - return '}'; -} - - // Opens a graph definition function networkmap_open_graph( $layout, $nooverlap, $pure, $zoom, - $ranksep, + $rank_sep, $font_size, $size_canvas, $map_filter=[] @@ -1236,7 +1066,7 @@ function networkmap_open_graph( if (isset($map_filter['node_sep'])) { $node_sep = $map_filter['node_sep']; } else { - $node_sep = 0.25; + $node_sep = 0.1; } if (isset($map_filter['rank_sep'])) { @@ -1258,14 +1088,14 @@ function networkmap_open_graph( if (isset($map_filter['kval'])) { $kval = $map_filter['kval']; } else { - $kval = 0.3; + $kval = 0.1; } // BEWARE: graphwiz DONT use single ('), you need double (") $head = 'graph networkmap { dpi=100; bgcolor="transparent"; labeljust=l; margin=0; pad="0.75,0.75";'; if ($nooverlap != '') { $head .= 'overlap="false";'; - $head .= 'outputorder=edgesfirst;'; + $head .= 'outputorder=first;'; } if ($layout == 'flat' || $layout == 'spring1' || $layout == 'spring2') { @@ -1290,12 +1120,13 @@ function networkmap_open_graph( $head .= "mindist=\"$mindist\";"; } - $head .= 'ratio=fill;'; + $head .= 'ratio="fill";'; $head .= 'root=0;'; $head .= "nodesep=\"$node_sep\";"; $head .= "size=\"$size\";"; $head .= "\n"; + return $head; } @@ -1338,67 +1169,6 @@ function networkmap_get_filter($layout) } -/** - * Creates a networkmap. - * - * @param string Network map name. - * @param string Network map type (topology, groups or policies). - * @param layout Network map layout (circular, flat, radial, spring1 or spring2). - * @param bool overlapping activate flag. - * @param bool simple view activate flag. - * @param bool regenerate file activate flag. - * @param int font size. - * @param int group id filter (0 for all). - * @param int module group id filter (0 for all). - * @param int policy id filter (0 for all). - * @param string depth level. - * @param bool only modules with alerts flag. - * @param bool hide policy modules flag - * @param float zoom factor - * - * @return mixed New networkmap id if created. False if it could not be created. - */ -function networkmap_create_networkmap($values) -{ - global $config; - - // The name is required - if (! isset($values['name'])) { - return false; - } - - // Set defaults for the empty values - set_unless_defined($values['type'], 'topology'); - set_unless_defined($values['layout'], 'radial'); - set_unless_defined($values['nooverlap'], true); - set_unless_defined($values['simple'], false); - set_unless_defined($values['regenerate'], true); - set_unless_defined($values['font_size'], 12); - set_unless_defined($values['store_group'], 0); - set_unless_defined($values['id_group'], 0); - set_unless_defined($values['regenerate'], true); - set_unless_defined($values['id_module_group'], 0); - set_unless_defined($values['depth'], 'all'); - set_unless_defined($values['only_modules_with_alerts'], false); - set_unless_defined($values['hide_policy_modules'], false); - set_unless_defined($values['zoom'], 1); - set_unless_defined($values['distance_nodes'], 2.5); - set_unless_defined($values['center'], 0); - set_unless_defined($values['id_user'], $config['id_user']); - set_unless_defined($values['text_filter'], ''); - set_unless_defined($values['regenerate'], true); - set_unless_defined($values['dont_show_subgroups'], 0); - set_unless_defined($values['show_groups'], false); - set_unless_defined($values['pandoras_children'], false); - set_unless_defined($values['show_modules'], false); - set_unless_defined($values['show_snmp_modules'], 0); - set_unless_defined($values['l2_network'], 0); - set_unless_defined($values['server_name'], ''); - - return @db_process_sql_insert('tnetwork_map', $values); -} - - /** * Get a network map report. * @@ -1517,57 +1287,6 @@ function networkmap_type_to_str_type($type) } -/** - * Deletes a network map if the property is that user. - * - * @param string User id that call this funtion. - * @param int Map id to be deleted. - * - * @return boolean True if the map was deleted, false the map is not yours. - */ -function networkmap_delete_user_networkmap($id_user='', $id_networkmap) -{ - if ($id_user == '') { - $id_user = $config['id_user']; - } - - $id_networkmap = safe_int($id_networkmap); - if (empty($id_networkmap)) { - return false; - } - - $networkmap = networkmap_get_networkmap($id_networkmap); - if ($networkmap === false) { - return false; - } - - return @db_process_sql_delete('tnetwork_map', ['id_networkmap' => $id_networkmap, 'id_user' => $id_user]); -} - - -/** - * Updates a network map. - * - * @param int Map id. - * @param array Extra values to be set. - * - * @return boolean True if the map was updated. False otherwise. - */ -function networkmap_update_networkmap($id_networkmap, $values) -{ - $networkmap = networkmap_get_networkmap($id_networkmap); - if ($networkmap === false) { - return false; - } - - return (db_process_sql_update( - 'tnetwork_map', - $values, - ['id_networkmap' => $id_networkmap] - )) !== false; -} - - /** * Get different networkmaps types for creation. * @@ -1597,108 +1316,78 @@ function networkmap_get_types($strict_user=false) /** - * Get networkmaps types. + * Retrieve agent list matching desired network. * - * @return array Networkmap diferent types. + * @param string $ip_mask Networks. + * @param array $fields Extra fields. + * + * @return array Of agents. */ -function networkmap_get_filter_types($strict_user=false) -{ - $networkmap_types = []; - - $is_enterprise = enterprise_include_once('include/functions_policies.php'); - - $networkmap_types['topology'] = __('Topology'); - $networkmap_types['groups'] = __('Group'); - $networkmap_types['dynamic'] = __('Dynamic'); - if (!$strict_user) { - $networkmap_types['radial_dynamic'] = __('Radial dynamic'); - } - - if (($is_enterprise !== ENTERPRISE_NOT_HOOK) && (!$strict_user)) { - $enterprise_types = enterprise_hook('policies_get_networkmap_filter_types'); - - $networkmap_types = array_merge($networkmap_types, $enterprise_types); - } - - return $networkmap_types; -} - - -function networkmap_cidr_match($ip, $cidr_mask) -{ - // copy from open source code - // https://gist.github.com/linickx/1309388 - $chunks = explode('/', $cidr_mask); - $subnet = $chunks[0]; - $bits = $chunks[1]; - - $ip = ip2long($ip); - $subnet = ip2long($subnet); - $mask = (-1 << (32 - $bits)); - $subnet &= $mask; - // nb: in case the supplied subnet wasn't correctly aligned - return ($ip & $mask) == $subnet; -} - - -function networkmap_get_new_nodes_from_ip_mask( +function networkmap_get_nodes_from_ip_mask( $ip_mask, - $fields=[], - $strict_user=false + $return_ids_only=false ) { $list_ip_masks = explode(',', $ip_mask); - $list_address = db_get_all_rows_in_table('taddress'); - if (empty($address)) { - $address = []; - } - - if ($strict_user) { - $filter['group_by'] = 'tagente.id_agente'; - $fields = ['tagente.id_agente']; - $acltags = tags_get_user_groups_and_tags($config['id_user'], 'AR', $strict_user); - $user_agents = tags_get_all_user_agents(false, $config['id_user'], $acltags, $filter, $fields, false, $strict_user, true); - - foreach ($all_user_agents as $agent) { - $user_agents[$agent['id_agente']] = $agent['id_agente']; - } + if (empty($list_ip_masks)) { + return []; } $agents = []; - foreach ($list_address as $address) { - foreach ($list_ip_masks as $ip_mask) { - if (networkmap_cidr_match($address['ip'], $ip_mask)) { - $id_agent = db_get_value_filter( - 'id_agent', - 'taddress_agent', - ['id_a' => $address['id_a']] - ); + foreach ($list_ip_masks as $subnet) { + $net = explode('/', $subnet); - if (empty($id_agent)) { - continue; - } + // Calculate real network address. Avoid user bad input. + $mask = ~((1 << (32 - $net[1])) - 1); + $network = long2ip(ip2long($net[0]) & $mask); - if (empty($fields)) { - if ($strict_user) { - if (array_key_exists($id_agent, $user_agents)) { - $agents[] = db_get_value_filter('id_agent', 'taddress_agent', ['id_a' => $address['id_a']]); - } - } else { - $agents[] = db_get_value_filter('id_agent', 'taddress_agent', ['id_a' => $address['id_a']]); - } - } else { - if ($strict_user) { - if (array_key_exists($id_agent, $user_agents)) { - $agents[] = db_get_row('tagente', 'id_agente', $id_agent, $fields); - } - } else { - $agents[] = db_get_row('tagente', 'id_agente', $id_agent, $fields); - } - } - } + $sql = sprintf( + 'SELECT * + FROM `tagente` + INNER JOIN + (SELECT DISTINCT `id_agent` FROM + (SELECT `id_agente` AS "id_agent", `direccion` AS "ip" + FROM `tagente` + UNION + SELECT ag.`id_agent`, a.`ip` + FROM `taddress_agent` ag + INNER JOIN `taddress` a + ON ag.id_a=a.id_a + ) t_tmp + WHERE (-1 << %d) & INET_ATON(t_tmp.ip) = INET_ATON("%s") + ) t_res + ON t_res.`id_agent` = `tagente`.`id_agente`', + (32 - $net[1]), + $network + ); + + $subnet_agents = db_get_all_rows_sql($sql); + + if ($subnet_agents !== false) { + $agents = array_merge($agents, $subnet_agents); } } + if ($return_ids_only === false) { + $agents = array_reduce( + $agents, + function ($carry, $item) { + $carry[$item['id_agente']] = $item; + return $carry; + }, + [] + ); + } else { + $agents = array_reduce( + $agents, + function ($carry, $item) { + $carry[$item['id_agente']] = $item['id_agente']; + return $carry; + }, + [] + ); + } + return $agents; } @@ -1729,7 +1418,944 @@ function modules_get_all_interfaces($id_agent) } -?> +function networkmap_delete_networkmap($id=0) +{ + if (enterprise_installed()) { + // Relations + $result = delete_relations($id); + + // Nodes + $result = delete_nodes($id); + } + + // Map + $result = db_process_sql_delete('tmap', ['id' => $id]); + + return $result; +} + + +function networkmap_delete_nodes($id_map) +{ + return db_process_sql_delete('titem', ['id_map' => $id_map]); +} + + +function get_networkmaps($id) +{ + $groups = array_keys(users_get_groups(null, 'IW')); + + $filter = []; + $filter['id_group'] = $groups; + $filter['id'] = '<>'.$id; + $networkmaps = db_get_all_rows_filter('tmap', $filter); + if ($networkmaps === false) { + $networkmaps = []; + } + + $return = []; + $return[0] = __('None'); + foreach ($networkmaps as $networkmap) { + $return[$networkmap['id']] = $networkmap['name']; + } + + return $return; +} + + +/** + * Translates node (nodes_and_relations) into JS node. + * + * @param array $node Node. + * @param integer $count Count. + * @param integer $count_item_holding_area Count_item_holding_area. + * @param boolean $simulated Simulated. + * + * @return array JS nodes. + */ +function networkmap_db_node_to_js_node( + $node, + &$count, + &$count_item_holding_area, + $simulated=false +) { + global $config; + + $networkmap = db_get_row('tmap', 'id', $node['id_map']); + + $networkmap['filter'] = json_decode($networkmap['filter'], true); + + // Hardcoded + $networkmap['filter']['holding_area'] = [ + 500, + 500, + ]; + + // 40 = DEFAULT NODE RADIUS + // 30 = for to align + $holding_area_max_y = ($networkmap['height'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][1] + 10 * 40); + + $item = []; + $item['id'] = $count; + + if (enterprise_installed() && $simulated === false) { + enterprise_include_once('include/functions_networkmap.php'); + $item['id_db'] = $node['id_in_db']; + } else { + $item['id_db'] = (int) $node['id']; + } + + if ((int) $node['type'] == 0) { + $item['type'] = 0; + $item['id_agent'] = (int) $node['source_data']; + $item['id_module'] = ''; + } else if ((int) $node['type'] == 1) { + $item['type'] = 1; + $item['id_agent'] = (int) $node['style']['id_agent']; + $item['id_module'] = (int) $node['source_data']; + } else { + $item['type'] = 3; + } + + $item['fixed'] = true; + $item['x'] = (int) $node['x']; + $item['y'] = (int) $node['y']; + $item['px'] = (int) $node['x']; + $item['py'] = (int) $node['y']; + $item['z'] = (int) $node['z']; + $item['state'] = $node['state']; + $item['deleted'] = $node['deleted']; + if ($item['state'] == 'holding_area') { + // 40 = DEFAULT NODE RADIUS + // 30 = for to align + $holding_area_x = ($networkmap['width'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][0] + ($count_item_holding_area % 11) * 40); + $holding_area_y = ($networkmap['height'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][1] + (int) (($count_item_holding_area / 11)) * 40); + + if ($holding_area_max_y <= $holding_area_y) { + $holding_area_y = $holding_area_max_y; + } + + $item['x'] = $holding_area_x; + $item['y'] = $holding_area_y; + + // Increment for the next node in holding area + $count_item_holding_area++; + } + + $item['image_url'] = ''; + $item['image_width'] = 0; + $item['image_height'] = 0; + if (!empty($node['style']['image'])) { + $item['image_url'] = html_print_image( + $node['style']['image'], + true, + false, + true + ); + $image_size = getimagesize( + $config['homedir'].'/'.$node['style']['image'] + ); + $item['image_width'] = (int) $image_size[0]; + $item['image_height'] = (int) $image_size[1]; + } + + $item['raw_text'] = $node['style']['label']; + $item['text'] = io_safe_output($node['style']['label']); + $item['shape'] = $node['style']['shape']; + + switch ($node['type']) { + case 0: + $color = get_status_color_networkmap($node['source_data']); + break; + + default: + // Old code + if ($node['source_data'] == -1) { + $color = '#364D1F'; + } else if ($node['source_data'] == -2) { + $color = '#364D1F'; + } else { + $color = get_status_color_networkmap($node['source_data']); + } + break; + } + + $item['color'] = $color; + $item['map_id'] = 0; + if (isset($node['id_map'])) { + $item['map_id'] = $node['id_map']; + } + + if (!isset($node['style']['id_networkmap']) || $node['style']['id_networkmap'] == '' || $node['style']['id_networkmap'] == 0) { + $item['networkmap_id'] = 0; + } else { + $item['networkmap_id'] = $node['style']['id_networkmap']; + } + + $count++; + + return $item; +} + + +function get_status_color_networkmap($id, $color=true) +{ + // $status = agents_get_status($id); + $agent_data = db_get_row_sql('SELECT * FROM tagente WHERE id_agente = '.$id); + + if ($agent_data === false) { + return COL_UNKNOWN; + } + + $status = agents_get_status_from_counts($agent_data); + + if (!$color) { + return $status; + } + + if ($agent_data['fired_count'] > 0) { + return COL_ALERTFIRED; + } + + // Select node color by checking status. + switch ($status) { + case AGENT_MODULE_STATUS_NORMAL: + return COL_NORMAL; + + case AGENT_MODULE_STATUS_NOT_INIT: + return COL_NOTINIT; + + case AGENT_MODULE_STATUS_CRITICAL_BAD: + return COL_CRITICAL; + + case AGENT_MODULE_STATUS_WARNING: + return COL_WARNING; + + case AGENT_MODULE_STATUS_UNKNOWN: + default: + return COL_UNKNOWN; + } + + return COL_UNKNOWN; +} + + +function networkmap_clean_relations_for_js(&$relations) +{ + do { + $cleaned = true; + + foreach ($relations as $key => $relation) { + if ($relation['id_parent_source_data'] == $relation['id_child_source_data']) { + if (($relation['child_type'] != 3) && $relation['parent_type'] != 3) { + $cleaned = false; + + if ($relation['parent_type'] == 1) { + $to_find = $relation['id_parent_source_data']; + $to_replace = $relation['id_child_source_data']; + } else if ($relation['child_type'] == 1) { + $to_find = $relation['id_child_source_data']; + $to_replace = $relation['id_parent_source_data']; + } + + // Replace and erase the links + foreach ($relations as $key2 => $relation2) { + if ($relation2['id_parent_source_data'] == $to_find) { + $relations[$key2]['id_parent_source_data'] = $to_replace; + } else if ($relation2['id_child_source_data'] == $to_find) { + $relations[$key2]['id_child_source_data'] = $to_replace; + } + } + + unset($relations[$key]); + + break; + } + } + } + } while (!$cleaned); +} + + +/** + * Transform networkmap relations into js links. + * + * @param array $relations Relations. + * @param array $nodes_graph Nodes_graph. + * @param boolean $simulated Simulated. + * + * @return array JS relations. + */ +function networkmap_links_to_js_links( + $relations, + $nodes_graph, + $simulated=false +) { + $return = []; + + if (enterprise_installed() && $simulated === false) { + enterprise_include_once('include/functions_networkmap.php'); + } + + $count = 0; + foreach ($relations as $key => $relation) { + if (($relation['parent_type'] == NODE_MODULE) + && ($relation['child_type'] == NODE_MODULE) + ) { + $id_target_agent = agents_get_agent_id_by_module_id( + $relation['id_parent_source_data'] + ); + $id_source_agent = agents_get_agent_id_by_module_id( + $relation['id_child_source_data'] + ); + $id_target_module = $relation['id_parent_source_data']; + $id_source_module = $relation['id_child_source_data']; + } else if (($relation['parent_type'] == NODE_MODULE) + && ($relation['child_type'] == NODE_AGENT) + ) { + $id_target_agent = agents_get_agent_id_by_module_id( + $relation['id_parent_source_data'] + ); + $id_target_module = $relation['id_parent_source_data']; + $id_source_agent = $relation['id_child_source_data']; + } else if (($relation['parent_type'] == NODE_AGENT) + && ($relation['child_type'] == NODE_MODULE) + ) { + $id_target_agent = $relation['id_parent_source_data']; + $id_source_module = $relation['id_child_source_data']; + $id_source_agent = agents_get_agent_id_by_module_id( + $relation['id_child_source_data'] + ); + } else { + $id_target_agent = $relation['id_parent_source_data']; + $id_source_agent = $relation['id_child_source_data']; + } + + $item = []; + $item['id'] = $count; + $count++; + if (enterprise_installed() && $simulated === false) { + $item['id_db'] = get_relation_id($relation); + } else { + $item['id_db'] = $key; + } + + $item['arrow_start'] = ''; + $item['arrow_end'] = ''; + $item['status_start'] = ''; + $item['status_end'] = ''; + $item['id_module_start'] = 0; + $item['id_agent_start'] = (int) $id_source_agent; + $item['id_module_end'] = 0; + $item['id_agent_end'] = (int) $id_target_agent; + $item['link_color'] = '#999'; + $item['target'] = -1; + $item['source'] = -1; + $item['deleted'] = $relation['deleted']; + + if (enterprise_installed() && $simulated === false) { + $target_and_source = []; + $target_and_source = get_id_target_and_source_in_db($relation); + $item['target_id_db'] = (int) $target_and_source['target']; + $item['source_id_db'] = (int) $target_and_source['source']; + } else { + if (($relation['parent_type'] == NODE_MODULE) && ($relation['child_type'] == NODE_MODULE)) { + $item['target_id_db'] = $id_target_agent; + $item['source_id_db'] = $id_source_agent; + } else if (($relation['parent_type'] == NODE_AGENT) && ($relation['child_type'] == NODE_AGENT)) { + $item['target_id_db'] = (int) $relation['id_parent_source_data']; + $item['source_id_db'] = $id_source_agent; + } else { + $item['target_id_db'] = (int) $relation['id_parent_source_data']; + $item['source_id_db'] = (int) $relation['id_child_source_data']; + } + } + + $item['text_end'] = ''; + $item['text_start'] = ''; + + if ($relation['parent_type'] == 1) { + $item['arrow_end'] = 'module'; + $item['status_end'] = modules_get_agentmodule_status((int) $id_target_module, false, false, null); + $item['id_module_end'] = (int) $id_target_module; + $text_end = modules_get_agentmodule_name((int) $id_target_module); + if (preg_match('/(.+)_ifOperStatus$/', (string) $text_end, $matches)) { + if ($matches[1]) { + // It's ok to safe_output as it inlo goint to be user into the map line + $item['text_end'] = io_safe_output($matches[1]); + } + } + } + + if ($relation['child_type'] == NODE_MODULE) { + $item['arrow_start'] = 'module'; + $item['status_start'] = modules_get_agentmodule_status((int) $id_source_module, false, false, null); + $item['id_module_start'] = (int) $id_source_module; + $text_start = modules_get_agentmodule_name((int) $id_source_module); + if (preg_match('/(.+)_ifOperStatus$/', (string) $text_start, $matches)) { + if ($matches[1]) { + // It's ok to safe_output as it inlo goint to be user into the map line + $item['text_start'] = io_safe_output($matches[1]); + } + } + } + + $agent = 0; + $agent2 = 0; + $control1 = false; + $control2 = false; + + if (($relation['parent_type'] == NODE_MODULE) && ($relation['child_type'] == NODE_MODULE)) { + if (($item['status_start'] == AGENT_MODULE_STATUS_CRITICAL_BAD) || ($item['status_end'] == AGENT_MODULE_STATUS_CRITICAL_BAD)) { + $item['link_color'] = '#FC4444'; + } else if (($item['status_start'] == AGENT_MODULE_STATUS_WARNING) || ($item['status_end'] == AGENT_MODULE_STATUS_WARNING)) { + $item['link_color'] = '#FAD403'; + } + + $agent = agents_get_agent_id_by_module_id( + $relation['id_parent_source_data'] + ); + $agent2 = agents_get_agent_id_by_module_id( + $relation['id_child_source_data'] + ); + foreach ($nodes_graph as $key2 => $node) { + if (isset($node['id_agent'])) { + if ($node['id_agent'] == $agent) { + $agent = $node['id_db']; + $control1 = true; + } + + if ($node['id_agent'] == $agent2) { + $agent2 = $node['id_db']; + $control2 = true; + } + + if ($control1 && $control2) { + break; + } + } + } + } else if ($relation['child_type'] == NODE_MODULE) { + if ($item['status_start'] == AGENT_MODULE_STATUS_CRITICAL_BAD) { + $item['link_color'] = '#FC4444'; + } else if ($item['status_start'] == AGENT_MODULE_STATUS_WARNING) { + $item['link_color'] = '#FAD403'; + } + + $agent2 = agents_get_agent_id_by_module_id( + $relation['id_child_source_data'] + ); + foreach ($nodes_graph as $key2 => $node) { + if (isset($node['id_agent'])) { + if ($node['id_agent'] == $relation['id_parent_source_data']) { + $agent = $node['id_db']; + $control1 = true; + } + + if ($node['id_agent'] == $agent2) { + $agent2 = $node['id_db']; + $control2 = true; + } + + if ($control1 && $control2) { + break; + } + } + } + } else if ($relation['parent_type'] == NODE_MODULE) { + if ($item['status_end'] == AGENT_MODULE_STATUS_CRITICAL_BAD) { + $item['link_color'] = '#FC4444'; + } else if ($item['status_end'] == AGENT_MODULE_STATUS_WARNING) { + $item['link_color'] = '#FAD403'; + } + + $agent = agents_get_agent_id_by_module_id( + $relation['id_parent_source_data'] + ); + foreach ($nodes_graph as $key2 => $node) { + if (isset($node['id_agent'])) { + if ($node['id_agent'] == $agent) { + $agent = $node['id_db']; + $control1 = true; + } + + if ($node['id_agent'] == $relation['id_child_source_data']) { + $agent2 = $node['id_db']; + $control2 = true; + } + + if ($control1 && $control2) { + break; + } + } + } + } else if (($relation['parent_type'] == NODE_PANDORA) + && ($relation['child_type'] == NODE_PANDORA) + ) { + foreach ($nodes_graph as $key2 => $node) { + if ($relation['id_parent'] == $node['id_db']) { + $agent = $node['id_db']; + } + } + + foreach ($nodes_graph as $key2 => $node) { + if ($relation['id_child'] == $node['id_db']) { + $agent2 = $node['id_db']; + } + } + } else if (($relation['parent_type'] == NODE_PANDORA) + || ($relation['child_type'] == NODE_PANDORA) + ) { + if ($relation['parent_type'] == NODE_PANDORA) { + foreach ($nodes_graph as $key2 => $node) { + if ($relation['id_parent'] == $node['id_db']) { + $agent = $node['id_db']; + } else if ($node['id_agent'] == $relation['id_child_source_data']) { + $agent2 = $node['id_db']; + } + } + } else if ($relation['child_type'] == NODE_PANDORA) { + foreach ($nodes_graph as $key2 => $node) { + if ($relation['id_child'] == $node['id_db']) { + $agent2 = $node['id_db']; + } else if ($node['id_agent'] == $relation['id_parent_source_data']) { + $agent = $node['id_db']; + } + } + } + } else { + foreach ($nodes_graph as $key2 => $node) { + if (isset($node['id_agent'])) { + if ($node['id_agent'] == $relation['id_parent_source_data']) { + $agent = $node['id_db']; + } else if ($node['id_agent'] == $relation['id_child_source_data']) { + $agent2 = $node['id_db']; + } + } + } + } + + foreach ($nodes_graph as $node) { + if ($node['id_db'] == $agent) { + $item['target'] = $node['id']; + } else if ($node['id_db'] == $agent2) { + $item['source'] = $node['id']; + } + } + + if ((($item['target'] == -1) || ($item['source'] == -1)) + && $relation['parent_type'] == NODE_MODULE + && $relation['child_type'] == NODE_MODULE + ) { + continue; + } + + $return[] = $item; + } + + return $return; +} + + +function get_status_color_module_networkmap($id_agente_modulo) +{ + $status = modules_get_agentmodule_status($id_agente_modulo); + + // Set node status + switch ($status) { + case 0: + // At the moment the networkmap enterprise does not show the + // alerts. + case AGENT_MODULE_STATUS_NORMAL_ALERT: + $status_color = COL_NORMAL; + // Normal monitor + break; + + case 1: + $status_color = COL_CRITICAL; + // Critical monitor + break; + + case 2: + $status_color = COL_WARNING; + // Warning monitor + break; + + case 4: + $status_color = COL_ALERTFIRED; + // Alert fired + break; + + default: + $status_color = COL_UNKNOWN; + // Unknown monitor + break; + } + + return $status_color; +} + + +function duplicate_networkmap($id) +{ + $return = true; + + $values = db_get_row('tmap', 'id', $id); + unset($values['id']); + $free_name = false; + $values['name'] = io_safe_input(__('Copy of ')).$values['name']; + $count = 1; + while (!$free_name) { + $exist = db_get_row_filter('tmap', ['name' => $values['name']]); + if ($exist === false) { + $free_name = true; + } else { + $values['name'] = $values['name'].io_safe_input(' '.$count); + } + } + + $correct_or_id = db_process_sql_insert('tmap', $values); + if ($correct_or_id === false) { + $return = false; + } else { + if (enterprise_installed()) { + $new_id = $correct_or_id; + duplicate_map_insert_nodes_and_relations($id, $new_id); + } + } + + if ($return) { + return true; + } else { + // Clean DB. + if (enterprise_installed()) { + // Relations + delete_relations($new_id); + + // Nodes + delete_nodes($new_id); + } + + db_process_sql_delete('tmap', ['id' => $new_id]); + + return false; + } +} + + +function clean_duplicate_links($relations) +{ + if (enterprise_installed()) { + enterprise_include_once('include/functions_networkmap.php'); + } + + $segregation_links = []; + $index = 0; + $index2 = 0; + $index3 = 0; + $index4 = 0; + foreach ($relations as $rel) { + if (($rel['parent_type'] == 0) && ($rel['child_type'] == 0)) { + $segregation_links['aa'][$index] = $rel; + $index++; + } else if (($rel['parent_type'] == 1) && ($rel['child_type'] == 1)) { + $segregation_links['mm'][$index2] = $rel; + $index2++; + } else if (($rel['parent_type'] == 3) && ($rel['child_type'] == 3)) { + $segregation_links['ff'][$index4] = $rel; + $index4++; + } else { + $segregation_links['am'][$index3] = $rel; + $index3++; + } + } + + $final_links = []; + + // ---------------------------------------------------------------- + // --------------------- Clean duplicate links -------------------- + // ---------------------------------------------------------------- + $duplicated = false; + $index_to_del = 0; + $index = 0; + if (isset($segregation_links['aa']) === true + && is_array($segregation_links['aa']) === true + ) { + foreach ($segregation_links['aa'] as $link) { + foreach ($segregation_links['aa'] as $link2) { + if ($link['id_parent'] == $link2['id_child'] + && $link['id_child'] == $link2['id_parent'] + ) { + if (enterprise_installed()) { + delete_link($segregation_links['aa'][$index_to_del]); + } + + unset($segregation_links['aa'][$index_to_del]); + } + + $index_to_del++; + } + + $final_links['aa'][$index] = $link; + $index++; + + $duplicated = false; + $index_to_del = 0; + } + } + + $duplicated = false; + $index_to_del = 0; + $index2 = 0; + if (isset($segregation_links['mm']) === true + && is_array($segregation_links['mm']) === true + ) { + foreach ($segregation_links['mm'] as $link) { + foreach ($segregation_links['mm'] as $link2) { + if ($link['id_parent'] == $link2['id_child'] + && $link['id_child'] == $link2['id_parent'] + ) { + if (enterprise_installed()) { + delete_link($segregation_links['mm'][$index_to_del]); + } + } + + $index_to_del++; + } + + $final_links['mm'][$index2] = $link; + $index2++; + + $duplicated = false; + $index_to_del = 0; + } + } + + $duplicated = false; + $index_to_del = 0; + $index3 = 0; + + if (isset($segregation_links['ff']) === true + && is_array($segregation_links['ff']) === true + ) { + foreach ($segregation_links['ff'] as $link) { + foreach ($segregation_links['ff'] as $link2) { + if ($link['id_parent'] == $link2['id_child'] + && $link['id_child'] == $link2['id_parent'] + ) { + if (enterprise_installed()) { + delete_link($segregation_links['ff'][$index_to_del]); + } + + unset($segregation_links['ff'][$index_to_del]); + } + + $index_to_del++; + } + + $final_links['ff'][$index3] = $link; + $index3++; + + $duplicated = false; + $index_to_del = 0; + } + } + + $final_links['am'] = $segregation_links['am']; + + /* + ---------------------------------------------------------------- + ----------------- AA, AM and MM links management --------------- + ------------------ Priority: ----------------------------------- + -------------------- 1 -> MM (module - module) ----------------- + -------------------- 2 -> AM (agent - module) ------------------ + -------------------- 3 -> AA (agent - agent) ------------------- + ---------------------------------------------------------------- + */ + + $final_links2 = []; + $index = 0; + $l3_link = []; + $agent1 = 0; + $agent2 = 0; + + if (isset($final_links['mm']) === true + && is_array($final_links['mm']) === true + ) { + foreach ($final_links['mm'] as $rel_mm) { + $module_parent = $rel_mm['id_parent_source_data']; + $module_children = $rel_mm['id_child_source_data']; + $agent1 = (int) agents_get_agent_id_by_module_id($module_parent); + $agent2 = (int) agents_get_agent_id_by_module_id($module_children); + foreach ($final_links['aa'] as $key => $rel_aa) { + $l3_link = $rel_aa; + $id_p_source_data = (int) $rel_aa['id_parent_source_data']; + $id_c_source_data = (int) $rel_aa['id_child_source_data']; + if ((($id_p_source_data == $agent1) + && ($id_c_source_data == $agent2)) + || (($id_p_source_data == $agent2) + && ($id_c_source_data == $agent1)) + ) { + if (enterprise_installed()) { + delete_link($final_links['aa'][$key]); + } + + unset($final_links['aa'][$key]); + } + } + } + } + + $final_links2['aa'] = $final_links['aa']; + $final_links2['mm'] = $final_links['mm']; + $final_links2['am'] = $final_links['am']; + $final_links2['ff'] = $final_links['ff']; + + $same_m = []; + $index = 0; + if (isset($final_links2['am']) === true + && is_array($final_links2['am']) === true + ) { + foreach ($final_links2['am'] as $rel_am) { + foreach ($final_links2['am'] as $rel_am2) { + if (($rel_am['id_child_source_data'] == $rel_am2['id_child_source_data']) + && ($rel_am['id_parent_source_data'] != $rel_am2['id_parent_source_data']) + ) { + $same_m[$index]['rel'] = $rel_am2; + $same_m[$index]['agent_parent'] = $rel_am['id_parent_source_data']; + $index++; + } + } + } + } + + $final_links3 = []; + $index = 0; + $l3_link = []; + $have_l3 = false; + if (isset($final_links2['aa']) === true + && is_array($final_links2['aa']) === true + ) { + foreach ($final_links2['aa'] as $key => $rel_aa) { + $l3_link = $rel_aa; + foreach ($same_m as $rel_am) { + if ((($rel_aa['id_parent_source_data'] == $rel_am['parent']['id_parent_source_data']) + && ($rel_aa['id_child_source_data'] == $rel_am['rel']['id_parent_source_data'])) + || (($rel_aa['id_child_source_data'] == $rel_am['parent']['id_parent_source_data']) + && ($rel_aa['id_parent_source_data'] == $rel_am['rel']['id_parent_source_data'])) + ) { + if (enterprise_installed()) { + delete_link($final_links2['aa'][$key]); + } + + unset($final_links2['aa'][$key]); + } + } + } + } + + $final_links3['aa'] = $final_links2['aa']; + $final_links3['mm'] = $segregation_links['mm']; + $final_links3['am'] = $segregation_links['am']; + $final_links3['ff'] = $final_links2['ff']; + + $cleaned_links = []; + if (isset($final_links3['aa']) === true + && is_array($final_links3['aa']) === true + ) { + foreach ($final_links3['aa'] as $link) { + $cleaned_links[] = $link; + } + } + + if (isset($final_links3['am']) === true + && is_array($final_links3['am']) === true + ) { + foreach ($final_links3['am'] as $link) { + $cleaned_links[] = $link; + } + } + + if (isset($final_links3['mm']) === true + && is_array($final_links3['mm']) === true + ) { + foreach ($final_links3['mm'] as $link) { + $cleaned_links[] = $link; + } + } + + if (isset($final_links3['ff']) === true + && is_array($final_links3['ff']) === true + ) { + foreach ($final_links3['ff'] as $link) { + $cleaned_links[] = $link; + } + } + + return $cleaned_links; +} + + +function migrate_older_open_maps($id) +{ + global $config; + + $old_networkmap = db_get_row_filter( + 'tnetwork_map', + ['id_networkmap' => $id] + ); + + $map_values = []; + $map_values['id_group'] = $old_networkmap['id_group']; + $map_values['id_user'] = $old_networkmap['id_user']; + $map_values['type'] = 0; + $map_values['subtype'] = 0; + $map_values['name'] = $old_networkmap['name']; + + $new_map_filter = []; + $new_map_filter['dont_show_subgroups'] = $old_networkmap['dont_show_subgroups']; + $new_map_filter['node_radius'] = 40; + $new_map_filter['id_migrate_map'] = $id; + $map_values['filter'] = json_encode($new_map_filter); + + $map_values['description'] = 'Mapa open migrado'; + $map_values['width'] = 4000; + $map_values['height'] = 4000; + $map_values['center_x'] = 2000; + $map_values['center_y'] = 2000; + $map_values['background'] = ''; + $map_values['background_options'] = 0; + $map_values['source_period'] = 60; + $map_values['source'] = 0; + $map_values['source_data'] = $old_networkmap['id_group']; + if ($old_networkmap['type'] == 'radial_dinamic') { + $map_values['generation_method'] = 6; + } else { + $map_values['generation_method'] = 4; + } + + $map_values['generated'] = 0; + + $id_new_map = db_process_sql_insert('tmap', $map_values); + + if (!$id_new_map) { + return false; + } + + return true; +} + + +/** + * Load cluetip required files and JS. + * + * @return void + */ +function networkmap_load_cluetip() +{ + ui_require_css_file('cluetip', 'include/styles/js/'); + + ?> + ')], ' ', $message_info['mensaje']) + io_safe_output($message_info['subject']), + strip_tags(io_safe_output($message_info['mensaje']), '
    ')
         );
     }
    diff --git a/pandora_console/include/functions_pandora_networkmap.php b/pandora_console/include/functions_pandora_networkmap.php
    index 9870172de4..cad7fc7edf 100644
    --- a/pandora_console/include/functions_pandora_networkmap.php
    +++ b/pandora_console/include/functions_pandora_networkmap.php
    @@ -1,2189 +1,29 @@
      $id]);
    -
    -    return $result;
    -}
    -
    -
    -function networkmap_delete_nodes($id_map)
    -{
    -    return db_process_sql_delete('titem', ['id_map' => $id_map]);
    -}
    -
    -
    -function networkmap_process_networkmap($id=0)
    -{
    -    global $config;
    -
    -    include_once 'include/functions_os.php';
    -
    -    $numNodes = (int) db_get_num_rows(
    -        '
    -		SELECT *
    -		FROM titem
    -		WHERE id_map = '.$id.' and deleted = 0'
    -    );
    -
    -    $networkmap = db_get_row_filter(
    -        'tmap',
    -        ['id' => $id]
    -    );
    -    $map_filter = json_decode($networkmap['filter'], true);
    -
    -    $pure = (int) get_parameter('pure', 0);
    -
    -    switch ($networkmap['generation_method']) {
    -        case 0:
    -            $filter = 'circo';
    -            $layout = 'circular';
    -        break;
    -
    -        case 1:
    -            $filter = 'dot';
    -            $layout = 'flat';
    -        break;
    -
    -        case 2:
    -            $filter = 'twopi';
    -            $layout = 'radial';
    -        break;
    -
    -        case 3:
    -            $filter = 'neato';
    -            $layout = 'spring1';
    -        break;
    -
    -        case 4:
    -            $filter = 'fdp';
    -            $layout = 'spring2';
    -        break;
    -    }
    -
    -    $simple = 0;
    -    $font_size = 12;
    -    $nooverlap = false;
    -    $zoom = 1;
    -    $ranksep = 0.5;
    -    $center = 0;
    -    $regen = 1;
    -    $show_snmp_modules = false;
    -    $dont_show_subgroups = false;
    -
    -    $id_group = $networkmap['id_group'];
    -    $ip_mask = '';
    -    switch ($networkmap['source']) {
    -        case 1:
    -            $recon_task = db_get_row_filter(
    -                'trecon_task',
    -                ['id_rt' => $networkmap['source_data']]
    -            );
    -
    -            $ip_mask = $recon_task['subnet'];
    -        break;
    -
    -        case 2:
    -            $ip_mask = $networkmap['source_data'];
    -        break;
    -    }
    -
    -    $nodes_and_relations = [];
    -
    -    if (enterprise_installed() && ($numNodes > 0)) {
    -        $nodes_and_relations = get_structure_nodes($id);
    -    } else {
    -        if ($map_filter['empty_map']) {
    -            // Open Graph
    -            $graph = networkmap_open_graph(
    -                $layout,
    -                $nooverlap,
    -                $pure,
    -                $zoom,
    -                $ranksep,
    -                $font_size,
    -                null
    -            );
    -            $graph .= networkmap_create_pandora_node(get_product_name(), $font_size, $simple);
    -            $graph .= networkmap_close_graph();
    -
    -            switch (PHP_OS) {
    -                case 'WIN32':
    -                case 'WINNT':
    -                case 'Windows':
    -                    $filename_dot = sys_get_temp_dir()."\\networkmap_".$filter;
    -                break;
    -
    -                default:
    -                    $filename_dot = sys_get_temp_dir().'/networkmap_'.$filter;
    -                break;
    -            }
    -
    -            if ($simple) {
    -                $filename_dot .= '_simple';
    -            }
    -
    -            if ($nooverlap) {
    -                $filename_dot .= '_nooverlap';
    -            }
    -
    -            $filename_dot .= '_'.$id.'.dot';
    -
    -            file_put_contents($filename_dot, $graph);
    -
    -            switch (PHP_OS) {
    -                case 'WIN32':
    -                case 'WINNT':
    -                case 'Windows':
    -                    $filename_plain = sys_get_temp_dir().'\\plain.txt';
    -
    -                    $cmd = io_safe_output(
    -                        $config['graphviz_bin_dir']."\\$filter.exe -Tplain -o ".$filename_plain.' '.$filename_dot
    -                    );
    -                break;
    -
    -                default:
    -                    $filename_plain = sys_get_temp_dir().'/plain.txt';
    -
    -                    $cmd = "$filter -Tplain -o ".$filename_plain.' '.$filename_dot;
    -                break;
    -            }
    -
    -            system($cmd);
    -
    -            unlink($filename_dot);
    -
    -            $nodes = networkmap_loadfile(
    -                $id,
    -                $filename_plain,
    -                $relation_nodes,
    -                $graph
    -            );
    -
    -            unlink($filename_plain);
    -
    -            // Set the position of modules
    -            foreach ($nodes as $key => $node) {
    -                if ($node['type'] == 'module') {
    -                    // Search the agent of this module for to get the
    -                    // position
    -                    foreach ($nodes as $key2 => $node2) {
    -                        if ($node2['id_agent'] != 0 && $node2['type'] == 'agent') {
    -                            if ($node2['id_agent'] == $node['id_agent']) {
    -                                $nodes[$key]['coords'][0] = ($nodes[$key2]['coords'][0] + $node['height'] / 2);
    -                                $nodes[$key]['coords'][1] = ($nodes[$key2]['coords'][1] + $node['width'] / 2);
    -                            }
    -                        }
    -                    }
    -                }
    -            }
    -
    -            $nodes_and_relations['nodes'] = [];
    -            $index = 0;
    -            foreach ($nodes as $key => $node) {
    -                $nodes_and_relations['nodes'][$index]['id'] = $node['id'];
    -                $nodes_and_relations['nodes'][$index]['id_map'] = $id;
    -
    -                $nodes_and_relations['nodes'][$index]['x'] = (int) $node['coords'][0];
    -                $nodes_and_relations['nodes'][$index]['y'] = (int) $node['coords'][1];
    -
    -                if (($node['type'] == 'agent') || ($node['type'] == '')) {
    -                    $nodes_and_relations['nodes'][$index]['source_data'] = $node['id_agent'];
    -                    $nodes_and_relations['nodes'][$index]['type'] = 0;
    -                } else {
    -                    $nodes_and_relations['nodes'][$index]['source_data'] = $node['id_module'];
    -                    $nodes_and_relations['nodes'][$index]['id_agent'] = $node['id_agent'];
    -                    $nodes_and_relations['nodes'][$index]['type'] = 1;
    -                }
    -
    -                $style = [];
    -                $style['shape'] = 'circle';
    -                $style['image'] = $node['image'];
    -                $style['width'] = $node['width'];
    -                $style['height'] = $node['height'];
    -                $style['label'] = $node['text'];
    -                $style['id_networkmap'] = $node['networkmap'];
    -                $nodes_and_relations['nodes'][$index]['style'] = json_encode($style);
    -
    -                $index++;
    -            }
    -
    -            $nodes_and_relations['relations'] = [];
    -
    -            if (enterprise_installed()) {
    -                enterprise_include_once('include/functions_pandora_networkmap.php');
    -                save_generate_nodes($id, $nodes_and_relations);
    -            }
    -        } else {
    -            // Generate dot file
    -            $graph = networkmap_generate_dot(
    -                get_product_name(),
    -                $id_group,
    -                $simple,
    -                $font_size,
    -                $layout,
    -                $nooverlap,
    -                $zoom,
    -                $ranksep,
    -                $center,
    -                $regen,
    -                $pure,
    -                $id,
    -                $show_snmp_modules,
    -                false,
    -                // cut_names
    -                true,
    -                // relative
    -                '',
    -                $ip_mask,
    -                $dont_show_subgroups,
    -                false,
    -                null,
    -                $old_mode,
    -                $map_filter
    -            );
    -
    -            switch (PHP_OS) {
    -                case 'WIN32':
    -                case 'WINNT':
    -                case 'Windows':
    -                    $filename_dot = sys_get_temp_dir()."\\networkmap_".$filter;
    -                break;
    -
    -                default:
    -                    $filename_dot = sys_get_temp_dir().'/networkmap_'.$filter;
    -                break;
    -            }
    -
    -            if ($simple) {
    -                $filename_dot .= '_simple';
    -            }
    -
    -            if ($nooverlap) {
    -                $filename_dot .= '_nooverlap';
    -            }
    -
    -            $filename_dot .= '_'.$id.'.dot';
    -
    -            file_put_contents($filename_dot, $graph);
    -
    -            switch (PHP_OS) {
    -                case 'WIN32':
    -                case 'WINNT':
    -                case 'Windows':
    -                    $filename_plain = sys_get_temp_dir().'\\plain.txt';
    -
    -                    $cmd = io_safe_output(
    -                        $config['graphviz_bin_dir']."\\$filter.exe -Tplain -o ".$filename_plain.' '.$filename_dot
    -                    );
    -                break;
    -
    -                default:
    -                    $filename_plain = sys_get_temp_dir().'/plain.txt';
    -
    -                    $cmd = "$filter -Tplain -o ".$filename_plain.' '.$filename_dot;
    -                break;
    -            }
    -
    -            system($cmd);
    -
    -            unlink($filename_dot);
    -
    -            $nodes = networkmap_loadfile(
    -                $id,
    -                $filename_plain,
    -                $relation_nodes,
    -                $graph
    -            );
    -
    -            unlink($filename_plain);
    -
    -            // Set the position of modules
    -            foreach ($nodes as $key => $node) {
    -                if ($node['type'] == 'module') {
    -                    // Search the agent of this module for to get the
    -                    // position
    -                    foreach ($nodes as $key2 => $node2) {
    -                        if ($node2['id_agent'] != 0 && $node2['type'] == 'agent') {
    -                            if ($node2['id_agent'] == $node['id_agent']) {
    -                                $nodes[$key]['coords'][0] = ($nodes[$key2]['coords'][0] + $node['height'] / 2);
    -                                $nodes[$key]['coords'][1] = ($nodes[$key2]['coords'][1] + $node['width'] / 2);
    -                            }
    -                        }
    -                    }
    -                }
    -            }
    -
    -            $nodes_and_relations['nodes'] = [];
    -            $index = 0;
    -            $node_center = [];
    -            foreach ($nodes as $key => $node) {
    -                $nodes_and_relations['nodes'][$index]['id'] = $node['id'];
    -                $nodes_and_relations['nodes'][$index]['id_map'] = $id;
    -
    -                $children_count = 0;
    -                foreach ($relation_nodes as $relation) {
    -                    if (($relation['parent_type'] == 'agent') || ($relation['parent_type'] == '')) {
    -                        if ($nodes[$relation['id_parent']]['id_agent'] == $node['id_agent']) {
    -                            $children_count++;
    -                        }
    -                    } else if ($relation['parent_type'] == 'module') {
    -                        if ($nodes[$relation['id_parent']]['id_module'] == $node['id_module']) {
    -                            $children_count++;
    -                        }
    -                    }
    -                }
    -
    -                if (empty($node_center) || $node_center['counter'] < $children_count) {
    -                    $node_center['x'] = (int) $node['coords'][0];
    -                    $node_center['y'] = (int) $node['coords'][1];
    -                    $node_center['counter'] = $children_count;
    -                }
    -
    -                $nodes_and_relations['nodes'][$index]['x'] = (int) $node['coords'][0];
    -                $nodes_and_relations['nodes'][$index]['y'] = (int) $node['coords'][1];
    -
    -                if (($node['type'] == 'agent') || ($node['type'] == '')) {
    -                    $nodes_and_relations['nodes'][$index]['source_data'] = $node['id_agent'];
    -                    $nodes_and_relations['nodes'][$index]['type'] = 0;
    -                } else {
    -                    $nodes_and_relations['nodes'][$index]['source_data'] = $node['id_module'];
    -                    $nodes_and_relations['nodes'][$index]['id_agent'] = $node['id_agent'];
    -                    $nodes_and_relations['nodes'][$index]['type'] = 1;
    -                }
    -
    -                $style = [];
    -                $style['shape'] = 'circle';
    -                $style['image'] = $node['image'];
    -                $style['width'] = $node['width'];
    -                $style['height'] = $node['height'];
    -                $style['label'] = $node['text'];
    -                $nodes_and_relations['nodes'][$index]['style'] = json_encode($style);
    -
    -                $index++;
    -            }
    -
    -            $nodes_and_relations['relations'] = [];
    -            $index = 0;
    -            foreach ($relation_nodes as $relation) {
    -                $nodes_and_relations['relations'][$index]['id_map'] = $id;
    -
    -                if (($relation['parent_type'] == 'agent') || ($relation['parent_type'] == '')) {
    -                    $nodes_and_relations['relations'][$index]['id_parent'] = $relation['id_parent'];
    -                    $nodes_and_relations['relations'][$index]['id_parent_source_data'] = $nodes[$relation['id_parent']]['id_agent'];
    -                    $nodes_and_relations['relations'][$index]['parent_type'] = 0;
    -                } else if ($relation['parent_type'] == 'module') {
    -                    $nodes_and_relations['relations'][$index]['id_parent'] = $relation['id_parent'];
    -                    $nodes_and_relations['relations'][$index]['id_parent_source_data'] = $nodes[$relation['id_parent']]['id_module'];
    -                    $nodes_and_relations['relations'][$index]['parent_type'] = 1;
    -                } else {
    -                    $nodes_and_relations['relations'][$index]['id_parent'] = $relation['id_parent'];
    -                    $nodes_and_relations['relations'][$index]['id_child_source_data'] = -2;
    -                    $nodes_and_relations['relations'][$index]['parent_type'] = 3;
    -                }
    -
    -                if (($relation['child_type'] == 'agent') || ($relation['child_type'] == '')) {
    -                    $nodes_and_relations['relations'][$index]['id_child'] = $relation['id_child'];
    -                    $nodes_and_relations['relations'][$index]['id_child_source_data'] = $nodes[$relation['id_child']]['id_agent'];
    -                    $nodes_and_relations['relations'][$index]['child_type'] = 0;
    -                } else if ($relation['child_type'] == 'module') {
    -                    $nodes_and_relations['relations'][$index]['id_child'] = $relation['id_child'];
    -                    $nodes_and_relations['relations'][$index]['id_child_source_data'] = $nodes[$relation['id_child']]['id_module'];
    -                    $nodes_and_relations['relations'][$index]['child_type'] = 1;
    -                } else {
    -                    $nodes_and_relations['relations'][$index]['id_child'] = $relation['id_child'];
    -                    $nodes_and_relations['relations'][$index]['id_child_source_data'] = -2;
    -                    $nodes_and_relations['relations'][$index]['child_type'] = 3;
    -                }
    -
    -                $index++;
    -            }
    -
    -            if (enterprise_installed()) {
    -                enterprise_include_once('include/functions_pandora_networkmap.php');
    -                save_generate_nodes($id, $nodes_and_relations);
    -            }
    -
    -            $pandorafms_node = $nodes_and_relations['nodes'][0];
    -            $center = [
    -                'x' => $node_center['x'],
    -                'y' => $node_center['y'],
    -            ];
    -
    -            $networkmap['center_x'] = $center['x'];
    -            $networkmap['center_y'] = $center['y'];
    -            db_process_sql_update(
    -                'tmap',
    -                [
    -                    'center_x' => $networkmap['center_x'],
    -                    'center_y' => $networkmap['center_y'],
    -                ],
    -                ['id' => $id]
    -            );
    -        }
    -    }
    -
    -    return $nodes_and_relations;
    -}
    -
    -
    -function get_networkmaps($id)
    -{
    -    $groups = array_keys(users_get_groups(null, 'IW'));
    -
    -    $filter = [];
    -    $filter['id_group'] = $groups;
    -    $filter['id'] = '<>'.$id;
    -    $networkmaps = db_get_all_rows_filter('tmap', $filter);
    -    if ($networkmaps === false) {
    -        $networkmaps = [];
    -    }
    -
    -    $return = [];
    -    $return[0] = __('None');
    -    foreach ($networkmaps as $networkmap) {
    -        $return[$networkmap['id']] = $networkmap['name'];
    -    }
    -
    -    return $return;
    -}
    -
    -
    -function networkmap_db_node_to_js_node($node, &$count, &$count_item_holding_area)
    -{
    -    global $config;
    -
    -    $networkmap = db_get_row('tmap', 'id', $node['id_map']);
    -
    -    $networkmap['filter'] = json_decode($networkmap['filter'], true);
    -
    -    // Hardcoded
    -    $networkmap['filter']['holding_area'] = [
    -        500,
    -        500,
    -    ];
    -
    -    // 40 = DEFAULT NODE RADIUS
    -    // 30 = for to align
    -    $holding_area_max_y = ($networkmap['height'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][1] + 10 * 40);
    -
    -    $item = [];
    -    $item['id'] = $count;
    -
    -    if (enterprise_installed()) {
    -        enterprise_include_once('include/functions_pandora_networkmap.php');
    -        $item['id_db'] = $node['id_in_db'];
    -    } else {
    -        $item['id_db'] = (int) $node['id'];
    -    }
    -
    -    if ((int) $node['type'] == 0) {
    -        $item['type'] = 0;
    -        $item['id_agent'] = (int) $node['source_data'];
    -        $item['id_module'] = '';
    -    } else if ((int) $node['type'] == 1) {
    -        $item['type'] = 1;
    -        $item['id_agent'] = (int) $node['style']['id_agent'];
    -        $item['id_module'] = (int) $node['source_data'];
    -    } else {
    -        $item['type'] = 3;
    -    }
    -
    -    $item['fixed'] = true;
    -    $item['x'] = (int) $node['x'];
    -    $item['y'] = (int) $node['y'];
    -    $item['px'] = (int) $node['x'];
    -    $item['py'] = (int) $node['y'];
    -    $item['z'] = (int) $node['z'];
    -    $item['state'] = $node['state'];
    -    $item['deleted'] = $node['deleted'];
    -    if ($item['state'] == 'holding_area') {
    -        // 40 = DEFAULT NODE RADIUS
    -        // 30 = for to align
    -        $holding_area_x = ($networkmap['width'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][0] + ($count_item_holding_area % 11) * 40);
    -        $holding_area_y = ($networkmap['height'] + 30 + 40 * 2 - $networkmap['filter']['holding_area'][1] + (int) (($count_item_holding_area / 11)) * 40);
    -
    -        if ($holding_area_max_y <= $holding_area_y) {
    -            $holding_area_y = $holding_area_max_y;
    -        }
    -
    -        $item['x'] = $holding_area_x;
    -        $item['y'] = $holding_area_y;
    -
    -        // Increment for the next node in holding area
    -        $count_item_holding_area++;
    -    }
    -
    -    $item['image_url'] = '';
    -    $item['image_width'] = 0;
    -    $item['image_height'] = 0;
    -    if (!empty($node['style']['image'])) {
    -        $item['image_url'] = html_print_image(
    -            $node['style']['image'],
    -            true,
    -            false,
    -            true
    -        );
    -        $image_size = getimagesize(
    -            $config['homedir'].'/'.$node['style']['image']
    -        );
    -        $item['image_width'] = (int) $image_size[0];
    -        $item['image_height'] = (int) $image_size[1];
    -    }
    -
    -    $item['raw_text'] = $node['style']['label'];
    -    $item['text'] = io_safe_output($node['style']['label']);
    -    $item['shape'] = $node['style']['shape'];
    -    switch ($node['type']) {
    -        case 0:
    -            $color = get_status_color_networkmap($node['source_data']);
    -        break;
    -
    -        default:
    -            // Old code
    -            if ($node['source_data'] == -1) {
    -                $color = '#364D1F';
    -            } else if ($node['source_data'] == -2) {
    -                $color = '#364D1F';
    -            } else {
    -                $color = get_status_color_networkmap($node['source_data']);
    -            }
    -        break;
    -    }
    -
    -    $item['color'] = $color;
    -    $item['map_id'] = 0;
    -    if (isset($node['id_map'])) {
    -        $item['map_id'] = $node['id_map'];
    -    }
    -
    -    if (!isset($node['style']['id_networkmap']) || $node['style']['id_networkmap'] == '' || $node['style']['id_networkmap'] == 0) {
    -        $item['networkmap_id'] = 0;
    -    } else {
    -        $item['networkmap_id'] = $node['style']['id_networkmap'];
    -    }
    -
    -    $count++;
    -
    -    return $item;
    -}
    -
    -
    -function get_status_color_networkmap($id, $color=true)
    -{
    -    $status = agents_get_status($id);
    -
    -    if (!$color) {
    -        return $status;
    -    }
    -
    -    // Set node status
    -    switch ($status) {
    -        case 0:
    -            $status_color = COL_NORMAL;
    -            // Normal monitor
    -        break;
    -
    -        case 1:
    -            $status_color = COL_CRITICAL;
    -            // Critical monitor
    -        break;
    -
    -        case 2:
    -            $status_color = COL_WARNING;
    -            // Warning monitor
    -        break;
    -
    -        case 4:
    -            $status_color = COL_ALERTFIRED;
    -            // Alert fired
    -        break;
    -
    -        default:
    -            $status_color = COL_UNKNOWN;
    -            // Unknown monitor
    -        break;
    -    }
    -
    -    return $status_color;
    -}
    -
    -
    -function networkmap_clean_relations_for_js(&$relations)
    -{
    -    do {
    -        $cleaned = true;
    -
    -        foreach ($relations as $key => $relation) {
    -            if ($relation['id_parent_source_data'] == $relation['id_child_source_data']) {
    -                if (($relation['child_type'] != 3) && $relation['parent_type'] != 3) {
    -                    $cleaned = false;
    -
    -                    if ($relation['parent_type'] == 1) {
    -                        $to_find = $relation['id_parent_source_data'];
    -                        $to_replace = $relation['id_child_source_data'];
    -                    } else if ($relation['child_type'] == 1) {
    -                        $to_find = $relation['id_child_source_data'];
    -                        $to_replace = $relation['id_parent_source_data'];
    -                    }
    -
    -                    // Replace and erase the links
    -                    foreach ($relations as $key2 => $relation2) {
    -                        if ($relation2['id_parent_source_data'] == $to_find) {
    -                            $relations[$key2]['id_parent_source_data'] = $to_replace;
    -                        } else if ($relation2['id_child_source_data'] == $to_find) {
    -                            $relations[$key2]['id_child_source_data'] = $to_replace;
    -                        }
    -                    }
    -
    -                    unset($relations[$key]);
    -
    -                    break;
    -                }
    -            }
    -        }
    -    } while (!$cleaned);
    -}
    -
    -
    -function networkmap_links_to_js_links($relations, $nodes_graph)
    -{
    -    $return = [];
    -
    -    if (enterprise_installed()) {
    -        enterprise_include_once('include/functions_pandora_networkmap.php');
    -    }
    -
    -    $count = 0;
    -    foreach ($relations as $key => $relation) {
    -        if (($relation['parent_type'] == 1) && ($relation['child_type'] == 1)) {
    -            $id_target_agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']);
    -            $id_source_agent = agents_get_agent_id_by_module_id($relation['id_child_source_data']);
    -            $id_target_module = $relation['id_parent_source_data'];
    -            $id_source_module = $relation['id_child_source_data'];
    -        } else if (($relation['parent_type'] == 1) && ($relation['child_type'] == 0)) {
    -            $id_target_agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']);
    -            $id_target_module = $relation['id_parent_source_data'];
    -            $id_source_agent = $relation['id_child_source_data'];
    -        } else if (($relation['parent_type'] == 0) && ($relation['child_type'] == 1)) {
    -            $id_target_agent = $relation['id_parent_source_data'];
    -            $id_source_module = $relation['id_child_source_data'];
    -            $id_source_agent = agents_get_agent_id_by_module_id($relation['id_child_source_data']);
    -        } else {
    -            $id_target_agent = $relation['id_parent_source_data'];
    -            $id_source_agent = $relation['id_child_source_data'];
    -        }
    -
    -        $item = [];
    -        $item['id'] = $count;
    -        $count++;
    -        if (enterprise_installed()) {
    -            $item['id_db'] = get_relation_id($relation);
    -        } else {
    -            $item['id_db'] = $key;
    -        }
    -
    -        $item['arrow_start'] = '';
    -        $item['arrow_end'] = '';
    -        $item['status_start'] = '';
    -        $item['status_end'] = '';
    -        $item['id_module_start'] = 0;
    -        $item['id_agent_start'] = (int) $id_source_agent;
    -        $item['id_module_end'] = 0;
    -        $item['id_agent_end'] = (int) $id_target_agent;
    -        $item['link_color'] = '#999';
    -        $item['target'] = -1;
    -        $item['source'] = -1;
    -        $item['deleted'] = $relation['deleted'];
    -
    -        if (enterprise_installed()) {
    -            $target_and_source = [];
    -            $target_and_source = get_id_target_and_source_in_db($relation);
    -            $item['target_id_db'] = (int) $target_and_source['target'];
    -            $item['source_id_db'] = (int) $target_and_source['source'];
    -        } else {
    -            if (($relation['parent_type'] == 1) && ($relation['child_type'] == 1)) {
    -                $item['target_id_db'] = $id_target_agent;
    -                $item['source_id_db'] = $id_source_agent;
    -            } else if (($relation['parent_type'] == 0) && ($relation['child_type'] == 0)) {
    -                $item['target_id_db'] = (int) $relation['id_parent_source_data'];
    -                $item['source_id_db'] = $id_source_agent;
    -            } else {
    -                $item['target_id_db'] = (int) $relation['id_parent_source_data'];
    -                $item['source_id_db'] = (int) $relation['id_child_source_data'];
    -            }
    -        }
    -
    -        $item['text_end'] = '';
    -        $item['text_start'] = '';
    -
    -        if ($relation['parent_type'] == 1) {
    -            $item['arrow_end'] = 'module';
    -            $item['status_end'] = modules_get_agentmodule_status((int) $id_target_module, false, false, null);
    -            $item['id_module_end'] = (int) $id_target_module;
    -            $text_end = modules_get_agentmodule_name((int) $id_target_module);
    -            if (preg_match('/(.+)_ifOperStatus$/', (string) $text_end, $matches)) {
    -                if ($matches[1]) {
    -                    // It's ok to safe_output as it inlo goint to be user into the map line
    -                    $item['text_end'] = io_safe_output($matches[1]);
    -                }
    -            }
    -        }
    -
    -        if ($relation['child_type'] == 1) {
    -            $item['arrow_start'] = 'module';
    -            $item['status_start'] = modules_get_agentmodule_status((int) $id_source_module, false, false, null);
    -            $item['id_module_start'] = (int) $id_source_module;
    -            $text_start = modules_get_agentmodule_name((int) $id_source_module);
    -            if (preg_match('/(.+)_ifOperStatus$/', (string) $text_start, $matches)) {
    -                if ($matches[1]) {
    -                    // It's ok to safe_output as it inlo goint to be user into the map line
    -                    $item['text_start'] = io_safe_output($matches[1]);
    -                }
    -            }
    -        }
    -
    -        $agent = 0;
    -        $agent2 = 0;
    -
    -        if (($relation['parent_type'] == 1) && ($relation['child_type'] == 1)) {
    -            $mod1_status = db_get_value_filter('estado', 'tagente_estado', ['id_agente_modulo' => $relation['id_parent_source_data']]);
    -            $mod2_status = db_get_value_filter('estado', 'tagente_estado', ['id_agente_modulo' => $relation['id_child_source_data']]);
    -
    -            if (($mod1_status == AGENT_MODULE_STATUS_CRITICAL_BAD) || ($mod2_status == AGENT_MODULE_STATUS_CRITICAL_BAD)) {
    -                $item['link_color'] = '#FC4444';
    -            } else if (($mod1_status == AGENT_MODULE_STATUS_WARNING) || ($mod2_status == AGENT_MODULE_STATUS_WARNING)) {
    -                $item['link_color'] = '#FAD403';
    -            }
    -
    -            $agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']);
    -            $agent2 = agents_get_agent_id_by_module_id($relation['id_child_source_data']);
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if (isset($node['id_agent'])) {
    -                    if ($node['id_agent'] == $agent) {
    -                        $agent = $node['id_db'];
    -                    } else if ($node['id_agent'] == $agent2) {
    -                        $agent2 = $node['id_db'];
    -                    }
    -                }
    -            }
    -        } else if ($relation['child_type'] == 1) {
    -            $mod1_status = db_get_value_filter('estado', 'tagente_estado', ['id_agente_modulo' => $relation['id_child_source_data']]);
    -
    -            if ($mod1_status == AGENT_MODULE_STATUS_CRITICAL_BAD) {
    -                $item['link_color'] = '#FC4444';
    -            } else if ($mod1_status == AGENT_MODULE_STATUS_WARNING) {
    -                $item['link_color'] = '#FAD403';
    -            }
    -
    -            $agent2 = agents_get_agent_id_by_module_id($relation['id_child_source_data']);
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if (isset($node['id_agent'])) {
    -                    if ($node['id_agent'] == $relation['id_parent_source_data']) {
    -                        $agent = $node['id_db'];
    -                    } else if ($node['id_agent'] == $agent2) {
    -                        $agent2 = $node['id_db'];
    -                    }
    -                }
    -            }
    -        } else if ($relation['parent_type'] == 1) {
    -            $mod1_status = db_get_value_filter('estado', 'tagente_estado', ['id_agente_modulo' => $relation['id_parent_source_data']]);
    -
    -            if ($mod1_status == AGENT_MODULE_STATUS_CRITICAL_BAD) {
    -                $item['link_color'] = '#FC4444';
    -            } else if ($mod1_status == AGENT_MODULE_STATUS_WARNING) {
    -                $item['link_color'] = '#FAD403';
    -            }
    -
    -            $agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']);
    -
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if (isset($node['id_agent'])) {
    -                    if ($node['id_agent'] == $agent) {
    -                        $agent = $node['id_db'];
    -                    } else if ($node['id_agent'] == $relation['id_child_source_data']) {
    -                        $agent2 = $node['id_db'];
    -                    }
    -                }
    -            }
    -        } else if (($relation['parent_type'] == 3) && ($relation['child_type'] == 3)) {
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if ($relation['id_parent'] == $node['id_db']) {
    -                    $agent = $node['id_db'];
    -                }
    -            }
    -
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if ($relation['id_child'] == $node['id_db']) {
    -                    $agent2 = $node['id_db'];
    -                }
    -            }
    -        } else if (($relation['parent_type'] == 3) || ($relation['child_type'] == 3)) {
    -            if ($relation['parent_type'] == 3) {
    -                foreach ($nodes_graph as $key2 => $node) {
    -                    if ($relation['id_parent'] == $node['id_db']) {
    -                        $agent = $node['id_db'];
    -                    } else if ($node['id_agent'] == $relation['id_child_source_data']) {
    -                        $agent2 = $node['id_db'];
    -                    }
    -                }
    -            } else if ($relation['child_type'] == 3) {
    -                foreach ($nodes_graph as $key2 => $node) {
    -                    if ($relation['id_child'] == $node['id_db']) {
    -                        $agent2 = $node['id_db'];
    -                    } else if ($node['id_agent'] == $relation['id_parent_source_data']) {
    -                        $agent = $node['id_db'];
    -                    }
    -                }
    -            }
    -        } else {
    -            foreach ($nodes_graph as $key2 => $node) {
    -                if (isset($node['id_agent'])) {
    -                    if ($node['id_agent'] == $relation['id_parent_source_data']) {
    -                        $agent = $node['id_db'];
    -                    } else if ($node['id_agent'] == $relation['id_child_source_data']) {
    -                        $agent2 = $node['id_db'];
    -                    }
    -                }
    -            }
    -        }
    -
    -        foreach ($nodes_graph as $node) {
    -            if ($node['id_db'] == $agent) {
    -                $item['target'] = $node['id'];
    -            } else if ($node['id_db'] == $agent2) {
    -                $item['source'] = $node['id'];
    -            }
    -        }
    -
    -        if ((($item['target'] == -1) || ($item['source'] == -1)) && $relation['parent_type'] == 1 && $relation['child_type'] == 1) {
    -            continue;
    -        }
    -
    -        $return[] = $item;
    -    }
    -
    -    return $return;
    -}
    -
    -
    -function networkmap_write_js_array($id, $nodes_and_relations=[], $map_dash_details=[])
    -{
    -    global $config;
    -
    -    db_clean_cache();
    -
    -    $ent_installed = (int) enterprise_installed();
    -
    -    $networkmap = db_get_row('tmap', 'id', $id);
    -
    -    $networkmap['filter'] = json_decode($networkmap['filter'], true);
    -
    -    // Hardcoded
    -    $networkmap['filter']['holding_area'] = [
    -        500,
    -        500,
    -    ];
    -
    -    echo "\n";
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -    echo "// VARS FROM THE DB\n";
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -    echo "\n";
    -    echo "var url_background_grid = '".ui_get_full_url(
    -        'images/background_grid.png'
    -    )."'\n";
    -    echo 'var networkmap_id = '.$id.";\n";
    -
    -    if (!empty($map_dash_details)) {
    -        echo 'var x_offs = '.$map_dash_details['x_offs'].";\n";
    -        echo 'var y_offs = '.$map_dash_details['y_offs'].";\n";
    -        echo 'var z_dash = '.$map_dash_details['z_dash'].";\n";
    -    } else {
    -        echo "var x_offs = null;\n";
    -        echo "var y_offs = null;\n";
    -        echo "var z_dash = null;\n";
    -    }
    -
    -    echo 'var networkmap_refresh_time = 1000 * '.$networkmap['source_period'].";\n";
    -    echo 'var networkmap_center = [ '.$networkmap['center_x'].', '.$networkmap['center_y']."];\n";
    -    echo 'var networkmap_dimensions = [ '.$networkmap['width'].', '.$networkmap['height']."];\n";
    -
    -    echo 'var enterprise_installed = '.$ent_installed.";\n";
    -
    -    echo 'var node_radius = '.$networkmap['filter']['node_radius'].";\n";
    -
    -    echo 'var networkmap_holding_area_dimensions = '.json_encode($networkmap['filter']['holding_area']).";\n";
    -
    -    echo "var networkmap = {'nodes': [], 'links':  []};\n";
    -
    -    $nodes = $nodes_and_relations['nodes'];
    -
    -    if (empty($nodes)) {
    -        $nodes = [];
    -    }
    -
    -    $count_item_holding_area = 0;
    -    $count = 0;
    -    $nodes_graph = [];
    -
    -    foreach ($nodes as $key => $node) {
    -        $style = json_decode($node['style'], true);
    -        $node['style'] = json_decode($node['style'], true);
    -
    -        // Only agents can be show
    -        if (isset($node['type'])) {
    -            if ($node['type'] == 1) {
    -                continue;
    -            }
    -        } else {
    -            $node['type'] = '';
    -        }
    -
    -        $item = networkmap_db_node_to_js_node(
    -            $node,
    -            $count,
    -            $count_item_holding_area
    -        );
    -        if ($item['deleted']) {
    -            continue;
    -        }
    -
    -        echo 'networkmap.nodes.push('.json_encode($item).");\n";
    -        $nodes_graph[$item['id']] = $item;
    -    }
    -
    -    $relations = $nodes_and_relations['relations'];
    -
    -    if ($relations === false) {
    -        $relations = [];
    -    }
    -
    -    // Clean the relations and transform the module relations into
    -    // interfaces
    -    networkmap_clean_relations_for_js($relations);
    -
    -    $links_js = networkmap_links_to_js_links($relations, $nodes_graph);
    -
    -    $array_aux = [];
    -    foreach ($links_js as $link_js) {
    -        if ($link_js['deleted']) {
    -            unset($links_js[$link_js['id']]);
    -        }
    -
    -        if ($link_js['target'] == -1) {
    -            unset($links_js[$link_js['id']]);
    -        }
    -
    -        if ($link_js['source'] == -1) {
    -            unset($links_js[$link_js['id']]);
    -        }
    -
    -        if ($link_js['target'] == $link_js['source']) {
    -            unset($links_js[$link_js['id']]);
    -        }
    -
    -        if ($link_js['arrow_start'] == 'module' && $link_js['arrow_end'] == 'module') {
    -            echo 'networkmap.links.push('.json_encode($link_js).");\n";
    -            $array_aux[$link_js['id_agent_start']] = 1;
    -            unset($links_js[$link_js['id']]);
    -        }
    -    }
    -
    -    foreach ($links_js as $link_js) {
    -        if (($link_js['id_agent_end'] === 0) && $array_aux[$link_js['id_agent_start']] === 1) {
    -            continue;
    -        } else {
    -            echo 'networkmap.links.push('.json_encode($link_js).");\n";
    -        }
    -    }
    -
    -    echo "\n";
    -    echo "\n";
    -
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -    echo "// INTERFACE STATUS COLORS\n";
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -
    -    $module_color_status = [];
    -    $module_color_status[] = [
    -        'status_code' => AGENT_MODULE_STATUS_NORMAL,
    -        'color'       => COL_NORMAL,
    -    ];
    -    $module_color_status[] = [
    -        'status_code' => AGENT_MODULE_STATUS_CRITICAL_BAD,
    -        'color'       => COL_CRITICAL,
    -    ];
    -    $module_color_status[] = [
    -        'status_code' => AGENT_MODULE_STATUS_WARNING,
    -        'color'       => COL_WARNING,
    -    ];
    -    $module_color_status[] = [
    -        'status_code' => AGENT_STATUS_ALERT_FIRED,
    -        'color'       => COL_ALERTFIRED,
    -    ];
    -    $module_color_status_unknown = COL_UNKNOWN;
    -
    -    echo 'var module_color_status = '.json_encode($module_color_status).";\n";
    -    echo "var module_color_status_unknown = '".$module_color_status_unknown."';\n";
    -
    -    echo "\n";
    -    echo "\n";
    -
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -    echo "// Other vars\n";
    -    echo "////////////////////////////////////////////////////////////////////\n";
    -
    -    echo "var translation_none = '".__('None')."';\n";
    -    echo "var dialog_node_edit_title = '".__('Edit node %s')."';\n";
    -    echo "var holding_area_title = '".__('Holding Area')."';\n";
    -    echo "var edit_menu = '".__('Show details and options')."';\n";
    -    echo "var interface_link_add = '".__('Add a interface link')."';\n";
    -    echo "var set_parent_link = '".__('Set parent interface')."';\n";
    -    echo "var set_as_children_menu = '".__('Set as children')."';\n";
    -    echo "var set_parent_menu = '".__('Set parent')."';\n";
    -    echo "var abort_relationship_menu = '".__('Abort the action of set relationship')."';\n";
    -    echo "var delete_menu = '".__('Delete')."';\n";
    -    echo "var add_node_menu = '".__('Add node')."';\n";
    -    echo "var set_center_menu = '".__('Set center')."';\n";
    -    echo "var refresh_menu = '".__('Refresh')."';\n";
    -    echo "var refresh_holding_area_menu = '".__('Refresh Holding area')."';\n";
    -    echo "var ok_button = '".__('Proceed')."';\n";
    -    echo "var message_to_confirm = '".__('Resetting the map will delete all customizations you have done, including manual relationships between elements, new items, etc.')."';\n";
    -    echo "var warning_message = '".__('WARNING')."';\n";
    -    echo "var ok_button = '".__('Proceed')."';\n";
    -    echo "var cancel_button = '".__('Cancel')."';\n";
    -    echo "var restart_map_menu = '".__('Restart map')."';\n";
    -    echo "var abort_relationship_interface = '".__('Abort the interface relationship')."';\n";
    -    echo "var abort_relationship_menu = '".__('Abort the action of set relationship')."';\n";
    -
    -    echo "\n";
    -    echo "\n";
    -}
    -
    -
    -function networkmap_loadfile(
    -    $id=0,
    -    $file='',
    -    &$relations_param,
    -    $graph
    -) {
    -    global $config;
    -
    -    $height_map = db_get_value('height', 'tmap', 'id', $id);
    -
    -    $networkmap_nodes = [];
    -
    -    $relations = [];
    -
    -    $other_file = file($file);
    -
    -    // Remove the graph head
    -    $graph = preg_replace('/^graph .*/', '', $graph);
    -    // Cut in nodes the graph
    -    $graph = explode(']', $graph);
    -
    -    $ids = [];
    -    foreach ($graph as $node) {
    -        $line = str_replace("\n", ' ', $node);
    -
    -        if (preg_match('/([0-9]+) \[.*tooltip.*id_module=([0-9]+)/', $line, $match) != 0) {
    -            $ids[$match[1]] = [
    -                'type'      => 'module',
    -                'id_module' => $match[2],
    -            ];
    -        } else if (preg_match('/([0-9]+) \[.*tooltip.*id_agent=([0-9]+)/', $line, $match) != 0) {
    -            $ids[$match[1]] = [
    -                'type'     => 'agent',
    -                'id_agent' => $match[2],
    -            ];
    -        }
    -    }
    -
    -    foreach ($other_file as $key => $line) {
    -        // clean line a long spaces for one space caracter
    -        $line = preg_replace('/[ ]+/', ' ', $line);
    -
    -        $data = [];
    -
    -        if (preg_match('/^node.*$/', $line) != 0) {
    -            $items = explode(' ', $line);
    -            $node_id = $items[1];
    -            $node_x = ($items[2] * 100);
    -            // 200 is for show more big
    -            $node_y = ($height_map - $items[3] * 100);
    -            // 200 is for show more big
    -            $data['id'] = $node_id;
    -            $data['text'] = '';
    -            $data['image'] = '';
    -            $data['width'] = 10;
    -            $data['height'] = 10;
    -            $data['id_agent'] = 0;
    -
    -            if (preg_match('/ $line_orig,
    -                'dest' => $line_dest,
    -            ];
    -        }
    -    }
    -
    -    $relations_param = [];
    -
    -    foreach ($relations as $rel) {
    -        if (strpos($rel['orig'], 'transp_') !== false) {
    -            // removed the transparent nodes
    -            continue;
    -        }
    -
    -        if (strpos($rel['dest'], 'transp_') !== false) {
    -            // removed the transparent nodes
    -            continue;
    -        }
    -
    -        $row = [
    -            'id_child'    => $rel['orig'],
    -            'child_type'  => $networkmap_nodes[$rel['orig']]['type'],
    -            'id_parent'   => $rel['dest'],
    -            'parent_type' => $networkmap_nodes[$rel['dest']]['type'],
    -        ];
    -        $relations_param[] = $row;
    -    }
    -
    -    return $networkmap_nodes;
    -}
    -
    -
    -function get_status_color_module_networkmap($id_agente_modulo)
    -{
    -    $status = modules_get_agentmodule_status($id_agente_modulo);
    -
    -    // Set node status
    -    switch ($status) {
    -        case 0:
    -            // At the moment the networkmap enterprise does not show the
    -            // alerts.
    -        case AGENT_MODULE_STATUS_NORMAL_ALERT:
    -            $status_color = COL_NORMAL;
    -            // Normal monitor
    -        break;
    -
    -        case 1:
    -            $status_color = COL_CRITICAL;
    -            // Critical monitor
    -        break;
    -
    -        case 2:
    -            $status_color = COL_WARNING;
    -            // Warning monitor
    -        break;
    -
    -        case 4:
    -            $status_color = COL_ALERTFIRED;
    -            // Alert fired
    -        break;
    -
    -        default:
    -            $status_color = COL_UNKNOWN;
    -            // Unknown monitor
    -        break;
    -    }
    -
    -    return $status_color;
    -}
    -
    -
    -function duplicate_networkmap($id)
    -{
    -    $return = true;
    -
    -    $values = db_get_row('tmap', 'id', $id);
    -    unset($values['id']);
    -    $free_name = false;
    -    $values['name'] = io_safe_input(__('Copy of ')).$values['name'];
    -    $count = 1;
    -    while (!$free_name) {
    -        $exist = db_get_row_filter('tmap', ['name' => $values['name']]);
    -        if ($exist === false) {
    -            $free_name = true;
    -        } else {
    -            $values['name'] = $values['name'].io_safe_input(' '.$count);
    -        }
    -    }
    -
    -    $correct_or_id = db_process_sql_insert('tmap', $values);
    -    if ($correct_or_id === false) {
    -        $return = false;
    -    } else {
    -        if (enterprise_installed()) {
    -            $new_id = $correct_or_id;
    -            duplicate_map_insert_nodes_and_relations($id, $new_id);
    -        }
    -    }
    -
    -    if ($return) {
    -        return true;
    -    } else {
    -        // Clean DB.
    -        if (enterprise_installed()) {
    -            // Relations
    -            delete_relations($new_id);
    -
    -            // Nodes
    -            delete_nodes($new_id);
    -        }
    -
    -        db_process_sql_delete('tmap', ['id' => $new_id]);
    -
    -        return false;
    -    }
    -}
    -
    -
    -function clean_duplicate_links($relations)
    -{
    -    if (enterprise_installed()) {
    -        enterprise_include_once('include/functions_pandora_networkmap.php');
    -    }
    -
    -    $segregation_links = [];
    -    $index = 0;
    -    $index2 = 0;
    -    $index3 = 0;
    -    $index4 = 0;
    -    foreach ($relations as $rel) {
    -        if (($rel['parent_type'] == 0) && ($rel['child_type'] == 0)) {
    -            $segregation_links['aa'][$index] = $rel;
    -            $index++;
    -        } else if (($rel['parent_type'] == 1) && ($rel['child_type'] == 1)) {
    -            $segregation_links['mm'][$index2] = $rel;
    -            $index2++;
    -        } else if (($rel['parent_type'] == 3) && ($rel['child_type'] == 3)) {
    -            $segregation_links['ff'][$index4] = $rel;
    -            $index4++;
    -        } else {
    -            $segregation_links['am'][$index3] = $rel;
    -            $index3++;
    -        }
    -    }
    -
    -    $final_links = [];
    -
    -    // ----------------------------------------------------------------
    -    // --------------------- Clean duplicate links --------------------
    -    // ----------------------------------------------------------------
    -    $duplicated = false;
    -    $index_to_del = 0;
    -    $index = 0;
    -    if (isset($segregation_links['aa']) === true
    -        && is_array($segregation_links['aa']) === true
    -    ) {
    -        foreach ($segregation_links['aa'] as $link) {
    -            foreach ($segregation_links['aa'] as $link2) {
    -                if ($link['id_parent'] == $link2['id_child']
    -                    && $link['id_child'] == $link2['id_parent']
    -                ) {
    -                    if (enterprise_installed()) {
    -                        delete_link($segregation_links['aa'][$index_to_del]);
    -                    }
    -
    -                    unset($segregation_links['aa'][$index_to_del]);
    -                }
    -
    -                $index_to_del++;
    -            }
    -
    -            $final_links['aa'][$index] = $link;
    -            $index++;
    -
    -            $duplicated = false;
    -            $index_to_del = 0;
    -        }
    -    }
    -
    -    $duplicated = false;
    -    $index_to_del = 0;
    -    $index2 = 0;
    -    if (isset($segregation_links['mm']) === true
    -        && is_array($segregation_links['mm']) === true
    -    ) {
    -        foreach ($segregation_links['mm'] as $link) {
    -            foreach ($segregation_links['mm'] as $link2) {
    -                if ($link['id_parent'] == $link2['id_child']
    -                    && $link['id_child'] == $link2['id_parent']
    -                ) {
    -                    if (enterprise_installed()) {
    -                        delete_link($segregation_links['mm'][$index_to_del]);
    -                    }
    -                }
    -
    -                $index_to_del++;
    -            }
    -
    -            $final_links['mm'][$index2] = $link;
    -            $index2++;
    -
    -            $duplicated = false;
    -            $index_to_del = 0;
    -        }
    -    }
    -
    -    $duplicated = false;
    -    $index_to_del = 0;
    -    $index3 = 0;
    -
    -    if (isset($segregation_links['ff']) === true
    -        && is_array($segregation_links['ff']) === true
    -    ) {
    -        foreach ($segregation_links['ff'] as $link) {
    -            foreach ($segregation_links['ff'] as $link2) {
    -                if ($link['id_parent'] == $link2['id_child']
    -                    && $link['id_child'] == $link2['id_parent']
    -                ) {
    -                    if (enterprise_installed()) {
    -                        delete_link($segregation_links['ff'][$index_to_del]);
    -                    }
    -
    -                    unset($segregation_links['ff'][$index_to_del]);
    -                }
    -
    -                $index_to_del++;
    -            }
    -
    -            $final_links['ff'][$index3] = $link;
    -            $index3++;
    -
    -            $duplicated = false;
    -            $index_to_del = 0;
    -        }
    -    }
    -
    -    $final_links['am'] = $segregation_links['am'];
    -
    -    /*
    -        ----------------------------------------------------------------
    -        ----------------- AA, AM and MM links management ---------------
    -        ------------------ Priority: -----------------------------------
    -        -------------------- 1 -> MM (module - module) -----------------
    -        -------------------- 2 -> AM (agent - module) ------------------
    -        -------------------- 3 -> AA (agent - agent) -------------------
    -        ----------------------------------------------------------------
    -    */
    -
    -    $final_links2 = [];
    -    $index = 0;
    -    $l3_link = [];
    -    $agent1 = 0;
    -    $agent2 = 0;
    -
    -    if (isset($final_links['mm']) === true
    -        && is_array($final_links['mm']) === true
    -    ) {
    -        foreach ($final_links['mm'] as $rel_mm) {
    -            $module_parent = $rel_mm['id_parent_source_data'];
    -            $module_children = $rel_mm['id_child_source_data'];
    -            $agent1 = (int) agents_get_agent_id_by_module_id($module_parent);
    -            $agent2 = (int) agents_get_agent_id_by_module_id($module_children);
    -            foreach ($final_links['aa'] as $key => $rel_aa) {
    -                $l3_link = $rel_aa;
    -                $id_p_source_data = (int) $rel_aa['id_parent_source_data'];
    -                $id_c_source_data = (int) $rel_aa['id_child_source_data'];
    -                if ((($id_p_source_data == $agent1)
    -                    && ($id_c_source_data == $agent2))
    -                    || (($id_p_source_data == $agent2)
    -                    && ($id_c_source_data == $agent1))
    -                ) {
    -                    if (enterprise_installed()) {
    -                        delete_link($final_links['aa'][$key]);
    -                    }
    -
    -                    unset($final_links['aa'][$key]);
    -                }
    -            }
    -        }
    -    }
    -
    -    $final_links2['aa'] = $final_links['aa'];
    -    $final_links2['mm'] = $final_links['mm'];
    -    $final_links2['am'] = $final_links['am'];
    -    $final_links2['ff'] = $final_links['ff'];
    -
    -    $same_m = [];
    -    $index = 0;
    -    if (isset($final_links2['am']) === true
    -        && is_array($final_links2['am']) === true
    -    ) {
    -        foreach ($final_links2['am'] as $rel_am) {
    -            foreach ($final_links2['am'] as $rel_am2) {
    -                if (($rel_am['id_child_source_data'] == $rel_am2['id_child_source_data'])
    -                    && ($rel_am['id_parent_source_data'] != $rel_am2['id_parent_source_data'])
    -                ) {
    -                    $same_m[$index]['rel'] = $rel_am2;
    -                    $same_m[$index]['agent_parent'] = $rel_am['id_parent_source_data'];
    -                    $index++;
    -                }
    -            }
    -        }
    -    }
    -
    -    $final_links3 = [];
    -    $index = 0;
    -    $l3_link = [];
    -    $have_l3 = false;
    -    if (isset($final_links2['aa']) === true
    -        && is_array($final_links2['aa']) === true
    -    ) {
    -        foreach ($final_links2['aa'] as $key => $rel_aa) {
    -            $l3_link = $rel_aa;
    -            foreach ($same_m as $rel_am) {
    -                if ((($rel_aa['id_parent_source_data'] == $rel_am['parent']['id_parent_source_data'])
    -                    && ($rel_aa['id_child_source_data'] == $rel_am['rel']['id_parent_source_data']))
    -                    || (($rel_aa['id_child_source_data'] == $rel_am['parent']['id_parent_source_data'])
    -                    && ($rel_aa['id_parent_source_data'] == $rel_am['rel']['id_parent_source_data']))
    -                ) {
    -                    if (enterprise_installed()) {
    -                        delete_link($final_links2['aa'][$key]);
    -                    }
    -
    -                    unset($final_links2['aa'][$key]);
    -                }
    -            }
    -        }
    -    }
    -
    -    $final_links3['aa'] = $final_links2['aa'];
    -    $final_links3['mm'] = $segregation_links['mm'];
    -    $final_links3['am'] = $segregation_links['am'];
    -    $final_links3['ff'] = $final_links2['ff'];
    -
    -    $cleaned_links = [];
    -    if (isset($final_links3['aa']) === true
    -        && is_array($final_links3['aa']) === true
    -    ) {
    -        foreach ($final_links3['aa'] as $link) {
    -            $cleaned_links[] = $link;
    -        }
    -    }
    -
    -    if (isset($final_links3['am']) === true
    -        && is_array($final_links3['am']) === true
    -    ) {
    -        foreach ($final_links3['am'] as $link) {
    -            $cleaned_links[] = $link;
    -        }
    -    }
    -
    -    if (isset($final_links3['mm']) === true
    -        && is_array($final_links3['mm']) === true
    -    ) {
    -        foreach ($final_links3['mm'] as $link) {
    -            $cleaned_links[] = $link;
    -        }
    -    }
    -
    -    if (isset($final_links3['ff']) === true
    -        && is_array($final_links3['ff']) === true
    -    ) {
    -        foreach ($final_links3['ff'] as $link) {
    -            $cleaned_links[] = $link;
    -        }
    -    }
    -
    -    return $cleaned_links;
    -}
    -
    -
    -function is_in_rel_array($relations, $relation)
    -{
    -    $is_in_array = false;
    -    foreach ($relations as $rel) {
    -        if ($rel['id_parent_source_data'] == $relation['id_parent_source_data']
    -            && $rel['id_child_source_data'] == $relation['id_child_source_data']
    -        ) {
    -            $is_in_array = true;
    -        }
    -    }
    -
    -    return $is_in_array;
    -}
    -
    -
    -function map_migrated($id)
    -{
    -    $new_maps = db_get_all_rows_sql('SELECT filter FROM tmap');
    -    $new_map_filter = json_decode($new_maps, true);
    -
    -    foreach ($new_map_filter as $filter) {
    -        if ((isset($filter['id_migrate_map'])) && ($filter['id_migrate_map'] == $id)) {
    -            return true;
    -        }
    -    }
    -
    -    return false;
    -}
    -
    -
    -function migrate_older_open_maps($id)
    -{
    -    global $config;
    -
    -    $old_networkmap = db_get_row_filter(
    -        'tnetwork_map',
    -        ['id_networkmap' => $id]
    -    );
    -
    -    $map_values = [];
    -    $map_values['id_group'] = $old_networkmap['id_group'];
    -    $map_values['id_user'] = $old_networkmap['id_user'];
    -    $map_values['type'] = 0;
    -    $map_values['subtype'] = 0;
    -    $map_values['name'] = $old_networkmap['name'];
    -
    -    $new_map_filter = [];
    -    $new_map_filter['dont_show_subgroups'] = $old_networkmap['dont_show_subgroups'];
    -    $new_map_filter['node_radius'] = 40;
    -    $new_map_filter['id_migrate_map'] = $id;
    -    $map_values['filter'] = json_encode($new_map_filter);
    -
    -    $map_values['description'] = 'Mapa open migrado';
    -    $map_values['width'] = 4000;
    -    $map_values['height'] = 4000;
    -    $map_values['center_x'] = 2000;
    -    $map_values['center_y'] = 2000;
    -    $map_values['background'] = '';
    -    $map_values['background_options'] = 0;
    -    $map_values['source_period'] = 60;
    -    $map_values['source'] = 0;
    -    $map_values['source_data'] = $old_networkmap['id_group'];
    -    if ($old_networkmap['type'] == 'radial_dinamic') {
    -        $map_values['generation_method'] = 6;
    -    } else {
    -        $map_values['generation_method'] = 4;
    -    }
    -
    -    $map_values['generated'] = 0;
    -
    -    $id_new_map = db_process_sql_insert('tmap', $map_values);
    -
    -    if (!$id_new_map) {
    -        return false;
    -    }
    -
    -    return true;
    -}
    -
    -
    -function show_networkmap($id=0, $user_readonly=false, $nodes_and_relations=[], $dashboard_mode=false, $map_dash_details=[])
    -{
    -    global $config;
    -    $clean_relations = clean_duplicate_links($nodes_and_relations['relations']);
    -
    -    $hide_minimap = '';
    -
    -    $nodes_and_relations['relations'] = $clean_relations;
    -
    -    $networkmap = db_get_row('tmap', 'id', $id);
    -    $networkmap['filter'] = json_decode($networkmap['filter'], true);
    -
    -    $networkmap['filter']['l2_network_interfaces'] = 1;
    -
    -    echo '';
    -    ui_require_css_file('jquery.contextMenu', 'include/styles/js/');
    -    echo '';
    -    echo '';
    -    echo '
    '; - if ($dashboard_mode) { - $hide_minimap = 'none'; - } - - echo '
    '; - echo ' - '; - - echo '
    - - - -
    '; - echo '
    '; - - echo '
    - - - -
    '; - echo ''; - - echo '
    '; - - ?> - - - - - - - - - - - - - $e['criticity'], 'validated_by' => $e['id_usuario'], 'timestamp' => $e['timestamp_rep'], + 'id_evento' => $e['id_evento'], ]; } else { $return_data[] = [ @@ -7743,6 +7748,7 @@ function reporting_get_agents_detailed_event( 'criticity' => $e['criticity'], 'validated_by' => $e['id_usuario'], 'timestamp' => $e['timestamp'], + 'id_evento' => $e['id_evento'], ]; } } @@ -7765,11 +7771,11 @@ function reporting_get_agents_detailed_event( foreach ($events as $eventRow) { foreach ($eventRow as $k => $event) { - // First pass along the class of this row + // First pass along the class of this row. $table->cellclass[$k][1] = $table->cellclass[$k][2] = $table->cellclass[$k][4] = $table->cellclass[$k][5] = $table->cellclass[$k][6] = get_priority_class($event['criticity']); $data = []; - // Colored box + // Colored box. switch ($event['estado']) { case 0: $img_st = 'images/star.png'; @@ -11436,33 +11442,95 @@ function reporting_sla_is_ignored_from_array($sla_array) * * @return integer Status */ -function reporting_sla_get_status_period($sla_times, $priority_mode=REPORT_PRIORITY_MODE_OK) -{ - if ($sla_times['time_error'] > 0) { +function reporting_sla_get_status_period( + $sla, + $priority_mode=REPORT_PRIORITY_MODE_OK +) { + if ($sla['time_error'] > 0) { return REPORT_STATUS_ERR; } - if ($priority_mode == REPORT_PRIORITY_MODE_OK && $sla_times['time_ok'] > 0) { + if ($priority_mode == REPORT_PRIORITY_MODE_OK && $sla['time_ok'] > 0) { return REPORT_STATUS_OK; } - if ($sla_times['time_out'] > 0) { + if ($sla['time_out'] > 0) { return REPORT_STATUS_IGNORED; } - if ($sla_times['time_downtime'] > 0) { + if ($sla['time_downtime'] > 0) { return REPORT_STATUS_DOWNTIME; } - if ($sla_times['time_unknown'] > 0) { + if ($sla['time_unknown'] > 0) { return REPORT_STATUS_UNKNOWN; } - if ($sla_times['time_not_init'] > 0) { + if ($sla['time_not_init'] > 0) { return REPORT_STATUS_NOT_INIT; } - if ($sla_times['time_ok'] > 0) { + if ($sla['time_ok'] > 0) { + return REPORT_STATUS_OK; + } + + return REPORT_STATUS_IGNORED; +} + + +/** + * @brief Given a period, get the SLA status + * of the period compare with sla_limit. + * + * @param Array An array with all times to calculate the SLA. + * @param int Limit SLA pass for user. + * Only used for monthly, weekly And hourly report. + * + * @return integer Status + */ +function reporting_sla_get_status_period_compliance( + $sla, + $sla_limit +) { + global $config; + + $time_compliance = ( + $sla['time_ok'] + $sla['time_unknown'] + $sla['time_downtime'] + ); + + $time_total_working = ( + $time_compliance + $sla['time_error'] + ); + + $time_compliance = ($time_compliance == 0) ? 0 : (($time_compliance / $time_total_working) * 100); + + if ($sla['time_error'] > 0 && ($time_compliance < $sla_limit)) { + return REPORT_STATUS_ERR; + } + + if ($priority_mode == REPORT_PRIORITY_MODE_OK + && $sla['time_ok'] > 0 && ($time_compliance >= $sla_limit) + ) { + return REPORT_STATUS_OK; + } + + if ($sla['time_out'] > 0 && ($time_compliance < $sla_limit)) { + return REPORT_STATUS_IGNORED; + } + + if ($sla['time_downtime'] > 0 && ($time_compliance < $sla_limit)) { + return REPORT_STATUS_DOWNTIME; + } + + if ($sla['time_unknown'] > 0 && ($time_compliance < $sla_limit)) { + return REPORT_STATUS_UNKNOWN; + } + + if ($sla['time_not_init'] > 0 && ($time_compliance < $sla_limit)) { + return REPORT_STATUS_NOT_INIT; + } + + if ($sla['time_ok'] > 0 && ($time_compliance >= $sla_limit)) { return REPORT_STATUS_OK; } @@ -11512,3 +11580,38 @@ function reporting_header_table_for_pdf(string $title='', string $description='' return $result_pdf; } + + +/** + * Build the required data to build network traffic top N report + * + * @param int Period (time window). + * @param array Information about the item of report. + * @param bool Pdf or not + * + * @return array With report presentation info and report data. + */ +function reporting_nt_top_n_report($period, $content, $pdf) +{ + $return = []; + $return['type'] = 'nt_top_n'; + $return['title'] = $content['name']; + $return['description'] = $content['description']; + + // Get the data sent and received + $return['data'] = []; + $start_time = ($period['datetime'] - (int) $content['period']); + $return['data']['send'] = network_matrix_get_top( + $content['top_n_value'], + true, + $start_time, + $period['datetime'] + ); + $return['data']['recv'] = network_matrix_get_top( + $content['top_n_value'], + false, + $start_time, + $period['datetime'] + ); + return $return; +} diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index b469e930c3..7265c721ec 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -271,21 +271,7 @@ function reporting_html_print_report($report, $mini=false, $report_info=1) break; case 'netflow_area': - reporting_html_graph($table, $item); - break; - - case 'netflow_pie': - reporting_html_graph($table, $item); - break; - case 'netflow_data': - reporting_html_graph($table, $item); - break; - - case 'netflow_statistics': - reporting_html_graph($table, $item); - break; - case 'netflow_summary': reporting_html_graph($table, $item); break; @@ -367,6 +353,10 @@ function reporting_html_print_report($report, $mini=false, $report_info=1) reporting_enterprise_html_SLA_monthly($table, $item, $mini); break; + case 'nt_top_n': + reporting_html_nt_top_n($table, $item, $mini); + break; + case 'SLA_weekly': reporting_enterprise_html_SLA_weekly($table, $item, $mini); break; @@ -549,10 +539,6 @@ function reporting_html_SLA($table, $item, $mini, $pdf=0) foreach ($item['data'] as $sla) { if (isset($sla)) { - $the_first_men_time = get_agent_first_time( - io_safe_output($sla['agent']) - ); - // First_table. $row = []; $row[] = $sla['agent']; @@ -914,6 +900,9 @@ function reporting_html_top_n($table, $item, $pdf=0) function reporting_html_event_report_group($table, $item, $pdf=0) { global $config; + + $show_extended_events = $item['show_extended_events']; + if ($item['total_events']) { $table1 = new stdClass(); $table1->width = '99%'; @@ -1021,6 +1010,17 @@ function reporting_html_event_report_group($table, $item, $pdf=0) } array_push($table1->data, $data); + + if ($show_extended_events == 1 && events_has_extended_info($event['id_evento'])) { + $extended_events = events_get_extended_events($event['id_evento']); + + foreach ($extended_events as $extended_event) { + $extended_data = []; + + $extended_data[] = "".io_safe_output($extended_event['description'])."".date($config['date_format'], $extended_event['utimestamp']).''; + array_push($table1->data, $extended_data); + } + } } if ($pdf) { @@ -1130,6 +1130,9 @@ function reporting_html_event_report_group($table, $item, $pdf=0) function reporting_html_event_report_module($table, $item, $pdf=0) { global $config; + + $show_extended_events = $item['show_extended_events']; + $show_summary_group = $item['show_summary_group']; if ($item['total_events']) { if (!empty($item['failed'])) { @@ -1213,6 +1216,17 @@ function reporting_html_event_report_module($table, $item, $pdf=0) } $table1->data[] = $data; + + if ($show_extended_events == 1 && events_has_extended_info($event['id_evento'])) { + $extended_events = events_get_extended_events($event['id_evento']); + + foreach ($extended_events as $extended_event) { + $extended_data = []; + + $extended_data[] = "".io_safe_output($extended_event['description'])."".date($config['date_format'], $extended_event['utimestamp']).''; + array_push($table1->data, $extended_data); + } + } } } @@ -1902,6 +1916,8 @@ function reporting_html_event_report_agent($table, $item, $pdf=0) { global $config; + $show_extended_events = $item['show_extended_events']; + if ($item['total_events'] != 0) { $table1 = new stdClass(); $table1->width = '99%'; @@ -1989,6 +2005,17 @@ function reporting_html_event_report_agent($table, $item, $pdf=0) } array_push($table1->data, $data); + + if ($show_extended_events == 1 && events_has_extended_info($event['id_evento'])) { + $extended_events = events_get_extended_events($event['id_evento']); + + foreach ($extended_events as $extended_event) { + $extended_data = []; + + $extended_data[] = "".io_safe_output($extended_event['description'])."".date($config['date_format'], $extended_event['utimestamp']).''; + array_push($table1->data, $extended_data); + } + } } if ($pdf) { @@ -2964,10 +2991,6 @@ function reporting_html_availability($table, $item, $pdf=0) $table2->style[5] = 'text-align: right'; foreach ($item['data'] as $row) { - $the_first_men_time = get_agent_first_time( - io_safe_output($row['agent']) - ); - $table_row = []; $table_row[] = $row['agent']; $table_row[] = $row['availability_item']; @@ -3276,9 +3299,8 @@ function get_agent_first_time($agent_name) $id = agents_get_agent_id($agent_name, true); $utimestamp = db_get_all_rows_sql( - 'SELECT utimestamp FROM tagente_datos WHERE id_agente_modulo IN - (SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = '.$id.') - ORDER BY utimestamp ASC LIMIT 1' + 'SELECT min(utimestamp) FROM tagente_datos WHERE id_agente_modulo IN + (SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = '.$id.')' ); $utimestamp = $utimestamp[0]['utimestamp']; @@ -4737,6 +4759,65 @@ function reporting_get_event_histogram_meta($width) } +/** + * Print network traffic data into top n tables + * (one for received data and another for sent) + * + * @param stdClass Table class to paint the report + * @param array Associative array with info about + * @param bool Unused + */ +function reporting_html_nt_top_n($table, $item, $mini) +{ + // Prepare the table + $table_top = new stdClass(); + $table_top->cellpadding = 0; + $table_top->cellspacing = 0; + $table_top->width = '100%'; + $table_top->class = 'databox data'; + $table_top->cellpadding = 0; + $table_top->cellspacing = 0; + $table_top->width = '100%'; + $table_top->class = 'databox data'; + $table_top->head['host'] = __('Agent'); + $table_top->head['bytes'] = __('Kilobytes'); + $table_top->head['pkts'] = __('Packages'); + + // Build the table for sent packages + if (empty($item['data']['send'])) { + $table->data['send_title'] = '

    '.__('No network traffic sent data').'

    '; + } else { + foreach ($item['data']['send'] as $s_item) { + $table_top->data[] = [ + 'host' => $s_item['host'], + 'bytes' => remove_right_zeros(number_format(($s_item['sum_bytes'] / 1024), $config['graph_precision'])), + 'pkts' => remove_right_zeros(number_format($s_item['sum_pkts'], $config['graph_precision'])), + ]; + } + + $table->data['send_title'] = '

    '.__('Network traffic sent').'

    '; + $table->data['send'] = html_print_table($table_top, true); + } + + // Reset the table and build the table for received packages + $table_top->data = []; + if (empty($item['data']['send'])) { + $table->data['recv_title'] = '

    '.__('No network traffic received data').'

    '; + } else { + foreach ($item['data']['recv'] as $s_item) { + $table_top->data[] = [ + 'host' => $s_item['host'], + 'bytes' => remove_right_zeros(number_format(($s_item['sum_bytes'] / 1024), $config['graph_precision'])), + 'pkts' => remove_right_zeros(number_format($s_item['sum_pkts'], $config['graph_precision'])), + ]; + } + + $table->data['recv_title'] = '

    '.__('Network traffic received').'

    '; + $table->data['recv'] = html_print_table($table_top, true); + } +} + + function reporting_html_planned_downtimes_table($planned_downtimes) { global $config; diff --git a/pandora_console/include/functions_reporting_xml.php b/pandora_console/include/functions_reporting_xml.php index d1b28ac2a0..0179a27b06 100644 --- a/pandora_console/include/functions_reporting_xml.php +++ b/pandora_console/include/functions_reporting_xml.php @@ -11,10 +11,10 @@ // 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. -require_once 'include/functions_modules.php'; -require_once 'include/functions_events.php'; -require_once 'include/functions_groups.php'; -require_once 'include/functions_netflow.php'; +require_once __DIR__.'/functions_modules.php'; +require_once __DIR__.'/functions_events.php'; +require_once __DIR__.'/functions_groups.php'; +require_once __DIR__.'/functions_netflow.php'; enterprise_include_once('include/functions_metaconsole.php'); @@ -31,7 +31,7 @@ function reporting_xml_get_report($report, $filename, $return=false) unset($report['private']); unset($report['custom_logo']); // ---------------------------------------------------------------------- - // change agent name + // change agent name. if (count($report['contents']) > 0) { for ($i = 0; $i < count($report['contents']); $i++) { $aux = explode('-', $report['contents'][$i]['subtitle']); @@ -44,16 +44,18 @@ function reporting_xml_get_report($report, $filename, $return=false) $xml = preg_replace('/(<[^>]+>)(<[^>]+>)(<[^>]+>)/', "$1\n$2\n$3", $xml); $xml = preg_replace('/(<[^>]+>)(<[^>]+>)/', "$1\n$2", $xml); - // Return if is marked to return + // Return if is marked to return. if ($return) { return $xml; } - // Download if marked to download - header('Content-Type: application/xml; charset=UTF-8'); - header('Content-Disposition: attachment; filename="'.$filename.'.xml"'); + // Download if marked to download. + if ($filename === false) { + header('Content-Type: application/xml; charset=UTF-8'); + header('Content-Disposition: attachment; filename="'.$filename.'.xml"'); + } - // Clean the output buffer + // Clean the output buffer. ob_clean(); echo $xml; diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index fd68aa0da2..0bf1f8fe70 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -867,18 +867,10 @@ function reports_get_report_types($template=false, $not_editor=false) 'optgroup' => __('Netflow'), 'name' => __('Netflow area chart'), ]; - $types['netflow_pie'] = [ - 'optgroup' => __('Netflow'), - 'name' => __('Netflow pie chart'), - ]; $types['netflow_data'] = [ 'optgroup' => __('Netflow'), 'name' => __('Netflow data table'), ]; - $types['netflow_statistics'] = [ - 'optgroup' => __('Netflow'), - 'name' => __('Netflow statistics table'), - ]; $types['netflow_summary'] = [ 'optgroup' => __('Netflow'), 'name' => __('Netflow summary table'), @@ -892,5 +884,10 @@ function reports_get_report_types($template=false, $not_editor=false) ]; } + $types['nt_top_n'] = [ + 'optgroup' => __('Network traffic'), + 'name' => __('Network Traffic Top N'), + ]; + return $types; } diff --git a/pandora_console/include/functions_servers.php b/pandora_console/include/functions_servers.php index ba6659ddc1..0850dcbfac 100644 --- a/pandora_console/include/functions_servers.php +++ b/pandora_console/include/functions_servers.php @@ -88,6 +88,58 @@ function servers_force_recon_task($id_recon_task) } +/** + * Retrieves total number of modules per server. + * + * @return array Modules per server (total). + */ +function servers_get_total_modules() +{ + $modules = []; + + $modules_from_monitors = db_get_all_rows_sql( + 'SELECT + tserver.server_type, + count(tagente_estado.id_agente_modulo) as modules_assigned + FROM tserver, tagente_estado, tagente_modulo, tagente + WHERE tagente.disabled=0 + AND tagente_modulo.id_agente = tagente.id_agente + AND tagente_modulo.disabled = 0 + AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo + AND tagente_estado.running_by = tserver.id_server + GROUP BY tserver.server_type;' + ); + + if ($modules_from_monitors !== false) { + $modules = array_reduce( + $modules_from_monitors, + function ($carry, $item) { + $carry[$item['server_type']] = $item['modules_assigned']; + return $carry; + } + ); + } + + $modules[SERVER_TYPE_INVENTORY] = db_get_sql( + 'SELECT COUNT(tagent_module_inventory.id_agent_module_inventory) + FROM tagente, tagent_module_inventory + WHERE tagente.disabled=0 + AND tagent_module_inventory.id_agente = tagente.id_agente' + ); + + $modules[SERVER_TYPE_EXPORT] = db_get_sql( + 'SELECT COUNT(tagente_modulo.id_agente_modulo) + FROM tagente, tagente_modulo + WHERE tagente.disabled=0 + AND tagente_modulo.id_agente = tagente.id_agente + AND tagente_modulo.id_export != 0' + ); + + return $modules; + +} + + /** * This function will get several metrics from the database to get info about server performance * @@ -989,6 +1041,9 @@ function servers_get_server_string_name(int $server) case SERVER_TYPE_WUX: return __('WUX server'); + case SERVER_TYPE_ENTERPRISE_SATELLITE: + return __('Satellite'); + default: return __('N/A'); } diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index ecc4905c37..b2a4a98b36 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -1265,7 +1265,7 @@ function ui_print_alert_template_example($id_alert_template, $return=false, $pri * * @return string The help tip */ -function ui_print_help_icon($help_id, $return=false, $home_url='', $image='images/help.png', $is_relative=false) +function ui_print_help_icon($help_id, $return=false, $home_url='', $image='images/help_green.png', $is_relative=false) { global $config; @@ -2124,7 +2124,7 @@ function ui_print_session_action_icon($action, $return=false) * * @return string HTML code if return parameter is true. */ -function ui_print_help_tip($text, $return=false, $img='images/tip.png', $is_relative=false) +function ui_print_help_tip($text, $return=false, $img='images/tip_help.png', $is_relative=false) { $output = ''.html_print_image( $img, @@ -2764,7 +2764,8 @@ function ui_print_page_header( $modal=false, $message='', $numChars=GENERIC_SIZE_TEXT, - $alias='' + $alias='', + $breadcrumbs='' ) { $title = io_safe_input_html($title); if (($icon == '') && ($godmode == true)) { @@ -2777,15 +2778,21 @@ function ui_print_page_header( if ($godmode == true) { $type = 'view'; - $type2 = 'menu_tab_frame_view'; + $type2 = (empty($breadcrumbs)) ? 'menu_tab_frame_view' : 'menu_tab_frame_view_bc'; $separator_class = 'separator'; } else { $type = 'view'; - $type2 = 'menu_tab_frame_view'; + $type2 = (empty($breadcrumbs)) ? 'menu_tab_frame_view' : 'menu_tab_frame_view_bc'; $separator_class = 'separator_view'; } - $buffer = '