#!/usr/bin/perl use strict; use warnings; use Net::SNMP; my $host = $ARGV[0] or die "Usage: $0 <host>\n"; print "Scanning $host...\n"; my $sess = Net::SNMP->session( -hostname => $host . '.kam.mff.cuni.cz', -version => 1, -community => 'public', ) or die; my $prmib = '1.3.6.1.2.1.43'; sub parse_table($) { my $raw = $sess->get_table(-baseoid => $_[0]) or return {}; my %tab = (); for my $bb (keys %$raw) { my $bk = substr($bb, length($_[0]) + 1); $bk =~ /(.*)\.1\.(\d+)/ or die "OID parse error at $bk"; $tab{$2}{$1} = $raw->{$bb}; } return \%tab; } sub media_unit($) { my ($unit) = @_; return unless defined $unit; return 25.4 / 10000 if $unit == 3; return 0.001 if $unit == 4; return 1 if $unit == 0; # Some printers (Xerox 3300MFP) send unit 0 -- what does it mean? die "Unknown media unit $unit\n"; } sub subunit_status($) { my ($s) = @_; my @bases = ('Idle', 'OnReq', 'Standby', 'Broken', 'Active', 'Unknown', 'Busy', '??7??'); my $base = $bases[$s & 7]; if ($s & 8) { $base .= '/Alert'; } if ($s & 16) { $base .= '/CritAlert'; } if ($s & 32) { $base .= '/Offline'; } if ($s & 64) { $base .= '/Transition'; } return $base; } sub current($) { my ($c) = @_; return "other" if $c == -2; return "unknown" if $c == -2; return "OK" if $c == -3; return "???" if $c < 0; return $c; } print "\n### Inputs ###\n"; my $ins = parse_table("$prmib.8.2.1"); for my $i (sort keys %$ins) { my $b = $ins->{$i}; printf "%-10s ", ($b->{13} // "Input #$i"); my $unit = media_unit($b->{3}); print join("x", map { (!defined($_) || $_ < 0) ? '?' : sprintf("%.0f", $_*$unit) } ($b->{4}, $b->{5})); print " capa=", $b->{9}; print " cur=", current($b->{10}); print " stat=", subunit_status($b->{11}); print " media=", $b->{12}; print "\n"; } print "\n### Outputs ###\n"; my $outs = parse_table("$prmib.9.2.1"); for my $i (sort keys %$outs) { my $b = $outs->{$i}; printf "%-10s ", ($b->{7} // "Output #$i"); my $unit = media_unit($b->{14}); print join("x", map { (!defined($_) || $_ < 0) ? '?' : sprintf("%.0f", $_*$unit) } ($b->{15}, $b->{16})); print " capa=", $b->{4}; print " remains=", current($b->{5}); print " stat=", subunit_status($b->{6}); print "\n"; } print "\n### Marker ###\n"; my $mkrs = parse_table("$prmib.10.2.1"); my $mkr = $mkrs->{1}; # Multiple markers not supported by this simple-minded script $mkr->{3} == 7 or die "Unknown marker counter unit " . $mkr->{3}; print "Life counter: ", $mkr->{4}, "\n"; my $mmu = media_unit($mkr->{8}); print "Resolution: ", join("x", map { sprintf("%.0f", $_ / (10000*$mmu) * 25.4); } ($mkr->{9}, $mkr->{10})), " DPI\n"; print "Margins: ", join("/", map { sprintf("%.2f", $_*$mmu) } ($mkr->{11}, $mkr->{12}, $mkr->{13}, $mkr->{14})), " mm\n"; print "Status: ", subunit_status($mkr->{15}), "\n"; print "\n### Colorants ###\n"; my $colors = parse_table("$prmib.12.1.1"); my %clrants = (); for my $i (sort keys %$colors) { my $c = $colors->{$i}; print "Color $i: ", $c->{4}, "\n"; $clrants{$i} = $c->{4}; } my %supply_types = ( 1 => 'other', 2 => 'unknown', 3 => 'toner', 4 => 'wasteToner', 5 => 'ink', 6 => 'inkCartridge', 7 => 'inkRibbon', 8 => 'wasteInk', 9 => 'opc', 10 => 'developer', 11 => 'fuserOil', 12 => 'solidWax', 13 => 'ribbonWax', 14 => 'wasteWax', 15 => 'fuser', 16 => 'coronaWire', 17 => 'fuserOilWick', 18 => 'cleanerUnit', 19 => 'fuserCleaningPad', 20 => 'transferUnit', 21 => 'tonerCartridge', 22 => 'fuserOiler', 23 => 'water', 24 => 'wasteWater', 25 => 'glueWaterAdditive', 26 => 'wastePaper', 27 => 'bindingSupply', 28 => 'bandingSupply', 29 => 'stitchingWire', 30 => 'shrinkWrap', 31 => 'paperWrap', 32 => 'staples', 33 => 'inserts', 34 => 'covers' ); print "\n### Supplies ###\n"; my $supp = parse_table("$prmib.11.1.1"); for my $i (sort { $a <=> $b } keys %$supp) { my $s = $supp->{$i}; printf "%2d: ", $i; printf "%-16s", ($supply_types{$s->{5}} // "??" . $s->{4} . "??"); printf "%-8s", $s->{3} ? ($clrants{$s->{3}} // "Color" . $s->{3}) : "---"; printf "%-16s", (current($s->{9}) . "/" . $s->{8}); if ($s->{8} && $s->{9} >= 0) { printf " %3.0f%%", $s->{9} * 100 / $s->{8}; } else { print " ----"; } print " ", $s->{6}; print "\n"; } print "\n### Console ###\n"; my $con = parse_table("$prmib.16.5.1"); for my $i (sort keys %$con) { print "$i:", $con->{$i}->{2}, "\n" if $con->{$i}->{2} =~ /\S/; } print "\n### Lights ###\n"; my $lights = parse_table("$prmib.17.6.1"); for my $i (sort keys %$lights) { my $l = $lights->{$i}; my %color = ( 1=>'other', 2=>'unkn', 3=>'white', 4=>'red', 5=>'green', 6=>'blue', 7=>'cyan', 8=>'mgnta', 9=>'yellw', 10=>'ornge' ); if ($l->{2} && !$l->{3}) { print "[*]"; } elsif (!$l->{2} && $l->{3}) { print "[ ]"; } elsif ($l->{2} && $l->{3}) { print "[.]"; } else { print "[?]"; } printf " %5s", $color{$l->{4}} // "?????"; print " ", $l->{5}; print "\n"; } print "\n### Alerts ###\n"; my $alerts = parse_table("$prmib.18.1.1"); for my $i (sort keys %$alerts) { my $a = $alerts->{$i}; print "$i:"; my %severity = ( 1=>'other', 2=>'CRIT', 3=>'WARN', 4=>'WARN' ); print " sev=", $severity{$a->{2}} // "???"; my %training = ( 6=>'management', 5=>'service', 4=>'trained', 3=>'untrained', 2=>'unknown', 1=>'other' ); print " who=", $training{$a->{3}} // "???"; print " group=", $a->{4}; print " index=", $a->{5}; print " loc=", $a->{6}; print " code=", $a->{7}; print " desc=", $a->{8}; print " time=", $a->{9}; print "\n"; } print "\n### Finisher ###\n"; my $finisher = parse_table("$prmib.30.1.1"); for my $i (sort keys %$finisher) { my $f = $finisher->{$i}; print "$i:"; print " type=", $f->{2}; print " present=", $f->{3}; print " capa=", $f->{5}; print " current=", current($f->{6}); print " status=", subunit_status($f->{9}); print " desc=", $f->{10}; print "\n"; } print "\n### Finisher supplies ###\n"; my $fsu = parse_table("$prmib.31.1.1"); for my $i (sort keys %$fsu) { my $f = $fsu->{$i}; print "$i:"; print " dev=", $f->{2}; print " class=", $f->{3}; print " type=", $f->{4}; print " desc=", $f->{5}; print " capa=", $f->{7}; print " current=", current($f->{8}); print "\n"; }