function discover_new_device_ip($host) { global $config; if (match_network($config['autodiscovery']['ip_nets'], $host)) { if (isPingable($host)) { echo "Pingable "; foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, "v2c", "161", "udp", NULL); print_message("Trying community {$community} ..."); if (isSNMPable($device)) { echo "SNMPable "; $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); if (dbFetchCell("SELECT COUNT(device_id) FROM devices WHERE sysName = ?", array($snmphost)) == '0') { $device_id = createHost($snmphost, $community, "v2c", "161", "udp"); $device = device_by_id_cache($device_id, 1); array_push($GLOBALS['devices'], $device); return $device_id; } else { echo "Already have host with sysName {$snmphost}\n"; } } } } } }
/** * Observium * * This file is part of Observium. * * @package observium * @subpackage discovery * @subpackage functions * @author Adam Armstrong <*****@*****.**> * @copyright (C) 2006-2014 Adam Armstrong * */ function discover_new_device_ip($host, $source = 'xdp', $protocol = NULL, $device = NULL, $port = NULL) { global $config; print_debug("Discovering possible new device on {$host}"); if ($config['autodiscovery'][$source]) { if (match_network($config['autodiscovery']['ip_nets'], $host)) { $db = dbFetchRow("SELECT * FROM ipv4_addresses AS A, ports AS P, devices AS D WHERE A.ipv4_address = ? AND P.port_id = A.port_id AND D.device_id = P.device_id", array($host)); if (is_array($db)) { print_debug("Already have {$host} on " . $db['hostname']); } else { if (isPingable($host)) { echo "Pingable "; foreach ($config['snmp']['community'] as $community) { $newdevice = deviceArray($host, $community, "v2c", "161", "udp", NULL); print_message("Trying community {$community} ..."); if (isSNMPable($newdevice)) { echo "SNMPable "; $snmphost = snmp_get($newdevice, "sysName.0", "-Oqv", "SNMPv2-MIB"); if (dbFetchCell("SELECT COUNT(device_id) FROM devices WHERE sysName = ?", array($snmphost)) == '0') { $device_id = createHost($snmphost, $community, "v2c", "161", "udp"); $newdevice = device_by_id_cache($device_id, 1); array_push($GLOBALS['devices'], $newdevice); if (!$protocol) { $protocol = strtoupper($source); } if ($port) { humanize_port($port); log_event("Device autodiscovered through {$protocol} on " . $device['hostname'] . " (port " . $port['label'] . ")", $remote_device_id, 'interface', $port['port_id']); } else { log_event("Device autodiscovered through {$protocol} on " . $device['hostname'], $remote_device_id); } return $device_id; } else { echo "Already have host with sysName {$snmphost}\n"; } } } } else { print_debug("IP not pingable."); } } } else { print_debug("Host does not match configured nets"); } } else { print_debug("Source {$source} disabled for autodiscovery!"); } }
function addHost($host, $snmpver, $port = '161', $transport = 'udp', $quiet = '0', $poller_group = '0', $force_add = '0') { global $config; list($hostshort) = explode(".", $host); // Test Database Exists if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($host)) == '0') { if ($config['addhost_alwayscheckip'] === TRUE) { $ip = gethostbyname($host); } else { $ip = $host; } if (ip_exists($ip) === false) { // Test reachability if ($force_add == 1 || isPingable($host)) { if (empty($snmpver)) { // Try SNMPv2c $snmpver = 'v2c'; $ret = addHost($host, $snmpver, $port, $transport, $quiet, $poller_group, $force_add); if (!$ret) { //Try SNMPv3 $snmpver = 'v3'; $ret = addHost($host, $snmpver, $port, $transport, $quiet, $poller_group, $force_add); if (!$ret) { // Try SNMPv1 $snmpver = 'v1'; return addHost($host, $snmpver, $port, $transport, $quiet, $poller_group, $force_add); } else { return $ret; } } else { return $ret; } } if ($snmpver === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $v3) { $device = deviceArray($host, NULL, $snmpver, $port, $transport, $v3); if ($quiet == '0') { print_message("Trying v3 parameters " . $v3['authname'] . "/" . $v3['authlevel'] . " ... "); } if ($force_add == 1 || isSNMPable($device)) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); if (empty($snmphost) or $snmphost == $host || ($hostshort = $host)) { $device_id = createHost($host, NULL, $snmpver, $port, $transport, $v3, $poller_group); return $device_id; } else { if ($quiet == '0') { print_error("Given hostname does not match SNMP-read hostname ({$snmphost})!"); } } } else { if ($quiet == '0') { print_error("No reply on credentials " . $v3['authname'] . "/" . $v3['authlevel'] . " using {$snmpver}"); } } } } elseif ($snmpver === "v2c" or $snmpver === "v1") { // try each community from config foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, $snmpver, $port, $transport, NULL); if ($quiet == '0') { print_message("Trying community {$community} ..."); } if ($force_add == 1 || isSNMPable($device)) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); if (empty($snmphost) || $snmphost && ($snmphost == $host || ($hostshort = $host))) { $device_id = createHost($host, $community, $snmpver, $port, $transport, array(), $poller_group); return $device_id; } else { if ($quiet == '0') { print_error("Given hostname does not match SNMP-read hostname ({$snmphost})!"); } } } else { if ($quiet == '0') { print_error("No reply on community {$community} using {$snmpver}"); } } } } else { if ($quiet == '0') { print_error("Unsupported SNMP Version \"{$snmpver}\"."); } } if (!$device_id) { // Failed SNMP if ($quiet == '0') { print_error("Could not reach {$host} with given SNMP community using {$snmpver}"); } } } else { // failed Reachability if ($quiet == '0') { print_error("Could not ping {$host}"); } } } else { if ($quiet == 0) { print_error("Already have host with this IP {$host}"); } } } else { // found in database if ($quiet == '0') { print_error("Already got host {$host}"); } } return 0; }
function add_device($hostname, $snmp_version = array(), $snmp_port = 161, $snmp_transport = 'udp', $options = array()) { global $config; // If $options['break'] set as TRUE, break recursive function execute if (isset($options['break']) && $options['break']) { return FALSE; } $return = FALSE; // By default return FALSE // Reset snmp timeout and retries options for speedup device adding unset($config['snmp']['timeout'], $config['snmp']['retries']); $hostname = trim($hostname); list($hostshort) = explode(".", $hostname); // Test if host exists in database if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($hostname)) == '0') { $snmp_transport = strtolower($snmp_transport); $try_a = !($snmp_transport == 'udp6' || $snmp_transport == 'tcp6'); // Use IPv6 only if transport 'udp6' or 'tcp6' // Test DNS lookup. $ip = gethostbyname6($hostname, $try_a); if ($ip) { $ip_version = get_ip_version($ip); // Test reachability if (isPingable($hostname, $try_a)) { // Test directory exists in /rrd/ if (!$config['rrd_override'] && file_exists($config['rrd_dir'] . '/' . $hostname)) { print_error("Directory <observium>/rrd/{$hostname} already exists."); return FALSE; } // Detect snmp transport if (stripos($snmp_transport, 'tcp') !== FALSE) { $snmp_transport = $ip_version == 4 ? 'tcp' : 'tcp6'; } else { $snmp_transport = $ip_version == 4 ? 'udp' : 'udp6'; } // Detect snmp port if (!is_numeric($snmp_port) || $snmp_port < 1 || $snmp_port > 65535) { $snmp_port = 161; } else { $snmp_port = (int) $snmp_port; } // Detect snmp version if (empty($snmp_version)) { // Here set default snmp version order $i = 1; $snmp_version_order = array(); foreach (array('v2c', 'v3', 'v1') as $tmp_version) { if ($config['snmp']['version'] == $tmp_version) { $snmp_version_order[0] = $tmp_version; } else { $snmp_version_order[$i] = $tmp_version; } $i++; } ksort($snmp_version_order); foreach ($snmp_version_order as $tmp_version) { $ret = add_device($hostname, $tmp_version, $snmp_port, $snmp_transport, $options); if ($ret === FALSE) { // Set $options['break'] for break recursive $options['break'] = TRUE; } else { if (is_numeric($ret) && $ret != 0) { return $ret; } } } } else { if ($snmp_version === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $snmp_v3) { $device = build_initial_device_array($hostname, NULL, $snmp_version, $snmp_port, $snmp_transport, $snmp_v3); print_message("Trying v3 parameters " . $device['snmp_authname'] . "/" . $device['snmp_authlevel'] . " ... "); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { if (isset($options['test']) && $options['test']) { print_message('%WDevice "' . $hostname . '" has successfully been tested and available by ' . strtoupper($snmp_transport) . ' transport with SNMP ' . $snmp_version . ' credentials.%n', 'color'); $device_id = -1; } else { $device_id = createHost($hostname, NULL, $snmp_version, $snmp_port, $snmp_transport, $snmp_v3); } return $device_id; } } else { print_warning("No reply on credentials " . $device['snmp_authname'] . "/" . $device['snmp_authlevel'] . " using {$snmp_version}."); } } } else { if ($snmp_version === "v2c" || $snmp_version === "v1") { // Try each community from config foreach ($config['snmp']['community'] as $snmp_community) { $device = build_initial_device_array($hostname, $snmp_community, $snmp_version, $snmp_port, $snmp_transport); print_message("Trying {$snmp_version} community {$snmp_community} ..."); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { if (isset($options['test']) && $options['test']) { print_message('%W设备 "' . $hostname . '" 已成功地测试和可用于 ' . strtoupper($snmp_transport) . ' transport with SNMP ' . $snmp_version . ' credentials.%n', 'color'); $device_id = -1; } else { $device_id = createHost($hostname, $snmp_community, $snmp_version, $snmp_port, $snmp_transport); } return $device_id; } } else { print_warning("No reply on community {$snmp_community} using {$snmp_version}."); $return = 0; // Return zero for continue trying next auth } } } else { print_error("Unsupported SNMP Version \"{$snmp_version}\"."); $return = 0; // Return zero for continue trying next auth } } } if (!$device_id) { // Failed SNMP print_error("无法到达主机 {$hostname} 使用给定的SNMP参数 {$snmp_version}."); $return = 0; // Return zero for continue trying next auth } } else { // failed Reachability print_error("无法 ping {$hostname}."); } } else { // Failed DNS lookup print_error("无法解析 {$hostname}."); } } else { // found in database print_error("已经发现设备 {$hostname}."); } return $return; }
function add_device($host, $snmpver = array(), $port = 161, $transport = 'udp', $error = FALSE) { global $config; // If $error set as TRUE break recursive function execute if ($error) { return FALSE; } // Reset snmp timeout and retries options for speedup device adding unset($config['snmp']['timeout'], $config['snmp']['retries']); $host = trim($host); list($hostshort) = explode(".", $host); // Test if host exists in database if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($host)) == '0') { $transport = strtolower($transport); $try_a = !($transport == 'udp6' || $transport == 'tcp6'); // Use IPv6 only if transport 'udp6' or 'tcp6' // Test DNS lookup. $ip = gethostbyname6($host, $try_a); if ($ip) { $ip_version = get_ip_version($ip); // Test reachability if (isPingable($host)) { // Test directory exists in /rrd/ if (!$config['rrd_override'] && file_exists($config['rrd_dir'] . '/' . $host)) { print_error("Directory <observium>/rrd/{$host} already exists."); return FALSE; } // Detect snmp transport if (stripos($transport, 'tcp') !== FALSE) { $transport = $ip_version == 4 ? 'tcp' : 'tcp6'; } else { $transport = $ip_version == 4 ? 'udp' : 'udp6'; } // Detect snmp port if (!is_numeric($port) || $port < 1 || $port > 65535) { $port = 161; } else { $port = (int) $port; } // Detect snmp version if (empty($snmpver)) { // Here set default snmp version order $i = 1; $snmpver_order = array(); foreach (array('v2c', 'v3', 'v1') as $snmpver) { if ($config['snmp']['version'] == $snmpver) { $snmpver_order[0] = $snmpver; } else { $snmpver_order[$i] = $snmpver; } $i++; } ksort($snmpver_order); foreach ($snmpver_order as $snmpver) { $ret = add_device($host, $snmpver, $port, $transport, $error); if ($ret === FALSE) { $error = TRUE; } elseif (is_numeric($ret) && $ret > 0) { return $ret; } } } if ($snmpver === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $v3) { $device = deviceArray($host, NULL, $snmpver, $port, $transport, $v3); print_message("Trying v3 parameters " . $v3['authname'] . "/" . $v3['authlevel'] . " ... "); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { $device_id = createHost($host, NULL, $snmpver, $port, $transport, $v3); return $device_id; } } else { print_warning("No reply on credentials " . $v3['authname'] . "/" . $v3['authlevel'] . " using {$snmpver}."); } } } elseif ($snmpver === "v2c" || $snmpver === "v1") { // Try each community from config foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, $snmpver, $port, $transport); print_message("Trying {$snmpver} community {$community} ..."); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { $device_id = createHost($host, $community, $snmpver, $port, $transport); return $device_id; } } else { print_warning("No reply on community {$community} using {$snmpver}."); } } } else { print_error("Unsupported SNMP Version \"{$snmpver}\"."); } if (!$device_id) { // Failed SNMP print_error("Could not reach {$host} with given SNMP parameters using {$snmpver}."); } } else { // failed Reachability print_error("Could not ping {$host}."); } } else { // Failed DNS lookup print_error("Could not resolve {$host}."); } } else { // found in database print_error("Already got device {$host}."); } return FALSE; }
function discover_new_device($hostname, $source = 'xdp', $protocol = NULL, $device = NULL, $snmp_port = 161) { global $config; $source = strtolower($source); // Check if source is enabled for autodiscovery if ($config['autodiscovery'][$source]) { $flags = OBS_DNS_ALL; if (!$protocol) { $protocol = strtoupper($source); } print_cli_data("Try discovering host", "{$hostname} through {$protocol}", 3); // By first detect hostname is IP or domain name (IPv4/6 == 4/6, hostname == FALSE) $ip_version = get_ip_version($hostname); if ($ip_version) { // Hostname is IPv4/IPv6 $use_ip = TRUE; $ip = $hostname; } else { $use_ip = FALSE; // Add "mydomain" configuration if this resolves, converts switch1 -> switch1.mydomain.com if (!empty($config['mydomain']) && isDomainResolves($hostname . '.' . $config['mydomain'], $flags)) { $hostname .= '.' . $config['mydomain']; } // Determine v4 vs v6 $ip = gethostbyname6($hostname, $flags); if ($ip) { $ip_version = get_ip_version($ip); print_debug("Host {$hostname} resolved as {$ip}"); } else { // No DNS records print_debug("Host {$hostname} not resolved, autodiscovery fails."); return FALSE; } } if ($ip_version == 6) { $flags = $flags ^ OBS_DNS_A; // Exclude IPv4 } if (isset($config['autodiscovery']['ping_skip']) && $config['autodiscovery']['ping_skip']) { $flags = $flags | OBS_PING_SKIP; // Add skip pings flag } if (match_network($ip, $config['autodiscovery']['ip_nets'])) { print_debug("Host {$hostname} ({$ip}) founded inside configured nets, trying to add:"); // By first check if pingable $pingable = isPingable($ip, $flags); if (!$pingable && (isset($config['autodiscovery']['ping_skip']) && $config['autodiscovery']['ping_skip'])) { $flags = $flags | OBS_PING_SKIP; // Add skip pings flag if allowed in config $pingable = TRUE; } if ($pingable) { // Check if device duplicated by IP $ip = $ip_version == 4 ? $ip : Net_IPv6::uncompress($ip, TRUE); $db = dbFetchRow('SELECT D.`hostname` FROM ipv' . $ip_version . '_addresses AS A LEFT JOIN `ports` AS P ON A.`port_id` = P.`port_id` LEFT JOIN `devices` AS D ON D.`device_id` = P.`device_id` WHERE D.`disabled` = 0 AND A.`ipv' . $ip_version . '_address` = ?', array($ip)); if ($db) { print_debug('Already have device ' . $db['hostname'] . " with IP {$ip}"); return FALSE; } // Detect snmp transport, net-snmp needs udp6 for ipv6 $snmp_transport = $ip_version == 4 ? 'udp' : 'udp6'; $new_device = detect_device_snmpauth($ip, $snmp_port, $snmp_transport); if ($new_device) { if ($use_ip) { // Detect FQDN hostname // by sysName $snmphost = snmp_get($new_device, 'sysName.0', '-Oqv', 'SNMPv2-MIB'); if ($snmphost) { $snmp_ip = gethostbyname6($snmphost, $flags); } if ($snmp_ip == $ip) { $hostname = $snmphost; } else { // by PTR $ptr = gethostbyaddr6($ip); if ($ptr) { $ptr_ip = gethostbyname6($ptr, $flags); } if ($ptr && $ptr_ip == $ip) { $hostname = $ptr; } else { if ($config['autodiscovery']['require_hostname']) { print_debug("Device IP {$ip} does not seem to have FQDN."); return FALSE; } else { $hostname = $ip_version == 4 ? $ip : Net_IPv6::compress($hostname, TRUE); // Always use compressed IPv6 name } } } print_debug("Device IP {$ip} linked to FQDN name: {$hostname}"); } $new_device['hostname'] = $hostname; if (!check_device_duplicated($new_device)) { $snmp_v3 = array(); if ($new_device['snmp_version'] === 'v3') { $snmp_v3['snmp_authlevel'] = $new_device['snmp_authlevel']; $snmp_v3['snmp_authname'] = $new_device['snmp_authname']; $snmp_v3['snmp_authpass'] = $new_device['snmp_authpass']; $snmp_v3['snmp_authalgo'] = $new_device['snmp_authalgo']; $snmp_v3['snmp_cryptopass'] = $new_device['snmp_cryptopass']; $snmp_v3['snmp_cryptoalgo'] = $new_device['snmp_cryptoalgo']; } $remote_device_id = createHost($new_device['hostname'], $new_device['snmp_community'], $new_device['snmp_version'], $new_device['snmp_port'], $new_device['snmp_transport'], $snmp_v3); if ($remote_device_id) { if (is_flag_set(OBS_PING_SKIP, $flags)) { set_entity_attrib('device', $remote_device_id, 'ping_skip', 1); } $remote_device = device_by_id_cache($remote_device_id, 1); if ($port) { humanize_port($port); log_event("Device autodiscovered through {$protocol} on " . $device['hostname'] . " (port " . $port['port_label'] . ")", $remote_device_id, 'port', $port['port_id']); } else { log_event("Device autodiscovered through {$protocol} on " . $device['hostname'], $remote_device_id, $protocol); } //array_push($GLOBALS['devices'], $remote_device); // createHost() already puth this return $remote_device_id; } } } } } else { print_debug("IP {$ip} ({$hostname}) not permitted inside \$config['autodiscovery']['ip_nets'] in config.php"); } print_debug('Autodiscovery for host ' . $hostname . ' failed.'); } else { print_debug('Autodiscovery for protocol ' . $protocol . ' disabled.'); } return FALSE; }
$no_http_headers = true; $community = "public"; #Show the host template using add_device $hosttemplate = 17; // Alcatel ISAM $hostlist = 'devices.txt'; $localdomain = "telenor.dk"; # $snmpqueryid = 48; $snmpquerytype = 19; $handle = fopen($hostlist, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { $line = chop($line); print "[" . $line . "] \n"; createHost($line); } } else { die("Could not open file {$filename}!"); } die; function createHost($dev) { global $community; global $hosttemplate; print "================== Creating DSLAM for {$dev} =======================\n"; $ret = cmd("/usr/bin/php add_device.php --quiet --description='" . $dev . "' --ip='{$dev}.{$localdomain} --template={$hosttemplate} --community='" . $community . "' --avail=snmp"); //Get host id from: [RET] Success - new device-id: (20) if (preg_match("/\\((\\d+)\\)/", $ret, $matches)) { $deviceID = $matches[1]; print "Device ID: {$deviceID} \n";
<?php header('Content-type: text/html; charset=ISO-8859-1'); // Allow access from anywhere. Can be domains or * (any) header('Access-Control-Allow-Origin: *'); // Allow these methods of data retrieval header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); // Allow these header types header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept'); include "fhost.php"; $codhost = $_GET["codhost"]; $tracking = $_GET["tracking"]; $preview = $_GET["preview"]; if (is_null($codhost)) { debugl("<h1>Informe um codigo de hostname</h1>"); exit; } else { /** * Cria o objeto de host com todos os valores possiveis. **/ $identificador = generateID(); $host = createHost($codhost); debugl("Grafico ID -> {$identificador}"); debugl("Inseridos -> " . registraGeracaoHTML($identificador, $host)); if (strcmp($preview, "true") == 0) { echo processaRelatorioHost($identificador, $host); } echo "<h2>Id Gerado: {$identificador}<h2>"; }
function addHost($host, $snmpver, $port = '161', $transport = 'udp', $quiet = '0') { global $config; list($hostshort) = explode(".", $host); // Test Database Exists if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($host)) == '0') { // Test if IP or Hostname if (!inet_pton($host)) { // Test reachability if (isPingable($host)) { $added = 0; if (empty($snmpver)) { // Try SNMPv2c $snmpver = 'v2c'; $ret = addHost($host, $snmpver); if (!$ret) { //Try SNMPv3 $snmpver = 'v3'; $ret = addHost($host, $snmpver); if (!$ret) { // Try SNMPv1 $snmpver = 'v1'; return addHost($host, $snmpver); } else { return $ret; } } else { return $ret; } } if ($snmpver === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $v3) { $device = deviceArray($host, NULL, $snmpver, $port, $transport, $v3); if ($quiet == '0') { print_message("Trying v3 parameters " . $v3['authname'] . "/" . $v3['authlevel'] . " ... "); } if (isSNMPable($device)) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); if (empty($snmphost) or $snmphost == $host || ($hostshort = $host)) { $device_id = createHost($host, NULL, $snmpver, $port, $transport, $v3); return $device_id; } else { if ($quiet == '0') { print_error("Given hostname does not match SNMP-read hostname ({$snmphost})!"); } } } else { if ($quiet == '0') { print_error("No reply on credentials " . $v3['authname'] . "/" . $v3['authlevel'] . " using {$snmpver}"); } } } } elseif ($snmpver === "v2c" or $snmpver === "v1") { // try each community from config foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, $snmpver, $port, $transport, NULL); if ($quiet == '0') { print_message("Trying community {$community} ..."); } if (isSNMPable($device)) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); if ($snmphost == "" || $snmphost && ($snmphost == $host || ($hostshort = $host))) { $device_id = createHost($host, $community, $snmpver, $port, $transport); return $device_id; } else { if ($quiet == '0') { print_error("Given hostname does not match SNMP-read hostname ({$snmphost})!"); } } } else { if ($quiet == '0') { print_error("No reply on community {$community} using {$snmpver}"); } } } } else { if ($quiet == '0') { print_error("Unsupported SNMP Version \"{$snmpver}\"."); } } if (!$device_id) { // Failed SNMP if ($quiet == '0') { print_error("Could not reach {$host} with given SNMP community using {$snmpver}"); } } } else { // failed Reachability if ($quiet == '0') { print_error("Could not ping {$host}"); } } } else { // Failed DNS lookup if ($quiet == '0') { print_error("{$host} looks like an IP address, please use FQDN"); } } } else { // found in database if ($quiet == '0') { print_error("Already got host {$host}"); } } return 0; }
function addHost($host, $community, $snmpver, $port = 161) { global $config; list($hostshort) = explode(".", $host); if (isDomainResolves($host)) { if (isPingable($host)) { if (mysql_result(mysql_query("SELECT COUNT(*) FROM `devices` WHERE `hostname` = '{$host}'"), 0) == '0') { $snmphost = shell_exec($config['snmpget'] . " -m SNMPv2-MIB -Oqv -{$snmpver} -c {$community} {$host}:{$port} sysName.0"); if ($snmphost == $host || ($hostshort = $host)) { createHost($host, $community, $snmpver, $port); } else { echo "Given hostname does not match SNMP-read hostname!\n"; } } else { echo "Already got host {$host}\n"; } } else { echo "Could not ping {$host}\n"; } } else { echo "Could not resolve {$host}\n"; } }
function add_device($host, $snmpver = array(), $port = '161', $transport = 'udp', $error = FALSE) { global $config; // If $error set as TRUE break recursive function execute if ($error) { return FALSE; } // Reset snmp timeout and retries options for speedup device adding unset($config['snmp']['timeout'], $config['snmp']['retries']); list($hostshort) = explode(".", $host); // Test if host exists in database if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($host)) == '0') { // Test DNS lookup. if (gethostbyname6($host, TRUE)) { // Test reachability if (isPingable($host)) { // Test directory exists in /rrd/ if (!$config['rrd_override'] && file_exists($config['rrd_dir'] . '/' . $host)) { print_error("目录 rrd/{$host} 已经存在."); return FALSE; } if (empty($snmpver)) { foreach (array('v2c', 'v3', 'v1') as $snmpver) { // Try SNMP v2c, v3 and v1 $ret = add_device($host, $snmpver, $port, $transport, $error); if ($ret === FALSE) { $error = TRUE; } elseif (is_numeric($ret) && $ret > 0) { return $ret; } } } if ($snmpver === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $v3) { $device = deviceArray($host, NULL, $snmpver, $port, $transport, $v3); print_message("Trying v3 parameters " . $v3['authname'] . "/" . $v3['authlevel'] . " ... "); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { $device_id = createHost($host, NULL, $snmpver, $port, $transport, $v3); return $device_id; } } else { print_warning("证书没有回应 " . $v3['authname'] . "/" . $v3['authlevel'] . " using {$snmpver}."); } } } elseif ($snmpver === "v2c" || $snmpver === "v1") { // Try each community from config foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, $snmpver, $port, $transport, NULL); print_message("尝试 {$snmpver} community {$community} ..."); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { $device_id = createHost($host, $community, $snmpver, $port, $transport); return $device_id; } } else { print_warning("Community 没有应答 {$community} 使用 {$snmpver}."); } } } else { print_error("不支持的协议版本 \"{$snmpver}\"."); } if (!$device_id) { // Failed SNMP print_error("不可到达的 {$host} 与给定 SNMP community 使用 {$snmpver}."); } } else { // failed Reachability print_error("无法 ping {$host}."); } } else { // Failed DNS lookup print_error("无法解析 {$host}."); } } else { // found in database print_error("已有设备 {$host}."); } return FALSE; }
} else { $port = 161; } if (!$snmpver) { $snmpver = "v2c"; } if (!$community) { $community = $config['community']; } list($hostshort) = explode(".", $host); if (isDomainResolves($argv[1])) { if (isPingable($argv[1])) { if (mysql_result(mysql_query("SELECT COUNT(*) FROM `devices` WHERE `hostname` = '" . mres($host) . "'"), 0) == '0') { $snmphost = trim(str_replace("\"", "", shell_exec($config['snmpget'] . " -m SNMPv2-MIB -Oqv -{$snmpver} -c {$community} {$host}:{$port} sysName.0"))); if ($snmphost && ($snmphost == $host || ($hostshort = $host))) { $return = createHost($host, $community, $snmpver, $port); if ($return) { echo $return . "\n"; } else { echo "Adding {$host} failed\n"; } } else { echo "Given hostname does not match SNMP-read hostname!\n"; } } else { echo "Already got host {$host}\n"; } } else { echo "Could not ping {$host}\n"; } } else {
function discover_new_device($hostname, $source = 'xdp', $protocol = NULL, $device = NULL, $port = 161) { global $config; $source = strtolower($source); if ($config['autodiscovery'][$source]) { if (!$protocol) { $protocol = strtoupper($source); } print_message("Discovering new host {$hostname} through {$protocol}"); // By first detect hostname is IP or domain name (IPv4/6 == 4/6, hostname == FALSE) $ip_version = get_ip_version($hostname); if ($ip_version) { // Hostname is IPv4/IPv6 $use_ip = TRUE; } else { $use_ip = FALSE; if (!empty($config['mydomain']) && isDomainResolves($hostname . '.' . $config['mydomain'])) { $hostname .= '.' . $config['mydomain']; } $ip = gethostbyname6($hostname); if ($ip) { $ip_version = get_ip_version($ip); print_debug("Host {$hostname} resolved as {$ip}"); } else { // No DNS records print_debug("Host {$hostname} not resolved, autodiscovery fails."); return FALSE; } } if (match_network($ip, $config['autodiscovery']['ip_nets'])) { print_debug("Host {$hostname} ({$ip}) founded inside configured nets, try to adding:"); if (isPingable($ip)) { // Check if device duplicated by IP $ip = $ip_version == 4 ? $hostname : Net_IPv6::uncompress($hostname, TRUE); $db = dbFetchRow('SELECT D.`hostname` FROM ipv' . $ip_version . '_addresses AS A LEFT JOIN `ports` AS P ON A.`port_id` = P.`port_id` LEFT JOIN `devices` AS D ON D.`device_id` = P.`device_id` WHERE D.`disabled` = 0 AND A.`ipv' . $ip_version . '_address` = ?', array($ip)); if ($db) { print_debug('Already have device ' . $db['hostname'] . " with {$ip}"); return FALSE; } // Detect snmp transport $transport = $ip_version == 4 ? 'udp' : 'udp6'; $new_device = detect_device_snmpauth($ip, $port, $transport); if ($new_device) { if ($use_ip) { // Detect FQDN hostname // by sysName $snmphost = snmp_get($new_device, "sysName.0", "-Oqv", "SNMPv2-MIB", mib_dirs()); if ($snmphost) { $snmp_ip = gethostbyname6($snmphost); } if ($snmp_ip == $ip) { $hostname = $snmphost; } else { // by PTR $ptr = gethostbyaddr6($ip); if ($ptr) { $ptr_ip = gethostbyname6($ptr); } if ($ptr && $ptr_ip == $ip) { $hostname = $ptr; } else { print_debug("Device IP {$ip} not have FQDN name"); return FALSE; } } print_debug("Device IP {$ip} founded FQDN name: {$hostname}"); } $new_device['hostname'] = $hostname; if (!check_device_duplicated($new_device)) { $v3 = array(); if ($new_device['snmpver'] === 'v3') { $v3['authlevel'] = $new_device['authlevel']; $v3['authname'] = $new_device['authname']; $v3['authpass'] = $new_device['authpass']; $v3['authalgo'] = $new_device['authalgo']; $v3['cryptopass'] = $new_device['cryptopass']; $v3['cryptoalgo'] = $new_device['cryptoalgo']; } $remote_device_id = createHost($new_device['hostname'], $new_device['community'], $new_device['snmpver'], $new_device['port'], $new_device['transport'], $v3); if ($remote_device_id) { $remote_device = device_by_id_cache($remote_device_id, 1); if ($port) { humanize_port($port); log_event("Device autodiscovered through {$protocol} on " . $device['hostname'] . " (port " . $port['label'] . ")", $remote_device_id, 'port', $port['port_id']); } else { log_event("Device autodiscovered through {$protocol} on " . $device['hostname'], $remote_device_id, $protocol); } //array_push($GLOBALS['devices'], $remote_device); // createHost() already puth this return $remote_device_id; } } } } } else { print_debug("IP {$ip} ({$hostname}) not permitted inside \$config['autodiscovery']['ip_nets'] in config.php"); } print_debug('Autodiscovery for host ' . $hostname . ' fails.'); } else { print_debug('Autodiscovery for protocol ' . $protocol . ' disabled.'); } return FALSE; }
/** * Add a device to LibreNMS * * @param string $host dns name or ip address * @param string $snmp_version If this is empty, try v2c,v3,v1. Otherwise, use this specific version. * @param string $port the port to connect to for snmp * @param string $transport udp or tcp * @param string $poller_group the poller group this device will belong to * @param boolean $force_add add even if the device isn't reachable * @param string $port_assoc_mode snmp field to use to determine unique ports * * @return int returns the device_id of the added device * * @throws HostExistsException This hostname already exists * @throws HostIpExistsException We already have a host with this IP * @throws HostUnreachableException We could not reach this device is some way * @throws HostUnreachablePingException We could not ping the device * @throws InvalidPortAssocModeException The given port association mode was invalid * @throws SnmpVersionUnsupportedException The given snmp version was invalid */ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $poller_group = '0', $force_add = false, $port_assoc_mode = 'ifIndex') { global $config; // Test Database Exists if (host_exists($host) === true) { throw new HostExistsException("Already have host {$host}"); } // Valid port assoc mode if (!is_valid_port_assoc_mode($port_assoc_mode)) { throw new InvalidPortAssocModeException("Invalid port association_mode '{$port_assoc_mode}'. Valid modes are: " . join(', ', get_port_assoc_modes())); } // check if we have the host by IP if ($config['addhost_alwayscheckip'] === true) { $ip = gethostbyname($host); } else { $ip = $host; } if (ip_exists($ip)) { throw new HostIpExistsException("Already have host with this IP {$host}"); } // Test reachability if (!$force_add) { $address_family = snmpTransportToAddressFamily($transport); $ping_result = isPingable($host, $address_family); if (!$ping_result['result']) { throw new HostUnreachablePingException("Could not ping {$host}"); } } // if $snmpver isn't set, try each version of snmp if (empty($snmp_version)) { $snmpvers = array('v2c', 'v3', 'v1'); } else { $snmpvers = array($snmp_version); } $host_unreachable_exception = new HostUnreachableException("Could not connect, please check the snmp details and snmp reachability"); // try different snmp variables to add the device foreach ($snmpvers as $snmpver) { if ($snmpver === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $v3) { $device = deviceArray($host, null, $snmpver, $port, $transport, $v3, $port_assoc_mode); if ($force_add === true || isSNMPable($device)) { if ($force_add !== true) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); } $result = createHost($host, null, $snmpver, $port, $transport, $v3, $poller_group, $port_assoc_mode, $snmphost, $force_add); if ($result !== false) { return $result; } } else { $host_unreachable_exception->addReason("SNMP {$snmpver}: No reply with credentials " . $v3['authname'] . "/" . $v3['authlevel']); } } } elseif ($snmpver === "v2c" || $snmpver === "v1") { // try each community from config foreach ($config['snmp']['community'] as $community) { $device = deviceArray($host, $community, $snmpver, $port, $transport, null, $port_assoc_mode); if ($force_add === true || isSNMPable($device)) { if ($force_add !== true) { $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); } $result = createHost($host, $community, $snmpver, $port, $transport, array(), $poller_group, $port_assoc_mode, $snmphost, $force_add); if ($result !== false) { return $result; } } else { $host_unreachable_exception->addReason("SNMP {$snmpver}: No reply with community {$community}"); } } } else { throw new SnmpVersionUnsupportedException("Unsupported SNMP Version \"{$snmpver}\", must be v1, v2c, or v3"); } } throw $host_unreachable_exception; }
function add_device($hostname, $snmp_version = array(), $snmp_port = 161, $snmp_transport = 'udp', $options = array(), $flags = OBS_DNS_ALL) { global $config; // If $options['break'] set as TRUE, break recursive function execute if (isset($options['break']) && $options['break']) { return FALSE; } $return = FALSE; // By default return FALSE // Reset snmp timeout and retries options for speedup device adding unset($config['snmp']['timeout'], $config['snmp']['retries']); $snmp_transport = strtolower($snmp_transport); $hostname = strtolower(trim($hostname)); // Try detect if hostname is IP switch (get_ip_version($hostname)) { case 6: $hostname = Net_IPv6::compress($hostname, TRUE); // Always use compressed IPv6 name // Always use compressed IPv6 name case 4: if ($config['require_hostname']) { print_error("Hostname should be a valid resolvable FQDN name. Or set config option \$config['require_hostname'] as FALSE."); return $return; } $ip = $hostname; break; default: if ($snmp_transport == 'udp6' || $snmp_transport == 'tcp6') { $flags = $flags ^ OBS_DNS_A; // exclude A } // Test DNS lookup. $ip = gethostbyname6($hostname, $flags); } // Test if host exists in database if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `hostname` = ?", array($hostname)) == '0') { if ($ip) { $ip_version = get_ip_version($ip); // Test reachability $options['ping_skip'] = isset($options['ping_skip']) && $options['ping_skip']; if ($options['ping_skip']) { $flags = $flags | OBS_PING_SKIP; } if (isPingable($hostname, $flags)) { // Test directory exists in /rrd/ if (!$config['rrd_override'] && file_exists($config['rrd_dir'] . '/' . $hostname)) { print_error("Directory <observium>/rrd/{$hostname} already exists."); return FALSE; } // Detect snmp transport if (stripos($snmp_transport, 'tcp') !== FALSE) { $snmp_transport = $ip_version == 4 ? 'tcp' : 'tcp6'; } else { $snmp_transport = $ip_version == 4 ? 'udp' : 'udp6'; } // Detect snmp port if (!is_numeric($snmp_port) || $snmp_port < 1 || $snmp_port > 65535) { $snmp_port = 161; } else { $snmp_port = (int) $snmp_port; } // Detect snmp version if (empty($snmp_version)) { // Here set default snmp version order $i = 1; $snmp_version_order = array(); foreach (array('v2c', 'v3', 'v1') as $tmp_version) { if ($config['snmp']['version'] == $tmp_version) { $snmp_version_order[0] = $tmp_version; } else { $snmp_version_order[$i] = $tmp_version; } $i++; } ksort($snmp_version_order); foreach ($snmp_version_order as $tmp_version) { $ret = add_device($hostname, $tmp_version, $snmp_port, $snmp_transport, $options); if ($ret === FALSE) { // Set $options['break'] for break recursive $options['break'] = TRUE; } else { if (is_numeric($ret) && $ret != 0) { return $ret; } } } } else { if ($snmp_version === "v3") { // Try each set of parameters from config foreach ($config['snmp']['v3'] as $snmp_v3) { $device = build_initial_device_array($hostname, NULL, $snmp_version, $snmp_port, $snmp_transport, $snmp_v3); print_message("Trying v3 parameters " . $device['snmp_authname'] . "/" . $device['snmp_authlevel'] . " ... "); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { if (isset($options['test']) && $options['test']) { print_message('%WDevice "' . $hostname . '" has successfully been tested and available by ' . strtoupper($snmp_transport) . ' transport with SNMP ' . $snmp_version . ' credentials.%n', 'color'); $device_id = -1; } else { $device_id = createHost($hostname, NULL, $snmp_version, $snmp_port, $snmp_transport, $snmp_v3); if ($options['ping_skip']) { set_entity_attrib('device', $device_id, 'ping_skip', 1); // Force pingable check if (isPingable($hostname, $flags ^ OBS_PING_SKIP)) { print_warning("You passed option for skip device is pingable checks, but device available by ismp echo. Check device preferences."); } } } return $device_id; } } else { print_warning("No reply on credentials " . $device['snmp_authname'] . "/" . $device['snmp_authlevel'] . " using {$snmp_version}."); } } } else { if ($snmp_version === "v2c" || $snmp_version === "v1") { // Try each community from config foreach ($config['snmp']['community'] as $snmp_community) { $device = build_initial_device_array($hostname, $snmp_community, $snmp_version, $snmp_port, $snmp_transport); print_message("Trying {$snmp_version} community {$snmp_community} ..."); if (isSNMPable($device)) { if (!check_device_duplicated($device)) { if (isset($options['test']) && $options['test']) { print_message('%WDevice "' . $hostname . '" has successfully been tested and available by ' . strtoupper($snmp_transport) . ' transport with SNMP ' . $snmp_version . ' credentials.%n', 'color'); $device_id = -1; } else { $device_id = createHost($hostname, $snmp_community, $snmp_version, $snmp_port, $snmp_transport); if ($options['ping_skip']) { set_entity_attrib('device', $device_id, 'ping_skip', 1); // Force pingable check if (isPingable($hostname, $flags ^ OBS_PING_SKIP)) { print_warning("You passed option for skip device is pingable checks, but device available by ismp echo. Check device preferences."); } } } return $device_id; } } else { print_warning("No reply on community {$snmp_community} using {$snmp_version}."); $return = 0; // Return zero for continue trying next auth } } } else { print_error("Unsupported SNMP Version \"{$snmp_version}\"."); $return = 0; // Return zero for continue trying next auth } } } if (!$device_id) { // Failed SNMP print_error("Could not reach {$hostname} with given SNMP parameters using {$snmp_version}."); $return = 0; // Return zero for continue trying next auth } } else { // failed Reachability print_error("Could not ping {$hostname}."); } } else { // Failed DNS lookup print_error("Could not resolve {$hostname}."); } } else { // found in database print_error("Already got device {$hostname}."); } return $return; }
function discover_new_device($hostname, $source = 'xdp', $protocol = NULL, $device = NULL, $snmp_port = 161) { global $config; $source = strtolower($source); if ($config['autodiscovery'][$source]) { if (!$protocol) { $protocol = strtoupper($source); } print_message("发现新主机 {$hostname} 通过 {$protocol}"); // By first detect hostname is IP or domain name (IPv4/6 == 4/6, hostname == FALSE) $ip_version = get_ip_version($hostname); if ($ip_version) { // Hostname is IPv4/IPv6 $use_ip = TRUE; $ip = $hostname; } else { $use_ip = FALSE; if (!empty($config['mydomain']) && isDomainResolves($hostname . '.' . $config['mydomain'])) { $hostname .= '.' . $config['mydomain']; } $ip = gethostbyname6($hostname); if ($ip) { $ip_version = get_ip_version($ip); print_debug("主机 {$hostname} 解析为 {$ip}"); } else { // No DNS records print_debug("主机 {$hostname} 无法解析, 自动发现失败."); return FALSE; } } if (match_network($ip, $config['autodiscovery']['ip_nets'])) { print_debug("主机 {$hostname} ({$ip}) 内部网络创建配置, 尝试增加:"); if (isPingable($ip)) { // Check if device duplicated by IP $ip = $ip_version == 4 ? $ip : Net_IPv6::uncompress($ip, TRUE); $db = dbFetchRow('SELECT D.`hostname` FROM ipv' . $ip_version . '_addresses AS A LEFT JOIN `ports` AS P ON A.`port_id` = P.`port_id` LEFT JOIN `devices` AS D ON D.`device_id` = P.`device_id` WHERE D.`disabled` = 0 AND A.`ipv' . $ip_version . '_address` = ?', array($ip)); if ($db) { print_debug('已经有设备 ' . $db['hostname'] . " 包含 {$ip}"); return FALSE; } // Detect snmp transport $snmp_transport = $ip_version == 4 ? 'udp' : 'udp6'; $new_device = detect_device_snmpauth($ip, $snmp_port, $snmp_transport); if ($new_device) { if ($use_ip) { // Detect FQDN hostname // by sysName $snmphost = snmp_get($new_device, "sysName.0", "-Oqv", "SNMPv2-MIB", mib_dirs()); if ($snmphost) { $snmp_ip = gethostbyname6($snmphost); } if ($snmp_ip == $ip) { $hostname = $snmphost; } else { // by PTR $ptr = gethostbyaddr6($ip); if ($ptr) { $ptr_ip = gethostbyname6($ptr); } if ($ptr && $ptr_ip == $ip) { $hostname = $ptr; } else { print_debug("设备 IP {$ip} 没有 FQDN 名称"); return FALSE; } } print_debug("设备 IP {$ip} 发现 FQDN 名称: {$hostname}"); } $new_device['hostname'] = $hostname; if (!check_device_duplicated($new_device)) { $snmp_v3 = array(); if ($new_device['snmp_version'] === 'v3') { $snmp_v3['snmp_authlevel'] = $new_device['snmp_authlevel']; $snmp_v3['snmp_authname'] = $new_device['snmp_authname']; $snmp_v3['snmp_authpass'] = $new_device['snmp_authpass']; $snmp_v3['snmp_authalgo'] = $new_device['snmp_authalgo']; $snmp_v3['snmp_cryptopass'] = $new_device['snmp_cryptopass']; $snmp_v3['snmp_cryptoalgo'] = $new_device['snmp_cryptoalgo']; } $remote_device_id = createHost($new_device['hostname'], $new_device['snmp_community'], $new_device['snmp_version'], $new_device['snmp_port'], $new_device['snmp_transport'], $snmp_v3); if ($remote_device_id) { $remote_device = device_by_id_cache($remote_device_id, 1); if ($port) { humanize_port($port); log_event("设备自动发现通过 {$protocol} 在 " . $device['hostname'] . " (port " . $port['label'] . ")", $remote_device_id, 'port', $port['port_id']); } else { log_event("设备自动发现通过 {$protocol} 在 " . $device['hostname'], $remote_device_id, $protocol); } //array_push($GLOBALS['devices'], $remote_device); // createHost() already puth this return $remote_device_id; } } } } } else { print_debug("IP {$ip} ({$hostname}) 不允许内部 \$config['autodiscovery']['ip_nets'] 位于 config.php"); } print_debug('自动发现主机 ' . $hostname . ' 错误.'); } else { print_debug('自动发现协议 ' . $protocol . ' 禁用.'); } return FALSE; }