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 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 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; }
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; }
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; }
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; }