#!/usr/athena/bin/perl
# This script just uses Net::SNMP to query some OID's in HP laserjet printers.
# While some laserjets support SNMPv2c, there are a bunch that don't.  The OIDs
# were found by snmpwalk'ing various printers and picking out interesting
# values.  jhawk apparently grabbed an old copy of HP's SNMP MIB and put it in:
# /afs/sipb.mit.edu/project/outland/share/snmp/mibs/hpnp.mib
# It's not 100% correct though, so don't trust it completely.
# -Rob Radez <rradez> 2005/3/16

use Net::SNMP;
use Socket;

if(@ARGV == 1){
	$detailed = 0;
	$hostname = $ARGV[0];
} elsif(@ARGV == 2){
	$hostname = $ARGV[1];
	if($ARGV[0] =~ /-t/){
		$detailed = 0;
	} elsif($ARGV[0] =~ /-T/){
		$detailed = 1;
	} else {
		&usage();
		exit(-1);
	}
} else {
	&usage();
	exit(-1);
}

$community = "public";
$port = 161;

%syslogfacilities = (
16<<3		=>	'local0',
17<<3		=>	'local1',
18<<3		=>	'local2',
19<<3		=>	'local3',
20<<3		=>	'local4',
21<<3		=>	'local5',
22<<3		=>	'local6',
23<<3		=>	'local7',
);

%tonerstatus = (
0		=>	'Toner Okay',
1		=>	'Toner Low',
2		=>	'No Toner Cartridge Loaded',
);

%paperstatus = (
0		=>	'Paper Okay',
1		=>	'Out Of Paper or No Cassette Loaded',
2		=>	'Manual Paper Feed Required',
);

%jamstatus = (
0		=>	'No Jam Detected',
1		=>	'Paper Jam Detected',
);

%configsrc = (
3		=>	'Front Panel',
4		=>	'BOOTP',
);

($session, $error) = Net::SNMP->session(-hostname => $hostname, -community => $community, -port => $port);

if(!defined($session)){
	print "Error trying SNMPv1: $error\n";
	exit 1;
}

%map = (
'HOSTNAME'	=>	'.1.3.6.1.2.1.1.5.0',
'CONFIGSRC'	=>	'.1.3.6.1.4.1.11.2.4.3.5.1.0',
'IPADDR'	=>	'.1.3.6.1.4.1.11.2.4.3.5.2.0',
'UPTIME'	=>	'.1.3.6.1.2.1.1.3.0',
# I think I got the following OIDs from npadmin --debugsnmp --display $HOST
'FRONTPANEL'	=>	'.1.3.6.1.2.1.43.16.5.1.2.1.1',
'FRONTPANEL2'	=>	'.1.3.6.1.2.1.43.16.5.1.2.1.2',
'FRONTPANEL3'	=>	'.1.3.6.1.2.1.43.16.5.1.2.1.3',
'FRONTPANEL4'	=>	'.1.3.6.1.2.1.43.16.5.1.2.1.4',
'FRONTPANEL5'	=>	'.1.3.6.1.2.1.43.16.5.1.2.1.5',
# the OID below works also, but only appears to get the first line
#'FRONTPANEL'	=>	'.1.3.6.1.4.1.11.2.3.9.1.1.3.0',
'TONERLOW'	=>	'.1.3.6.1.4.1.11.2.3.9.1.1.2.10.0',
'PAPERJAM'	=>	'.1.3.6.1.4.1.11.2.3.9.1.1.2.9.0',
'PAPEROUT'	=>	'.1.3.6.1.4.1.11.2.3.9.1.1.2.8.0',
'LASTFATAL'	=>	'.1.3.6.1.4.1.11.2.4.3.1.3.0',
'NETMASK'	=>	'.1.3.6.1.4.1.11.2.4.3.5.12.0',
#'DEFAULTGW'	=>	'.1.3.6.1.2.1.4.21.1.7.0.0.0.0',
'DEFAULTGW'	=>	'.1.3.6.1.4.1.11.2.4.3.5.13.0',
'IDLETIMEOUT'	=>	'.1.3.6.1.4.1.11.2.4.3.5.10.0',
'SYSLOGSERVER'	=>	'.1.3.6.1.4.1.11.2.4.3.5.5.0',
'SYSLOGFACILITY'=>	'.1.3.6.1.4.1.11.2.4.3.5.6.0',
'BOOTPSERVER'	=>	'.1.3.6.1.4.1.11.2.4.3.5.3.0',
'LOCATION'	=>	'.1.3.6.1.2.1.1.6.0',
'CONTACT'	=>	'.1.3.6.1.2.1.1.4.0',
#'ACLLEN'	=>	'.1.3.6.1.4.1.11.2.4.3.5.8.0',
);

