Device View

<& SELF:show_device &>

Device Search - Quick

Device name or IP : [Reset Page]

[Full Search]

<%args> $ip => '' # Can be IP or hostname @port => () # Ports to be shown @portcol => () # Columns to Show for each port $submit => '' # Can have all/hide to control ports $device_age => 'off' $archive => 'off' $node_ip => 'off' # Show the IPs used by each MAC $node_dns => 'off' # Resolve IPs of connected devices <%shared> my ($arg_age,$arg_arch,$device,$devip,$arg_node_ip, $arg_node_dns); my $ports = []; my $node_ips = {}; my @arg_port; my $domain = $netdisco::CONFIG{domain}; my $now = time; my $match = 0; my $odd = 1; # Change which columns are shown in ports by default. my %port_cols = ( 'descr'=> ['Description',0], 'type' => ['Type',0], 'duplex' => ['Duplex
(Link/Admin)',1], 'speed' => ['Speed',1], 'name' => ['Name',1], 'mac' => ['Port MAC',0], 'mtu' => ['MTU',0], 'vlan' => ['VLAN',1], 'lastchange' => ['Last Change',0], 'stp' => ['Spanning Tree',0], ); my %device_info = ( 'Aliases' => 'aliases', 'First Discovered' => 'creation', 'Last MacSuck' => 'last_macsuck', 'Last ArpNip' => 'last_arpnip', 'Mac Address' => 'mac', #'OSI Layers' => 'layers', 'VTP Domain' => 'vtp_domain', #'Ports' => 'ports', #'Backplane Slots' => 'slots', ); # These are switches that we want a link to their web interface. my $web_vendors = $netdisco::CONFIG{web_console_vendors} || {}; my $web_models = $netdisco::CONFIG{web_console_models} || {}; my $user = $m->session->{user}; my $secure = &is_secure; my $port_ctl = $m->session->{user_port_ctl}; my $port_control = ($port_ctl and $secure); my $port_info = (defined $netdisco::CONFIG{port_info} and $netdisco::CONFIG{port_info} =~ /(1|t|T|y|Y)/) ? 1 : 0; my $admin = defined $m->session->{user_admin} and $m->session->{user_admin} ? 1 : 0; <%init> # Parsing of Arguments $arg_age = $device_age; $arg_arch = $archive; @arg_port = @port; $arg_node_ip = $node_ip; $arg_node_dns = $node_dns; if ($ip) { # Save Search Term $match = $ip; # Resolve input my $hostname = &hostname($ip); my $ip = &getip($ip); # Check if we're an alias of another device $devip = &root_device($ip); # redirect to search if no match $m->redirect("device_search.html?text=$match") unless $devip; # Grab Device INFO $device = sql_hash('device', ['ip','extract(epoch from creation) as creation','dns', 'description','uptime','contact','name','location','layers', 'ports','mac','serial','model','ps1_type','ps2_type','ps1_status', 'ps2_status','fan','slots','vendor','log','os_ver','os','vtp_domain', 'extract(epoch from last_discover) as last_discover', 'extract(epoch from last_macsuck) as last_macsuck', 'extract(epoch from last_arpnip) as last_arpnip' ], {'ip'=>$devip}); # This could take a while. $m->flush_buffer(); # Grab aliases my $aliases = sql_rows('device_ip',['alias','dns','port'], {'ip'=>$devip}); # Sort Aliases by Port my $port_aliases = {}; foreach my $a (@$aliases) { push @{$port_aliases->{$a->{port}}},$a; } $device->{aliases} = $aliases; # Hide Ports if ($submit =~ /hide/i) { @port = @arg_port = (); } # All Ports if ($submit =~ /all/i or grep(/^all$/,@port)){ @arg_port = @port = ('all'); $ports = sql_rows('device_port',['*'],{'ip'=>$devip}) || []; } # Selected Ports else { foreach my $portreq (@port) { next unless defined $portreq; my $db_ports = sql_rows('device_port',['*'], {'ip'=>$devip,'port'=>$portreq}); # add our results to the list if (defined $db_ports and scalar @$db_ports){ push (@$ports,@$db_ports); } } } # PORTS - Connected Nodes, aliases and log entries foreach my $portreq (@$ports) { my $switch = $portreq->{ip}; my $port = $portreq->{port}; $portreq->{portdisp} = $portreq->{port}; # Get count of log entries for this port $portreq->{logs} = sql_scalar('device_port_log',['count(id)'],{'ip'=>$switch,'port'=>$port}); # Get Nodes Attached my $nodes = sql_rows('node', ['mac','active','extract (epoch from time_first) as time_first', 'extract (epoch from time_last) as time_last'], {'switch' => $switch, 'port' => $port } ); $portreq->{macs} = (defined $nodes and scalar @$nodes) ? $nodes : undef; # Save MAC addresses for IP lookup foreach my $node (@$nodes){ my $mac = $node->{mac}; $node_ips->{$mac}++; } # Add aliases to display of port name my $aliases = $port_aliases->{$port} || []; foreach my $alias ( sort {sort_ip($a->{alias},$b->{alias})} @$aliases ) { my $alias_ip = $alias->{alias}; my $dns = $alias->{dns} || '[No DNS]'; $dns =~ s/\Q$domain\E//; $portreq->{portdisp} .= "
$alias_ip ($dns)"; } } # Get IP addresses of connected nodes if ($node_ip eq 'on'){ my @macs = keys %$node_ips; my $ips = sql_rows('node_ip',['mac','ip'], {active => 1, mac => [\@macs] } ); $node_ips = {}; # Push IP address into list in %node_ips hash foreach my $macip (@$ips){ my $mac = $macip->{mac}; my $ip = $macip->{ip}; push ( @{$node_ips->{$mac}},$ip); } } # Resolve IPs of connected nodes to host names if ($node_ip eq 'on' and $node_dns eq 'on'){ } } # Change the columns of ports shown if (scalar @portcol and join('',@portcol) !~ /^\s*$/) { # Set all to not seen foreach my $key (keys %port_cols){ $port_cols{$key}->[1] = 0; } # show the ones we want foreach my $col (@portcol) { # Check for funny things passed next unless defined ($port_cols{$col}); # Set the passed one as shown $port_cols{$col}->[1] = 1; } } %# %# END MAIN COMPONENT %# %# port_view() - Prints out the Port View control form %# <%method port_view>

