From 510c2b0fc4d6e79e54df1a100599ea785dbf5ba3 Mon Sep 17 00:00:00 2001 From: Paul Gear Date: Mon, 28 Oct 2013 15:55:57 +1000 Subject: [PATCH] Add ARP discovery patch (untested) --- includes/defaults.inc.php | 9 +++ includes/discovery/discovery-arp.inc.php | 99 ++++++++++++++++++++++++ includes/discovery/functions.inc.php | 24 ++++++ 3 files changed, 132 insertions(+) create mode 100644 includes/discovery/discovery-arp.inc.php diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 67fbc2097..e162abcb1 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -162,6 +162,14 @@ $config['autodiscovery']['snmpscan'] = TRUE; // autodiscover hosts via SNM $config['discover_services'] = FALSE; // Autodiscover services via SNMP on devices of type "server" +// Networks to exclude from autodiscovery + +$config['autodiscovery']['nets-exclude'][] = "0.0.0.0/8"; +$config['autodiscovery']['nets-exclude'][] = "127.0.0.0/8"; +$config['autodiscovery']['nets-exclude'][] = "169.254.0.0/16"; +$config['autodiscovery']['nets-exclude'][] = "224.0.0.0/4"; +$config['autodiscovery']['nets-exclude'][] = "240.0.0.0/4"; + // Mailer backend Settings $config['email_backend'] = 'mail'; // Mail backend. Allowed: "mail" (PHP's built-in), "sendmail", "smtp". @@ -520,6 +528,7 @@ $config['discovery_modules']['storage'] = 1; $config['discovery_modules']['hr-device'] = 1; $config['discovery_modules']['discovery-protocols'] = 1; $config['discovery_modules']['arp-table'] = 1; +$config['discovery_modules']['discovery-arp'] = 0; $config['discovery_modules']['junose-atm-vp'] = 1; $config['discovery_modules']['bgp-peers'] = 1; $config['discovery_modules']['vlans'] = 1; diff --git a/includes/discovery/discovery-arp.inc.php b/includes/discovery/discovery-arp.inc.php new file mode 100644 index 000000000..6595ce28f --- /dev/null +++ b/includes/discovery/discovery-arp.inc.php @@ -0,0 +1,99 @@ + +// +// Author: Paul Gear +// License: GPLv3 +// + +include_once("../../includes/print-interface.inc.php"); + +echo("ARP Discovery: "); + +$hostname = $device['hostname']; +$deviceid = $device['device_id']; + +// Find all IPv4 addresses in the MAC table that haven't been discovered on monitored devices. +$sql = " +SELECT * +FROM ip_mac as m, ports as i +WHERE m.port_id = i.port_id + AND i.device_id = ? + AND i.deleted = 0 + AND NOT EXISTS ( + SELECT * FROM ipv4_addresses a + WHERE a.ipv4_address = m.ip_address + ) +GROUP BY ip_address +ORDER BY ip_address +"; + +unset($names); +unset($ips); + +foreach (dbFetchRows($sql, array($deviceid)) as $entry) +{ + global $config; + + $ip = $entry['ip_address']; + $mac = $entry['mac_address']; + $if = $entry['port_id']; + $int = humanize_port($if); + $label = $int['label']; + + // Even though match_network is done inside discover_new_device, we do it here + // as well in order to skip unnecessary reverse DNS lookups on discovered IPs. + if (match_network($config['autodiscovery']['nets-exclude'], $ip)) { + echo("x"); + continue; + } + if (!match_network($config['nets'], $ip)) { + echo("i"); + log_event("Ignored $ip", $deviceid, 'interface', $if); + continue; + } + + // Attempt discovery of each IP only once per run. + if (arp_discovery_is_cached($ip)) { + echo("."); + continue; + } + arp_discovery_add_cache($ip); + + // Log reverse DNS failures so the administrator can take action. + $name = gethostbyaddr($ip); + if ($name != $ip) { // gethostbyaddr returns the original argument on failure + echo("+"); + $names[] = $name; + $ips[$name] = $ip; + } + else { + echo("-"); + log_event("ARP discovery of $ip failed due to absent reverse DNS", $deviceid, 'interface', $if); + } +} +echo("\n"); + +// Run device discovery on each of the devices we've detected so far. +foreach ($names as $name) { + $remote_device_id = discover_new_device($name); + if ($remote_device_id) { + log_event("Device autodiscovered through ARP on $hostname", $remote_device_id, 'interface', $if); + } + else { + log_event("ARP discovery of $name (" . $ips[$name] . ") failed - check ping and SNMP access", $deviceid, 'interface', $if); + } +} + +unset($names); +unset($ips); + +?> + diff --git a/includes/discovery/functions.inc.php b/includes/discovery/functions.inc.php index 5118b5ad1..f2b1427e0 100644 --- a/includes/discovery/functions.inc.php +++ b/includes/discovery/functions.inc.php @@ -23,6 +23,12 @@ function discover_new_device($hostname) } $ip = gethostbyname($dst_host); + $dst_host = rtrim($dst_host, '.'); // remove trailing dot + + if ( match_network($config['autodiscovery']['nets-exclude'], $ip)) { + return FALSE; + } + if ( match_network($config['nets'], $ip) ) { $remote_device_id = addHost ($dst_host); @@ -543,4 +549,22 @@ function discover_process_ipv6(&$valid, $ifIndex,$ipv6_address,$ipv6_prefixlen,$ } } +// maintain a simple cache of seen IPs during ARP discovery +function arp_discovery_add_cache($ip) +{ + global $arp_discovery; + $arp_discovery[$ip] = TRUE; +} + +function arp_discovery_is_cached($ip) +{ + global $arp_discovery; + if (array_key_exists($ip, $arp_discovery)) { + return $arp_discovery[$ip]; + } + else { + return FALSE; + } +} + ?>