@oids = values(%map);

# Get the values for all of the SNMP OIDs listed above in %map
$result = $session->get_request(-varbindlist => \@oids);

# Get the Access Control List Entries as a table, because there are unknown
# number of them.  They're all children of the SNMP OID below, so we can just
# get a table and it should do the right thing.
$HOSTACLOID = ".1.3.6.1.4.1.11.2.4.3.5.9.1.2";
$aclres = $session->get_table(-baseoid => $HOSTACLOID);
if($session->error()){
	print $session->error()." lol\n";
}

$session->close;

$ipaddr = $result->{$map{'IPADDR'}};
$fqdn = gethostbyaddr(inet_aton($ipaddr), AF_INET);
$srctype = $result->{$map{'CONFIGSRC'}};
$toner = $result->{$map{'TONERLOW'}};
$paper = $result->{$map{'PAPEROUT'}};
$jam = $result->{$map{'PAPERJAM'}};

$frontpanel = $result->{$map{'FRONTPANEL'}};
$frontpanel2 = $result->{$map{'FRONTPANEL2'}};
$frontpanel3 = $result->{$map{'FRONTPANEL3'}};
$frontpanel4 = $result->{$map{'FRONTPANEL4'}};
$frontpanel5 = $result->{$map{'FRONTPANEL5'}};

print "Host Name		: $result->{$map{'HOSTNAME'}}\n";
print "Config Source		: $configsrc{$srctype}\n";
print "IP Address		: " . &fqdn($ipaddr) . "\n";
print "Uptime			: $result->{$map{'UPTIME'}}\n";

print "Front Panel Message	: $frontpanel\n";
print "	(line 2)	: $frontpanel2\n" if($frontpanel2 =~ /.+/);
print "	(line 3)	: $frontpanel3\n" if($frontpanel3 =~ /.+/);
print "	(line 4)	: $frontpanel4\n" if($frontpanel4 =~ /.+/);
print "	(line 5)	: $frontpanel5\n" if($frontpanel5 =~ /.+/);

print "Toner Status		: ($toner) $tonerstatus{$toner}\n";
print "Paper Status		: ($paper) $paperstatus{$paper}\n";
print "Paper Jam Status	: ($jam) $jamstatus{$jam}\n";
print "Last Fatal Error	: $result->{$map{'LASTFATAL'}}\n";

if($detailed){
	$syslogserver = $result->{$map{'SYSLOGSERVER'}};
	$syslogfqdn = gethostbyaddr(inet_aton($syslogserver), AF_INET);
	$bootpserver = $result->{$map{'BOOTPSERVER'}};
	print "\n";
	print "Host Name		: $result->{$map{'HOSTNAME'}}\n";
	print "Config Source		: $configsrc{$srctype}\n";
	print "IP Address		: " . &fqdn($ipaddr) . "\n";
	print "Network Mask		: $result->{$map{'NETMASK'}}\n";
	print "Default Gateway		: $result->{$map{'DEFAULTGW'}}\n";
	print "Idle Timeout		: $result->{$map{'IDLETIMEOUT'}}\n";
	print "Syslog Server		: " . &fqdn($syslogserver) . "\n";
	print "Syslog Facility		: $syslogfacilities{$result->{$map{'SYSLOGFACILITY'}}}\n";
	print "BOOTP Server		: " . &fqdn($bootpserver) . "\n";
	print "System Location		: $result->{$map{'LOCATION'}}\n";
	print "System Contact		: $result->{$map{'CONTACT'}}\n";
	print "\nAccess List\n";
	foreach $key (keys %$aclres){
		$aclip = $aclres->{$key};
		$aclfqdn = gethostbyaddr(inet_aton($aclip), AF_INET);
		$string = sprintf("%-22.22s", $aclfqdn);
		print "\tHost: $string Addr: $aclip\n";
	}
}

sub usage {
	my $prog = $0;
	$prog =~ s#.*\/(.*)$#$1#;
	print "Usage: ";
	print "$prog [-t/-T] hostname\n";
	print "-t is short statistics (default)\n";
	print "-T is detailed statistics\n";
}

sub fqdn {
	my ($ip) = shift(@_);
	my $fqdn = gethostbyaddr(inet_aton($ip), AF_INET);
	if($fqdn =~ /.+/){
		return "$fqdn ($ip)";
	} else {
		return "$ip";
	}
}