Port View

% foreach my $port (@arg_port){ %} % if (defined $ports and scalar @$ports) { % }

Columns: % foreach my $col (keys %port_cols) { % my $name = $port_cols{$col}->[0]; % my $check = $port_cols{$col}->[1]; % $name =~ s/
.*$//; <%$name%>>  % }
Connected Device Age Stamp: >Off >On         Show Archived Data: >Off >On
Show Connected Device IP: >Off >On         Resolve IPs >Off >On

%# %# show_device() - Display device Info. %# <%method show_device> <%perl> return unless defined $device; my $dns = $device->{dns} || '[No DNS]'; my $vendor = $device->{vendor}; my $model = $device->{model}; my $want_web_link = (defined $web_vendors->{$vendor} or defined $web_models->{$model}); my $web_dns = $dns; $web_dns =~ s/\Q$domain\E//; <%$dns%> (<%$devip%>) % if ($want_web_link or $admin) {
%} % if ($want_web_link) { [Web Console] % } % if ($admin) { [Device Control] % }
% if (defined $device->{fan} or $device->{ps1_status}) { % } <%perl> # Print out each item in the database that we have using the # %device_info map. foreach my $item (sort keys %device_info) { my $db_col = $device_info{$item}; my $val = $device->{$db_col}; next unless defined $val and length($val); # Munge if ($db_col eq 'aliases'){ next unless scalar @$val; my @vals; foreach my $alias (sort { sort_ip($a->{alias}, $b->{alias}) } @$val){ my $ip = $alias->{alias}; my $dns = $alias->{dns}; $dns = defined $dns ? $dns : '[No DNS]'; $dns =~ s/\Q$domain\E//; my $port = $alias->{port}; push (@vals, "$ip ($dns) \@ $port"); } $val = join("
",@vals); } if ($db_col eq 'creation') { $val = localtime($val); } if ($db_col eq 'last_discover') { $val = localtime($val); } if ($db_col eq 'last_macsuck') { $val = localtime($val); } if ($db_col eq 'last_arpnip') { $val = localtime($val); } my $match_class = ++$odd % 2; $m->out(""); $m->out("\n"); } # Treat the log a little different my $log = $device->{log}; if (defined $log and length($log)){ my $logclass = ++$odd % 2; %}
Name <%$device->{name}|h%>
Location / Contact <%$device->{location} || '[Not Set]' |h%> / <%$device->{contact} || '[Not Set]' |h%>
Model / Serial <%$device->{vendor}%> <%$device->{model}%> / <%$device->{serial} || 'Unknown'%>
OS / Version <%$device->{os} || 'Unknown'%> / <%$device->{os_ver} || 'Unknown'%>
Description <%$device->{description}|h%>
Uptime/
Last Discovered
<% $m->comp('SELF:uptime', uptime => $device->{uptime})%> / <% scalar localtime($device->{last_discover}) %>
Power % if (defined $device->{fan}) { Fan : <%$device->{fan}%>    % } % if (defined $device->{ps1_status}) { PS1 [<%$device->{ps1_type}%>] : <%$device->{ps1_status}%>   % } % if (defined $device->{ps2_status}) { PS2 [<%$device->{ps2_type}%>] : <%$device->{ps2_status}%>   % }
$item$val
Log
<& SELF:show_ports &> %# %# port_header() - Prints out the header block depending on the columns selected %# <%method port_header> Port % foreach my $col (sort keys %port_cols){ % my $desc = $port_cols{$col}->[0]; % my $on = $port_cols{$col}->[1]; % next unless $on; <%$desc%> %} Connected
Devices<% $arg_age eq 'on' ? '
(Last Seen)' : ''%> %# if ($port_control) { Port
Control %#} %# %# show_ports() %# <%method show_ports> <%perl> # No ports specified unless (scalar @$ports) { $m->comp('SELF:port_view' ); return; } # Ports Found my $link = $r->uri() . "?ip=$devip"; <& SELF:port_header &> <%perl> # Display the Ports foreach my $port (sort sort_port @$ports){ my $remote_ip = $port->{remote_ip}; my $remote_port = $port->{remote_port}; my $remote_id = $port->{remote_id}; my $remote_type = $port->{remote_type}; my $up_admin = $port->{up_admin} || ''; my $stp = $port->{stp} || ''; my $up = $port->{up} || ''; # An uplink is a port that has a remote_ip but is not a phone # We do _not_ allow shutdown of ports that have remote info but are not # in our database. Consider an SNMP problem. Or consider your routes off-site # where your ISP might squawk CDP, but we don't have SNMP. We don't want to # allow people to turn those off. my $is_uplink = (defined $remote_ip and !(defined $remote_type and $remote_type =~ /ip.phone/i)) ? 1 : 0; my $class = $up eq 'down' ? 'port-down' : 'port-up'; $class = $up_admin eq 'down' ? 'port-off' : $class; # Check for STP blocking, but not down $class = ($up ne 'down' and $stp =~ /(blocking|broken)/) ? 'port-block' : $class; my $rowclass = (++$odd % 2 ) ? 'match-0': 'match-1'; <%perl> foreach my $col (sort keys %port_cols){ my $colname = $port_cols{$col}->[0]; my $colcheck = $port_cols{$col}->[1]; next unless $colcheck; my $val = $port->{$col}; # Munge Port Columns if ($col eq 'duplex') { $val = defined $val ? $val : '[NA]'; my $duplex_admin = $port->{duplex_admin}; $duplex_admin = defined $duplex_admin ? $duplex_admin : '[NA]'; $val .= "/$duplex_admin"; } if ($col eq 'lastchange'){ # lastchange is a timestamp of the sysUpTime # we subtract it from the current uptime to find out how many # seconds*100 it was, then we subtract that from the current time to # see when that was. my $diff_sec = ($device->{uptime} - $val) / 100; $val = scalar localtime(time - $diff_sec); } % } % # Connected Devices Column % # Port Control Column % } # end foreach port % % # Print out the legend again if we have lots of results % $m->comp('SELF:port_header') if (scalar @$ports > 10); % <& SELF:port_key &> <& SELF:port_view &> <%method port_key>
<% $port->{portdisp} %> <% $val || '' |h %> <%perl> # CDP speaking device connected if (defined $remote_ip) { my $name = ''; my $link = ''; my $remote_dev = sql_hash('device',['ip','dns'], {'ip'=>$remote_ip}); my $alias = sql_hash('device_ip',['ip','dns'], {'alias'=>$remote_ip}); # Resolve IP address squawked to root device if (defined $alias) { $remote_ip = $alias->{ip}; $name = $alias->{dns}; $name = defined $name ? $name : $remote_ip; $name =~ s/\Q$domain\E//; $name .= " ($remote_port)"; $name = "$name"; $link = "device.html?ip=$remote_ip&port=$remote_port"; # Not an alias, use info from device table } elsif (defined $remote_dev) { $name = $remote_dev->{'dns'}; $name = defined $name ? $name : $remote_ip; $name =~ s/\Q$domain\E//; $name .= " ($remote_port)"; $name = "$name"; $link = "device.html?ip=$remote_ip&port=$remote_port"; # Found a device, but not in our database } else { if ($arg_node_dns eq 'on') { $name = hostname($remote_ip) || $remote_ip; $name =~ s/\Q$domain\E//; } else { $name = $remote_ip; } my $spanclass = (defined $remote_type and $remote_type =~ /ip.phone/i) ? 'ip-phone' : 'dead-link'; $name = "$name"; $name .= " ($remote_port)"; $name .= "
   ($remote_type)" if defined $remote_type; $name .= "/($remote_id)" if defined $remote_id; $link = "node.html?node=$remote_ip"; } <%$name%> \ <%perl> } $m->out("
