function get_cache($host, $value) { global $dev_cache; $host = strtolower(trim($host)); // Check cache expiration $now = time(); $expired = TRUE; if (isset($dev_cache[$host]['lastchecked'])) { if ($now - $dev_cache[$host]['lastchecked'] < 3600) { $expired = FALSE; } // will expire after 1 hour } if ($expired) { $dev_cache[$host]['lastchecked'] = $now; } if (!isset($dev_cache[$host][$value]) || $expired) { switch ($value) { case 'device_id': // Try by hostname $dev_cache[$host]['device_id'] = dbFetchCell('SELECT `device_id` FROM `devices` WHERE `hostname` = ? OR `sysName` = ?', array($host, $host)); // If failed, try by IP if (!is_numeric($dev_cache[$host]['device_id'])) { $ip = $host; $ip_version = get_ip_version($ip); if ($ip_version !== FALSE) { if ($ip_version == 6) { $ip = Net_IPv6::uncompress($ip, TRUE); } $address_count = dbFetchCell('SELECT COUNT(*) FROM `ipv' . $ip_version . '_addresses` WHERE `ipv' . $ip_version . '_address` = ?;', array($ip)); if ($address_count) { $query = 'SELECT `device_id` FROM `ipv' . $ip_version . '_addresses` AS A, `ports` AS I WHERE A.`ipv' . $ip_version . '_address` = ? AND I.`port_id` = A.`port_id`'; // If more than one IP address, also check the status of the port. if ($address_count > 1) { $query .= " AND I.`ifOperStatus` = 'up'"; } $dev_cache[$host]['device_id'] = dbFetchCell($query, array($ip)); } } } break; case 'os': case 'version': $dev_cache[$host][$value] = dbFetchCell('SELECT `' . $value . '` FROM `devices` WHERE `device_id` = ?', array(get_cache($host, 'device_id'))); break; case 'os_group': $os = get_cache($host, 'os'); $dev_cache[$host]['os_group'] = isset($GLOBALS['config']['os'][$os]['group']) ? $GLOBALS['config']['os'][$os]['group'] : ''; break; default: return NULL; } } return $dev_cache[$host][$value]; }
/** * Display ARP/NDP table addresses. * * Display pages with ARP/NDP tables addresses from devices. * * @param array $vars * @return none * */ function print_arptable($vars) { // With pagination? (display page numbers in header) $pagination = isset($vars['pagination']) && $vars['pagination']; $pageno = isset($vars['pageno']) && !empty($vars['pageno']) ? $vars['pageno'] : 1; $pagesize = isset($vars['pagesize']) && !empty($vars['pagesize']) ? $vars['pagesize'] : 10; $start = $pagesize * $pageno - $pagesize; $param = array(); $where = ' WHERE 1 '; foreach ($vars as $var => $value) { if ($value != '') { switch ($var) { case 'device': case 'device_id': $where .= ' AND I.`device_id` = ?'; $param[] = $value; break; case 'port': case 'port_id': $where .= ' AND I.`port_id` = ?'; $param[] = $value; break; case 'ip_version': $where .= ' AND `ip_version` = ?'; $param[] = $value; break; case 'address': if (isset($vars['searchby']) && $vars['searchby'] == 'ip') { $where .= ' AND `ip_address` LIKE ?'; $value = trim($value); ///FIXME. Need another conversion ("2001:b08:b08" -> "2001:0b08:0b08") -- mike if (Net_IPv6::checkIPv6($value)) { $value = Net_IPv6::uncompress($value, true); } $param[] = '%' . $value . '%'; } else { $where .= ' AND `mac_address` LIKE ?'; $param[] = '%' . str_replace(array(':', ' ', '-', '.', '0x'), '', mres($value)) . '%'; } break; } } } // Show ARP tables only for permitted ports $query_permitted = generate_query_permitted(array('port'), array('port_table' => 'I')); $query = 'FROM `ip_mac` AS M '; $query .= 'LEFT JOIN `ports` AS I ON I.`port_id` = M.`port_id` '; $query .= $where . $query_permitted; $query_count = 'SELECT COUNT(`mac_id`) ' . $query; $query = 'SELECT * ' . $query; $query .= ' ORDER BY M.`mac_address`'; $query .= " LIMIT {$start},{$pagesize}"; // Query ARP/NDP table addresses $entries = dbFetchRows($query, $param); // Query ARP/NDP table address count if ($pagination) { $count = dbFetchCell($query_count, $param); } $list = array('device' => FALSE, 'port' => FALSE); if (!isset($vars['device']) || empty($vars['device']) || $vars['page'] == 'search') { $list['device'] = TRUE; } if (!isset($vars['port']) || empty($vars['port']) || $vars['page'] == 'search') { $list['port'] = TRUE; } $string = '<table class="table table-bordered table-striped table-hover table-condensed">' . PHP_EOL; if (!$short) { $string .= ' <thead>' . PHP_EOL; $string .= ' <tr>' . PHP_EOL; $string .= ' <th>MAC Address</th>' . PHP_EOL; $string .= ' <th>IP Address</th>' . PHP_EOL; if ($list['device']) { $string .= ' <th>Device</th>' . PHP_EOL; } if ($list['port']) { $string .= ' <th>Interface</th>' . PHP_EOL; } $string .= ' <th>Remote Device</th>' . PHP_EOL; $string .= ' <th>Remote Interface</th>' . PHP_EOL; $string .= ' </tr>' . PHP_EOL; $string .= ' </thead>' . PHP_EOL; } $string .= ' <tbody>' . PHP_EOL; foreach ($entries as $entry) { humanize_port($entry); $ip_version = $entry['ip_version']; $ip_address = $ip_version == 6 ? Net_IPv6::compress($entry['ip_address']) : $entry['ip_address']; $arp_host = dbFetchRow('SELECT * FROM `ipv' . $ip_version . '_addresses` AS A LEFT JOIN `ports` AS I ON A.`port_id` = I.`port_id` LEFT JOIN `devices` AS D ON D.`device_id` = I.`device_id` WHERE A.`ipv' . $ip_version . '_address` = ?', array($ip_address)); $arp_name = $arp_host ? generate_device_link($arp_host) : ''; $arp_if = $arp_host ? generate_port_link($arp_host) : ''; if ($arp_host['device_id'] == $entry['device_id']) { $arp_name = 'Self Device'; } if ($arp_host['port_id'] == $entry['port_id']) { $arp_if = 'Self Port'; } $string .= ' <tr>' . PHP_EOL; $string .= ' <td width="160">' . formatMac($entry['mac_address']) . '</td>' . PHP_EOL; $string .= ' <td width="140">' . $ip_address . '</td>' . PHP_EOL; if ($list['device']) { $dev = device_by_id_cache($entry['device_id']); $string .= ' <td class="entity" nowrap>' . generate_device_link($dev) . '</td>' . PHP_EOL; } if ($list['port']) { if ($entry['ifInErrors_delta'] > 0 || $entry['ifOutErrors_delta'] > 0) { $port_error = generate_port_link($entry, '<span class="label label-important">Errors</span>', 'port_errors'); } $string .= ' <td class="entity">' . generate_port_link($entry, short_ifname($entry['label'])) . ' ' . $port_error . '</td>' . PHP_EOL; } $string .= ' <td class="entity" width="200">' . $arp_name . '</td>' . PHP_EOL; $string .= ' <td class="entity">' . $arp_if . '</td>' . PHP_EOL; $string .= ' </tr>' . PHP_EOL; } $string .= ' </tbody>' . PHP_EOL; $string .= '</table>'; // Print pagination header if ($pagination) { $string = pagination($vars, $count) . $string . pagination($vars, $count); } // Print ARP/NDP table echo $string; }
// local(7) -> ifIndex switch ($lldp['lldpRemPortIdSubtype']) { case 'interfaceAlias': $id = snmp_hexstring($id); $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ports` WHERE (`ifAlias` = ? OR `ifDescr` = ?) AND `device_id` = ?", array($id, $if, $remote_device_id)); break; case 'interfaceName': $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ?) AND `device_id` = ?", array($id, $if, $remote_device_id)); break; case 'macAddress': $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ports` WHERE `ifPhysAddress` = ? AND `device_id` = ?", array(strtolower(str_replace(array(' ', '-'), '', $id)), $remote_device_id)); break; case 'networkAddress': $ip_version = get_ip_version($id); if ($ip_version) { $ip = $ip_version === 6 ? Net_IPv6::uncompress($id, TRUE) : $id; $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ipv" . $ip_version . "_addresses` LEFT JOIN `ports` USING (`port_id`) WHERE `ipv" . $ip_version . "_address` = ? AND `device_id` = ?", array($ip, $remote_device_id)); } break; case 'local': // local not always ifIndex or FIXME (see: http://jira.observium.org/browse/OBSERVIUM-1716) if (!ctype_digit($id)) { // Not sure what should be if $id ifName and it just numeric $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ports` WHERE (`ifName`= ? OR `ifDescr` = ?) AND `device_id` = ?", array($id, $if, $remote_device_id)); } case 'ifIndex': // These cases are handled by the ifDescr/ifIndex combination fallback below // These cases are handled by the ifDescr/ifIndex combination fallback below default: break; }
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; }
foreach ($cache_arp as $entry) { $old_if = $entry['ifIndex']; $old_mac = $entry['mac_address']; $old_address = $entry['ip_address']; $old_version = $entry['ip_version']; $old_table[$old_if][$old_version][$old_address] = $old_mac; } $ipv4_pattern = '/\\[(\\d+)\\](?:\\[ipv4\\])?\\["?([\\d\\.]+)"?\\]\\s+([a-f\\d]+):([a-f\\d]+):([a-f\\d]+):([a-f\\d]+):([a-f\\d]+):([a-f\\d]{1,2})/i'; $ipv6_pattern = '/\\[(\\d+)\\](?:\\[ipv6\\])?\\["?([a-f\\d:]+)"?\\]\\s+(?:([a-f\\d]+):([a-f\\d]+):)?([a-f\\d]+):([a-f\\d]+):([a-f\\d]+):([a-f\\d]{1,2})/i'; foreach (explode("\n", $oid_data) as $data) { if (preg_match($ipv4_pattern, $data, $matches)) { $ip = $matches[2]; $ip_version = 4; } elseif (preg_match($ipv6_pattern, $data, $matches)) { if (count(explode(':', $matches[2])) === 8) { $ip = Net_IPv6::uncompress($matches[2], TRUE); } else { $ip = hex2ip($matches[2]); } $ip_version = 6; } else { // In principle the such shouldn't be. continue; } $if = $matches[1]; $port_id = $interface[$if]; if ($ip & $port_id) { if ($matches[3] === '' && $matches[4] === '') { // Convert IPv4 to fake MAC for 6to4 tunnels //ipNetToPhysicalPhysAddress[27][ipv6]["20:02:c0:58:63:01:00:00:00:00:00:00:00:00:00:00"] 0:0:c0:58 $matches[3] = 'ff';
function uncompress_ipv6($ip) { // Singleton static $class = null; if ($class === null) { $class = new Net_IPv6(); } return $class->uncompress($ip, true); }
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; }
/** * ipCalc calculations */ function calculateIpCalcResult($cidr) { /* first verify address type */ $type = IdentifyAddress($cidr); /* IPv4 */ if ($type == "IPv4") { $net = Net_IPv4::parseAddress($cidr); //set ip address type $out['Type'] = 'IPv4'; //calculate network details $out['IP address'] = $net->ip; // 192.168.0.50 $out['Network'] = $net->network; // 192.168.0.0 $out['Broadcast'] = $net->broadcast; // 192.168.255.255 $out['Subnet bitmask'] = $net->bitmask; // 16 $out['Subnet netmask'] = $net->netmask; // 255.255.0.0 $out['Subnet wildcard'] = long2ip(~ip2long($net->netmask)); //0.0.255.255 //calculate min/max IP address $out['Min host IP'] = long2ip(ip2long($out['Network']) + 1); $out['Max host IP'] = long2ip(ip2long($out['Broadcast']) - 1); $out['Number of hosts'] = ip2long($out['Broadcast']) - ip2long($out['Min host IP']); //subnet class $out['Subnet Class'] = checkIpv4AddressType($out['Network'], $out['Broadcast']); //if IP == subnet clear the Host fields if ($out['IP address'] == $out['Network']) { $out['IP address'] = "/"; } } else { //set ip address type $out['Type'] = 'IPv6'; //calculate network details /* $out['Host address'] = Net_IPv6::removeNetmaskSpec ( $cidr ); */ $out['Host address'] = $cidr; $out['Host address'] = Net_IPv6::compress($out['Host address'], 1); $out['Host address (uncompressed)'] = Net_IPv6::uncompress($out['Host address']); $mask = Net_IPv6::getNetmaskSpec($cidr); $subnet = Net_IPv6::getNetmask($cidr); $out['Subnet prefix'] = Net_IPv6::compress($subnet) . '/' . $mask; $out['Prefix length'] = Net_IPv6::getNetmaskSpec($cidr); // get reverse DNS entries $out['Host Reverse DNS'] = calculateReverseDNS6($out['Host address (uncompressed)']); $out['Subnet Reverse DNS'] = calculateReverseDNS6($subnet, $mask); //if IP == subnet clear the Host fields and Host Reverse DNS if ($out['Host address'] == $out['Subnet prefix']) { $out['Host address'] = '/'; $out['Host address (uncompressed)'] = '/'; unset($out['Host Reverse DNS']); } //min / max hosts $maxIp = gmp_strval(gmp_add(gmp_sub(gmp_pow(2, 128 - $mask), 1), ip2long6($subnet))); $out['Min host IP'] = long2ip6(gmp_strval(gmp_add(ip2long6($subnet), 1))); $out['Max host IP'] = long2ip6($maxIp); $out['Number of hosts'] = MaxHosts($mask, 1); //address type $out['Address type'] = Net_IPv6::getAddressType($cidr); $out['Address type'] = checkIpv6AddressType($out['Address type']); } /* return results */ return $out; }
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; }
/** * Params: * * pagination, pageno, pagesize * device, port */ function get_pseudowires_array($vars) { $array = array(); // With pagination? (display page numbers in header) $array['pagination'] = isset($vars['pagination']) && $vars['pagination']; pagination($vars, 0, TRUE); // Get default pagesize/pageno $array['pageno'] = $vars['pageno']; $array['pagesize'] = $vars['pagesize']; $start = $array['pagesize'] * $array['pageno'] - $array['pagesize']; $pagesize = $array['pagesize']; // Begin query generate $param = array(); $where = ' WHERE 1 '; foreach ($vars as $var => $value) { if ($value != '') { switch ($var) { case 'device': case 'device_a': $where .= generate_query_values($value, 'device_id'); break; case 'port': case 'port_a': $where .= generate_query_values($value, 'port_id'); break; //case 'type': // $where .= generate_query_values($value, 'type'); // break; //case 'message': // $where .= generate_query_values($value, 'message', '%LIKE%'); // break; } } } // Show pseudowires only for permitted devices and ports $query_permitted = generate_query_permitted(array('device', 'port')); $query = 'FROM `pseudowires` '; $query .= $where . $query_permitted; $query_count = 'SELECT COUNT(*) ' . $query; //$query_updated = 'SELECT MAX(`timestamp`) '.$query; $query = 'SELECT * ' . $query; //$query .= ' ORDER BY `event_id` DESC '; $query .= " LIMIT {$start},{$pagesize}"; // Query pseudowires foreach (dbFetchRows($query, $param) as $entry) { if ($entry['peer_addr']) { $peer_addr = $entry['peer_addr']; } else { if ($entry['pwMplsPeerLdpID']) { $peer_addr = preg_replace('/:\\d+$/', '', $pw['pwMplsPeerLdpID']); } } $peer_addr_type = get_ip_version($peer_addr); if ($peer_addr_type) { if ($peer_addr_type == 6) { $peer_addr = Net_IPv6::uncompress($peer_addr, TRUE); } $peer_addr_type = 'ipv' . $peer_addr_type; $entry['peer_addr'] = $peer_addr; $entry['peer_addr_type'] = $peer_addr_type; } else { continue; // Peer address unknown } if (!is_array($cache_pseudowires['ips'][$peer_addr])) { $cache_pseudowires['ips'][$peer_addr]['port_id'] = dbFetchCell('SELECT `port_id` FROM `' . $peer_addr_type . '_addresses` WHERE `' . $peer_addr_type . '_address` = ? ' . generate_query_values($GLOBALS['cache']['ports']['pseudowires'], 'port_id') . ' LIMIT 1;', array($peer_addr)); if (!is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id'])) { $cache_pseudowires['ips'][$peer_addr]['port_id'] = dbFetchCell('SELECT `port_id` FROM `' . $peer_addr_type . '_addresses` WHERE `' . $peer_addr_type . '_address` = ? ' . $GLOBALS['cache']['where']['ports_permitted'] . ' LIMIT 1;', array($peer_addr)); if (is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id'])) { // If we found port on remote device, than both devices in DB and will try to fix real port $peer_port_tmp = get_port_by_id_cache($cache_pseudowires['ips'][$peer_addr]['port_id']); $peer_port_fix = dbFetchCell('SELECT `port_id` FROM `pseudowires` WHERE `device_id` = ? AND `pwID` = ? LIMIT 1;', array($peer_port_tmp['device_id'], $entry['pwID'])); if (is_numeric($peer_port_fix)) { $cache_pseudowires['ips'][$peer_addr]['port_id'] = $peer_port_fix; } } } //$cache_pseudowires['ips'][$peer_addr]['host'] = $entry['reverse_dns']; } $entry['peer_port_id'] = $cache_pseudowires['ips'][$peer_addr]['port_id']; //$entry['peer_port'] = get_port_by_id_cache($entry['peer_port_id']); //$entry['peer_device_id'] = $entry['peer_port']['device_id']; //$entry['peer_device'] = device_by_id_cache($entry['peer_device_id']); $array['entries'][] = $entry; } // Query pseudowires count if ($array['pagination']) { $array['count'] = dbFetchCell($query_count, $param); $array['pagination_html'] = pagination($vars, $array['count']); } else { $array['count'] = count($array['entries']); } // Query for last timestamp //$array['updated'] = dbFetchCell($query_updated, $param); return $array; }
} $if_id = dbFetchCell('SELECT `port_id` FROM `ports` WHERE `ifDescr` = ? AND `device_id` = ? LIMIT 1;', array($pw['cpwVcName'], $device['device_id'])); if (!is_numeric($if_id) && strpos($pw['cpwVcName'], '_')) { // IOS-XR some time use '_' instead '/'. http://jira.observium.org/browse/OBSERVIUM-246 // cpwVcName.3221225526 = TenGigE0_3_0_6.438 // ifDescr.84 = TenGigE0/3/0/6.438 $if_id = dbFetchCell('SELECT `port_id` FROM `ports` WHERE `ifDescr` = ? AND `device_id` = ? LIMIT 1;', array(str_replace('_', '/', $pw['cpwVcName']), $device['device_id'])); } if (!is_numeric($if_id) && strpos($pw['cpwVcMplsLocalLdpID'], ':')) { // Last (know) way for detect local port by MPLS LocalLdpID, // because IOS-XR some time use Remote IP instead ifDescr in cpwVcName // cpwVcName.3221225473 = STRING: 82.209.169.153,3055 // cpwVcMplsLocalLdpID.3221225473 = STRING: 82.209.169.129:0 list($local_addr) = explode(':', $pw['cpwVcMplsLocalLdpID']); if ($peer_addr_type == 'ipv6') { $local_addr = Net_IPv6::uncompress($local_addr, TRUE); } $if_id = dbFetchCell('SELECT `port_id` FROM `' . $peer_addr_type . '_addresses` LEFT JOIN `ports` USING (`port_id`) WHERE `' . $peer_addr_type . '_address` = ? AND `device_id` = ? LIMIT 1;', array($local_addr, $device['device_id'])); } // Note, Cisco experimental 'cpwVc' oid prefix converted to 'pw' prefix as in rfc PW-STD-MIB $pws_new = array('device_id' => $device['device_id'], 'mib' => $mib, 'port_id' => $if_id, 'peer_device_id' => $remote_device, 'peer_addr' => $peer_addr, 'peer_rdns' => $peer_rdns, 'pwIndex' => $pw_id, 'pwType' => $pw['cpwVcType'], 'pwID' => $pw['cpwVcID'], 'pwOutboundLabel' => $pw['cpwVcOutboundVcLabel'], 'pwInboundLabel' => $pw['cpwVcInboundVcLabel'], 'pwPsnType' => $pw['cpwVcPsnType'], 'pwDescr' => $pw['cpwVcDescr'], 'pwRemoteIfString' => $pw['cpwVcRemoteIfString'], 'pwRowStatus' => $pw['cpwVcRowStatus']); if (!empty($pws_cache['pws_db'][$mib][$pw_id])) { $pws_old = $pws_cache['pws_db'][$mib][$pw_id]; $pseudowire_id = $pws_old['pseudowire_id']; if (empty($pws_old['peer_device_id'])) { $pws_old['peer_device_id'] = array('NULL'); } $update_array = array(); //var_dump(array_keys($pws_new)); foreach (array_keys($pws_new) as $column) { if ($pws_new[$column] != $pws_old[$column]) {
function get_cache($host, $value) { global $dev_cache; if (empty($host)) { return; } // Check cache expiration $now = time(); $expired = TRUE; if (isset($dev_cache[$host]['lastchecked'])) { if ($now - $dev_cache[$host]['lastchecked'] < 600) { $expired = FALSE; } // will expire after 10 min } if ($expired) { $dev_cache[$host]['lastchecked'] = $now; } if (!isset($dev_cache[$host][$value]) || $expired) { switch ($value) { case 'device_id': // Try by map in config if (isset($GLOBALS['config']['syslog']['host_map'][$host])) { $new_host = $GLOBALS['config']['syslog']['host_map'][$host]; if (is_numeric($new_host)) { // Check if device id exist $dev_cache[$host]['device_id'] = dbFetchCell('SELECT `device_id` FROM `devices` WHERE `device_id` = ?', array($new_host)); } else { $dev_cache[$host]['device_id'] = dbFetchCell('SELECT `device_id` FROM `devices` WHERE `hostname` = ? OR `sysName` = ?', array($new_host, $new_host)); } // If syslog host map correct, return device id or try onward if ($dev_cache[$host]['device_id']) { return $dev_cache[$host]['device_id']; } } // Try by hostname $dev_cache[$host]['device_id'] = dbFetchCell('SELECT `device_id` FROM `devices` WHERE `hostname` = ? OR `sysName` = ?', array($host, $host)); // If failed, try by IP if (!is_numeric($dev_cache[$host]['device_id'])) { $ip = $host; $ip_version = get_ip_version($ip); if ($ip_version !== FALSE) { if ($ip_version == 6 && preg_match('/::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)/', $ip, $matches)) { // IPv4 mapped to IPv6, like ::ffff:192.0.2.128 // See: http://jira.observium.org/browse/OBSERVIUM-1274 $ip = $matches[1]; $ip_version = 4; } else { if ($ip_version == 6) { $ip = Net_IPv6::uncompress($ip, TRUE); } } $address_count = dbFetchCell('SELECT COUNT(*) FROM `ipv' . $ip_version . '_addresses` WHERE `ipv' . $ip_version . '_address` = ?;', array($ip)); if ($address_count) { $query = 'SELECT `device_id` FROM `ipv' . $ip_version . '_addresses` AS A, `ports` AS I WHERE A.`ipv' . $ip_version . '_address` = ? AND I.`port_id` = A.`port_id`'; // If more than one IP address, also check the status of the port. if ($address_count > 1) { $query .= " AND I.`ifOperStatus` = 'up'"; } $dev_cache[$host]['device_id'] = dbFetchCell($query, array($ip)); } } } break; case 'os': case 'version': if ($device_id = get_cache($host, 'device_id')) { $dev_cache[$host][$value] = dbFetchCell('SELECT `' . $value . '` FROM `devices` WHERE `device_id` = ?', array($device_id)); } else { return NULL; } break; case 'os_group': $os = get_cache($host, 'os'); $dev_cache[$host]['os_group'] = isset($GLOBALS['config']['os'][$os]['group']) ? $GLOBALS['config']['os'][$os]['group'] : ''; break; default: return NULL; } } return $dev_cache[$host][$value]; }
function get_pseudowire_table($vars) { $sql = generate_pseudowire_query($vars); $entries = array(); foreach (dbFetchRows($sql) as $entry) { if (!isset($GLOBALS['cache']['devices']['id'][$entry['device_id']])) { continue; } // Device hostname $entry['hostname'] = $GLOBALS['cache']['devices']['id'][$entry['device_id']]['hostname']; // Remote Peer $peer_addr = $entry['peer_addr']; $peer_addr_type = get_ip_version($peer_addr); if ($peer_addr_type && $entry['peer_device_id']) { if ($peer_addr_type == 6) { $peer_addr = Net_IPv6::uncompress($peer_addr, TRUE); } $peer_addr_type = 'ipv' . $peer_addr_type; //$entry['peer_addr'] = $peer_addr; //$entry['peer_addr_type'] = $peer_addr_type; if (!is_array($cache_pseudowires['ips'][$peer_addr])) { $cache_pseudowires['ips'][$peer_addr]['port_id'] = dbFetchCell('SELECT `port_id` FROM `' . $peer_addr_type . '_addresses` WHERE `' . $peer_addr_type . '_address` = ? ' . generate_query_values($GLOBALS['cache']['ports']['pseudowires'], 'port_id') . ' LIMIT 1;', array($peer_addr)); if (!is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id'])) { // Separate entry for find correct port $cache_pseudowires['ips'][$peer_addr]['port_id_fix'] = dbFetchCell('SELECT `port_id` FROM `' . $peer_addr_type . '_addresses` WHERE `' . $peer_addr_type . '_address` = ? ' . $GLOBALS['cache']['where']['ports_permitted'] . ' LIMIT 1;', array($peer_addr)); } //$cache_pseudowires['ips'][$peer_addr]['host'] = $entry['reverse_dns']; } $entry['peer_port_id'] = $cache_pseudowires['ips'][$peer_addr]['port_id']; if (is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id_fix'])) { // If we found port on remote device, than both devices in DB and will try to fix real port $peer_port_tmp = get_port_by_id_cache($cache_pseudowires['ips'][$peer_addr]['port_id_fix']); $peer_port_fix = dbFetchCell('SELECT `port_id` FROM `pseudowires` WHERE `device_id` = ? AND `pwID` = ? LIMIT 1;', array($peer_port_tmp['device_id'], $entry['pwID'])); if (is_numeric($peer_port_fix)) { $entry['peer_port_id'] = $peer_port_fix; } else { $entry['peer_port_id'] = $cache_pseudowires['ips'][$peer_addr]['port_id_fix']; } } //r($entry['peer_port_id']); if ($entry['peer_port_id']) { $entry['peer_port'] = get_port_by_id_cache($entry['peer_port_id']); //r($entry['peer_port']); $entry['peer_device_id'] = $entry['peer_port']['device_id']; //r($entry['peer_device_id']); $entry['peer_device'] = device_by_id_cache($entry['peer_device_id']); } } $entry['hostname'] = $GLOBALS['cache']['devices']['id'][$entry['device_id']]['hostname']; // Attach hostname for sorting $entries[] = $entry; } // Sorting switch ($vars['sort_order']) { case 'desc': $sort_order = SORT_DESC; $sort_neg = SORT_ASC; break; case 'reset': unset($vars['sort'], $vars['sort_order']); // no break here // no break here default: $sort_order = SORT_ASC; $sort_neg = SORT_DESC; } switch ($vars['sort']) { case 'device': $entries = array_sort_by($entries, 'hostname', $sort_order, SORT_STRING); break; case 'pwid': $entries = array_sort_by($entries, 'pwID', $sort_order, SORT_NUMERIC); break; case 'pwtype': $entries = array_sort_by($entries, 'pwType', $sort_order, SORT_STRING, 'pwPsnType', $sort_order, SORT_STRING); //$pws = array_sort_by($pws, 'pwType', $sort_order, SORT_STRING); break; case 'peer_addr': $entries = array_sort_by($entries, 'peer_addr', $sort_order, SORT_NUMERIC); break; case 'event': $entries = array_sort_by($entries, 'event', $sort_order, SORT_STRING); break; case 'uptime': $entries = array_sort_by($entries, 'pwUptime', $sort_order, SORT_NUMERIC); break; case 'last_change': $entries = array_sort_by($entries, 'last_change', $sort_neg, SORT_NUMERIC); break; case 'status': $entries = array_sort_by($entries, 'pwOperStatus', $sort_order, SORT_STRING); break; default: // Not sorted } return $entries; }
function get_port_id_by_ip_cache($device, $ip) { global $cache; $ip_version = get_ip_version($ip); if (is_array($device) && isset($device['device_id'])) { $device_id = $device['device_id']; } else { if (is_numeric($device)) { $device_id = $device; } } if (!isset($device_id) || !$ip_version) { print_error("Invalid arguments passed into function get_port_id_by_ip_cache(). Please report to developers."); return FALSE; } if ($ip_version == 6) { $ip = Net_IPv6::uncompress($ip, TRUE); } if (isset($cache['port_ip'][$device_id][$ip])) { return $cache['port_ip'][$device_id][$ip]; } $ips = dbFetchRows('SELECT `port_id`, `ifOperStatus`, `ifAdminStatus` FROM `ipv' . $ip_version . '_addresses` LEFT JOIN `ports` USING(`port_id`) WHERE `deleted` = 0 AND `device_id` = ? AND `ipv' . $ip_version . '_address` = ?', array($device_id, $ip)); if (count($ips) === 1) { // Simple $port = current($ips); //return $port['port_id']; } else { foreach ($ips as $entry) { if ($entry['ifAdminStatus'] == 'up' && $entry['ifOperStatus'] == 'up') { // First UP entry $port = $entry; break; } else { if ($entry['ifAdminStatus'] == 'up') { // Admin up, but port down or other state $ips_up[] = $entry; } else { // Admin down $ips_down[] = $entry; } } } if (!isset($port)) { if ($ips_up) { $port = current($ips_up); } else { $port = current($ips_down); } } } $cache['port_ip'][$device_id][$ip] = $port['port_id'] ? $port['port_id'] : FALSE; return $cache['port_ip'][$device_id][$ip]; }
if (!isset($config['mib_dir'])) { $config['mib_dir'] = $config['install_dir'] . '/mibs'; } else { $config['mib_dir'] = rtrim($config['mib_dir'], ' /'); } // Old variable backwards compatibility if (isset($config['rancid_configs']) && !is_array($config['rancid_configs'])) { $config['rancid_configs'] = array($config['rancid_configs']); } if (isset($config['auth_ldap_group']) && !is_array($config['auth_ldap_group'])) { $config['auth_ldap_group'] = array($config['auth_ldap_group']); } // Database currently stores v6 networks non-compressed, check for any compressed subnet and expand them foreach ($config['ignore_common_subnet'] as $index => $content) { if (strstr($content, ':') !== FALSE) { $config['ignore_common_subnet'][$index] = Net_IPv6::uncompress($content); } } // Disable nonexistant features in CE, do not try to turn on, it will not give effect if (OBSERVIUM_EDITION == 'community') { $config['enable_billing'] = 0; $config['poller-wrapper']['alerter'] = FALSE; } // If we're on SSL, let's properly detect it // DOCME needs phpdoc block // TESTME needs unit testing // MOVEME to includes/common.inc.php function is_ssl() { if (isset($_SERVER['HTTPS'])) { if ('on' == strtolower($_SERVER['HTTPS'])) {
/** * Returns the lowest and highest IPv6 address * for a given IP and netmask specification * * The netmask may be a part of the $ip or * the number of netwask bits is provided via $bits * * The result is an indexed array. The key 'start' * contains the lowest possible IP adress. The key * 'end' the highest address. * * @param String $ipToParse the IPv6 address * @param String $bits the optional count of netmask bits * * @return Array ['start', 'end'] the lowest and highest IPv6 address * @access public * @static * @author Nicholas Williams */ public static function parseAddress($ipToParse, $bits = null) { $ip = null; $bitmask = null; if (null == $bits) { $elements = explode('/', $ipToParse); if (2 == count($elements)) { $ip = Net_IPv6::uncompress($elements[0]); $bitmask = $elements[1]; } else { include_once 'PEAR.php'; return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG, NET_IPV6_NO_NETMASK); } } else { $ip = Net_IPv6::uncompress($ipToParse); $bitmask = $bits; } $binNetmask = str_repeat('1', $bitmask) . str_repeat('0', 128 - $bitmask); $maxNetmask = str_repeat('1', 128); $netmask = Net_IPv6::_bin2Ip($binNetmask); $startAddress = Net_IPv6::_bin2Ip(Net_IPv6::_ip2Bin($ip) & $binNetmask); $endAddress = Net_IPv6::_bin2Ip(Net_IPv6::_ip2Bin($ip) | $binNetmask ^ $maxNetmask); return array('start' => $startAddress, 'end' => $endAddress); }
foreach ($entry as $pw_name => $entry2) { foreach ($entry2 as $pw_ifIndex => $pw) { //if (strlen($pw['jnxVpnPwRowStatus']) && $pw['jnxVpnPwRowStatus'] != 'active') { continue; } // Skip inactive (active, notinService, notReady, createAndGo, createAndWait, destroy) // Get full index $pw_index = snmp_translate('jnxVpnPwRowStatus.' . $pw_type . '."' . $pw_name . '".' . $pw_ifIndex, 'JUNIPER-VPN-MIB'); $pw_index = str_replace('.1.3.6.1.4.1.2636.3.26.1.4.1.4.', '', $pw_index); $peer_addr = hex2ip($pw['jnxVpnRemotePeIdAddress']); $peer_addr_version = get_ip_version($peer_addr); $peer_addr_type = $pw['jnxVpnRemotePeIdAddrType']; if ($peer_addr_version) { $peer_addr_type = 'ipv' . $peer_addr_version; // Override address type, because snmp sometime return incorrect $peer_rdns = gethostbyaddr6($peer_addr); // PTR name if ($peer_addr_type == 'ipv6') { $peer_addr = Net_IPv6::uncompress($peer_addr, TRUE); } // FIXME. Retarded way $remote_device = dbFetchCell('SELECT `device_id` FROM `' . $peer_addr_type . '_addresses` LEFT JOIN `ports` USING(`port_id`) WHERE `' . $peer_addr_type . '_address` = ? LIMIT 1;', array($peer_addr)); } else { $peer_rdns = ''; $peer_addr = ''; // Unset peer address print_debug("Not found correct peer address. See snmpwalk for 'jnxVpnRemotePeIdAddress'."); } if (empty($remote_device)) { $remote_device = array('NULL'); } if (!is_numeric($pw['jnxVpnPwAssociatedInterface']) || $pw['jnxVpnPwAssociatedInterface'] <= 0) {
function ipv62snmp($ipv6) { $ipv6_split = array(); $ipv6_ex = explode(':', Net_IPv6::uncompress($ipv6)); for ($i = 0; $i < 8; $i++) { $ipv6_ex[$i] = zeropad($ipv6_ex[$i], 4); } $ipv6_ip = implode('', $ipv6_ex); for ($i = 0; $i < 32; $i += 2) { $ipv6_split[] = hexdec(substr($ipv6_ip, $i, 2)); } return implode('.', $ipv6_split); }
/** * Display ARP/NDP table addresses. * * Display pages with ARP/NDP tables addresses from devices. * * @param array $vars * @return none * */ function print_arptable($vars) { // With pagination? (display page numbers in header) $pagination = isset($vars['pagination']) && $vars['pagination']; pagination($vars, 0, TRUE); // Get default pagesize/pageno $pageno = $vars['pageno']; $pagesize = $vars['pagesize']; $start = $pagesize * $pageno - $pagesize; $param = array(); $where = ' WHERE 1 '; foreach ($vars as $var => $value) { if ($value != '') { switch ($var) { case 'device': case 'device_id': $where .= generate_query_values($value, 'device_id'); break; case 'port': case 'port_id': $where .= generate_query_values($value, 'I.port_id'); break; case 'ip_version': $where .= generate_query_values($value, 'ip_version'); break; case 'address': if (isset($vars['searchby']) && $vars['searchby'] == 'ip') { $value = trim($value); if (strpos($value, ':') !== FALSE) { if (Net_IPv6::checkIPv6($value)) { $value = Net_IPv6::uncompress($value, TRUE); } else { // FIXME. Need another conversion ("2001:b08:b08" -> "2001:0b08:0b08") -- mike } } $where .= generate_query_values($value, 'ip_address', '%LIKE%'); } else { // MAC Addresses $value = str_replace(array(':', ' ', '-', '.', '0x'), '', $value); $where .= generate_query_values($value, 'mac_address', '%LIKE%'); } break; } } } if (isset($vars['sort'])) { switch ($vars['sort']) { case "port": $sort = " ORDER BY `I`.`port_label`"; break; case "ip_version": $sort = " ORDER BY `ip_version`"; break; case "ip": case "address": $sort = " ORDER BY `ip_address`"; break; case "mac": default: $sort = " ORDER BY `mac_address`"; } } // Show ARP tables only for permitted ports $query_permitted = generate_query_permitted(array('port'), array('port_table' => 'I')); $query = 'FROM `ip_mac` AS M '; $query .= 'LEFT JOIN `ports` AS I ON I.`port_id` = M.`port_id` '; $query .= $where . $query_permitted; $query_count = 'SELECT COUNT(`mac_id`) ' . $query; $query = 'SELECT * ' . $query; $query .= $sort; $query .= " LIMIT {$start},{$pagesize}"; // Query ARP/NDP table addresses $entries = dbFetchRows($query, $param); // Query ARP/NDP table address count if ($pagination) { $count = dbFetchCell($query_count, $param); } $list = array('device' => FALSE, 'port' => FALSE); if (!isset($vars['device']) || empty($vars['device']) || $vars['page'] == 'search') { $list['device'] = TRUE; } if (!isset($vars['port']) || empty($vars['port']) || $vars['page'] == 'search') { $list['port'] = TRUE; } $string = generate_box_open(); $string .= '<table class="table table-striped table-hover table-condensed">' . PHP_EOL; $cols = array('mac' => 'MAC Address', 'ip' => 'IP Address', 'device' => 'Device', 'port' => 'Port', '!remote_device' => 'Remote Device', '!remote_port' => 'Remote Port'); if (!$list['device']) { unset($cols['device']); } if (!$list['port']) { unset($cols['port']); } if (!$short) { $string .= get_table_header($cols, $vars); // Currently sorting is not available } foreach ($entries as $entry) { humanize_port($entry); $ip_version = $entry['ip_version']; $ip_address = $ip_version == 6 ? Net_IPv6::compress($entry['ip_address']) : $entry['ip_address']; $arp_host = dbFetchRow('SELECT * FROM `ipv' . $ip_version . '_addresses` AS A LEFT JOIN `ports` AS I ON A.`port_id` = I.`port_id` LEFT JOIN `devices` AS D ON D.`device_id` = I.`device_id` WHERE A.`ipv' . $ip_version . '_address` = ?', array($ip_address)); $arp_name = $arp_host ? generate_device_link($arp_host) : ''; $arp_if = $arp_host ? generate_port_link($arp_host) : ''; if ($arp_host['device_id'] == $entry['device_id']) { $arp_name = 'Self Device'; } if ($arp_host['port_id'] == $entry['port_id']) { $arp_if = 'Self Port'; } $string .= ' <tr>' . PHP_EOL; $string .= ' <td style="width: 160px;" class="entity">' . generate_popup_link('mac', format_mac($entry['mac_address'])) . '</td>' . PHP_EOL; $string .= ' <td style="width: 140px;">' . generate_popup_link('ip', $ip_address) . '</td>' . PHP_EOL; if ($list['device']) { $dev = device_by_id_cache($entry['device_id']); $string .= ' <td class="entity" style="white-space: nowrap;">' . generate_device_link($dev) . '</td>' . PHP_EOL; } if ($list['port']) { if ($entry['ifInErrors_delta'] > 0 || $entry['ifOutErrors_delta'] > 0) { $port_error = generate_port_link($entry, '<span class="label label-important">Errors</span>', 'port_errors'); } $string .= ' <td class="entity">' . generate_port_link($entry, $entry['port_label_short']) . ' ' . $port_error . '</td>' . PHP_EOL; } $string .= ' <td class="entity" style="width: 200px;">' . $arp_name . '</td>' . PHP_EOL; $string .= ' <td class="entity">' . $arp_if . '</td>' . PHP_EOL; $string .= ' </tr>' . PHP_EOL; } $string .= ' </tbody>' . PHP_EOL; $string .= '</table>'; $string .= generate_box_close(); // Print pagination header if ($pagination) { $string = pagination($vars, $count) . $string . pagination($vars, $count); } // Print ARP/NDP table echo $string; }