From ac001191dc17b5304421931bbf16427c750c788b Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Tue, 22 Sep 2015 02:25:35 +0200 Subject: [PATCH 1/7] Use fping6 instead of fping for hosts with udp6/tcp6 SNMP transports --- includes/defaults.inc.php | 1 + includes/functions.php | 32 ++++++++++++++++++++++++------ includes/polling/functions.inc.php | 4 +++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 21057ea49..9236ef353 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'] = '/usr/bin/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 84e95af1d..a98b5bfd3 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -275,7 +275,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, $addressFamily)) { if (empty($snmpver)) { // Try SNMPv2c $snmpver = 'v2c'; @@ -501,7 +502,7 @@ function isSNMPable($device) { } } -function isPingable($hostname,$device_id = FALSE) { +function isPingable($hostname,$address_family = AF_INET,$device_id = FALSE) { global $config; $fping_params = ''; @@ -518,7 +519,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; } @@ -1186,7 +1187,7 @@ function ip_exists($ip) { return true; } -function fping($host,$params) { +function fping($host,$params,$address_family = AF_INET) { global $config; @@ -1196,7 +1197,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)) { @@ -1230,4 +1237,17 @@ function function_check($function) { function get_last_commit() { return `git log -n 1|head -n1`; -}//end get_last_commit +}//end get_last_commit + +function snmpTransportToAddressFamily($transport) { + if (!isset($transport)) { + $transport = 'udp'; + } + + if ($transport == 'udp6' || $transport == 'tcp6') { + return AF_INET6; + } + else { + return AF_INET; + } +} diff --git a/includes/polling/functions.inc.php b/includes/polling/functions.inc.php index d97555d46..bbec52732 100644 --- a/includes/polling/functions.inc.php +++ b/includes/polling/functions.inc.php @@ -154,7 +154,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']; From 772d1762a7feff9849b9c1bf17f847f131be98f2 Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Tue, 22 Sep 2015 14:57:23 +0200 Subject: [PATCH 2/7] Use relative path for fping6 fping6 will be in /usr/bin on Debian-based systems, but /usr/sbin on CentOS. Have PHP figure out where fping6 is, to avoid breaking existing setups on CentOS. --- doc/Support/Configuration.md | 2 +- includes/defaults.inc.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Support/Configuration.md b/doc/Support/Configuration.md index 1694a4fb9..865b00b9b 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 9236ef353..2b28dbba6 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -52,7 +52,7 @@ $config['own_hostname'] = 'localhost'; // Location of executables $config['rrdtool'] = '/usr/bin/rrdtool'; $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; From 4c2d66791d6c729e48baf56325394cc78073ff79 Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Tue, 22 Sep 2015 15:27:36 +0200 Subject: [PATCH 3/7] Fixed typo in variable name --- includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/functions.php b/includes/functions.php index a98b5bfd3..8c3acfe93 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -276,7 +276,7 @@ function addHost($host, $snmpver, $port = '161', $transport = 'udp', $quiet = '0 if (ip_exists($ip) === false) { // Test reachability $address_family = snmpTransportToAddressFamily($transport); - if ($force_add == 1 || isPingable($host, $addressFamily)) { + if ($force_add == 1 || isPingable($host, $address_family)) { if (empty($snmpver)) { // Try SNMPv2c $snmpver = 'v2c'; From 7d7e7098ab952709e5ec4c98edad7db5b8198dff Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Thu, 24 Sep 2015 02:07:15 +0200 Subject: [PATCH 4/7] Added PHPDoc for function isPingable() --- includes/functions.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/includes/functions.php b/includes/functions.php index 8c3acfe93..b9306d895 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -502,6 +502,15 @@ function isSNMPable($device) { } } +/** + * 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; From e5327594a5e27e47f6aa90a703552113c7a31969 Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Thu, 24 Sep 2015 02:07:33 +0200 Subject: [PATCH 5/7] Code formatting --- includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/functions.php b/includes/functions.php index b9306d895..cf23d07b8 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -511,7 +511,7 @@ function isSNMPable($device) { * * @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) { +function isPingable($hostname, $address_family = AF_INET, $device_id = FALSE) { global $config; $fping_params = ''; From a973e538c4d3744004c302ad894182e5d72da8a2 Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Fri, 25 Sep 2015 19:03:47 +0200 Subject: [PATCH 6/7] Added complete list of IPv6-based SNMP transport specifiers in snmpTransportToAddressFamily() --- includes/functions.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/functions.php b/includes/functions.php index cf23d07b8..30aa01e0e 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1253,7 +1253,9 @@ function snmpTransportToAddressFamily($transport) { $transport = 'udp'; } - if ($transport == 'udp6' || $transport == 'tcp6') { + $ipv6_snmp_transport_specifiers = array('udp6', 'udpv6', 'udpipv6', 'tcp6', 'tcpv6', 'tcpipv6'); + + if (in_array($transport, $ipv6_snmp_transport_specifiers)) { return AF_INET6; } else { From 65ca58a1ccc57ddc746f727bd2b156bdc19c863d Mon Sep 17 00:00:00 2001 From: Nils Steinger Date: Fri, 25 Sep 2015 19:03:58 +0200 Subject: [PATCH 7/7] PHPDoc for snmpTransportToAddressFamily() --- includes/functions.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/includes/functions.php b/includes/functions.php index 30aa01e0e..9cd2575f2 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1248,6 +1248,18 @@ function get_last_commit() { return `git log -n 1|head -n1`; }//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';