\n") if (defined $remote_ip and defined $port->{macs}); # Show connected nodes my $seen_macs=0; my $portnodes = $port->{macs} || []; foreach my $node (sort {$a->{mac} cmp $b->{mac}} @$portnodes) { my $mac = $node->{mac}; my $active = $node->{active}; my $time_last = $node->{time_last}; # Connected Device Age Stamp? my $age = $now - $time_last; $age = sprintf("%d", ($age / (60*60*24))); my $show_age = ($arg_age eq 'on' and $age > 0) ? " ($age days)" : ''; # Show Archived Data? next unless ($active or $arg_arch eq 'on'); $seen_macs++; <% $mac%><%$show_age%><% $active ? '' : '*'%>
<%perl> # Show node_ips? if ($arg_node_ip eq 'on' and defined $node_ips->{$mac}) { foreach my $ip (sort sort_ip @{$node_ips->{$mac}}) { # Show Node DNS ? my $host = $ip; if ($arg_node_dns eq 'on'){ $host = hostname($ip) || $ip; $host =~ s/\Q$domain\E//; # Add IP if we found a hostname. $host .= " ($ip)" if ($host ne $ip); }      <%$host%>
<%perl> } # /each node_ip } # /if node_ip } # /each node # Place holder for no connected devices unless ($seen_macs or defined $remote_ip) { $m->out(' '); } # end connected dev col.
\ % if ($device->{dns} =~ /^hub/i and $port_info) { Pinnacles DB Info \ % } % if ($port->{logs}){ <%$port->{logs}%> Admin Log Entries \ % } % if ($port_control and !$is_uplink) { % my $dir = $port->{up_admin} eq 'down' ? 'up' : 'down'; Bring Port <%$dir%> \ % } elsif (! $port->{logs}){   \ % }

Key

% if ($port_control) { %} % if ($arg_arch eq 'on' or $arg_age eq 'on'){ % }
Ports: [Admin Disabled] [Link Down] [Blocking] [IP Phone] (Discovered Neighbor not accessible)
Admin : Log Enable Disable Pinnacle DB Info
Settings : Entries without timestamps are less than 1 day old.
* denotes archived data
%# %# uptime() - Returns pretty-print of uptime values %# <%method uptime> <%args> $uptime <%perl> # uptime is in 100ths of seconds my $val = int($uptime/100); my $sec = $val % 60; $val = ( $val - $sec ) / 60; my $min = $val % 60; $val = ( $val - $min ) / 60; my $hour = $val % 24; $val = ( $val - $hour ) / 24; my $day = $val % 7; my $week = ($val - $day) / 7; my @times; push (@times,"$week weeks") if $week; push (@times,"$day days") if ($week or $day); push (@times,"$hour hours") if ($week or $day or $hour); push (@times,"$min min.") if ($week or $day or $hour or $min); return join(',',@times); <%method title> - Device View \ %# $Id: device.html,v 1.28 2004/12/06 16:41:30 maxbaker Exp $ %# vim:syntax=mason