diff --git a/doc/Support/Configuration.md b/doc/Support/Configuration.md index 1694a4fb91..865b00b9b5 100644 --- a/doc/Support/Configuration.md +++ b/doc/Support/Configuration.md @@ -46,7 +46,7 @@ $config['rrdtool'] = "/usr/bin/rrdtool"; ```php $config['fping'] = "/usr/bin/fping"; -$config['fping6'] = "/usr/bin/fping6"; +$config['fping6'] = "fping6"; $config['fping_options']['retries'] = 3; $config['fping_options']['timeout'] = 500; $config['fping_options']['count'] = 3; diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 20fb803e4a..6e864d1845 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -52,6 +52,7 @@ $config['own_hostname'] = 'localhost'; // Location of executables $config['rrdtool'] = '/usr/bin/rrdtool'; $config['fping'] = '/usr/bin/fping'; +$config['fping6'] = 'fping6'; $config['fping_options']['retries'] = 3; $config['fping_options']['timeout'] = 500; $config['fping_options']['count'] = 3; diff --git a/includes/functions.php b/includes/functions.php index 2b95c28ff5..42e9d0b251 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -251,7 +251,8 @@ function addHost($host, $snmpver, $port = '161', $transport = 'udp', $quiet = '0 } if (ip_exists($ip) === false) { // Test reachability - if ($force_add == 1 || isPingable($host)) { + $address_family = snmpTransportToAddressFamily($transport); + if ($force_add == 1 || isPingable($host, $address_family)) { if (empty($snmpver)) { // Try SNMPv2c $snmpver = 'v2c'; @@ -477,7 +478,16 @@ function isSNMPable($device) { } } -function isPingable($hostname,$device_id = FALSE) { +/** + * Check if the given host responds to ICMP echo requests ("pings"). + * + * @param string $hostname The hostname or IP address to send ping requests to. + * @param int $address_family The address family (AF_INET for IPv4 or AF_INET6 for IPv6) to use. Defaults to IPv4. Will *not* be autodetected for IP addresses, so it has to be set to AF_INET6 when pinging an IPv6 address or an IPv6-only host. + * @param int $device_id This parameter is currently ignored. + * + * @return bool TRUE if the host responded to at least one ping request, FALSE otherwise. + */ +function isPingable($hostname, $address_family = AF_INET, $device_id = FALSE) { global $config; $fping_params = ''; @@ -494,7 +504,7 @@ function isPingable($hostname,$device_id = FALSE) { $fping_params .= ' -p ' . $config['fping_options']['millisec']; } $response = array(); - $status = fping($hostname,$fping_params); + $status = fping($hostname,$fping_params,$address_family); if ($status['loss'] == 100) { $response['result'] = FALSE; } @@ -1162,7 +1172,7 @@ function ip_exists($ip) { return true; } -function fping($host,$params) { +function fping($host,$params,$address_family = AF_INET) { global $config; @@ -1172,7 +1182,13 @@ function fping($host,$params) { 2 => array("pipe", "w") ); - $process = proc_open($config['fping'] . ' -e -q ' .$params . ' ' .$host.' 2>&1', $descriptorspec, $pipes); + // Default to AF_INET (IPv4) + $fping_path = $config['fping']; + if ($address_family == AF_INET6) { + $fping_path = $config['fping6']; + } + + $process = proc_open($fping_path . ' -e -q ' .$params . ' ' .$host.' 2>&1', $descriptorspec, $pipes); $read = ''; if (is_resource($process)) { @@ -1206,4 +1222,31 @@ function function_check($function) { function get_last_commit() { return `git log -n 1|head -n1`; -}//end get_last_commit +}//end get_last_commit + +/** + * Try to determine the address family (IPv4 or IPv6) associated with an SNMP + * transport specifier (like "udp", "udp6", etc.). + * + * @param string $transport The SNMP transport specifier, for example "udp", + * "udp6", "tcp", or "tcp6". See `man snmpcmd`, + * section "Agent Specification" for a full list. + * + * @return int The address family associated with the given transport + * specifier: AF_INET for IPv4 (or local connections not associated + * with an IP stack), AF_INET6 for IPv6. + */ +function snmpTransportToAddressFamily($transport) { + if (!isset($transport)) { + $transport = 'udp'; + } + + $ipv6_snmp_transport_specifiers = array('udp6', 'udpv6', 'udpipv6', 'tcp6', 'tcpv6', 'tcpipv6'); + + if (in_array($transport, $ipv6_snmp_transport_specifiers)) { + return AF_INET6; + } + else { + return AF_INET; + } +} diff --git a/includes/polling/functions.inc.php b/includes/polling/functions.inc.php index f9399e86fb..ffe79340e0 100644 --- a/includes/polling/functions.inc.php +++ b/includes/polling/functions.inc.php @@ -158,7 +158,9 @@ function poll_device($device, $options) { echo "Created directory : $host_rrd\n"; } - $ping_response = isPingable($device['hostname'], $device['device_id']); + $address_family = snmpTransportToAddressFamily($device['transport']); + + $ping_response = isPingable($device['hostname'], $address_family, $device['device_id']); $device_perf = $ping_response['db']; $device_perf['device_id'] = $device['device_id'];