#!/usr/bin/perl -w # $Id$ $DevMatrix = '../DeviceMatrix.txt'; $DevHTML = 'DeviceMatrix.html'; $DevPNG = 'DeviceMatrix.png'; $Attributes= {}; # Parse Data File $matrix = parse_data($DevMatrix); # Graph it for fun eval "use GraphViz::Data::Structure;"; if ($@) { print "GraphViz::Data::Structure not installed. $@\n"; } else { my %graph = (); foreach my $vendor (sort sort_nocase keys %$matrix){ $graph{$vendor} = {}; foreach my $family (sort sort_nocase keys %{$matrix->{$vendor}->{families}} ){ my @models; foreach my $mod (keys %{$matrix->{$vendor}->{families}->{$family}->{models}}){ push(@models,split(/\s*,\s*/,$mod)); } if (scalar @models){ $graph{$vendor}->{$family}=\@models; } else { $graph{$vendor}->{$family}=[]; } } } my $now = scalar localtime; my $gvds = GraphViz::Data::Structure->new(\%graph,Orientation=>'vertical', Colors=> 'Deep', graph => {label=>"SNMP::Info and Netdisco Supported Devices \n $now",'fontpath'=>'/usr/local/netdisco','fontname'=>'lucon',concentrate=>'true','overlap'=>'false',spline=>'true',bgcolor=>'wheat'}, node => {fontname=>'lucon'}, ); $gvds->graph()->as_png($DevPNG); } open (HTML, "> $DevHTML") or die "Can't open $DevHTML. $!\n"; $old_fh = select(HTML); &html_head; print_vendors($matrix); foreach my $vendor (sort sort_nocase keys %$matrix){ print "$vendor\n"; print "
\n"; my $vendor_defaults = $matrix->{$vendor}->{defaults}; print_notes($vendor_defaults,1); my $families = $matrix->{$vendor}->{families}; foreach my $family (sort sort_nocase keys %$families ) { print "
$family Family\n"; my $family_defaults = $families->{$family}->{defaults}; print_notes($family_defaults,2); my $models = $families->{$family}->{models}; foreach my $model (sort sort_nocase keys %$models ){ my $model_defaults = $models->{$model}->{defaults}; print "
$model\n"; print "
\n"; print_notes($model_defaults,3); print "
\n"; print_headers(); print "\n"; foreach my $a (sort sort_nocase keys %$Attributes) { my $val; next if $a eq 'note'; $val = ['-']; $class = 'none'; if (defined $model_defaults->{$a}) { $val = $model_defaults->{$a}; $class = 'model'; } elsif (defined $family_defaults->{$a}){ $val = $family_defaults->{$a}; $class = 'family'; } elsif (defined $vendor_defaults->{$a}){ $val = $vendor_defaults->{$a}; $class = 'vendor'; } print " \n"; } print "
",join("
\n",@$val),"
\n"; print "
\n"; } } print "
\n"; } &html_tail; select ($old_fh); close (HTML) or die "Can't write $DevHTML. $!\n"; # Data Structures # Matrix = # ( vendor => { families => { family => family_hash }, # defaults => { cmd => [values] }, # } # ) # Family Hash # ( models => { model => model_hash }, # defaults => { cmd => [values] } # ) # Model Hash # ( defaults => { cmd => [values] } ) sub parse_data { my $file = shift; my %ignore = map { $_ => 1 } @_; my $Matrix; my @Lines; open (DM, "< $file") or die "Can't open $file. $!\n"; { @Lines = ; } close (DM); my ($device,$family,$vendor,$class); foreach my $line (@Lines){ chomp($line); # Comments $line =~ s/#.*//; # Blank Lines next if $line =~ /^\s*$/; # Trim whitespace $line =~ s/^\s+//; $line =~ s/\s+$//; my ($cmd,$value); if ($line =~ /^([a-z-_]+)\s*:\s*(.*)$/) { $cmd = $1; $value = $2; } else { print "What do i do with this line : $line \n"; next; } if (exists $ignore{$cmd}){ print "Ignoring $cmd\n"; } # Set Class {vendor,family,device} if ($cmd eq 'device-vendor'){ $vendor = $value; $family = $model = undef; $Matrix->{$vendor} = {} unless defined $Matrix->{$vendor}; $class = $Matrix->{$vendor}; $class->{defaults}->{type}='vendor'; next; } if ($cmd eq 'device-family'){ $family = $value; $model = undef; print "$family has no vendor.\n" unless defined $vendor; $Matrix->{$vendor}->{families}->{$family} = {} unless defined $Matrix->{$vendor}->{families}->{$family}; $class = $Matrix->{$vendor}->{families}->{$family}; $class->{defaults}->{type}='family'; next; } if ($cmd eq 'device') { $model = $value; print "$model has no family.\n" unless defined $family; print "$model has no vendor.\n" unless defined $vendor; $Matrix->{$vendor}->{families}->{$family}->{models}->{$model} = {} unless defined $Matrix->{$vendor}->{families}->{$family}->{models}->{$model}; $class = $Matrix->{$vendor}->{families}->{$family}->{models}->{$model}; $class->{defaults}->{type}='device'; next; } # Store attribute push (@{$class->{defaults}->{$cmd}} , $value); $Attributes->{$cmd}++; } return $Matrix; } sub sort_nocase { return lc($a) cmp lc($b); } sub print_notes { my $defaults = shift; my $level = shift; my $notes = $defaults->{note} || []; foreach my $note (@$notes){ if ($note =~ s/^!//){ $note = '' . $note . ''; } } if (scalar @$notes){ print "
\n"; my $print_note = join("\n
  • ",@$notes); print "
    • $print_note
    \n"; } } sub print_vendors { my $matrix=shift; print "

    Device Vendors

    \n"; foreach my $vendor (sort sort_nocase keys %$matrix){ print "[$vendor]\n"; } print "
    \n"; } sub html_head { print <<"end_head"; SNMP::Info - Device Compatibility Matrix

    SNMP::Info - Device Compatibility Matrix

    end_head } sub html_tail { print <<'end_tail';


    Color Key

    [Model Attribute] [Family Attribute] [Vendor Attribute]

    Attribute Key

    A value of - signifies the information is not specified and can be assumed working.
    Arpnip Ability to collect ARP tables for MAC to IP translation.
    CDP Cisco Discovery Protocol usable.
    • Yes - Has CDP information through CISCO-CDP-MIB
    • Proprietary means the device has its own L2 Discovery Protocol.
    Class SNMP::Info Class the the device currently uses. Devices using more generic interfaces like Layer2 or Layer3 may eventually get their own subclass.
    Duplex Ability to cull duplex settings from device.
    • no - Can't recover current or admin setting.
    • link - Can get current setting only.
    • both - Can get admin and link setting.
    • write - Can get admin and link setting and perform sets.
    Macsuck Ability to get CAM tables for MAC to switch port mapping.
    • no - Have not found an SNMP method to get data yet.
    • yes - Can get through normal SWITCH-MIB method.
    • vlan - Have to re-connect to each VLAN and then fetch with normal method.
    Portmac Whether the device will list the MAC address of the switch port on each switch port when doing a Macsuck.
    Ver SNMP Protocol Version the device has to use.
    Vlan Ability to get VLAN port assignments.
    • no - Have not found an SNMP method to get data yet.
    • yes - Can read information.
    • write - Can read and write (set).
    end_tail } sub print_headers { print "\n"; foreach my $a (sort sort_nocase keys %$Attributes) { next if $a eq 'note'; print " $a\n"; } print "\n"; }