#!/usr/bin/perl -w
#
# Graphs busy channels on L(ivingston|ucent) Portmaster 3 Network Access
# Servers (maybe PM2 and PM4, too. Dunno 'bout that)...
#
# Usage:
# 	To monitor host pm3-1.foo.example, do:
#
# 		ln -s /path/to/pm3users /etc/munin/plugins/pm3users_pm3-1_foo_example
#
# 	Then add this to /etc/munin/munin.conf:
#
# 		[pm3-1.foo.example]
# 		    address 127.0.0.1
#
# Requirements:
# 	Perl Net::SNMP
#
# Parameters supported:
# 	None
#
# Configurable variables:
#  	maxpstn		- Number of analog modems onboard the PM3 (default: 20)
#  	maxisdn		- Number of ISDN channels available (default: 30 == a full E1 line)
#  	community	- SNMP read community to use (default: public)
#
# Bugs:
# 	The code is pretty stupid and slow
# 	The `users' label is misleading
#
# $Log: pm3users.in,v $
# Revision 1.1  2004/05/09 21:11:15  jimmyo
# New plugin (pm3users) and a bunch of patches from Jacques Caruso.
#
#
# Magic markers:
#%# family=contrib
#%# capabilities=

use Net::SNMP;
use strict;

my $usertable = '1.3.6.1.4.1.307.3.2.1.1.1.4';
my $modemtable = '1.3.6.1.4.1.307.3.2.1.1.1.13';
my ($total, $pstn, $isdn) = (0, 0, 0);
my ($maxpstn, $maxisdn) = (20, 30);
my ($user, $modem) = ('', '');
my $community = 'public';
my $cmd = (defined($ARGV[0])) ? $ARGV[0] : '';

# Check how we were called to guess the PM3's hostname
my ($progname, @hostarry) = split(/_/, $0);
my $hostname = join('.', @hostarry);

# Let's see if our configuration differs from the defaults
# XXX maybe there is a way to get this info from the equipment
# XXX remember to look into this
(defined($ENV{'maxpstn'})) and $maxpstn = $ENV{'maxpstn'};
(defined($ENV{'maxisdn'})) and $maxisdn = $ENV{'maxisdn'};
(defined($ENV{'community'})) and $community = $ENV{'community'};
my $maxtotal = $maxisdn;
exit(1) if (!defined($hostname) or ($hostname eq ''));

# Show default values if requested
if ($cmd eq 'config') {
	print("host_name $hostname\n");
	print("graph_title Users on $hostname\n");
	print("graph_args --lower-limit 0 --upper-limit $maxtotal\n");
	print("graph_vlabel users\n");
	print("pstn.label PSTN users\n");
	print("pstn.max $maxpstn\n");
	print("pstn.type GAUGE\n");
	print("pstn.draw AREA\n");
	print("isdn.label ISDN users\n");
	print("isdn.max $maxisdn\n");
	print("isdn.type GAUGE\n");
	print("isdn.draw STACK\n");
	print("total.label Total users\n");
	print("total.max $maxtotal\n");
	print("total.type GAUGE\n");
	print("total.draw LINE1\n");

# These options are unsupported in the current version:
#	print("pstn.colour 50f0ff\n");
#	print("isdn.colour 9598dd\n");
#	print("total.colour 000000\n");
#	print("hrules $maxpstn:ff8800:Max PSTN users,$maxisdn:ff0000:Max ISDN users\n");

	exit(0);
}

# Else proceed to poll the equipment
my ($session, $error) = Net::SNMP->session(
	-hostname	=> $hostname,
	-community	=> $community,
	-port		=> 161
);
if (defined($session)) {
	# Interface 1 is the console port, thus we start at 2
	for my $i (2 .. 61) {
		my $user = $session->get_request(
			-varbindlist => ["$usertable.$i"]
		);
		my $modem = $session->get_request(
			-varbindlist => ["$modemtable.$i"]
		);
		if (!defined($user) or !defined($modem)) {
			($total, $pstn) = (0, 0);
			last;
		}
		(scalar($user->{"$usertable.$i"}) ne '') and $total++;
		(scalar($modem->{"$modemtable.$i"}) ne '') and $pstn++;
	}
	$session->close;
}
$isdn = $total - $pstn;
print("pstn.value $pstn\n");
print("isdn.value $isdn\n");
print("total.value $total\n");
exit(0);
