1<?php
2
3// Pandora FMS - http://pandorafms.com
4// ==================================================
5// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
6// Please see http://pandorafms.org for full contribution list
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the  GNU Lesser General Public License
10// as published by the Free Software Foundation; version 2
11
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17
18
19/**
20 * @package Include
21 * @subpackage Network_Map
22 */
23
24/**
25 * Include agents function
26 */
27require_once ('functions_agents.php');
28require_once($config['homedir'] . "/include/functions_modules.php");
29require_once($config['homedir'] . "/include/functions_groups.php");
30ui_require_css_file ('cluetip');
31
32// Check if a node descends from a given node
33function networkmap_is_descendant ($node, $ascendant, $parents) {
34	if (! isset ($parents[$node])) {
35		return false;
36	}
37
38	if ($node == $ascendant) {
39		return true;
40	}
41
42	return networkmap_is_descendant ($parents[$node], $ascendant, $parents);
43}
44
45
46function networkmap_print_jsdata($graph, $js_tags = true) {
47	if ($js_tags) {
48		echo "<script type='text/javascript'>";
49
50		if (empty($graph)) {
51			echo "var graph = null;\n";
52			return;
53		}
54		else {
55			echo "var graph = \n";
56		}
57	}
58
59	echo "{\n";
60	echo "'nodes' : \n";
61	echo "[\n";
62	$first = true;
63	foreach ($graph['nodes'] as $id => $node) {
64		if (!$first) {
65			echo ",\n";
66		}
67		$first = false;
68
69		echo "{
70			'id' : " . $id . ",
71			'name' : '" . $node['label'] . "',
72			'url' : '" . $node['url'] . "',
73			'tooltip' : '" . $node['tooltip'] . "',
74			'default_tooltip' : 1,
75			'tooltip_content' : ' " . html_print_image('images/spinner.gif',true) . "',
76			'color' : '" . $node['color'] . "'}\n";
77	}
78	echo "],\n";
79
80	echo "'links' : \n";
81	echo "[\n";
82	$first = true;
83	foreach ($graph['lines'] as $line) {
84		if (!$first) {
85			echo ",\n";
86		}
87		$first = false;
88
89		echo "{
90			'source' : " . $line['source'] . ",
91			'target' : " . $line['target'] . "}\n";
92	}
93	echo "]\n";
94
95	echo "}\n";
96
97	if ($js_tags) {
98		echo ";\n";
99		echo "</script>";
100	}
101}
102
103function networkmap_generate_hash($pandora_name, $group = 0,
104	$simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0,
105	$zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0,
106	$id_networkmap = 0, $show_snmp_modules = 0, $cut_names = true,
107	$relative = false, $text_filter = '') {
108
109	$graph = networkmap_generate_dot($pandora_name, $group,
110		$simple, $font_size, $layout, $nooverlap, $zoom, $ranksep,
111		$center, $regen, $pure, $id_networkmap, $show_snmp_modules,
112		$cut_names, $relative, $text_filter, false, null, false, $strict_user);
113
114	$return = array();
115	if (!empty($graph)) {
116		$graph = str_replace("\r", "\n", $graph);
117		$graph = str_replace("\n", " ", $graph);
118
119		//Removed the head
120		preg_match("/graph networkmap {(.*)}/", $graph, $matches);
121		$graph = $matches[1];
122
123
124		//Get the lines and nodes
125		$tokens = preg_split("/; /", $graph);
126		foreach ($tokens as $token) {
127			if (empty($token)) {
128				continue;
129			}
130
131			//Ignore the head rests.
132			if (preg_match("/(.+)\s*\[(.*)\]/", $token) != 0) {
133				$items[] = $token;
134			}
135		}
136
137		$lines = $nodes = array();
138		foreach ($items as $item) {
139			$matches = null;
140			preg_match("/(.+)\s*\[(.*)\]/", $item, $matches);
141			if (empty($matches))
142				continue;
143
144			$id_item = trim($matches[1]);
145			$content_item = trim($matches[2]);
146
147			//Check if is a edge or node
148			if (strstr($id_item, "--") !== false) {
149				//edge
150				$lines[$id_item] = $content_item;
151			}
152			else {
153				//node
154				$id_item = (int)$id_item;
155				$nodes[$id_item] = $content_item;
156			}
157		}
158
159
160		foreach($nodes as $key => $node) {
161			if ($key != 0) {
162				//Get label
163				$matches = null;
164				preg_match("/label=(.*),/", $node, $matches);
165				$label = $matches[1];
166				$matches = null;
167				preg_match("/\<TR\>\<TD\>(.*?)\<\/TD\>\<\/TR\>/",
168					$label, $matches);
169				$label = str_replace($matches[0], '', $label);
170				$matches = null;
171				preg_match("/\<TR\>\<TD\>(.*?)\<\/TD\>\<\/TR\>/",
172					$label, $matches);
173				$label = $matches[1];
174
175				//Get color
176				$matches = null;
177				preg_match("/color=\"([^\"]*)/", $node, $matches);
178				$color = $matches[1];
179
180				//Get tooltip
181				$matches = null;
182				preg_match("/tooltip=\"([^\"]*)/", $node, $matches);
183				$tooltip = $matches[1];
184
185				//Get URL
186				$matches = null;
187				preg_match("/URL=\"([^\"]*)/", $node, $matches);
188				$url = $matches[1];
189
190				$return['nodes'][$key]['label'] = $label;
191				$return['nodes'][$key]['color'] = $color;
192				$return['nodes'][$key]['tooltip'] = $tooltip;
193				$return['nodes'][$key]['url'] = $url;
194			}
195			else {
196				//Get tooltip
197				$matches = null;
198				preg_match("/tooltip=\"([^\"]*)/", $node, $matches);
199				$tooltip = $matches[1];
200
201				//Get URL
202				$matches = null;
203				preg_match("/URL=\"([^\"]*)/", $node, $matches);
204				$url = $matches[1];
205
206				$return['nodes'][$key]['label'] = "Pandora FMS";
207				$return['nodes'][$key]['color'] = "#7EBE3F";
208				$return['nodes'][$key]['tooltip'] = $tooltip;
209				$return['nodes'][$key]['url'] = $url;
210			}
211		}
212		ksort($return['nodes']);
213
214		foreach($lines as $key => $line) {
215			$data = array();
216
217			$points = explode(' -- ', $key);
218			$data['source'] = (int) $points[0];
219			$data['target'] = (int) $points[1];
220			$return['lines'][] = $data;
221		}
222	}
223
224	return $return;
225}
226
227// Generate a dot graph definition for graphviz
228function networkmap_generate_dot ($pandora_name, $group = 0,
229	$simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0,
230	$zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0,
231	$id_networkmap = 0, $show_snmp_modules = 0, $cut_names = true,
232	$relative = false, $text_filter = '', $l2_network = false, $ip_mask = null,
233	$dont_show_subgroups = false, $strict_user = false, $size_canvas = null,
234	$old_mode = false) {
235
236	global $config;
237
238
239	if ($l2_network) {
240		$nooverlap = 1;
241	}
242
243	$parents = array();
244	$orphans = array();
245
246	$filter = array ();
247	$filter['disabled'] = 0;
248
249	if (!empty($text_filter)) {
250		switch ($config['dbtype']) {
251			case "mysql":
252			case "postgresql":
253				$filter[] =
254					'(nombre COLLATE utf8_general_ci LIKE "%' . $text_filter . '%")';
255				break;
256			case "oracle":
257				$filter[] =
258					'(upper(nombre) LIKE upper(\'%' . $text_filter . '%\'))';
259				break;
260		}
261	}
262
263	if ($group >= 1) {
264		if ($dont_show_subgroups)
265			$filter['id_grupo'] = $group;
266		else {
267			$childrens = groups_get_childrens($group, null, true);
268			if (!empty($childrens)) {
269				$childrens = array_keys($childrens);
270
271				$filter['id_grupo'] = $childrens;
272				$filter['id_grupo'][] = $group;
273			}
274			else {
275				$filter['id_grupo'] = $group;
276			}
277		}
278
279		//Order by id_parent ascendant for to avoid the bugs
280		//because the first agents to process in the next
281		//foreach loop are without parent (id_parent = 0)
282
283		// Get agents data
284		if ($strict_user) {
285			if ($dont_show_subgroups)
286				$filter['id_group'] = $group;
287			else {
288				if (!empty($childrens)) {
289					foreach ($childrens as $children) {
290						$filter_id_groups[$children] = $children;
291					}
292				}
293				$filter_id_groups[$group] = $group;
294				$filter['id_group'] = implode(',', $filter_id_groups);
295			}
296
297			$filter['group_by'] = 'tagente.id_agente';
298			$fields = array ('tagente.id_grupo, tagente.nombre, tagente.id_os, tagente.id_parent, tagente.id_agente,
299						tagente.normal_count, tagente.warning_count, tagente.critical_count,
300						tagente.unknown_count, tagente.total_count, tagente.notinit_count');
301			$acltags = tags_get_user_module_and_tags ($config['id_user'],'AR', $strict_user);
302			$agents = tags_get_all_user_agents (false, $config['id_user'], $acltags, $filter, $fields, false, $strict_user, true);
303		}
304		else {
305			$agents = agents_get_agents ($filter,
306				array ('id_grupo, nombre, id_os, id_parent, id_agente,
307					normal_count, warning_count, critical_count,
308					unknown_count, total_count, notinit_count'), 'AR',
309					array('field' => 'id_parent', 'order' => 'ASC'));
310		}
311
312	}
313	else if ($group == -666) {
314		$agents = false;
315	}
316	else if (!empty($ip_mask)) {
317		$agents = networkmap_get_new_nodes_from_ip_mask($ip_mask,
318			array ('id_grupo, nombre, id_os, id_parent, id_agente,
319				normal_count, warning_count, critical_count,
320				unknown_count, total_count, notinit_count'), $strict_user);
321	}
322	else {
323		//Order by id_parent ascendant for to avoid the bugs
324		//because the first agents to process in the next
325		//foreach loop are without parent (id_parent = 0)
326
327		if ($strict_user) {
328			$filter['group_by'] = 'tagente.id_agente';
329			$fields = array ('tagente.id_grupo, tagente.nombre, tagente.id_os, tagente.id_parent, tagente.id_agente,
330						tagente.normal_count, tagente.warning_count, tagente.critical_count,
331						tagente.unknown_count, tagente.total_count, tagente.notinit_count');
332			$acltags = tags_get_user_module_and_tags ($config['id_user'],'AR', $strict_user);
333			$agents = tags_get_all_user_agents (false, $config['id_user'], $acltags, $filter, $fields, false, $strict_user, true);
334		}
335		else {
336			$agents = agents_get_agents ($filter,
337				array ('id_grupo, nombre, id_os, id_parent, id_agente,
338					normal_count, warning_count, critical_count,
339					unknown_count, total_count, notinit_count'), 'AR',
340					array('field' => 'id_parent', 'order' => 'ASC'));
341		}
342	}
343
344	if ($agents === false)
345		//return false;
346		$agents = array();
347
348	// Open Graph
349	$graph = networkmap_open_graph ($layout, $nooverlap, $pure, $zoom,
350		$ranksep, $font_size, $size_canvas);
351
352	// Parse agents
353	$nodes = array ();
354
355	// Add node refs
356	$node_ref = array();
357	$modules_node_ref = array();
358
359	$node_count = 0;
360
361	foreach ($agents as $agent) {
362		$node_count++;
363
364		$node_ref[$agent['id_agente']] = $node_count;
365
366		$agent['id_node'] = $node_count;
367		$agent['type'] = 'agent';
368
369		// Add node
370		$nodes[$node_count] = $agent;
371
372		if ($l2_network || $show_snmp_modules) {
373
374			$filter = array();
375			$filter['disabled'] = 0;
376
377			// Get agent modules data
378			if ($strict_user) {
379				$modules = tags_get_agent_modules ($agent['id_agente'], false, $acltags, false, $filter, false);
380			}
381			else {
382				$modules = agents_get_modules($agent['id_agente'], '*', $filter, true, true);
383			}
384
385			if ($modules === false)
386				$modules = array();
387
388			// Parse modules
389			foreach ($modules as $key => $module) {
390
391				if ($module['id_tipo_modulo'] != 18 &&
392					(!$l2_network || $module['id_tipo_modulo'] != 6)) {
393					continue;
394				}
395
396				$node_count ++;
397				$modules_node_ref[$module['id_agente_modulo']] = $node_count;
398				$module['id_node'] = $node_count;
399				$module['type'] = 'module';
400
401				// Try to get the interface name
402				if (preg_match ("/_(.+)$/" , (string)$module['nombre'], $matches)) {
403					if ($matches[1]) {
404						$module['nombre'] = $matches[1];
405					}
406				}
407
408				// Save node parent information to define edges later
409				$parents[$node_count] = $module['parent'] = $agent['id_node'];
410
411				// Add node
412				$nodes[$node_count] = $module;
413			}
414		}
415	}
416
417	// Drop the modules without a partner if l2_network is true
418	// and the snmp interfaces token is false
419	if ($l2_network) {
420		foreach ($modules_node_ref as $id_module => $node_count) {
421			if (! modules_relation_exists($id_module, array_keys($modules_node_ref))) {
422				if ($show_snmp_modules) {
423					$module_type = modules_get_agentmodule_type($id_module);
424					if ($module_type != 18) {
425						unset($nodes[$node_count]);
426						unset($orphans[$node_count]);
427						unset($parents[$node_count]);
428					}
429				}
430				else {
431					unset($nodes[$node_count]);
432					unset($orphans[$node_count]);
433					unset($parents[$node_count]);
434				}
435			}
436			else {
437				$module_type = modules_get_agentmodule_type($id_module);
438				if ($module_type != 18) {
439					unset($nodes[$node_count]);
440					unset($orphans[$node_count]);
441					unset($parents[$node_count]);
442				}
443			}
444		}
445	}
446	else {
447		// Addded the relationship of parents of agents
448		foreach ($agents as $agent) {
449			if ($agent['id_parent'] != "0" &&
450				array_key_exists($agent['id_parent'], $node_ref)) {
451
452
453				$parents[$node_ref[$agent['id_agente']]] = $node_ref[$agent['id_parent']];
454			}
455			else {
456				$orphans[$node_ref[$agent['id_agente']]] = 1;
457			}
458		}
459	}
460
461	// Create void statistics array
462	$stats = array();
463
464	// Create nodes
465	foreach ($nodes as $node_id => $node) {
466		if ($center > 0 && ! networkmap_is_descendant ($node_id, $center, $parents)) {
467			unset ($parents[$node_id]);
468			unset ($orphans[$node_id]);
469			unset ($nodes[$node_id]);
470			continue;
471		}
472
473		switch ($node['type']) {
474			case 'agent':
475				$graph .= networkmap_create_agent_node($node, $simple,
476					$font_size, $cut_names, $relative) . "\n\t\t";
477				$stats['agents'][] = $node['id_agente'];
478				break;
479			case 'module':
480				$graph .= networkmap_create_module_node($node, $simple,
481					$font_size) . "\n\t\t";
482				$stats['modules'][] = $node['id_agente_modulo'];
483				break;
484		}
485	}
486
487	// Define edges
488	foreach ($parents as $node => $parent_id) {
489		// Verify that the parent is in the graph
490		if (isset ($nodes[$parent_id])) {
491			$graph .= networkmap_create_edge ($parent_id,
492				$node,
493				$layout,
494				$nooverlap,
495				$pure,
496				$zoom,
497				$ranksep,
498				$simple,
499				$regen,
500				$font_size,
501				$group,
502				'operation/agentes/networkmap',
503				'topology',
504				$id_networkmap);
505		}
506		else {
507			$orphans[$node] = 1;
508		}
509	}
510
511	// Define edges for the module interfaces relations
512	// Get the remote_snmp_proc relations
513	$relations = modules_get_relations();
514	if ($relations === false)
515		$relations = array();
516	foreach ($relations as $key => $relation) {
517		$module_a = $relation['module_a'];
518		$module_a_type = modules_get_agentmodule_type($module_a);
519		$agent_a = modules_get_agentmodule_agent($module_a);
520		$module_b = $relation['module_b'];
521		$module_b_type = modules_get_agentmodule_type($module_b);
522		$agent_b = modules_get_agentmodule_agent($module_b);
523
524		if ($module_a_type == 18 && $module_b_type == 18) {
525			if (isset($modules_node_ref[$module_a]) &&
526				isset($modules_node_ref[$module_b])) {
527				$graph .= networkmap_create_edge(
528					$modules_node_ref[$module_a],
529					$modules_node_ref[$module_b],
530					$layout,
531					$nooverlap,
532					$pure,
533					$zoom,
534					$ranksep,
535					$simple,
536					$regen,
537					$font_size,
538					$group,
539					'operation/agentes/networkmap',
540					'topology',
541					$id_networkmap);
542			}
543		}
544		elseif ($module_a_type == 6 && $module_b_type == 6) {
545			if (isset($node_ref[$agent_a]) &&
546				isset($node_ref[$agent_b])) {
547				$graph .= networkmap_create_edge(
548					$node_ref[$agent_a],
549					$node_ref[$agent_b],
550					$layout,
551					$nooverlap,
552					$pure,
553					$zoom,
554					$ranksep,
555					$simple,
556					$regen,
557					$font_size,
558					$group,
559					'operation/agentes/networkmap',
560					'topology',
561					$id_networkmap);
562			}
563
564		}
565		elseif ($module_a_type == 6 && $module_b_type == 18) {
566			if (isset($node_ref[$agent_a]) &&
567				isset($modules_node_ref[$module_b])) {
568				$graph .= networkmap_create_edge(
569					$node_ref[$agent_a],
570					$modules_node_ref[$module_b],
571					$layout,
572					$nooverlap,
573					$pure,
574					$zoom,
575					$ranksep,
576					$simple,
577					$regen,
578					$font_size,
579					$group,
580					'operation/agentes/networkmap',
581					'topology',
582					$id_networkmap);
583			}
584		}
585		elseif ($module_b_type == 6 && $module_a_type == 18) {
586			if (isset($node_ref[$agent_b]) &&
587				isset($modules_node_ref[$module_a])) {
588				$graph .= networkmap_create_edge(
589					$node_ref[$agent_b],
590					$modules_node_ref[$module_a],
591					$layout,
592					$nooverlap,
593					$pure,
594					$zoom,
595					$ranksep,
596					$simple,
597					$regen,
598					$font_size,
599					$group,
600					'operation/agentes/networkmap',
601					'topology',
602					$id_networkmap);
603			}
604		}
605	}
606
607	if ($l2_network || $old_mode) {
608		$count = 0;
609		$group_nodes = 10;
610		$graph .= networkmap_create_transparent_node($count);
611		foreach (array_keys($orphans) as $node) {
612			if ($group_nodes == 0) {
613				$count++;
614				$graph .= networkmap_create_transparent_node($count);
615
616				$group_nodes = 10;
617			}
618
619			$graph .= networkmap_create_transparent_edge('transp_' . $count,
620				$node);
621
622			$group_nodes--;
623		}
624	}
625	else {
626		// Create a central node if orphan nodes exist
627		if (count ($orphans) || empty ($nodes)) {
628			$graph .= networkmap_create_pandora_node ($pandora_name, $font_size, $simple, $stats);
629		}
630
631		// Define edges for orphan nodes
632		foreach (array_keys($orphans) as $node) {
633			$graph .= networkmap_create_edge ('0', $node, $layout, $nooverlap, $pure, $zoom, $ranksep, $simple, $regen, $font_size, $group, 'operation/agentes/networkmap', 'topology', $id_networkmap);
634		}
635
636	}
637
638	// Close graph
639	$graph .= networkmap_close_graph ();
640
641	return $graph;
642}
643
644// Generate a dot graph definition for graphviz with groups
645function networkmap_generate_dot_groups ($pandora_name, $group = 0,
646	$simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0,
647	$zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0,
648	$modwithalerts = 0, $module_group = 0, $hidepolicymodules = 0,
649	$depth = 'all', $id_networkmap = 0, $dont_show_subgroups = 0,
650	$text_filter = '', $strict_user = false, $size_canvas = null) {
651
652	global $config;
653
654	if ($strict_user) {
655		$acltags = tags_get_user_module_and_tags ($config['id_user'],'AR', $strict_user);
656	}
657	$parents = array();
658	$orphans = array();
659
660	$filter = array ();
661	$filter['disabled'] = 0;
662
663	if (!empty($text_filter)) {
664		switch ($config['dbtype']) {
665			case "mysql":
666			case "postgresql":
667				$filter[] =
668					'(nombre COLLATE utf8_general_ci LIKE "%' . $text_filter . '%")';
669				break;
670			case "oracle":
671				$filter[] =
672					'(upper(nombre) LIKE upper(\'%' . $text_filter . '%\'))';
673				break;
674		}
675	}
676
677	// Get groups data
678	if ($group > 0) {
679		$groups = array();
680		$id_groups = groups_get_id_recursive($group, true);
681
682		foreach($id_groups as $id_group) {
683			$add = false;
684			if (check_acl($config["id_user"], $id_group, 'AR')) {
685				$add = true;
686			}
687
688			if ($add) {
689				$groups[] = db_get_row ('tgrupo', 'id_grupo', $id_group);
690			}
691		}
692
693		$filter['id_grupo'] = $id_groups;
694	}
695	else {
696		if ($strict_user) {
697			$groups = users_get_groups ($config['id_user'],"AR", false, true);
698		} else {
699			$groups = db_get_all_rows_in_table ('tgrupo');
700		}
701		if ($groups === false) {
702			$groups = array();
703		}
704	}
705
706	// Open Graph
707	$graph = networkmap_open_graph ($layout, $nooverlap, $pure, $zoom,
708		$ranksep, $font_size, $size_canvas);
709
710	$node_count = 0;
711
712	// Parse groups
713	$nodes = array ();
714	$nodes_groups = array();
715	foreach ($groups as $group2) {
716		$node_count ++;
717		$group2['type'] = 'group';
718		$group2['id_node'] = $node_count;
719
720		// Add node
721		$nodes_groups[$group2['id_grupo']] = $group2;
722	}
723
724	$node_count = 0;
725
726	$groups_hiden = array();
727	foreach ($nodes_groups as $node_group) {
728
729		$node_count++;
730
731		// Save node parent information to define edges later
732		if ($node_group['parent'] != "0" && $node_group['id_grupo'] != $group) {
733			if ((!$dont_show_subgroups) || ($group == 0)) {
734				$parents[$node_count] = $nodes_groups[$node_group['parent']]['id_node'];
735			}
736			else {
737				$groups_hiden[$node_group['id_grupo']] = 1;
738				continue;
739			}
740		}
741		else {
742			$orphans[$node_count] = 1;
743		}
744
745		$nodes[$node_count] = $node_group;
746	}
747
748	if ($depth != 'group') {
749		if ($strict_user) {
750			$filter['group_by'] = 'tagente.nombre';
751			$filter['id_group'] = $filter['id_grupo'];
752			$fields = array ('tagente.id_grupo, tagente.nombre, tagente.id_os, tagente.id_agente,
753						tagente.normal_count, tagente.warning_count, tagente.critical_count,
754						tagente.unknown_count, tagente.total_count, tagente.notinit_count');
755			$agents = tags_get_all_user_agents (false, $config['id_user'], $acltags, $filter, $fields, false, $strict_user, true);
756			unset($filter['id_group']);
757		} else {
758		// Get agents data
759		$agents = agents_get_agents ($filter,
760			array ('id_grupo, nombre, id_os, id_agente,
761				normal_count, warning_count, critical_count,
762				unknown_count, total_count, notinit_count'));
763		}
764		if ($agents === false)
765			$agents = array();
766
767		// Parse agents
768		$nodes_agents = array();
769		foreach ($agents as $agent) {
770			if ($dont_show_subgroups) {
771				if (!empty($groups_hiden[$agent['id_grupo']])) {
772					continue;
773				}
774			}
775
776			// If only agents with alerts => agents without alerts discarded
777			$alert_agent = agents_get_alerts($agent['id_agente']);
778
779			if ($modwithalerts and empty($alert_agent['simple'])) {
780				continue;
781			}
782
783			$node_count ++;
784			// Save node parent information to define edges later
785			$parents[$node_count] = $agent['parent'] = $nodes_groups[$agent['id_grupo']]['id_node'];
786
787			$agent['id_node'] = $node_count;
788			$agent['type'] = 'agent';
789			// Add node
790			$nodes[$node_count] = $nodes_agents[$agent['id_agente']] = $agent;
791
792			if ($depth == 'agent') {
793				continue;
794			}
795
796			// Get agent modules data
797			if ($strict_user) {
798				$filter['disabled'] = 0;
799				$modules = tags_get_agent_modules ($agent['id_agente'], false, $acltags, false, $filter, false);
800			} else {
801				$modules = agents_get_modules ($agent['id_agente'], false, array('disabled' => 0), true, false);
802			}
803
804			// Parse modules
805			foreach ($modules as $key => $module) {
806				$node_count ++;
807				$agent_module = modules_get_agentmodule($key);
808				$alerts_module = db_get_sql('SELECT count(*) AS num
809					FROM talert_template_modules
810					WHERE id_agent_module = ' . $key);
811
812				if ($alerts_module == 0 && $modwithalerts) {
813					continue;
814				}
815
816				if ($agent_module['id_module_group'] != $module_group &&
817					$module_group != 0) {
818					continue;
819				}
820
821				if ($hidepolicymodules && $config['enterprise_installed']) {
822					enterprise_include_once('include/functions_policies.php');
823					if (policies_is_module_in_policy($key)) {
824						continue;
825					}
826				}
827
828				// Save node parent information to define edges later
829				$parents[$node_count] = $agent_module['parent'] = $agent['id_node'];
830
831				$agent_module['id_node'] = $node_count;
832
833				$agent_module['type'] = 'module';
834				// Add node
835				$nodes[$node_count] = $agent_module;
836			}
837		}
838	}
839
840	if (empty ($nodes)) {
841		return false;
842	}
843
844	// Create void statistics array
845	$stats = array();
846
847	// Create nodes
848	foreach ($nodes as $node_id => $node) {
849		if ($center > 0 && ! networkmap_is_descendant ($node_id, $center, $parents)) {
850			unset ($parents[$node_id]);
851			unset ($orphans[$node_id]);
852			unset ($nodes[$node_id]);
853			continue;
854		}
855		switch ($node['type']) {
856			case 'group':
857				$graph .= networkmap_create_group_node ($node , $simple, $font_size, $metaconsole = false, null, $strict_user) .
858					"\n\t\t";
859				$stats['groups'][] = $node['id_grupo'];
860				break;
861			case 'agent':
862				$graph .= networkmap_create_agent_node ($node , $simple, $font_size, true, true) .
863					"\n\t\t";
864				$stats['agents'][] = $node['id_agente'];
865				break;
866			case 'module':
867				$graph .= networkmap_create_module_node ($node , $simple, $font_size) .
868					"\n\t\t";
869				$stats['modules'][] = $node['id_agente_modulo'];
870				break;
871		}
872	}
873	// Define edges
874	foreach ($parents as $node => $parent_id) {
875		// Verify that the parent is in the graph
876		if (isset ($nodes[$parent_id])) {
877			$graph .= networkmap_create_edge ($node, $parent_id, $layout, $nooverlap, $pure, $zoom, $ranksep, $simple, $regen, $font_size, $group, 'operation/agentes/networkmap', 'groups', $id_networkmap);
878		}
879		else {
880			$orphans[$node] = 1;
881		}
882	}
883
884	// Create a central node if orphan nodes exist
885	if (count ($orphans)) {
886		$graph .= networkmap_create_pandora_node ($pandora_name, $font_size, $simple, $stats);
887	}
888
889	// Define edges for orphan nodes
890	foreach (array_keys($orphans) as $node) {
891		$graph .= networkmap_create_edge ('0', $node, $layout, $nooverlap, $pure, $zoom, $ranksep, $simple, $regen, $font_size, $group, 'operation/agentes/networkmap', 'groups', $id_networkmap);
892	}
893
894	// Close graph
895	$graph .= networkmap_close_graph ();
896
897	return $graph;
898}
899
900// Returns an edge definition
901function networkmap_create_edge ($head, $tail, $layout, $nooverlap, $pure, $zoom, $ranksep, $simple, $regen, $font_size, $group, $sec2 = 'operation/agentes/networkmap', $tab = 'topology', $id_networkmap = 0) {
902
903	if (defined("METACONSOLE")) {
904		$url = '';
905	}
906	else {
907		$url = 'index.php?sec=estado&' .
908			'sec2=' . $sec2 .'&' .
909			'tab=' . $tab . '&' .
910			'recenter_networkmap=1&' .
911			'center=' . $head . '&' .
912			'layout=' . $layout . '&' .
913			'nooverlap=' . $nooverlap . '&' .
914			'pure=' . $pure . '&' .
915			'zoom=' . $zoom . '&' .
916			'ranksep=' . $ranksep . '&' .
917			'simple=' . $simple . '&' .
918			'regen=1'. '&' .
919			'font_size=' . $font_size . '&' .
920			'group=' . $group . '&' .
921			'id_networkmap=' . $id_networkmap;
922	}
923
924	// edgeURL allows node navigation
925	$edge = "\n" . $head . ' -- ' . $tail .
926		'[color="#BDBDBD", headclip=false, tailclip=false, edgeURL=""];' . "\n";
927
928	return $edge;
929}
930
931function networkmap_create_transparent_edge($head, $tail) {
932	// edgeURL allows node navigation
933	$edge = "\n" . $head . ' -- ' . $tail .
934		'[color="#00000000", headclip=false, tailclip=false, edgeURL=""];' . "\n";
935
936	return $edge;
937}
938
939// Returns a group node definition
940function networkmap_create_group_node ($group, $simple = 0, $font_size = 10, $metaconsole = false, $id_server = null, $strict_user = false) {
941	global $config;
942	global $hack_networkmap_mobile;
943
944	$status = groups_get_status ($group['id_grupo'], $strict_user);
945
946	// Set node status
947	switch ($status) {
948		case 0:
949			$status_color = COL_NORMAL; // Normal monitor
950			break;
951		case 1:
952			$status_color = COL_CRITICAL; // Critical monitor
953			break;
954		case 2:
955			$status_color = COL_WARNING; // Warning monitor
956			break;
957		case 4:
958			$status_color = COL_ALERTFIRED; // Alert fired
959			break;
960		default:
961			$status_color = COL_UNKNOWN; // Unknown monitor
962			break;
963	}
964
965
966
967	$icon = groups_get_icon($group['id_grupo']);
968
969	if ($simple == 0) {
970		// Set node icon
971		if ($hack_networkmap_mobile) {
972			$img_node = $config['homedir'] . "/images/groups_small/" . $icon . ".png";
973
974			if (!file_exists($img_node)) {
975				$img_node = '-';
976			}
977			$img_node = '<img src="' . $img_node . '" />';
978		}
979		else if (file_exists (html_print_image("images/groups_small/" . $icon . ".png", true, false, true, true))) {
980			$img_node = html_print_image("images/groups_small/" . $icon . ".png", true, false, false, true);
981		}
982		else {
983			$img_node = '-';
984		}
985
986		if (strlen(groups_get_name($group['id_grupo'])) > 40) {
987			$name = substr(groups_get_name($group['id_grupo']), 0, 40) . '...';
988		}
989		else {
990			$name = groups_get_name($group['id_grupo']);
991		}
992
993		if (defined("METACONSOLE")) {
994			$url = '';
995			$url_tooltip = '';
996		}
997		else {
998			$url = 'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60&group_id='.$group['id_grupo'];
999			$url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_group_status_tooltip=1&id_group='.$group['id_grupo'];
1000		}
1001
1002		$node = "\n" . $group['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', style="filled", fixedsize=true, width=0.30, height=0.30, label=<<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"><TR><TD>'.$img_node.'</TD></TR>
1003		 <TR><TD>'.io_safe_output($name).'</TD></TR></TABLE>>,
1004		 shape="invtrapezium", URL="' . $url . '",
1005		 tooltip="' . $url_tooltip . '"];' . "\n";
1006	}
1007	else {
1008		if (defined("METACONSOLE")) {
1009			$url = '';
1010			$url_tooltip = '';
1011		}
1012		else {
1013			$url = 'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60&group_id='.$group['id_grupo'];
1014			$url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_group_status_tooltip=1&id_group='.$group['id_grupo'];
1015		}
1016
1017		$node = "\n" . $group['id_node'] . ' [ color="'.$status_color.'", fontsize='.$font_size.', shape="invtrapezium",
1018			URL="' . $url . '", style="filled", fixedsize=true, width=0.20, height=0.20, label="",
1019			tooltip="' . $url_tooltip . '"];' . "\n";
1020	}
1021	return $node;
1022}
1023
1024// Returns a node definition
1025function networkmap_create_agent_node ($agent, $simple = 0, $font_size = 10, $cut_names = true, $relative = false, $metaconsole = false, $id_server = null, $strict_user = false) {
1026	global $config;
1027	global $hack_networkmap_mobile;
1028
1029	if ($strict_user) {
1030		require_once($config['homedir']."/include/functions_tags.php");
1031		$acltags = tags_get_user_module_and_tags ($config["id_user"], 'AR', $strict_user);
1032
1033		$agent_filter = array("id" => $agent["id_agente"]);
1034		$strict_data['normal_count'] = (int) groups_get_normal_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1035		$strict_data['warning_count'] = (int) groups_get_warning_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1036		$strict_data['critical_count'] = (int) groups_get_critical_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1037		$strict_data['unknown_count'] = (int) groups_get_unknown_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1038		$strict_data['notinit_count'] = (int) groups_get_not_init_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1039		$strict_data['total_count'] = (int) groups_get_total_monitors ($agent['id_grupo'], $agent_filter, array(), $strict_user, $acltags);
1040		$status = agents_get_status_from_counts($strict_data);
1041	} else {
1042		$status = agents_get_status_from_counts($agent);
1043	}
1044
1045	if (defined('METACONSOLE')) {
1046		$server_data = db_get_row('tmetaconsole_setup', 'id',
1047			$agent['id_server']);
1048	}
1049
1050	if (empty($server_data)) {
1051		$server_name = '';
1052		$server_id = '';
1053		$url_hash = '';
1054		$console_url = '';
1055	}
1056	else {
1057		$server_name = $server_data['server_name'];
1058		$server_id = $server_data['id'];
1059		$console_url = $server_data['server_url'] . '/';
1060		$url_hash = metaconsole_get_servers_url_hash($server_data);
1061	}
1062
1063	// Set node status
1064	switch ($status) {
1065		case AGENT_STATUS_NORMAL:
1066			$status_color = COL_NORMAL;
1067			break;
1068		case AGENT_STATUS_CRITICAL:
1069			$status_color = COL_CRITICAL;
1070			break;
1071		case AGENT_STATUS_WARNING:
1072			$status_color = COL_WARNING;
1073			break;
1074		case AGENT_STATUS_ALERT_FIRED:
1075			$status_color = COL_ALERTFIRED;
1076			break;
1077		# Juanma (05/05/2014) Fix: Correct color for not init agents!
1078		case AGENT_STATUS_NOT_INIT:
1079			$status_color = COL_NOTINIT;
1080			break;
1081		default:
1082			//Unknown monitor
1083			$status_color = COL_UNKNOWN;
1084			break;
1085	}
1086
1087	// Short name
1088	$name = io_safe_output($agent["nombre"]);
1089	if ((strlen ($name) > 16) && ($cut_names)) {
1090		$name = ui_print_truncate_text($name, 16, false, true, false);
1091	}
1092
1093	if ($simple == 0) {
1094		if ($hack_networkmap_mobile) {
1095			$img_node = ui_print_os_icon($agent['id_os'], false, true, true, true, true, true);
1096
1097			$img_node = $config['homedir'] . '/' . $img_node;
1098			$img_node = '<img src="' . $img_node . '" />';
1099		}
1100		else {
1101			// Set node icon
1102			$img_node = ui_print_os_icon ($agent['id_os'], false, true, true, true, true, $relative);
1103			$img_node = str_replace($config['homeurl'] . '/', '', $img_node);
1104			$img_node = str_replace($config['homeurl'], '', $img_node);
1105
1106			if (defined('METACONSOLE')) {
1107				$img_node = str_replace('../../', '', $img_node);
1108			}
1109
1110			if ($relative) {
1111				$img_node = html_print_image($img_node, true, false, false, true);
1112			}
1113			else {
1114				$img_node = html_print_image($img_node, true, false, false, false);
1115			}
1116		}
1117
1118		if (defined("METACONSOLE")) {
1119			if (can_user_access_node ()) {
1120				$url = ui_meta_get_url_console_child($id_server,
1121					"estado", "operation/agentes/ver_agente&id_agente=" . $agent['id_agente']);
1122			}
1123			else {
1124				$url = '';
1125			}
1126			$url_tooltip = '../../ajax.php?' .
1127				'page=operation/agentes/ver_agente&' .
1128				'get_agent_status_tooltip=1&' .
1129				'id_agent='.$agent['id_agente'] . '&' .
1130				'metaconsole=1&' .
1131				'id_server=' . $agent['id_server'];
1132		}
1133		else {
1134			$url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$agent['id_agente'];
1135			$url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_agent_status_tooltip=1&id_agent='.$agent['id_agente'];
1136		}
1137
1138		$node = "\n" . $agent['id_node'].' [ color="'.$status_color.'", fontsize='.$font_size.', style="filled", fixedsize=true, width=0.40, height=0.40, label=<<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"><TR><TD>' . $img_node . '</TD></TR>
1139		 <TR><TD>'.io_safe_output($name).'</TD></TR></TABLE>>,
1140		 shape="doublecircle", URL="'.$url.'",
1141		 tooltip="' . $url_tooltip . '"];' . "\n";
1142	}
1143	else {
1144		$ajax_prefix = '';
1145		$meta_params = '';
1146
1147		if (defined('METACONSOLE')) {
1148			$ajax_prefix = '../../';
1149			$meta_params = '&metaconsole=1&id_server=' . $id_server;
1150		}
1151
1152		if (can_user_access_node ()) {
1153			$url_node_link = ', URL="' . $console_url . 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=' . $agent['id_agente'] . $url_hash . '"';
1154		}
1155		else {
1156			$url_node_link = '';
1157		}
1158		$node = $agent['id_node'] . ' [ color="' . $status_color . '", fontsize=' . $font_size . ', shape="doublecircle"' . $url_node_link . ', style="filled", fixedsize=true, width=0.20, height=0.20, label="", tooltip="' . $ajax_prefix . 'ajax.php?page=operation/agentes/ver_agente&get_agent_status_tooltip=1&id_agent=' . $agent['id_agente'] . $meta_params . '"];' . "\n";
1159	}
1160
1161	return $node;
1162}
1163
1164function networkmap_create_module_group_node ($module_group, $simple = 0, $font_size = 10, $metaconsole = false, $id_server = null) {
1165	global $config;
1166	global $hack_networkmap_mobile;
1167
1168
1169	// Set node status
1170	switch ($module_group['status']) {
1171		case 0:
1172			$status_color = COL_NORMAL; // Normal monitor
1173			break;
1174		case 1:
1175			$status_color = COL_CRITICAL; // Critical monitor
1176			break;
1177		case 2:
1178			$status_color = COL_WARNING; // Warning monitor
1179			break;
1180		case 4:
1181			$status_color = COL_ALERTFIRED; // Alert fired
1182			break;
1183		default:
1184			$status_color = COL_UNKNOWN; // Unknown monitor
1185			break;
1186	}
1187
1188	if ($simple == 0) {
1189		if (defined("METACONSOLE")) {
1190			$url = '';
1191			$url_tooltip = '';
1192		}
1193		else {
1194			$url = '';
1195			$url_tooltip = '';
1196		}
1197
1198		$node = $module_group['id_node'].' [ color="' . $status_color .
1199			'", fontsize='.$font_size.', style="filled", ' .
1200			'fixedsize=true, width=0.30, height=0.30, ' .
1201			'label=<<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"><TR><TD>' .
1202			io_safe_output($module_group['name']) . '</TD></TR></TABLE>>,
1203			shape="square", URL="' . $url . '",
1204			tooltip="' . $url_tooltip . '"];';
1205	}
1206	else {
1207		if ($hack_networkmap_mobile) {
1208			$img_node = ui_print_moduletype_icon($module['id_tipo_modulo'], true, true, false, true);
1209
1210			$img_node = $config['homedir'] . '/' . $img_node;
1211			$img_node = '<img src="' . $img_node . '" />';
1212		}
1213		else {
1214			$img_node = ui_print_moduletype_icon ($module['id_tipo_modulo'], true, true, false);
1215		}
1216		if (defined("METACONSOLE")) {
1217			$url = '';
1218			$url_tooltip = '';
1219		}
1220		else {
1221			$url = '';
1222			$url_tooltip = '';
1223		}
1224
1225		$node = $module_group['id_node'] . ' [ color="'.$status_color .
1226			'", fontsize='.$font_size.', shape="square", URL="' . $url . '", ' .
1227			'style="filled", fixedsize=true, width=0.20, ' .
1228			'height=0.20, label="", tooltip="' . $url_tooltip . '"];';
1229	}
1230	return $node;
1231}
1232
1233// Returns a module node definition
1234function networkmap_create_module_node ($module, $simple = 0, $font_size = 10, $metaconsole = false, $id_server = null) {
1235	global $config;
1236	global $hack_networkmap_mobile;
1237
1238	if (isset($module['status'])) {
1239		$status = $module['status'];
1240	}
1241	else {
1242		$status = modules_get_agentmodule_status($module['id_agente_modulo'],
1243			false, $metaconsole, $id_server);
1244	}
1245
1246	// Set node status
1247	switch ($status) {
1248		case AGENT_MODULE_STATUS_NORMAL:
1249			$status_color = COL_NORMAL; // Normal monitor
1250			break;
1251		case AGENT_MODULE_STATUS_CRITICAL_BAD:
1252			$status_color = COL_CRITICAL; // Critical monitor
1253			break;
1254		case AGENT_MODULE_STATUS_WARNING:
1255			$status_color = COL_WARNING; // Warning monitor
1256			break;
1257		case AGENT_STATUS_ALERT_FIRED:
1258			$status_color = COL_ALERTFIRED; // Alert fired
1259			break;
1260		default:
1261			$status_color = COL_UNKNOWN; // Unknown monitor
1262			break;
1263	}
1264
1265	if ($hack_networkmap_mobile) {
1266		$img_node = ui_print_moduletype_icon($module['id_tipo_modulo'], true, true, false, true);
1267
1268		$img_node = $config['homedir'] . '/' . $img_node;
1269		$img_node = '<img src="' . $img_node . '" />';
1270	}
1271	else {
1272		$img_node = ui_print_moduletype_icon ($module['id_tipo_modulo'], true, true, false);
1273	}
1274
1275
1276	if ($simple == 0) {
1277		if (defined("METACONSOLE")) {
1278			$url = '';
1279			$url_tooltip = '../../ajax.php?' .
1280				'page=operation/agentes/ver_agente&' .
1281				'get_agentmodule_status_tooltip=1&' .
1282				'id_module='.$module['id_agente_modulo'] .
1283				'&metaconsole=1' .
1284				'&id_server=' . $module['id_server'];
1285		}
1286		else {
1287			$url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$module['id_agente'];
1288			$url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_agentmodule_status_tooltip=1&id_module='.$module['id_agente_modulo'];
1289		}
1290
1291		$node = $module['id_node'].' [ color="' . $status_color .
1292			'", fontsize='.$font_size.', style="filled", ' .
1293			'fixedsize=true, width=0.30, height=0.30, ' .
1294			'label=<<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"><TR><TD>' .
1295			$img_node . '</TD></TR>
1296			<TR><TD>' . io_safe_output($module['nombre']) . '</TD></TR></TABLE>>,
1297			shape="circle", URL="' . $url . '",
1298			tooltip="' . $url_tooltip . '"];';
1299	}
1300	else {
1301		if (defined("METACONSOLE")) {
1302			$url = 'TODO';
1303			$url_tooltip = '../../ajax.php?page=operation/agentes/ver_agente' .
1304				'&get_agentmodule_status_tooltip=1' .
1305				'&id_module=' . $module['id_agente_modulo'] .
1306				'&metaconsole=1' .
1307				'&id_server=' . $module['id_server'];
1308		}
1309		else {
1310			$url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$module['id_agente'];
1311			$url_tooltip = 'ajax.php?page=operation/agentes/ver_agente&get_agentmodule_status_tooltip=1&id_module='.$module['id_agente_modulo'];
1312		}
1313
1314		$node = $module['id_node'] . ' [ ' .
1315			'color="' . $status_color .'", ' .
1316			'fontsize='.$font_size.', ' .
1317			'shape="circle", ' .
1318			'URL="' . $url . '", ' .
1319			'style="filled", ' .
1320			'fixedsize=true, ' .
1321			'width=0.20, ' .
1322			'height=0.20, ' .
1323			'label="", ' .
1324			'tooltip="' . $url_tooltip . '"' .
1325			'];';
1326	}
1327	return $node;
1328}
1329
1330// Returns the definition of the central module
1331function networkmap_create_pandora_node ($name, $font_size = 10, $simple = 0, $stats = array()) {
1332	global $hack_networkmap_mobile;
1333	global $config;
1334
1335	//$stats_json = base64_encode(json_encode($stats));
1336	$summary = array();
1337	if (isset($stats['policies'])) {
1338			$summary['policies'] = count($stats['policies']);
1339	}
1340	if (isset($stats['groups'])) {
1341		// TODO: GET STATUS OF THE GROUPS AND ADD IT TO SUMMARY
1342		$summary['groups'] = count($stats['groups']);
1343	}
1344	if (isset($stats['agents'])) {
1345		// TODO: GET STATUS OF THE AGENTS AND ADD IT TO SUMMARY
1346		$summary['agents'] = count($stats['agents']);
1347	}
1348	if (isset($stats['modules'])) {
1349		// TODO: GET STATUS OF THE MODULES AND ADD IT TO SUMMARY
1350		$summary['modules'] = count($stats['modules']) ;
1351	}
1352	$stats_json = base64_encode(json_encode($summary));
1353
1354	$img_src = "images/networkmap/pandora_node.png";
1355	if (defined('METACONSOLE')) {
1356
1357		$url_tooltip = '../../ajax.php?' .
1358			'page=include/ajax/networkmap.ajax&' .
1359			'action=get_networkmap_summary&' .
1360			'stats='.$stats_json . '&' .
1361			'metaconsole=1';
1362		$url = '';
1363		$color = '#052938';
1364	}
1365	else {
1366		$url_tooltip = 'ajax.php?page=include/ajax/networkmap.ajax&action=get_networkmap_summary&stats='.$stats_json.'", URL="index.php?sec=estado&sec2=operation/agentes/group_view';
1367		$url = 'index.php?sec=estado&sec2=operation/agentes/group_view';
1368		$color = '#373737';
1369	}
1370
1371	if ($hack_networkmap_mobile) {
1372		$img = '<TR><TD>' .
1373			"<img src='" . $config['homedir'] . '/' . "images/networkmap/pandora_node.png' />" .
1374			'</TD></TR>';
1375	}
1376	else {
1377		$image = html_print_image("images/networkmap/pandora_node.png", true, false, false, true);
1378		$image = str_replace('"',"'",$image);
1379		$img = '<TR><TD>' . $image . '</TD></TR>';
1380	}
1381	$name = "<TR><TD BGCOLOR='#FFFFFF'>" . $name . '</TD></TR>';
1382	$label = "<TABLE BORDER='0'>" . $img.$name . '</TABLE>';
1383	if ($simple == 1) {
1384		$label = '';
1385	}
1386
1387	$node = '0 [ color="' . $color . '", fontsize='.$font_size.', style="filled", fixedsize=true, width=0.8, height=0.6, label=<'.$label.'>,
1388		shape="ellipse", tooltip="' . $url_tooltip . '", URL="' . $url . '" ];';
1389
1390	return $node;
1391}
1392
1393function networkmap_create_transparent_node($count = 0) {
1394
1395	$node = 'transp_' .$count  . ' [ color="#00000000", style="filled", fixedsize=true, width=0.8, height=0.6, label=<>,
1396		shape="ellipse"];';
1397
1398	return $node;
1399}
1400
1401// Opens a group definition
1402function networkmap_open_group ($id) {
1403	$img = 'images/'.groups_get_icon ($id).'.png';
1404	$name = groups_get_name ($id);
1405
1406	$group = 'subgraph cluster_' . $id .
1407		' { style=filled; color=darkolivegreen3; label=<<TABLE BORDER=\'0\'>
1408		<TR><TD>' . html_print_image($img, true) . '</TD><TD>'.$name.'</TD></TR>
1409		</TABLE>>; tooltip="'.$name.'";
1410		URL="index.php?sec=estado&sec2=operation/agentes/estado_agente&group_id='
1411		. $id . '";';
1412
1413	return $group;
1414}
1415
1416// Closes a group definition
1417function networkmap_close_group () {
1418	return '}';
1419}
1420
1421// Opens a graph definition
1422function networkmap_open_graph ($layout, $nooverlap, $pure, $zoom,
1423	$ranksep, $font_size, $size_canvas) {
1424
1425	global $config;
1426
1427	$overlap = 'compress';
1428
1429	if (isset($config['networkmap_max_width'])) {
1430		$size_x = $config['networkmap_max_width'] / 100;
1431		$size_y = $size_x * 0.8;
1432	}
1433	else {
1434		$size_x = 8;
1435		$size_y = 5.4;
1436		$size = '';
1437	}
1438
1439
1440	if ($layout == 'radial') {
1441		$overlap = 'true';
1442	}
1443
1444	if ($layout == 'flat' || $layout == 'radial' || $layout == 'spring1' || $layout == "spring2") {
1445		if ($nooverlap != '') {
1446			$overlap = 'scalexy';
1447		}
1448	}
1449
1450	if ($zoom > 0) {
1451		$size_x *= $zoom;
1452		$size_y *= $zoom;
1453	}
1454	$size = $size_x . ',' . $size_y;
1455
1456	if (!is_null($size_canvas)) {
1457		$size = ($size_canvas['x'] / 100) . "," . ($size_canvas['y'] / 100);
1458	}
1459
1460	// BEWARE: graphwiz DONT use single ('), you need double (")
1461	$head = "graph networkmap { dpi=100; bgcolor=\"transparent\"; labeljust=l; margin=0; pad=\"0.75,0.75\";";
1462	if ($nooverlap != '') {
1463		$head .= "overlap=\"$overlap\";";
1464		$head .= "ranksep=\"$ranksep\";";
1465		$head .= "outputorder=edgesfirst;";
1466	}
1467
1468	$head .= "ratio=fill;";
1469	$head .= "root=0;";
1470	$head .= "size=\"$size\";";
1471
1472
1473
1474	return $head;
1475}
1476
1477// Closes a graph definition
1478function networkmap_close_graph () {
1479	return '}';
1480}
1481
1482// Returns the filter used to achieve the desired layout
1483function networkmap_get_filter ($layout) {
1484	switch ($layout) {
1485		case 'flat':
1486			return 'dot';
1487			break;
1488		case 'radial':
1489			return 'twopi';
1490			break;
1491		case 'circular':
1492			return 'circo';
1493			break;
1494		case 'spring1':
1495			return 'neato';
1496			break;
1497		case 'spring2':
1498			return 'fdp';
1499			break;
1500		default:
1501			return 'twopi';
1502			break;
1503	}
1504}
1505
1506/**
1507 * Creates a networkmap.
1508 *
1509 * @param string Network map name.
1510 * @param string Network map type (topology, groups or policies).
1511 * @param layout Network map layout (circular, flat, radial, spring1 or spring2).
1512 * @param bool overlapping activate flag.
1513 * @param bool simple view activate flag.
1514 * @param bool regenerate file activate flag.
1515 * @param int font size.
1516 * @param int group id filter (0 for all).
1517 * @param int module group id filter (0 for all).
1518 * @param int policy id filter (0 for all).
1519 * @param string depth level.
1520 * @param bool only modules with alerts flag.
1521 * @param bool hide policy modules flag
1522 * @param float zoom factor
1523 *
1524 * @return mixed New networkmap id if created. False if it could not be created.
1525 */
1526function networkmap_create_networkmap ($values) {
1527	global $config;
1528
1529	// The name is required
1530	if (! isset($values['name']))
1531		return false;
1532
1533	// Set defaults for the empty values
1534	set_unless_defined ($values['type'], 'topology');
1535	set_unless_defined ($values['layout'], 'radial');
1536	set_unless_defined ($values['nooverlap'], true);
1537	set_unless_defined ($values['simple'], false);
1538	set_unless_defined ($values['regenerate'], true);
1539	set_unless_defined ($values['font_size'], 12);
1540	set_unless_defined ($values['store_group'], 0);
1541	set_unless_defined ($values['id_group'], 0);
1542	set_unless_defined ($values['regenerate'], true);
1543	set_unless_defined ($values['id_module_group'], 0);
1544	set_unless_defined ($values['depth'], 'all');
1545	set_unless_defined ($values['only_modules_with_alerts'], false);
1546	set_unless_defined ($values['hide_policy_modules'], false);
1547	set_unless_defined ($values['zoom'], 1);
1548	set_unless_defined ($values['distance_nodes'], 2.5);
1549	set_unless_defined ($values['center'], 0);
1550	set_unless_defined ($values['id_user'], $config['id_user']);
1551	set_unless_defined ($values['text_filter'], '');
1552	set_unless_defined ($values['regenerate'], true);
1553	set_unless_defined ($values['dont_show_subgroups'], 0);
1554	set_unless_defined ($values['show_groups'], false);
1555	set_unless_defined ($values['pandoras_children'], false);
1556	set_unless_defined ($values['show_modules'], false);
1557	set_unless_defined ($values['show_snmp_modules'], 0);
1558	set_unless_defined ($values['l2_network'], 0);
1559	set_unless_defined ($values['server_name'], '');
1560
1561	return @db_process_sql_insert('tnetwork_map', $values);
1562}
1563
1564/**
1565 * Get a network map report.
1566 *
1567 * @param int Networkmap id to get.
1568 * @param array Extra filter.
1569 * @param array Fields to get.
1570 * @param bool Get only the map if is of the user ($config['id_user'])
1571 *
1572 * @return Networkmap with the given id. False if not available or readable.
1573 */
1574function networkmap_get_networkmap ($id_networkmap, $filter = false, $fields = false, $check_user = true) {
1575	global $config;
1576
1577	$id_networkmap = safe_int ($id_networkmap);
1578	if (empty ($id_networkmap))
1579		return false;
1580	if (! is_array ($filter))
1581		$filter = array ();
1582
1583	$filter['id_networkmap'] = $id_networkmap;
1584
1585	if ($check_user) {
1586		//If hte user has admin flag don't filter by user
1587		$user_info = users_get_user_by_id($config['id_user']);
1588
1589		if (!$user_info['is_admin']) {
1590			//$filter['id_user'] = $config['id_user'];
1591		}
1592	}
1593
1594	$networkmap = db_get_row_filter ('tnetwork_map', $filter, $fields);
1595
1596	return $networkmap;
1597}
1598
1599/**
1600 * Get a user networkmaps.
1601 *
1602 * @param int Networkmap id to get.
1603 * @param array Extra filter.
1604 * @param array Fields to get.
1605 *
1606 * @return Networkmap with the given id. False if not available or readable.
1607 */
1608function networkmap_get_networkmaps ($id_user = '', $type = '', $optgrouped = true, $strict_user = false) {
1609	global $config;
1610
1611	if ($id_user == '') {
1612		$id_user = $config['id_user'];
1613	}
1614
1615	// Configure filters
1616	$where = array ();
1617	$where['id_group'] = array_keys (users_get_groups($id_user));
1618	if ($type != '') {
1619		$where['type'] = $type;
1620	}
1621
1622	$where['order'][0]['field'] = 'type';
1623	$where['order'][0]['order'] = 'DESC';
1624	$where['order'][1]['field'] = 'name';
1625	$where['order'][1]['order'] = 'ASC';
1626
1627	$networkmaps_raw =  db_get_all_rows_filter('tnetwork_map', $where);
1628	if ($networkmaps_raw === false) {
1629		return false;
1630	}
1631
1632	$networkmaps = array();
1633	foreach ($networkmaps_raw as $key => $networkmapitem) {
1634		if ($optgrouped) {
1635			if ((($networkmapitem['type'] == 'policies') || ($networkmapitem['type'] == 'radial_dynamic')) && ($strict_user)) {
1636				continue;
1637			}
1638			$networkmaps[$networkmapitem['id_networkmap']] =
1639				array('name' => $networkmapitem['name'],
1640					'optgroup' => $networkmapitem['type']);
1641		}
1642		else {
1643			if ((($networkmapitem['type'] == 'policies') || ($networkmapitem['type'] == 'radial_dynamic')) && ($strict_user)) {
1644				continue;
1645			}
1646			$networkmaps[$networkmapitem['id_networkmap']] =
1647				$networkmapitem['name'];
1648		}
1649	}
1650
1651	return $networkmaps;
1652}
1653
1654/**
1655 * Deletes a network map.
1656 *
1657 * @param int Map id to be deleted.
1658 *
1659 * @return bool True if the map was deleted, false otherwise.
1660 */
1661function networkmap_delete_networkmap ($id_networkmap) {
1662	$id_networkmap = safe_int ($id_networkmap);
1663	if (empty ($id_networkmap))
1664		return false;
1665	$networkmap = networkmap_get_networkmap ($id_networkmap);
1666	if ($networkmap === false)
1667		return false;
1668	return @db_process_sql_delete ('tnetwork_map', array ('id_networkmap' => $id_networkmap));
1669}
1670
1671/**
1672 * Deletes a network map if the property is that user.
1673 *
1674 * @param string User id that call this funtion.
1675 * @param int Map id to be deleted.
1676 *
1677 * @return bool True if the map was deleted, false the map is not yours.
1678 */
1679function networkmap_delete_user_networkmap ($id_user = '', $id_networkmap) {
1680	if ($id_user == '') {
1681		$id_user = $config['id_user'];
1682	}
1683	$id_networkmap = safe_int ($id_networkmap);
1684	if (empty ($id_networkmap))
1685		return false;
1686	$networkmap = networkmap_get_networkmap ($id_networkmap);
1687	if ($networkmap === false)
1688		return false;
1689	return @db_process_sql_delete ('tnetwork_map', array ('id_networkmap' => $id_networkmap, 'id_user' => $id_user));
1690}
1691
1692/**
1693 * Updates a network map.
1694 *
1695 * @param int Map id.
1696 * @param array Extra values to be set.
1697 *
1698 * @return bool True if the map was updated. False otherwise.
1699 */
1700function networkmap_update_networkmap ($id_networkmap, $values) {
1701	$networkmap = networkmap_get_networkmap ($id_networkmap);
1702	if ($networkmap === false)
1703		return false;
1704	return (db_process_sql_update ('tnetwork_map',
1705		$values,
1706		array ('id_networkmap' => $id_networkmap))) !== false;
1707}
1708
1709/**
1710 * Get different networkmaps types for creation.
1711 *
1712 * @return Array Networkmap diferent types.
1713 */
1714function networkmap_get_types ($strict_user = false) {
1715	$networkmap_types = array();
1716
1717	$is_enterprise = enterprise_include_once('include/functions_policies.php');
1718
1719	$networkmap_types['topology'] = __('Create a new topology map');
1720	$networkmap_types['groups'] = __('Create a new group map');
1721	$networkmap_types['dynamic'] = __('Create a new dynamic map');
1722	if (!$strict_user) {
1723		$networkmap_types['radial_dynamic'] = __('Create a new radial dynamic map');
1724	}
1725
1726	if (($is_enterprise !== ENTERPRISE_NOT_HOOK) && (!$strict_user)) {
1727		$enterprise_types = enterprise_hook('policies_get_networkmap_types');
1728
1729		$networkmap_types = array_merge($networkmap_types, $enterprise_types);
1730	}
1731
1732	return $networkmap_types;
1733}
1734
1735/**
1736 * Get networkmaps types.
1737 *
1738 * @return Array Networkmap diferent types.
1739 */
1740function networkmap_get_filter_types ($strict_user = false) {
1741	$networkmap_types = array();
1742
1743	$is_enterprise = enterprise_include_once('include/functions_policies.php');
1744
1745	$networkmap_types['topology'] = __('Topology');
1746	$networkmap_types['groups'] = __('Group');
1747	$networkmap_types['dynamic'] = __('Dynamic');
1748	if (!$strict_user) {
1749		$networkmap_types['radial_dynamic'] = __('Radial dynamic');
1750	}
1751
1752	if (($is_enterprise !== ENTERPRISE_NOT_HOOK) && (!$strict_user)) {
1753		$enterprise_types = enterprise_hook('policies_get_networkmap_filter_types');
1754
1755		$networkmap_types = array_merge($networkmap_types, $enterprise_types);
1756	}
1757
1758	return $networkmap_types;
1759}
1760
1761function networkmap_cidr_match($ip, $cidr_mask) {
1762	//copy from open source code
1763	// https://gist.github.com/linickx/1309388
1764
1765	$chunks = explode("/", $cidr_mask);
1766	$subnet = $chunks[0];
1767	$bits = $chunks[1];
1768
1769	$ip = ip2long($ip);
1770	$subnet = ip2long($subnet);
1771	$mask = -1 << (32 - $bits);
1772	$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
1773
1774	return ($ip & $mask) == $subnet;
1775}
1776
1777function networkmap_get_new_nodes_from_ip_mask($ip_mask, $fields = array(), $strict_user = false) {
1778	$list_ip_masks = explode(",", $ip_mask);
1779
1780	$list_address = db_get_all_rows_in_table('taddress');
1781	if (empty($address))
1782		$address = array();
1783
1784	if ($strict_user) {
1785		$filter['group_by'] = 'tagente.id_agente';
1786		$fields = array ('tagente.id_agente');
1787		$acltags = tags_get_user_module_and_tags ($config['id_user'],'AR', $strict_user);
1788		$user_agents = tags_get_all_user_agents (false, $config['id_user'], $acltags, $filter, $fields, false, $strict_user, true);
1789
1790		foreach ($all_user_agents as $agent) {
1791			$user_agents[$agent['id_agente']] = $agent['id_agente'];
1792		}
1793	}
1794
1795	$agents = array();
1796	foreach ($list_address as $address) {
1797		foreach ($list_ip_masks as $ip_mask) {
1798			if (networkmap_cidr_match($address['ip'], $ip_mask)) {
1799				$id_agent = db_get_value_filter('id_agent', 'taddress_agent', array('id_a' => $address['id_a']));
1800
1801				if (empty($fields)) {
1802					if ($strict_user) {
1803						if (array_key_exists($id_agent, $user_agents)) {
1804							$agents[] = db_get_value_filter('id_agent', 'taddress_agent', array('id_a' => $address['id_a']));
1805						}
1806					} else {
1807						$agents[] = db_get_value_filter('id_agent', 'taddress_agent', array('id_a' => $address['id_a']));
1808					}
1809
1810				}
1811				else {
1812					if ($strict_user) {
1813						if (array_key_exists($id_agent, $user_agents)) {
1814							$agents[] = db_get_row('tagente', 'id_agente', $id_agent, $fields);
1815						}
1816					} else {
1817						$agents[] = db_get_row('tagente', 'id_agente', $id_agent, $fields);
1818					}
1819				}
1820			}
1821		}
1822	}
1823
1824	return $agents;
1825}
1826
1827?>
1828<script language="javascript" type="text/javascript">
1829	$(document).ready (function () {
1830		// TODO: Implement the jquery tooltip functionality everywhere
1831		// and remove the cluetip code.
1832		$("area[title!='<?php echo 'Pandora FMS'; ?>']")
1833			.each(function (index, element) {
1834				// Store the title.
1835				// The title stores the url into a data property
1836				$(element).data('uri', $(element).prop('title'));
1837			})
1838			.tooltip({
1839				track: true,
1840				content: '<?php html_print_image("images/spinner.gif"); ?>',
1841				open: function (evt, ui) {
1842					var elem = $(this);
1843					var uri = elem.data('uri');
1844
1845					if (typeof uri != 'undefined' && uri.length > 0) {
1846						var jqXHR = $.ajax(uri).done(function(data) {
1847							elem.tooltip('option', 'content', data);
1848						});
1849						// Store the connection handler
1850						elem.data('jqXHR', jqXHR);
1851					}
1852
1853					$(".ui-tooltip>.ui-tooltip-content:not(.cluetip-default)")
1854						.addClass("cluetip-default");
1855				},
1856				close: function (evt, ui) {
1857					var elem = $(this);
1858					var jqXHR = elem.data('jqXHR');
1859
1860					// Close the connection handler
1861					if (typeof jqXHR != 'undefined')
1862						jqXHR.abort();
1863				}
1864			});
1865	});
1866</script>
1867