コード例 #1
0
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";
                    }
                }
            }
        }
    }
}
コード例 #2
0
ファイル: snmp-scan.php プロジェクト: Tatermen/librenms
function perform_snmp_scan($net)
{
    global $stats, $config, $debug, $vdebug;
    echo 'Range: ' . $net->network . '/' . $net->bitmask . PHP_EOL;
    $config['snmp']['timeout'] = 1;
    $config['snmp']['retries'] = 0;
    $config['fping_options']['retries'] = 0;
    $start = ip2long($net->network);
    $end = ip2long($net->broadcast) - 1;
    while ($start++ < $end) {
        $stats['count']++;
        $host = long2ip($start);
        if (match_network($config['autodiscovery']['nets-exclude'], $host)) {
            echo '|';
            continue;
        }
        $test = isPingable($host);
        if ($test['result'] === false) {
            echo '.';
            continue;
        }
        if (ip_exists($host)) {
            $stats['known']++;
            echo '*';
            continue;
        }
        foreach (array('udp', 'tcp') as $transport) {
            try {
                addHost(gethostbyaddr($host), '', $config['snmp']['port'], $transport, $config['distributed_poller_group']);
                $stats['added']++;
                echo '+';
                break;
            } catch (HostExistsException $e) {
                $stats['known']++;
                echo '*';
                break;
            } catch (HostUnreachablePingException $e) {
                echo '.';
                break;
            } catch (HostUnreachableException $e) {
                if ($debug) {
                    print_error($e->getMessage() . " over {$transport}");
                    foreach ($e->getReasons() as $reason) {
                        echo "  {$reason}\n";
                    }
                }
                if ($transport == 'tcp') {
                    // tried both udp and tcp without success
                    $stats['failed']++;
                    echo '-';
                }
            }
        }
    }
    echo PHP_EOL;
}
コード例 #3
0
/**
 * 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!");
    }
}
コード例 #4
0
ファイル: snmp-scan.php プロジェクト: samyscoub/librenms
function perform_snmp_scan($net)
{
    global $stats, $config, $quiet;
    echo 'Range: ' . $net->network . '/' . $net->bitmask . PHP_EOL;
    $config['snmp']['timeout'] = 1;
    $config['snmp']['retries'] = 0;
    $config['fping_options']['retries'] = 0;
    $start = ip2long($net->network);
    $end = ip2long($net->broadcast) - 1;
    while ($start++ < $end) {
        $stats['count']++;
        $device_id = false;
        $host = long2ip($start);
        $test = isPingable($host);
        if ($test['result'] === false) {
            echo '.';
            continue;
        }
        if (ip_exists($host)) {
            $stats['known']++;
            echo '*';
            continue;
        }
        foreach (array('udp', 'tcp') as $transport) {
            if ($device_id !== false && $device_id > 0) {
                $stats['added']++;
                echo '+';
            } else {
                if ($device_id === 0) {
                    $stats['failed']++;
                    echo '-';
                    break;
                }
            }
            $device_id = addHost(gethostbyaddr($host), '', $config['snmp']['port'], $transport, $quiet, $config['distributed_poller_group'], 0);
        }
    }
    echo PHP_EOL;
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: functions.inc.php プロジェクト: jcbailey2/librenms
function poll_device($device, $options)
{
    global $config, $device, $polled_devices, $db_stats, $memcache;
    $attribs = get_dev_attribs($device['device_id']);
    $status = 0;
    unset($array);
    $device_start = utime();
    // Start counting device poll time
    echo $device['hostname'] . ' ' . $device['device_id'] . ' ' . $device['os'] . ' ';
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        echo '(' . $device['os_group'] . ')';
    }
    echo "\n";
    unset($poll_update);
    unset($poll_update_query);
    unset($poll_separator);
    $poll_update_array = array();
    $update_array = array();
    $host_rrd = $config['rrd_dir'] . '/' . $device['hostname'];
    if (!is_dir($host_rrd)) {
        mkdir($host_rrd);
        echo "Created directory : {$host_rrd}\n";
    }
    $address_family = snmpTransportToAddressFamily($device['transport']);
    $ping_response = isPingable($device['hostname'], $address_family, $attribs);
    $device_perf = $ping_response['db'];
    $device_perf['device_id'] = $device['device_id'];
    $device_perf['timestamp'] = array('NOW()');
    if (can_ping_device($attribs) === true && is_array($device_perf)) {
        dbInsert($device_perf, 'device_perf');
    }
    $device['pingable'] = $ping_response['result'];
    $ping_time = $ping_response['last_ping_timetaken'];
    $response = array();
    $status_reason = '';
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $status = '1';
            $response['status_reason'] = '';
        } else {
            echo 'SNMP Unreachable';
            $status = '0';
            $response['status_reason'] = 'snmp';
        }
    } else {
        echo 'Unpingable';
        $status = '0';
        $response['status_reason'] = 'icmp';
    }
    if ($device['status'] != $status) {
        $poll_update .= $poll_separator . "`status` = '{$status}'";
        $poll_separator = ', ';
        dbUpdate(array('status' => $status, 'status_reason' => $response['status_reason']), 'devices', 'device_id=?', array($device['device_id']));
        dbInsert(array('importance' => '0', 'device_id' => $device['device_id'], 'message' => 'Device is ' . ($status == '1' ? 'up' : 'down')), 'alerts');
        log_event('Device status changed to ' . ($status == '1' ? 'Up' : 'Down'), $device, $status == '1' ? 'up' : 'down');
    }
    if ($status == '1') {
        $graphs = array();
        $oldgraphs = array();
        if ($options['m']) {
            foreach (explode(',', $options['m']) as $module) {
                if (is_file('includes/polling/' . $module . '.inc.php')) {
                    include 'includes/polling/' . $module . '.inc.php';
                }
            }
        } else {
            foreach ($config['poller_modules'] as $module => $module_status) {
                if ($attribs['poll_' . $module] || $module_status && !isset($attribs['poll_' . $module])) {
                    // TODO per-module polling stats
                    include 'includes/polling/' . $module . '.inc.php';
                } else {
                    if (isset($attribs['poll_' . $module]) && $attribs['poll_' . $module] == '0') {
                        echo "Module [ {$module} ] disabled on host.\n";
                    } else {
                        echo "Module [ {$module} ] disabled globally.\n";
                    }
                }
            }
        }
        //end if
        if (!$options['m']) {
            // FIXME EVENTLOGGING -- MAKE IT SO WE DO THIS PER-MODULE?
            // This code cycles through the graphs already known in the database and the ones we've defined as being polled here
            // If there any don't match, they're added/deleted from the database.
            // Ideally we should hold graphs for xx days/weeks/polls so that we don't needlessly hide information.
            foreach (dbFetch('SELECT `graph` FROM `device_graphs` WHERE `device_id` = ?', array($device['device_id'])) as $graph) {
                if (isset($graphs[$graph['graph']])) {
                    $oldgraphs[$graph['graph']] = true;
                } else {
                    dbDelete('device_graphs', '`device_id` = ? AND `graph` = ?', array($device['device_id'], $graph['graph']));
                }
            }
            foreach ($graphs as $graph => $value) {
                if (!isset($oldgraphs[$graph])) {
                    echo '+';
                    dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph), 'device_graphs');
                }
                echo $graph . ' ';
            }
        }
        //end if
        $device_end = utime();
        $device_run = $device_end - $device_start;
        $device_time = substr($device_run, 0, 5);
        // TODO: These should be easy converts to rrd_create_update()
        // Poller performance rrd
        $poller_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/poller-perf.rrd';
        if (!is_file($poller_rrd)) {
            rrdtool_create($poller_rrd, 'DS:poller:GAUGE:600:0:U ' . $config['rrd_rra']);
        }
        if (!empty($device_time)) {
            $fields = array('poller' => $device_time);
            rrdtool_update($poller_rrd, $fields);
        }
        // Ping response rrd
        if (can_ping_device($attribs) === true) {
            $ping_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/ping-perf.rrd';
            if (!is_file($ping_rrd)) {
                rrdtool_create($ping_rrd, 'DS:ping:GAUGE:600:0:65535 ' . $config['rrd_rra']);
            }
            if (!empty($ping_time)) {
                $fields = array('ping' => $ping_time);
                rrdtool_update($ping_rrd, $fields);
            }
            $update_array['last_ping'] = array('NOW()');
            $update_array['last_ping_timetaken'] = $ping_time;
        }
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        // echo("$device_end - $device_start; $device_time $device_run");
        echo "Polled in {$device_time} seconds\n";
        d_echo('Updating ' . $device['hostname'] . "\n");
        d_echo($update_array);
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            echo "UPDATED!\n";
        }
        unset($storage_cache);
        // Clear cache of hrStorage ** MAYBE FIXME? **
        unset($cache);
        // Clear cache (unify all things here?)
    }
    //end if
}
コード例 #7
0
ファイル: functions.inc.php プロジェクト: skive/observium
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;
}
コード例 #8
0
ファイル: functions.inc.php プロジェクト: Natolumin/observium
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;
}
コード例 #9
0
ファイル: functions.inc.php プロジェクト: Natolumin/observium
function poll_device($device, $options)
{
    global $config, $device, $polled_devices, $db_stats, $exec_status, $alert_rules, $alert_table, $graphs, $attribs;
    $alert_metrics = array();
    $oid_cache = array();
    $old_device_state = unserialize($device['device_state']);
    $attribs = get_entity_attribs('device', $device['device_id']);
    $pid_info = check_process_run($device);
    // This just clear stalled DB entries
    add_process_info($device);
    // Store process info
    $alert_rules = cache_alert_rules();
    $alert_table = cache_device_alert_table($device['device_id']);
    if (OBS_DEBUG > 1 && (count($alert_rules) || count($alert_table))) {
        print_vars($alert_rules);
        print_vars($alert_table);
    }
    $status = 0;
    $device_start = utime();
    // Start counting device poll time
    print_cli_heading($device['hostname'] . " [" . $device['device_id'] . "]", 1);
    print_cli_data("OS", $device['os'], 1);
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        print_cli_data("OS Group", $device['os_group'], 1);
    }
    if (is_numeric($device['last_polled_timetaken'])) {
        print_cli_data("Last poll duration", $device['last_polled_timetaken'] . " seconds", 1);
    }
    print_cli_data("Last Polled", $device['last_polled'], 1);
    print_cli_data("SNMP Version", $device['snmp_version'], 1);
    //unset($poll_update); unset($poll_update_query); unset($poll_separator);
    $update_array = array();
    $host_rrd_dir = $config['rrd_dir'] . "/" . $device['hostname'];
    if (!is_dir($host_rrd_dir)) {
        mkdir($host_rrd_dir);
        echo "Created directory : {$host_rrd_dir}\n";
    }
    $flags = OBS_DNS_ALL;
    if ($device['snmp_transport'] == 'udp6' || $device['snmp_transport'] == 'tcp6') {
        $flags = $flags ^ OBS_DNS_A;
    }
    $attribs['ping_skip'] = isset($attribs['ping_skip']) && $attribs['ping_skip'];
    if ($attribs['ping_skip']) {
        $flags = $flags | OBS_PING_SKIP;
        // Add skip ping flag
    }
    $device['pingable'] = isPingable($device['hostname'], $flags);
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $ping_msg = $attribs['ping_skip'] ? '' : 'PING (' . $device['pingable'] . 'ms) and ';
            print_cli_data("Device status", "Device is reachable by " . $ping_msg . "SNMP (" . $device['snmpable'] . "ms)", 1);
            $status = "1";
            $status_type = '';
        } else {
            print_cli_data("Device status", "Device is not responding to SNMP requests", 1);
            $status = "0";
            $status_type = 'snmp';
        }
    } else {
        print_cli_data("Device status", "Device is not responding to PINGs", 1);
        $status = "0";
        $status_type = 'ping';
    }
    if ($device['status'] != $status) {
        dbUpdate(array('status' => $status), 'devices', 'device_id = ?', array($device['device_id']));
        // dbInsert(array('importance' => '0', 'device_id' => $device['device_id'], 'message' => "Device is " .($status == '1' ? 'up' : 'down')), 'alerts');
        $event_msg = 'Device status changed to ';
        if ($status == '1') {
            // Device Up, Severity Warning (4)
            $event_msg .= 'Up';
            $event_severity = 4;
        } else {
            // Device Down, Severity Error (3)!
            $event_msg .= 'Down';
            $event_severity = 3;
        }
        if ($status_type != '') {
            $event_msg .= ' (' . $status_type . ')';
        }
        log_event($event_msg, $device, 'device', $device['device_id'], $event_severity);
    }
    rrdtool_update_ng($device, 'status', array('status' => $status));
    if (!$attribs['ping_skip']) {
        // Ping response RRD database.
        rrdtool_update_ng($device, 'ping', array('ping' => $device['pingable'] ? $device['pingable'] : 'U'));
    }
    // SNMP response RRD database.
    rrdtool_update_ng($device, 'ping_snmp', array('ping_snmp' => $device['snmpable'] ? $device['snmpable'] : 'U'));
    $alert_metrics['device_status'] = $status;
    $alert_metrics['device_status_type'] = $status_type;
    $alert_metrics['device_ping'] = $device['pingable'];
    // FIXME, when ping skipped, here always 0.001
    $alert_metrics['device_snmp'] = $device['snmpable'];
    if ($status == "1") {
        // Arrays for store and check enabled/disabled graphs
        $graphs = array();
        $graphs_db = array();
        foreach (dbFetchRows("SELECT * FROM `device_graphs` WHERE `device_id` = ?", array($device['device_id'])) as $entry) {
            $graphs_db[$entry['graph']] = isset($entry['enabled']) ? (bool) $entry['enabled'] : TRUE;
        }
        if (!$attribs['ping_skip']) {
            // Enable Ping graphs
            $graphs['ping'] = TRUE;
        }
        // Enable SNMP graphs
        $graphs['ping_snmp'] = TRUE;
        // Run these base modules always and before all other modules!
        $poll_modules = array('system', 'os');
        $mods_disabled_global = array();
        $mods_disabled_device = array();
        $mods_excluded = array();
        if ($options['m']) {
            foreach (explode(',', $options['m']) as $module) {
                $module = trim($module);
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($module == 'unix-agent') {
                    array_unshift($poll_modules, $module);
                    // Add 'unix-agent' before all
                    continue;
                }
                if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                    $poll_modules[] = $module;
                }
            }
        } else {
            foreach ($config['poller_modules'] as $module => $module_status) {
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($attribs['poll_' . $module] || $module_status && !isset($attribs['poll_' . $module])) {
                    if (poller_module_excluded($device, $module)) {
                        $mods_excluded[] = $module;
                        //print_warning("Module [ $module ] excluded for device.");
                        continue;
                    }
                    if ($module == 'unix-agent') {
                        array_unshift($poll_modules, $module);
                        // Add 'unix-agent' before all
                        continue;
                    }
                    if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                        $poll_modules[] = $module;
                    }
                } elseif (isset($attribs['poll_' . $module]) && !$attribs['poll_' . $module]) {
                    $mods_disabled_device[] = $module;
                    //print_warning("Module [ $module ] disabled on device.");
                } else {
                    $mods_disabled_global[] = $module;
                    //print_warning("Module [ $module ] disabled globally.");
                }
            }
        }
        if (count($mods_excluded)) {
            print_cli_data("Modules Excluded", implode(", ", $mods_excluded), 1);
        }
        if (count($mods_disabled_global)) {
            print_cli_data("Disabled Globally", implode(", ", $mods_disabled_global), 1);
        }
        if (count($mods_disabled_device)) {
            print_cli_data("Disabled Device", implode(", ", $mods_disabled_global), 1);
        }
        if (count($poll_modules)) {
            print_cli_data("Modules Enabled", implode(", ", $poll_modules), 1);
        }
        echo PHP_EOL;
        foreach ($poll_modules as $module) {
            print_debug(PHP_EOL . "including: includes/polling/{$module}.inc.php");
            print_cli_heading("Module Start: %R" . $module . "");
            $m_start = utime();
            include $config['install_dir'] . "/includes/polling/{$module}.inc.php";
            $m_end = utime();
            $m_run = round($m_end - $m_start, 4);
            $device_state['poller_mod_perf'][$module] = $m_run;
            print_cli_data("Module time", number_format($m_run, 4) . "s");
            echo PHP_EOL;
        }
        print_cli_heading($device['hostname'] . " [" . $device['device_id'] . "] completed poller modules at " . date("Y-m-d H:i:s"), 1);
        // Check and update graphs DB
        $graphs_stat = array();
        if (!isset($options['m'])) {
            // Hardcoded poller performance
            $graphs['poller_perf'] = TRUE;
            // Delete not exists graphs from DB (only if poller run without modules option)
            foreach ($graphs_db as $graph => $value) {
                if (!isset($graphs[$graph])) {
                    dbDelete('device_graphs', "`device_id` = ? AND `graph` = ?", array($device['device_id'], $graph));
                    unset($graphs_db[$graph]);
                    $graphs_stat['deleted'][] = $graph;
                }
            }
        }
        // Add or update graphs in DB
        foreach ($graphs as $graph => $value) {
            if (!isset($graphs_db[$graph])) {
                dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph, 'enabled' => $value), 'device_graphs');
                $graphs_stat['added'][] = $graph;
            } else {
                if ($value != $graphs_db[$graph]) {
                    dbUpdate(array('enabled' => $value), 'device_graphs', '`device_id` = ? AND `graph` = ?', array($device['device_id'], $graph));
                    $graphs_stat['updated'][] = $graph;
                } else {
                    $graphs_stat['checked'][] = $graph;
                }
            }
        }
        // Print graphs stats
        foreach ($graphs_stat as $key => $stat) {
            if (count($stat)) {
                print_cli_data('Graphs [' . $key . ']', implode(', ', $stat), 1);
            }
        }
        $device_end = utime();
        $device_run = $device_end - $device_start;
        $device_time = round($device_run, 4);
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        $update_array['device_state'] = serialize($device_state);
        #echo("$device_end - $device_start; $device_time $device_run");
        print_cli_data("Poller time", $device_time . " seconds", 1);
        //print_message(PHP_EOL."Polled in $device_time seconds");
        // Only store performance data if we're not doing a single-module poll
        if (!$options['m']) {
            dbInsert(array('device_id' => $device['device_id'], 'operation' => 'poll', 'start' => $device_start, 'duration' => $device_run), 'devices_perftimes');
            rrdtool_update_ng($device, 'perf-poller', array('val' => $device_time));
        }
        if (OBS_DEBUG) {
            echo "Updating " . $device['hostname'] . " - ";
            print_vars($update_array);
            echo " \n";
        }
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            print_cli_data("Updated Data", implode(", ", array_keys($update_array)), 1);
        }
        $alert_metrics['device_uptime'] = $device['uptime'];
        $alert_metrics['device_rebooted'] = $rebooted;
        // 0 - not rebooted, 1 - rebooted
        $alert_metrics['device_duration_poll'] = $device['last_polled_timetaken'];
        unset($cache_storage);
        // Clear cache of hrStorage ** MAYBE FIXME? ** (ok, later)
        unset($cache);
        // Clear cache (unify all things here?)
    }
    check_entity('device', $device, $alert_metrics);
    echo PHP_EOL;
    // Clean
    del_process_info($device);
    // Remove process info
    unset($alert_metrics);
}
コード例 #10
0
ファイル: functions.inc.php プロジェクト: Natolumin/observium
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;
}
コード例 #11
0
function poll_device($device, $options)
{
    global $config, $debug, $device, $polled_devices, $db_stats, $memcache, $exec_status, $alert_rules, $alert_table;
    $oid_cache = array();
    $old_device_state = unserialize($device['device_state']);
    $attribs = get_dev_attribs($device['device_id']);
    $alert_rules = cache_alert_rules();
    $alert_table = cache_device_alert_table($device['device_id']);
    if ($debug && (count($alert_rules) || count($alert_table))) {
        print_vars($alert_rules);
        print_vars($alert_table);
    }
    $status = 0;
    unset($array);
    $device_start = utime();
    // Start counting device poll time
    echo $device['hostname'] . " " . $device['device_id'] . " " . $device['os'] . " ";
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        echo "(" . $device['os_group'] . ")";
    }
    echo "\n";
    unset($poll_update);
    unset($poll_update_query);
    unset($poll_separator);
    $poll_update_array = array();
    $host_rrd = $config['rrd_dir'] . "/" . $device['hostname'];
    if (!is_dir($host_rrd)) {
        mkdir($host_rrd);
        echo "Created directory : {$host_rrd}\n";
    }
    $device['pingable'] = isPingable($device['hostname']);
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $status = "1";
            $status_type = '';
        } else {
            echo "SNMP Unreachable";
            $status = "0";
            $status_type = ' (snmp)';
        }
    } else {
        echo "Unpingable";
        $status = "0";
        $status_type = ' (ping)';
    }
    if ($device['status'] != $status) {
        $poll_update .= $poll_separator . "`status` = '{$status}'";
        $poll_separator = ", ";
        dbUpdate(array('status' => $status), 'devices', 'device_id=?', array($device['device_id']));
        dbInsert(array('importance' => '0', 'device_id' => $device['device_id'], 'message' => "Device is " . ($status == '1' ? 'up' : 'down')), 'alerts');
        log_event('Device status changed to ' . ($status == '1' ? 'Up' : 'Down') . $status_type, $device, 'system');
        notify($device, "Device " . ($status == '1' ? 'Up' : 'Down') . ": " . $device['hostname'] . $status_type, "Device " . ($status == '1' ? 'up' : 'down') . ": " . $device['hostname']);
    }
    $rrd = $config['rrd_dir'] . "/" . $device['hostname'] . "/status.rrd";
    if (!is_file($rrd)) {
        rrdtool_create($rrd, "DS:status:GAUGE:600:0:1 ");
    }
    if ($status == "1" || $status == "0") {
        rrdtool_update($rrd, "N:" . $status);
    } else {
        rrdtool_update($rrd, "N:U");
    }
    // Ping response RRD database.
    $ping_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/ping.rrd';
    if (!is_file($ping_rrd)) {
        rrdtool_create($ping_rrd, "DS:ping:GAUGE:600:0:65535 ");
    }
    if ($device['pingable']) {
        rrdtool_update($ping_rrd, "N:" . $device['pingable']);
    } else {
        rrdtool_update($ping_rrd, "N:U");
    }
    // SNMP response RRD database.
    $ping_snmp_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/ping_snmp.rrd';
    if (!is_file($ping_snmp_rrd)) {
        rrdtool_create($ping_snmp_rrd, "DS:ping_snmp:GAUGE:600:0:65535 ");
    }
    if ($device['snmpable']) {
        rrdtool_update($ping_snmp_rrd, "N:" . $device['snmpable']);
    } else {
        rrdtool_update($ping_snmp_rrd, "N:U");
    }
    if ($status == "1") {
        $graphs = array();
        $oldgraphs = array();
        // Enable Ping graphs
        $graphs['ping'] = TRUE;
        // Enable SNMP graphs
        $graphs['ping_snmp'] = TRUE;
        // Run this base modules always and before all other modules!
        $poll_modules = array('system', 'os');
        if ($options['m']) {
            foreach (explode(',', $options['m']) as $module) {
                $module = trim($module);
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($module == 'unix-agent') {
                    array_unshift($poll_modules, $module);
                    // Add 'unix-agent' before all
                    continue;
                }
                if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                    $poll_modules[] = $module;
                }
            }
        } else {
            foreach ($config['poller_modules'] as $module => $module_status) {
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($attribs['poll_' . $module] || $module_status && !isset($attribs['poll_' . $module])) {
                    if (poller_module_excluded($device, $module)) {
                        print_warning("Module [ {$module} ] excluded for device.");
                        continue;
                    }
                    if ($module == 'unix-agent') {
                        array_unshift($poll_modules, $module);
                        // Add 'unix-agent' before all
                        continue;
                    }
                    if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                        $poll_modules[] = $module;
                    }
                } elseif (isset($attribs['poll_' . $module]) && !$attribs['poll_' . $module]) {
                    print_warning("Module [ {$module} ] disabled on device.");
                } else {
                    print_warning("Module [ {$module} ] disabled globally.");
                }
            }
        }
        foreach ($poll_modules as $module) {
            print_debug(PHP_EOL . "including: includes/polling/{$module}.inc.php");
            $m_start = utime();
            include $config['install_dir'] . "/includes/polling/{$module}.inc.php";
            $m_end = utime();
            $m_run = round($m_end - $m_start, 4);
            $device_state['poller_mod_perf'][$module] = number_format($m_run, 4);
            print_message("Module time: {$m_run}" . "s");
        }
        // Fields to notify about in event log - FIXME should move to definitions?
        $update_fields = array('version', 'features', 'hardware', 'serial', 'kernel', 'distro', 'distro_ver', 'arch', 'asset_tag', 'icon');
        // Log changed variables
        foreach ($update_fields as $field) {
            if (isset(${$field}) && ${$field} != $device[$field]) {
                $update_array[$field] = ${$field};
                log_event(ucfirst($field) . " -> " . $update_array[$field], $device, 'system');
            }
        }
        if (!isset($options['m'])) {
            // FIXME EVENTLOGGING -- MAKE IT SO WE DO THIS PER-MODULE?
            // This code cycles through the graphs already known in the database and the ones we've defined as being polled here
            // If there any don't match, they're added/deleted from the database.
            // Ideally we should hold graphs for xx days/weeks/polls so that we don't needlessly hide information.
            // Hardcoded poller performance
            $graphs['poller_perf'] = TRUE;
            foreach (dbFetch("SELECT `graph` FROM `device_graphs` WHERE `device_id` = ?", array($device['device_id'])) as $graph) {
                if (!isset($graphs[$graph["graph"]])) {
                    dbDelete('device_graphs', "`device_id` = ? AND `graph` = ?", array($device['device_id'], $graph["graph"]));
                } else {
                    $oldgraphs[$graph["graph"]] = TRUE;
                }
            }
            foreach ($graphs as $graph => $value) {
                if (!isset($oldgraphs[$graph])) {
                    echo "+";
                    dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph), 'device_graphs');
                }
                echo $graph . " ";
            }
        }
        $device_end = utime();
        $device_run = $device_end - $device_start;
        $device_time = round($device_run, 4);
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        $update_array['device_state'] = serialize($device_state);
        #echo("$device_end - $device_start; $device_time $device_run");
        echo "Polled in {$device_time} seconds\n";
        // Only store performance data if we're not doing a single-module poll
        if (!$options['m']) {
            dbInsert(array('device_id' => $device['device_id'], 'operation' => 'poll', 'start' => $device_start, 'duration' => $device_run), 'devices_perftimes');
            $poller_rrd = $config['rrd_dir'] . "/" . $device['hostname'] . "/perf-poller.rrd";
            if (!is_file($poller_rrd)) {
                rrdtool_create($poller_rrd, "DS:val:GAUGE:600:0:38400 ");
            }
            rrdtool_update($poller_rrd, "N:" . $device_time);
        }
        if ($debug) {
            echo "Updating " . $device['hostname'] . " - ";
            print_vars($update_array);
            echo " \n";
        }
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            echo "UPDATED!\n";
        }
        unset($cache_storage);
        // Clear cache of hrStorage ** MAYBE FIXME? ** (ok, later)
        unset($cache);
        // Clear cache (unify all things here?)
    }
}
コード例 #12
0
function poll_device($device, $options)
{
    global $config, $device, $polled_devices, $db_stats, $memcache, $exec_status, $alert_rules, $alert_table, $graphs, $attribs;
    $alert_metrics = array();
    $oid_cache = array();
    $old_device_state = unserialize($device['device_state']);
    $attribs = get_dev_attribs($device['device_id']);
    $alert_rules = cache_alert_rules();
    $alert_table = cache_device_alert_table($device['device_id']);
    if (OBS_DEBUG > 1 && (count($alert_rules) || count($alert_table))) {
        print_vars($alert_rules);
        print_vars($alert_table);
    }
    $status = 0;
    unset($array);
    $device_start = utime();
    // Start counting device poll time
    echo $device['hostname'] . " " . $device['device_id'] . " " . $device['os'] . " ";
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        echo "(" . $device['os_group'] . ")";
    }
    echo "\n";
    unset($poll_update);
    unset($poll_update_query);
    unset($poll_separator);
    $poll_update_array = array();
    $host_rrd_dir = $config['rrd_dir'] . "/" . $device['hostname'];
    if (!is_dir($host_rrd_dir)) {
        mkdir($host_rrd_dir);
        echo "创建的目录 : {$host_rrd_dir}\n";
    }
    $try_a = !($device['snmp_transport'] == 'udp6' || $device['snmp_transport'] == 'tcp6');
    // Use IPv6 only if transport 'udp6' or 'tcp6'
    $device['pingable'] = isPingable($device['hostname'], $try_a);
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $status = "1";
            $status_type = '';
        } else {
            echo "SNMP 无法访问";
            $status = "0";
            $status_type = 'snmp';
        }
    } else {
        echo "Unpingable";
        $status = "0";
        $status_type = 'ping';
    }
    if ($device['status'] != $status) {
        $poll_update .= $poll_separator . "`status` = '{$status}'";
        $poll_separator = ", ";
        dbUpdate(array('status' => $status), 'devices', 'device_id = ?', array($device['device_id']));
        dbInsert(array('importance' => '0', 'device_id' => $device['device_id'], 'message' => "设备的 " . ($status == '1' ? 'up' : 'down')), 'alerts');
        $event_msg = '设备状态变更为 ';
        if ($status == '1') {
            // Device Up, Severity Warning (4)
            $event_msg .= 'Up';
            $event_severity = 4;
        } else {
            // Device Down, Severity Error (3)!
            $event_msg .= 'Down';
            $event_severity = 3;
        }
        if ($status_type != '') {
            $event_msg .= ' (' . $status_type . ')';
        }
        log_event($event_msg, $device, 'device', $device['device_id'], $event_severity);
    }
    $rrd_filename = "status.rrd";
    rrdtool_create($device, $rrd_filename, "DS:status:GAUGE:600:0:1 ");
    if ($status == "1" || $status == "0") {
        rrdtool_update($device, $rrd_filename, "N:" . $status);
    } else {
        rrdtool_update($device, $rrd_filename, "N:U");
    }
    // Ping response RRD database.
    $ping_rrd = 'ping.rrd';
    rrdtool_create($device, $ping_rrd, "DS:ping:GAUGE:600:0:65535 ");
    if ($device['pingable']) {
        rrdtool_update($device, $ping_rrd, "N:" . $device['pingable']);
    } else {
        rrdtool_update($device, $ping_rrd, "N:U");
    }
    // SNMP response RRD database.
    $ping_snmp_rrd = 'ping_snmp.rrd';
    rrdtool_create($device, $ping_snmp_rrd, "DS:ping_snmp:GAUGE:600:0:65535 ");
    if ($device['snmpable']) {
        rrdtool_update($device, $ping_snmp_rrd, "N:" . $device['snmpable']);
    } else {
        rrdtool_update($device, $ping_snmp_rrd, "N:U");
    }
    $alert_metrics['device_status'] = $status;
    $alert_metrics['device_status_type'] = $status_type;
    $alert_metrics['device_ping'] = $device['pingable'];
    $alert_metrics['device_snmp'] = $device['snmpable'];
    if ($status == "1") {
        // Arrays for store and check enabled/disabled graphs
        $graphs = array();
        $graphs_db = array();
        foreach (dbFetchRows("SELECT * FROM `device_graphs` WHERE `device_id` = ?", array($device['device_id'])) as $entry) {
            $graphs_db[$entry['graph']] = isset($entry['enabled']) ? (bool) $entry['enabled'] : TRUE;
        }
        // Enable Ping graphs
        $graphs['ping'] = TRUE;
        // Enable SNMP graphs
        $graphs['ping_snmp'] = TRUE;
        // Run these base modules always and before all other modules!
        $poll_modules = array('system', 'os');
        if ($options['m']) {
            foreach (explode(',', $options['m']) as $module) {
                $module = trim($module);
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($module == 'unix-agent') {
                    array_unshift($poll_modules, $module);
                    // Add 'unix-agent' before all
                    continue;
                }
                if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                    $poll_modules[] = $module;
                }
            }
        } else {
            foreach ($config['poller_modules'] as $module => $module_status) {
                if (in_array($module, $poll_modules)) {
                    continue;
                }
                // Skip already added modules
                if ($attribs['poll_' . $module] || $module_status && !isset($attribs['poll_' . $module])) {
                    if (poller_module_excluded($device, $module)) {
                        print_warning("模块 [ {$module} ] 排除设备.");
                        continue;
                    }
                    if ($module == 'unix-agent') {
                        array_unshift($poll_modules, $module);
                        // Add 'unix-agent' before all
                        continue;
                    }
                    if (is_file($config['install_dir'] . "/includes/polling/{$module}.inc.php")) {
                        $poll_modules[] = $module;
                    }
                } elseif (isset($attribs['poll_' . $module]) && !$attribs['poll_' . $module]) {
                    print_warning("模块 [ {$module} ] 禁用设备.");
                } else {
                    print_warning("模块 [ {$module} ] 禁用全局.");
                }
            }
        }
        foreach ($poll_modules as $module) {
            print_debug(PHP_EOL . "including: includes/polling/{$module}.inc.php");
            $m_start = utime();
            include $config['install_dir'] . "/includes/polling/{$module}.inc.php";
            $m_end = utime();
            $m_run = round($m_end - $m_start, 4);
            $device_state['poller_mod_perf'][$module] = number_format($m_run, 4);
            print_message("Module [ {$module} ] time: {$m_run}" . "s");
        }
        // Fields to notify about in event log - FIXME should move to definitions?
        $update_fields = array('version', 'features', 'hardware', 'serial', 'kernel', 'distro', 'distro_ver', 'arch', 'asset_tag');
        // Log changed variables
        foreach ($update_fields as $field) {
            if (isset(${$field}) && ${$field} != $device[$field]) {
                $update_array[$field] = ${$field};
                log_event(ucfirst($field) . " -> " . $update_array[$field], $device, 'device', $device['device_id']);
            }
        }
        // Here additional fields, change only if not set already
        foreach (array('type', 'icon') as $field) {
            if (isset(${$field}) && ($device[$field] == "unknown" || $device[$field] == '')) {
                $update_array[$field] = ${$field};
                log_event(ucfirst($field) . " -> " . $update_array[$field], $device, 'device', $device['device_id']);
            }
        }
        // Check and update graphs DB
        $graphs_stat = array();
        if (!isset($options['m'])) {
            // Hardcoded poller performance
            $graphs['poller_perf'] = TRUE;
            // Delete not exists graphs from DB (only if poller run without modules option)
            foreach ($graphs_db as $graph => $value) {
                if (!isset($graphs[$graph])) {
                    dbDelete('device_graphs', "`device_id` = ? AND `graph` = ?", array($device['device_id'], $graph));
                    unset($graphs_db[$graph]);
                    $graphs_stat['deleted'][] = $graph;
                }
            }
        }
        // Add or update graphs in DB
        foreach ($graphs as $graph => $value) {
            if (!isset($graphs_db[$graph])) {
                dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph, 'enabled' => $value), 'device_graphs');
                $graphs_stat['added'][] = $graph;
            } else {
                if ($value != $graphs_db[$graph]) {
                    dbUpdate(array('enabled' => $value), 'device_graphs', '`device_id` = ? AND `graph` = ?', array($device['device_id'], $graph));
                    $graphs_stat['updated'][] = $graph;
                } else {
                    $graphs_stat['checked'][] = $graph;
                }
            }
        }
        // Print graphs stats
        foreach ($graphs_stat as $key => $stat) {
            if (count($stat)) {
                echo ' Graphs [' . $key . ']: ' . implode(', ', $stat) . PHP_EOL;
            }
        }
        $device_end = utime();
        $device_run = $device_end - $device_start;
        $device_time = round($device_run, 4);
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        $update_array['device_state'] = serialize($device_state);
        #echo("$device_end - $device_start; $device_time $device_run");
        print_message(PHP_EOL . "Polled in {$device_time} seconds");
        // Only store performance data if we're not doing a single-module poll
        if (!$options['m']) {
            dbInsert(array('device_id' => $device['device_id'], 'operation' => 'poll', 'start' => $device_start, 'duration' => $device_run), 'devices_perftimes');
            $poller_rrd = "perf-poller.rrd";
            rrdtool_create($device, $poller_rrd, "DS:val:GAUGE:600:0:38400 ");
            rrdtool_update($device, $poller_rrd, "N:" . $device_time);
        }
        if (OBS_DEBUG) {
            echo "更新 " . $device['hostname'] . " - ";
            print_vars($update_array);
            echo " \n";
        }
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            echo "已更新!\n";
        }
        $alert_metrics['device_uptime'] = $device['uptime'];
        $alert_metrics['device_rebooted'] = $rebooted;
        // 0 - not rebooted, 1 - rebooted
        $alert_metrics['device_duration_poll'] = $device['last_polled_timetaken'];
        unset($cache_storage);
        // Clear cache of hrStorage ** MAYBE FIXME? ** (ok, later)
        unset($cache);
        // Clear cache (unify all things here?)
    }
    check_entity('device', $device, $alert_metrics);
    unset($alert_metrics);
}
コード例 #13
0
ファイル: poller.php プロジェクト: kyrisu/observernms
    echo "DEBUG!\n";
    $debug = 1;
}
$i = 0;
$device_query = mysql_query("SELECT * FROM `devices` WHERE `ignore` = '0' AND `disabled` = '0' AND `status` = '1' {$where} ORDER BY device_id DESC");
while ($device = mysql_fetch_array($device_query)) {
    echo "-> " . $device['hostname'] . "\n";
    $device_start = utime();
    // Start counting device poll time
    $host_rrd = $config['rrd_dir'] . "/" . $device['hostname'];
    if (!is_dir($host_rrd)) {
        mkdir($host_rrd);
        echo "Created directory : {$host_rrd}\n";
    }
    $i++;
    $device['pingable'] = isPingable($device['hostname']);
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device['hostname'], $device['community'], $device['snmpver'], $device['port']);
    }
    if ($device['pingable'] && $device['snmpable']) {
        // Reachability Check
        if ($options['t']) {
            include "includes/polling/" . $options['t'] . ".inc.php";
        } else {
            include "includes/polling/ports.inc.php";
            include "includes/polling/ports-etherlike.inc.php";
            include "includes/polling/cisco-mac-accounting.inc.php";
        }
    } else {
        echo " Unreachable";
    }
コード例 #14
0
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;
}
コード例 #15
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";
    }
}
コード例 #16
0
 /**
  * @dataProvider providerIsPingable
  * @group network
  */
 public function testIsPingable($result, $hostname, $try_a = TRUE)
 {
     $flags = OBS_DNS_ALL;
     if (!$try_a) {
         $flags = $flags ^ OBS_DNS_A;
     }
     $ping = isPingable($hostname, $flags);
     $ping = is_numeric($ping) && $ping > 0;
     // Function return random float number
     $this->assertSame($result, $ping);
 }
