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) { // Default mapOptions values. // Default neato. $this->mapOptions['generation_method'] = 3; $this->mapOptions['simple'] = 0; $this->mapOptions['font_size'] = 12; $this->mapOptions['layout'] = 'spring1'; $this->mapOptions['nooverlap'] = 1; $this->mapOptions['zoom'] = 0.5; $this->mapOptions['ranksep'] = 0.5; $this->mapOptions['center'] = 0; $this->mapOptions['regen'] = 0; $this->mapOptions['pure'] = 1; $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'] = null; $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' => 0.1, 'rank_sep' => 1, 'mindist' => 1, 'kval' => 0.1, ]; if (is_array($options)) { if (isset($options['graph'])) { $this->graph = $options['graph']; } if (isset($options['nodes'])) { $this->nodes = $options['nodes']; } if (isset($options['relations'])) { $this->relations = $options['relations']; } if (isset($options['mode'])) { $this->mode = $options['mode']; } if (is_array($options['map_options'])) { foreach ($options['map_options'] as $k => $v) { $this->mapOptions[$k] = $v; } } // Load from Discovery task. 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 { 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 ($this->idMap) { $this->loadMap(); return; } if ($this->network) { $this->nodes = networkmap_get_new_nodes_from_ip_mask( $this->network ); } if ($this->idTask) { // Retrieve data from target task. $this->loadMap(); } } /** * Loads a map from a target map ID. * * @return void. */ public function loadMap() { if ($this->idMap) { $this->map = db_get_row('tmap', 'id', $this->idMap); // Retrieve or update nodes and relations. $this->getNodes(); $this->getRelations(); // Nodes and relations. $this->graph = networkmap_process_networkmap($this->idMap); } else { // Simulated map. $this->idMap = uniqid(); // No tmap definition. Paint data. if ($this->idTask) { $recon_task = db_get_row_filter( 'trecon_task', ['id_rt' => $networkmap['source_data']] ); $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' => 900, 'height' => 400, 'center_x' => 450, 'center_y' => 200, ]; $this->graph = $this->generateNetworkMap(); } } /** * 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; } /** * Generates a nodes - relationships array using graphviz dot * schema. * * @return array Node - relationship calculated. */ public function generateNetworkMap() { /* * Let graphviz place the nodes. */ switch ($this->mapOptions['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: default: $filter = 'neato'; $layout = 'spring1'; break; case 4: $filter = 'fdp'; $layout = 'spring2'; break; } $nodes_and_relations = []; // Generate dot file. $graph = networkmap_generate_dot( get_product_name(), $this->idGroup, $this->mapOptions['simple'], $this->mapOptions['font_size'], $this->mapOptions['layout'], $this->mapOptions['nooverlap'], $this->mapOptions['zoom'], $this->mapOptions['ranksep'], $this->mapOptions['center'], $this->mapOptions['regen'], $this->mapOptions['pure'], $this->mapOptions['id'], $this->mapOptions['show_snmp_modules'], $this->mapOptions['cut_names'], $this->mapOptions['relative'], $this->mapOptions['text_filter'], $this->network, $this->mapOptions['dont_show_subgroups'], // Strict user (strict_user). false, // Canvas size (size_canvas). null, $this->mapOptions['old_mode'], $this->mapOptions['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 .= '_'.$this->idMap.'.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; } $r = system($cmd); unlink($filename_dot); $nodes = networkmap_loadfile( $this->idMap, $filename_plain, $relation_nodes, $graph ); unlink($filename_plain); $id = $this->idMap; /* * Graphviz section ends here. */ /* * Calculate references. */ // 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 ($this->idMap > 0) { enterprise_hook( '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] ); } else { $this->map['center_x'] = $center['x']; $this->map['center_y'] = $center['y']; } return $nodes_and_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; } /** * Transform node information into JS data. * * @return string HTML code with JS data. */ public function loadMapData() { $networkmap = $this->map; if (!isset($networkmap['__simulated'])) { $networkmap['filter'] = json_decode( $networkmap['filter'], true ); } // Hardcoded. $networkmap['filter']['holding_area'] = [ 500, 500, ]; $this->graph['relations'] = clean_duplicate_links( $this->graph['relations'] ); // 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; } /** * 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 = ''; // 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; ui_require_css_file('networkmap'); ui_require_css_file('jquery.contextMenu', 'include/styles/js/'); $output = ''; $hide_minimap = ''; if ($dashboard_mode) { $hide_minimap = 'none'; } $networkmap = $this->map; $networkmap['filter'] = json_decode($networkmap['filter'], true); $networkmap['filter']['l2_network_interfaces'] = 1; $output .= ''; $output .= ''; $output .= ''; // Open networkconsole_id div. $output .= '