The Avaya IP Office 500 PBX does not appear to have an easy way to graph PRI usage.

We discovered a status packet sent by the phone system to Xima that contains the number of current calls on the PRI trunks. We need to convert a packet on the wire into a WhatsUp Gold Graph. I have created a crude proof of concept using a physical server, tcpdump, perl, snmpd extensions, and WhatsUp Actionscript. Any or all of these pieces could be replaced/refined if need be (for example, we could use a VM or sed instead).

I created a Cisco span port that replayed the traffic between the PBX and Xima, and attached a physical server to it.

Start with capturing the packet on the wire: /usr/sbin/tcpdump -nn -v -i eth1 -s0 -A host and host and udp

In the below mess of a packet, you can see CALLS=2

17:37:41.828161 IP (tos 0x0, ttl 99, id 25899, offset 0, flags [none], proto UDP (17), length 303)
	172.27.105.5.50794 > 172.27.105.6.60709: UDP, length 275
E../e+..c.Y^.........j.%.......f.........9 ...................L.A.W.=.U. .P.R.I.=.2.,. .B.R.I.=.0.,. .A.L.O.G.=.4.,. .V.C.O.M.P.=.7.4.,. .M.D.M.=.0.,. .W.A.N.=.0.,. .M.O.D.U.
..0. .L.A.N.M.=.0. .C.k.S.R.C.=.1. .V.M.A.I.L.=.1.(.V.E.R.=.3. .T.Y.P.=.1.). .1.-.X.=.1. .C.A.L.L.S.=.2.(.T.O.T.=.7.0.7.7.).

What a mess. Regex time! So I put together the following Perl script, could be replaced with bash or another language

#!/usr/bin/perl -w
# by jlebo to capture trunk calls on PRIs from Avaya phone system

use strict;

my $callcount = '0';
my $outputfile = '/tmp/trunkcalls';

open(STDIN,"/usr/sbin/tcpdump -nn -v -i eth1 -s0 -A host 172.27.105.5 and host 172.27.105.6 and udp | " );

while ( <> ) {
    if ( $_ =~ /C.A.L.L./  ) {
        #print $_;
        $_ =~ s/\.//g; #remove periods
        $_ =~ /CALLS=(\d+)/ ;
        $callcount = $1;
        #print "So calls is $callcount\n";
        open(OUTFILE, ">$outputfile") or die "Cant open file\n";
        print OUTFILE $callcount . "\n";
        close OUTFILE;
    }
}
exit 0;

The PBX sends these packets every minute. The above outputs the number of trunk calls to /tmp/trunkcalls as soon as they are recieved.

Now to configure the Linux SNMPD to display the contents of the above file. Created the below snmpd.conf file, which creates the custom OIDS

rocommunity snmpstring
trapcommunity snmpstring
syslocation Nowhere FL
syscontact nobody
proc snmpd
extend trunkcalls /bin/cat /tmp/trunkcalls

This OID contains our custom output: .1.3.6.1.4.1.8072.1.3

If I set the value of the above file to ‘50’ and query the new OID, I get this:

[root@netmon0 html]# snmpwalk -v1 -c tns-snmp 172.27.105.11 .1.3.6.1.4.1.8072.1.3.2.3.1
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."trunkcalls" = STRING: 50
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."trunkcalls" = STRING: 50
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."trunkcalls" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."trunkcalls" = INTEGER: 0

Again, showing the full OID path:
[root@netmon0 html]# snmpwalk -On -v1 -c tns-snmp 172.27.105.11 .1.3.6.1.4.1.8072.1.3.2.3.1
.1.3.6.1.4.1.8072.1.3.2.3.1.1.10.116.114.117.110.107.99.97.108.108.115 = STRING: 50     <--- Using this one
.1.3.6.1.4.1.8072.1.3.2.3.1.2.10.116.114.117.110.107.99.97.108.108.115 = STRING: 50
.1.3.6.1.4.1.8072.1.3.2.3.1.3.10.116.114.117.110.107.99.97.108.108.115 = INTEGER: 1
.1.3.6.1.4.1.8072.1.3.2.3.1.4.10.116.114.117.110.107.99.97.108.108.115 = INTEGER: 0

Note: 10.116.114.117.110.107.99.97.108.108.115 is an ascii representation of ‘trunkcalls’`

My initial thought was to use ‘ExtendOutput1Line’ as a simple SNMP monitor in WhatsUp.

Whatsup Monitors have 2 parts:

Object .1.3.6.1.4.1.8072.1.3.2.3.1.1 Instance 10.116.114.117.110.107.99.97.108.108.115

Entered the info into an SNMP monitor and … FAIL. WhatsUp complains that “The polled value was not numeric”.

Here’s where it gets fun. Extending Linux SNMP OIDs in this manner ALWAYS returns a string. Most monitoring systems are smart enough to convert a string of numbers to an integer number - WhatsUp Gold does not do this. Instead of a simple SNMP Performance Monitor, we have to create a Custom ActionScript Performance Monitor.
In the Performance Monitor we first create a Reference Variable from the above 2 part OID while the below code converts the string to an integer.

TrunkCalls = Context.GetReferenceVariable("TrunkCalls") 'import variable
TrunkCalls = cInt(TrunkCalls) ' does the conversion
Context.SetValue TrunkCalls  'write it back

Now we simply add the Performance Monitor to the device in question. Changing the frequency on the performance monitor to 1 minute gives good granularity.

Done [ x ]