コード例 #17
0
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;
}
コード例 #18
0
function poll_device($device, $options)
{
    global $config, $debug, $device, $polled_devices, $db_stats, $memcache;
    $old_device_state = unserialize($device['device_state']);
    $attribs = get_dev_attribs($device['device_id']);
    $status = 0;
    unset($array);
    $device_start = utime();
    // Start counting device poll time
    echo $device['hostname'] . " " . $device['device_id'] . " " . $device['os'] . " ";
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        echo "(" . $device['os_group'] . ")";
    }
    echo "\n";
    unset($poll_update);
    unset($poll_update_query);
    unset($poll_separator);
    $poll_update_array = array();
    $host_rrd = $config['rrd_dir'] . "/" . $device['hostname'];
    if (!is_dir($host_rrd)) {
        mkdir($host_rrd);
        echo "Created directory : {$host_rrd}\n";
    }
    $device['pingable'] = isPingable($device['hostname']);
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $status = "1";
            $status_type = '';
        } else {
            echo "SNMP Unreachable";
            $status = "0";
            $status_type = ' (snmp)';
        }
    } else {
        echo "Unpingable";
        $status = "0";
        $status_type = ' (ping)';
    }
    if ($device['status'] != $status) {
        $poll_update .= $poll_separator . "`status` = '{$status}'";
        $poll_separator = ", ";
        dbUpdate(array('status' => $status), 'devices', 'device_id=?', array($device['device_id']));
        dbInsert(array('importance' => '0', 'device_id' => $device['device_id'], 'message' => "Device is " . ($status == '1' ? 'up' : 'down')), 'alerts');
        log_event('Device status changed to ' . ($status == '1' ? 'Up' : 'Down') . $status_type, $device, 'system');
        notify($device, "Device " . ($status == '1' ? 'Up' : 'Down') . ": " . $device['hostname'] . $status_type, "Device " . ($status == '1' ? 'up' : 'down') . ": " . $device['hostname']);
    }
    $rrd = $config['rrd_dir'] . "/" . $device['hostname'] . "/status.rrd";
    if (!is_file($rrd)) {
        rrdtool_create($rrd, "DS:status:GAUGE:600:0:1 " . $config['rrd_rra']);
    }
    if ($status == "1" || $status == "0") {
        rrdtool_update($rrd, "N:" . $status);
    } else {
        rrdtool_update($rrd, "N:U");
    }
    // Ping response RRD database.
    $ping_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/ping.rrd';
    if (!is_file($ping_rrd)) {
        rrdtool_create($ping_rrd, "DS:ping:GAUGE:600:0:65535 " . $config['rrd_rra']);
    }
    if ($device['pingable']) {
        rrdtool_update($ping_rrd, "N:" . $device['pingable']);
    } else {
        rrdtool_update($ping_rrd, "N:U");
    }
    // SNMP response RRD database.
    $ping_snmp_rrd = $config['rrd_dir'] . '/' . $device['hostname'] . '/ping_snmp.rrd';
    if (!is_file($ping_snmp_rrd)) {
        rrdtool_create($ping_snmp_rrd, "DS:ping_snmp:GAUGE:600:0:65535 " . $config['rrd_rra']);
    }
    if ($device['snmpable']) {
        rrdtool_update($ping_snmp_rrd, "N:" . $device['snmpable']);
    } else {
        rrdtool_update($ping_snmp_rrd, "N:U");
    }
    if ($status == "1") {
        $graphs = array();
        $oldgraphs = array();
        // Enable Ping graphs
        $graphs['ping'] = TRUE;
        // Enable SNMP graphs
        $graphs['ping_snmp'] = TRUE;
        if ($options['m']) {
            foreach (explode(",", $options['m']) as $module) {
                if (is_file("includes/polling/" . $module . ".inc.php")) {
                    include "includes/polling/" . $module . ".inc.php";
                }
            }
        } else {
            foreach ($config['poller_modules'] as $module => $module_status) {
                if ($attribs['poll_' . $module] || $module_status && !isset($attribs['poll_' . $module])) {
                    if ($debug) {
                        echo "including: includes/polling/{$module}.inc.php\n";
                    }
                    include 'includes/polling/' . $module . '.inc.php';
                } elseif (isset($attribs['poll_' . $module]) && $attribs['poll_' . $module] == "0") {
                    echo "Module [ {$module} ] disabled on host.\n";
                } else {
                    echo "Module [ {$module} ] disabled globally.\n";
                }
            }
        }
        if (!isset($options['m'])) {
            // FIXME EVENTLOGGING -- MAKE IT SO WE DO THIS PER-MODULE?
            // This code cycles through the graphs already known in the database and the ones we've defined as being polled here
            // If there any don't match, they're added/deleted from the database.
            // Ideally we should hold graphs for xx days/weeks/polls so that we don't needlessly hide information.
            // Hardcoded poller performance
            $graphs['poller_perf'] = TRUE;
            foreach (dbFetch("SELECT `graph` FROM `device_graphs` WHERE `device_id` = ?", array($device['device_id'])) as $graph) {
                if (!isset($graphs[$graph["graph"]])) {
                    dbDelete('device_graphs', "`device_id` = ? AND `graph` = ?", array($device['device_id'], $graph["graph"]));
                } else {
                    $oldgraphs[$graph["graph"]] = TRUE;
                }
            }
            foreach ($graphs as $graph => $value) {
                if (!isset($oldgraphs[$graph])) {
                    echo "+";
                    dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph), 'device_graphs');
                }
                echo $graph . " ";
            }
        }
        $device_end = utime();
        $device_run = $device_end - $device_start;
        $device_time = substr($device_run, 0, 5);
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        $update_array['device_state'] = serialize($device_state);
        #echo("$device_end - $device_start; $device_time $device_run");
        echo "Polled in {$device_time} seconds\n";
        // Only store performance data if we're not doing a single-module poll
        if (!$options['m']) {
            dbInsert(array('device_id' => $device['device_id'], 'operation' => 'poll', 'start' => $device_start, 'duration' => $device_run), 'devices_perftimes');
            $poller_rrd = $config['rrd_dir'] . "/" . $device['hostname'] . "/perf-poller.rrd";
            if (!is_file($poller_rrd)) {
                rrdtool_create($poller_rrd, "DS:val:GAUGE:600:0:38400 " . $config['rrd_rra']);
            }
            rrdtool_update($poller_rrd, "N:" . $device_time);
        }
        if ($debug) {
            echo "Updating " . $device['hostname'] . " - " . print_r($update_array) . " \n";
        }
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            echo "UPDATED!\n";
        }
        unset($storage_cache);
        // Clear cache of hrStorage ** MAYBE FIXME? **
        unset($cache);
        // Clear cache (unify all things here?)
    }
}
コード例 #19
0
ファイル: snmp-scan.php プロジェクト: vitalisator/librenms
function perform_snmp_scan($net, $force_network, $force_broadcast)
{
    global $stats, $config, $debug, $vdebug;
    echo 'Range: ' . $net->network . '/' . $net->bitmask . PHP_EOL;
    $config['snmp']['timeout'] = 1;
    $config['snmp']['retries'] = 0;
    $config['fping_options']['retries'] = 0;
    $start = ip2long($net->network);
    $end = ip2long($net->broadcast) - 1;
    if ($force_network === true) {
        //Force-scan network address
        d_echo("Forcing network address scan" . PHP_EOL);
        $start = $start - 1;
    }
    if ($force_broadcast === true) {
        //Force-scan broadcast address
        d_echo("Forcing broadcast address scan" . PHP_EOL);
        $end = $end + 1;
    }
    if ($net->bitmask === "31") {
        //Handle RFC3021 /31 prefixes
        $start = ip2long($net->network) - 1;
        $end = ip2long($net->broadcast);
        d_echo("RFC3021 network, hosts " . long2ip($start + 1) . " and " . long2ip($end) . PHP_EOL . PHP_EOL);
    } elseif ($net->bitmask === "32") {
        //Handle single-host /32 prefixes
        $start = ip2long($net->network) - 1;
        $end = $start + 1;
        d_echo("RFC3021 network, hosts " . long2ip($start + 1) . " and " . long2ip($end) . PHP_EOL . PHP_EOL);
    } else {
        d_echo("Network:   " . $net->network . PHP_EOL);
        d_echo("Broadcast: " . $net->broadcast . PHP_EOL . PHP_EOL);
    }
    while ($start++ < $end) {
        $stats['count']++;
        $host = long2ip($start);
        if ($vdebug) {
            echo "Scanning: " . $host . PHP_EOL;
        }
        if (match_network($config['autodiscovery']['nets-exclude'], $host)) {
            if ($vdebug) {
                echo "Excluded by config.php" . PHP_EOL . PHP_EOL;
            } else {
                echo '|';
            }
            continue;
        }
        $test = isPingable($host);
        if ($test['result'] === false) {
            if ($vdebug) {
                echo "Unpingable Device" . PHP_EOL . PHP_EOL;
            } else {
                echo '.';
            }
            continue;
        }
        if (ip_exists($host)) {
            $stats['known']++;
            if ($vdebug) {
                echo "Known Device" . PHP_EOL;
            } else {
                echo '*';
            }
            continue;
        }
        foreach (array('udp', 'tcp') as $transport) {
            try {
                addHost(gethostbyaddr($host), '', $config['snmp']['port'], $transport, $config['distributed_poller_group']);
                $stats['added']++;
                if ($vdebug) {
                    echo "Added Device" . PHP_EOL . PHP_EOL;
                } else {
                    echo '+';
                }
                break;
            } catch (HostExistsException $e) {
                $stats['known']++;
                if ($vdebug) {
                    echo "Known Device" . PHP_EOL . PHP_EOL;
                } else {
                    echo '*';
                }
                break;
            } catch (HostUnreachablePingException $e) {
                if ($vdebug) {
                    echo "Unpingable Device" . PHP_EOL . PHP_EOL;
                } else {
                    echo '.';
                }
                break;
            } catch (HostUnreachableException $e) {
                if ($debug) {
                    print_error($e->getMessage() . " over {$transport}");
                    foreach ($e->getReasons() as $reason) {
                        echo "  {$reason}" . PHP_EOL;
                    }
                }
                if ($transport === 'tcp') {
                    // tried both udp and tcp without success
                    $stats['failed']++;
                    if ($vdebug) {
                        echo "Failed to Add Device" . PHP_EOL . PHP_EOL;
                    } else {
                        echo '-';
                    }
                }
            }
        }
    }
    echo PHP_EOL;
}
コード例 #20
0
ファイル: functions.php プロジェクト: ekoyle/librenms
/**
 * 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;
}
コード例 #21
0
ファイル: functions.inc.php プロジェクト: Rosiak/librenms
function poll_device($device, $options)
{
    global $config, $device, $polled_devices, $memcache;
    $attribs = get_dev_attribs($device['device_id']);
    $device['snmp_max_repeaters'] = $attribs['snmp_max_repeaters'];
    $device['snmp_max_oid'] = $attribs['snmp_max_oid'];
    $status = 0;
    unset($array);
    $device_start = microtime(true);
    // Start counting device poll time
    echo 'Hostname: ' . $device['hostname'] . PHP_EOL;
    echo 'Device ID: ' . $device['device_id'] . PHP_EOL;
    echo 'OS: ' . $device['os'];
    $ip = dnslookup($device);
    if (!empty($ip) && $ip != inet6_ntop($device['ip'])) {
        log_event('Device IP changed to ' . $ip, $device, 'system');
        $db_ip = inet_pton($ip);
        dbUpdate(array('ip' => $db_ip), 'devices', 'device_id=?', array($device['device_id']));
    }
    if ($config['os'][$device['os']]['group']) {
        $device['os_group'] = $config['os'][$device['os']]['group'];
        echo ' (' . $device['os_group'] . ')';
    }
    echo PHP_EOL . PHP_EOL;
    unset($poll_update);
    unset($poll_update_query);
    unset($poll_separator);
    $poll_update_array = array();
    $update_array = array();
    $host_rrd = $config['rrd_dir'] . '/' . $device['hostname'];
    if ($config['norrd'] !== true && !is_dir($host_rrd)) {
        mkdir($host_rrd);
        echo "Created directory : {$host_rrd}\n";
    }
    $address_family = snmpTransportToAddressFamily($device['transport']);
    $ping_response = isPingable($device['hostname'], $address_family, $attribs);
    $device_perf = $ping_response['db'];
    $device_perf['device_id'] = $device['device_id'];
    $device_perf['timestamp'] = array('NOW()');
    if (can_ping_device($attribs) === true && is_array($device_perf)) {
        dbInsert($device_perf, 'device_perf');
    }
    $device['pingable'] = $ping_response['result'];
    $ping_time = $ping_response['last_ping_timetaken'];
    $response = array();
    $status_reason = '';
    if ($device['pingable']) {
        $device['snmpable'] = isSNMPable($device);
        if ($device['snmpable']) {
            $status = '1';
            $response['status_reason'] = '';
        } else {
            echo 'SNMP Unreachable';
            $status = '0';
            $response['status_reason'] = 'snmp';
        }
    } else {
        echo 'Unpingable';
        $status = '0';
        $response['status_reason'] = 'icmp';
    }
    if ($device['status'] != $status) {
        $poll_update .= $poll_separator . "`status` = '{$status}'";
        $poll_separator = ', ';
        dbUpdate(array('status' => $status, 'status_reason' => $response['status_reason']), 'devices', 'device_id=?', array($device['device_id']));
        log_event('Device status changed to ' . ($status == '1' ? 'Up' : 'Down') . ' from ' . $response['status_reason'] . ' check.', $device, $status == '1' ? 'up' : 'down');
    }
    if ($status == '1') {
        $graphs = array();
        $oldgraphs = array();
        // we always want the core module to be included
        include 'includes/polling/core.inc.php';
        $force_module = false;
        if ($options['m']) {
            $config['poller_modules'] = array();
            foreach (explode(',', $options['m']) as $module) {
                if (is_file('includes/polling/' . $module . '.inc.php')) {
                    $config['poller_modules'][$module] = 1;
                    $force_module = true;
                }
            }
        }
        foreach ($config['poller_modules'] as $module => $module_status) {
            $os_module_status = $config['os'][$device['os']]['poller_modules'][$module];
            d_echo("Modules status: Global" . (isset($module_status) ? $module_status ? '+ ' : '- ' : '  '));
            d_echo("OS" . (isset($os_module_status) ? $os_module_status ? '+ ' : '- ' : '  '));
            d_echo("Device" . (isset($attribs['poll_' . $module]) ? $attribs['poll_' . $module] ? '+ ' : '- ' : '  '));
            if ($force_module === true || $attribs['poll_' . $module] || $os_module_status && !isset($attribs['poll_' . $module]) || $module_status && !isset($os_module_status) && !isset($attribs['poll_' . $module])) {
                $module_start = 0;
                $module_time = 0;
                $module_start = microtime(true);
                echo "\n#### Load poller module {$module} ####\n";
                include "includes/polling/{$module}.inc.php";
                $module_time = microtime(true) - $module_start;
                printf("\n>> Runtime for poller module '%s': %.4f seconds\n", $module, $module_time);
                echo "#### Unload poller module {$module} ####\n\n";
                // save per-module poller stats
                $tags = array('module' => $module, 'rrd_def' => 'DS:poller:GAUGE:600:0:U', 'rrd_name' => array('poller-perf', $module));
                $fields = array('poller' => $module_time);
                data_update($device, 'poller-perf', $tags, $fields);
                // remove old rrd
                $oldrrd = rrd_name($device['hostname'], array('poller', $module, 'perf'));
                if (is_file($oldrrd)) {
                    unlink($oldrrd);
                }
            } elseif (isset($attribs['poll_' . $module]) && $attribs['poll_' . $module] == '0') {
                echo "Module [ {$module} ] disabled on host.\n\n";
            } elseif (isset($os_module_status) && $os_module_status == '0') {
                echo "Module [ {$module} ] disabled on os.\n\n";
            } else {
                echo "Module [ {$module} ] disabled globally.\n\n";
            }
        }
        // Update device_groups
        UpdateGroupsForDevice($device['device_id']);
        if (!isset($options['m'])) {
            // FIXME EVENTLOGGING -- MAKE IT SO WE DO THIS PER-MODULE?
            // This code cycles through the graphs already known in the database and the ones we've defined as being polled here
            // If there any don't match, they're added/deleted from the database.
            // Ideally we should hold graphs for xx days/weeks/polls so that we don't needlessly hide information.
            foreach (dbFetch('SELECT `graph` FROM `device_graphs` WHERE `device_id` = ?', array($device['device_id'])) as $graph) {
                if (isset($graphs[$graph['graph']])) {
                    $oldgraphs[$graph['graph']] = true;
                } else {
                    dbDelete('device_graphs', '`device_id` = ? AND `graph` = ?', array($device['device_id'], $graph['graph']));
                }
            }
            foreach ($graphs as $graph => $value) {
                if (!isset($oldgraphs[$graph])) {
                    echo '+';
                    dbInsert(array('device_id' => $device['device_id'], 'graph' => $graph), 'device_graphs');
                }
                echo $graph . ' ';
            }
        }
        //end if
        $device_end = microtime(true);
        $device_run = $device_end - $device_start;
        $device_time = substr($device_run, 0, 5);
        // Poller performance
        if (!empty($device_time)) {
            $tags = array('rrd_def' => 'DS:poller:GAUGE:600:0:U', 'module' => 'ALL');
            $fields = array('poller' => $device_time);
            data_update($device, 'poller-perf', $tags, $fields);
        }
        // Ping response
        if (can_ping_device($attribs) === true && !empty($ping_time)) {
            $tags = array('rrd_def' => 'DS:ping:GAUGE:600:0:65535');
            $fields = array('ping' => $ping_time);
            $update_array['last_ping'] = array('NOW()');
            $update_array['last_ping_timetaken'] = $ping_time;
            data_update($device, 'ping-perf', $tags, $fields);
        }
        $update_array['last_polled'] = array('NOW()');
        $update_array['last_polled_timetaken'] = $device_time;
        // echo("$device_end - $device_start; $device_time $device_run");
        echo "Polled in {$device_time} seconds\n";
        d_echo('Updating ' . $device['hostname'] . "\n");
        $updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
        if ($updated) {
            echo "UPDATED!\n";
        }
        unset($storage_cache);
        // Clear cache of hrStorage ** MAYBE FIXME? **
        unset($cache);
        // Clear cache (unify all things here?)
    }
    //end if
}
コード例 #22
0
ファイル: functions.inc.php プロジェクト: skive/observium
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;
}
コード例 #23
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;
}
コード例 #24
0
ファイル: addhost.php プロジェクト: kyrisu/observernms
 $community = $argv[2];
 $snmpver = strtolower($argv[3]);
 if (is_numeric($argv[4])) {
     $port = $argv[4];
 } 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";
         }
コード例 #25
0
ファイル: functions.php プロジェクト: syzdek/librenms
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;
}
コード例 #26
0
#!/usr/bin/env php
<?php 
include "includes/defaults.inc.php";
include "config.php";
include "includes/functions.php";
$device_query = mysql_query("SELECT * FROM `devices` WHERE `device_id` LIKE '%" . $argv[1] . "' AND disabled = '0' ORDER BY `device_id` DESC");
while ($device = mysql_fetch_assoc($device_query)) {
    $port = $device['snmp_port'];
    echo $device['hostname'] . " ";
    if (isPingable($device['hostname'])) {
        $pos = snmp_get($device, "sysDescr.0", "-Oqv", "SNMPv2-MIB");
        echo $device['protocol'] . ":" . $device['hostname'] . ":" . $device['snmp_port'] . " - " . $device['snmp_community'] . " " . $device['snmp_version'] . ": ";
        if ($pos == '') {
            $status = '0';
        } else {
            $status = '1';
        }
    } else {
        $status = '0';
    }
    if ($status == '1') {
        echo "正常\n";
    } else {
        echo "异常\n";
    }
    if ($status != $device['status']) {
        mysql_query("UPDATE `devices` SET `status`= '{$status}' WHERE `device_id` = '" . $device['device_id'] . "'");
        if ($status == '1') {
            $stat = "正常";
            mysql_query("INSERT INTO alerts (importance, device_id, message) VALUES ('0', '" . $device['device_id'] . "', '设备正常\n')");
            if ($config['alerts']['email']['enable']) {