#!/usr/local/bin/perl5
# -*- mode: Perl -*-
##################################################################
# Config file creator
##################################################################
# Created by Laurie Gellatly <gellatly@one.net.au>
# based on mrtg cfgmaker by Tobias Oetiker <oetiker@ee.ethz.ch>
# this produces a config file for one router, by pulling info
# off the router via snmp and then writing files ready for
# snmpCollect to use (via xnmcollect) and later ovlg calls
#################################################################
#
# Distributed under the GNU copyleft
#
# $Id: cfgmakerov,v 1.1.1.1 2002/02/26 10:16:36 oetiker Exp $
#
use SNMP_Session "0.58";
use BER "0.57";
use Socket;
use strict;
use vars '$DEBUG';
my $DEBUG = 0;
my $webdir = "/var/opt/ns-fasttrack/docs/mrtg/";
%snmpget::OIDS = ( 'sysDescr' => '1.3.6.1.2.1.1.1.0',
'sysContact' => '1.3.6.1.2.1.1.4.0',
'sysName' => '1.3.6.1.2.1.1.5.0',
'sysLocation' => '1.3.6.1.2.1.1.6.0',
'sysUptime' => '1.3.6.1.2.1.1.3.0',
'ifNumber' => '1.3.6.1.2.1.2.1.0',
###################################
# add the ifNumber ....
'ifDescr' => '1.3.6.1.2.1.2.2.1.2',
'ifType' => '1.3.6.1.2.1.2.2.1.3',
'ifIndex' => '1.3.6.1.2.1.2.2.1.1',
'ifSpeed' => '1.3.6.1.2.1.2.2.1.5',
'ifOperStatus' => '1.3.6.1.2.1.2.2.1.8',
'ifAdminStatus' => '1.3.6.1.2.1.2.2.1.7',
# up 1, down 2, testing 3
'ipAdEntAddr' => '1.3.6.1.2.1.4.20.1.1',
'ipAdEntIfIndex' => '1.3.6.1.2.1.4.20.1.2',
'sysObjectID' => '1.3.6.1.2.1.1.2.0',
'CiscolocIfDescr' => '1.3.6.1.4.1.9.2.2.1.1.28',
'ifAlias' => '1.3.6.1.2.1.31.1.1.1.18',
'ifName' => '1.3.6.1.2.1.31.1.1.1.1'
);
sub main {
my(%ifType_d)=('1'=>'Other',
'2'=>'regular1822',
'3'=>'hdh1822',
'4'=>'ddnX25',
'5'=>'rfc877x25',
'6'=>'ethernetCsmacd',
'7'=>'iso88023Csmacd',
'8'=>'iso88024TokenBus',
'9'=>'iso88025TokenRing',
'10'=>'iso88026Man',
'11'=>'starLan',
'12'=>'proteon10Mbit',
'13'=>'proteon80Mbit',
'14'=>'hyperchannel',
'15'=>'fddi',
'16'=>'lapb',
'17'=>'sdlc',
'18'=>'ds1',
'19'=>'e1',
'20'=>'basicISDN',
'21'=>'primaryISDN',
'22'=>'propPointToPointSerial',
'23'=>'ppp',
'24'=>'softwareLoopback',
'25'=>'eon',
'26'=>'ethernet-3Mbit',
'27'=>'nsip',
'28'=>'slip',
'29'=>'ultra',
'30'=>'ds3',
'31'=>'sip',
'32'=>'frame-relay',
'33'=>'rs232',
'34'=>'para',
'35'=>'arcnet',
'36'=>'arcnetPlus',
'37'=>'atm',
'38'=>'miox25',
'39'=>'sonet',
'40'=>'x25ple',
'41'=>'iso88022llc',
'42'=>'localTalk',
'43'=>'smdsDxi',
'44'=>'frameRelayService',
'45'=>'v35',
'46'=>'hssi',
'47'=>'hippi',
'48'=>'modem',
'49'=>'aal5',
'50'=>'sonetPath',
'51'=>'sonetVT',
'52'=>'smdsIcip',
'53'=>'propVirtual',
'54'=>'propMultiplexor',
'55'=>'100BaseVG'
);
my($vendor)=0;
my($router) = $ARGV[0];
die <<USAGE unless $router;
USAGE: cfgmakerov 'router'
EXAMPLE: cfgmakerov ezwf7.ethz.ch >>mrtg.cfg
USAGE
my($sysDescr,$sysContact,$sysName,$sysLocation,$ifNumber,$sysObjectID) =
snmpget($router,
'sysDescr','sysContact','sysName', 'sysLocation', 'ifNumber', 'sysObjectID');
### The next three lines can be deleted once Someone gives this box a name
if ($router eq '10.26.254.1') {
$sysName = 'nrgiga';
}
if ($sysName eq "") {
$sysName = $router;
}
my($sysNameL) = $sysName;
$sysNameL =~ tr/[A-Z]/[a-z]/;
$sysDescr =~ s/\r/<BR>/g; # Change returns to <BR>
my($ciscobox) = ($sysObjectID =~ /cisco/);
my($portmaster) = ($sysObjectID =~ /livingston/);
$vendor = ($ciscobox || $portmaster) ;
my($ifInErrors) = '1.3.6.1.2.1.2.2.1.14';
my($ifOutErrors) = '1.3.6.1.2.1.2.2.1.20';
### Create the directory if it does not exist
mkdir("$webdir$sysNameL",0777);
print <<ECHO;
WorkDir: $webdir$sysNameL
IconDir: ../
######################################################################
# Description: $sysDescr
# Contact: $sysContact
# System Name: $sysName
# Location: $sysLocation
#.....................................................................
ECHO
if ( $ciscobox ) {
print <<ECHO;
# Router CPU load %
Target[$sysNameL.cpu]: `perl ovcvtfile $router 0 2`
MaxBytes[$sysNameL.cpu]: 100
Title[$sysNameL.cpu]: CPU LOAD
PageTop[$sysNameL.cpu]: <H1>CPU Load %</H1>
ShortLegend[$sysNameL.cpu]: %
XSize[$sysNameL.cpu]: 380
YSize[$sysNameL.cpu]: 100
YLegend[$sysNameL.cpu]: CPU Utilization
Legend1[$sysNameL.cpu]: CPU Utilization in % (Load)
Legend2[$sysNameL.cpu]: CPU Utilization in % (Load)
Legend3[$sysNameL.cpu]:
Legend4[$sysNameL.cpu]:
LegendI[$sysNameL.cpu]:
LegendO[$sysNameL.cpu]: Usage:
Options[$sysNameL.cpu]: growright, gauge
#---------------------------------------------------------------
ECHO
}
my @ipadent = snmpgettable($router, 'ipAdEntAddr');
print STDERR "Got Addresses\n" if $DEBUG;
my @ipadentif = snmpgettable($router, 'ipAdEntIfIndex');
print STDERR "Got IfTable\n" if $DEBUG;
my(%ipaddr, %iphost,$index);
while (scalar @ipadentif){
$index = shift @ipadentif;
$ipaddr{$index} = shift @ipadent;
$iphost{$index} =
gethostbyaddr(pack('C4',split(/\./,$ipaddr{$index})), AF_INET);
if ($iphost{$index} eq ''){
$iphost{$index} = $ipaddr{$index};
}
}
my(@ifdescr) = snmpgettable($router, 'ifDescr');
print STDERR "Got IfDescr\n" if $DEBUG;
my(@iftype) = snmpgettable($router, 'ifType');
print STDERR "Got IfType\n" if $DEBUG;
my(@ifspeed) = snmpgettable($router, 'ifSpeed');
print STDERR "Got IfSpeed\n" if $DEBUG;
my(@ifadminstatus) = snmpgettable($router, 'ifAdminStatus');
print STDERR "Got IfStatus\n" if $DEBUG;
my(@ifoperstatus) = snmpgettable($router, 'ifOperStatus');
print STDERR "Got IfOperStatus\n" if $DEBUG;
my(@ifindex) = snmpgettable($router, 'ifIndex');
print STDERR "Got IfIndex\n" if $DEBUG;
my(@ifname) = snmpgettable($router, 'ifName');
print STDERR "Got IfName\n" if $DEBUG;
my(%sifdesc,%siftype,%sifspeed,%sifadminstatus,%sifoperstatus,%sciscodescr,%sifname);
### May need the cisco IOS version number so we know which oid to use
### to get the cisco description.
###
### - mjd 2/5/98 (Mike Diehn) (mdiehn@mindspring.net)
###
my ($cisco_ver, $cisco_descr_oid, @ciscodescr);
if ( $ciscobox ) {
($cisco_ver) = ($sysDescr =~ /Version\s+([\d.]+)/);
$cisco_descr_oid = ($cisco_ver ge "11.3") ? "ifAlias" : "CiscolocIfDescr";
}
while (scalar @ifindex) {
# as these arrays get filled from the bottom,
# we need to empty them from the botom as well ...
# fifo
$index = shift @ifindex;
$sifdesc{$index} = shift @ifdescr;
$sifname{$index} = shift @ifname;
$siftype{$index} = shift @iftype;
$sifspeed{$index} = shift @ifspeed;
$sifadminstatus{$index} = shift @ifadminstatus;
$sifoperstatus{$index} = shift @ifoperstatus;
if ($portmaster) {
# Trying to extract extra info livingston
# We can only approximate speeds
#
# so we think that ppp can do 76800 bit/s, and slip 38400.
# (actualy, slip is a bit faster, but usualy users with newer modems
# use ppp). Alternatively, you can set async speed to 115200 or
# 230400 (the maximum speed supported by portmaster).
#
# But if the interface is ptpW (sync), max speed is 128000
# change it to your needs. On various Portmasters there are
# various numbers of sync interfaces, so modify it.
#
# The most commonly used PM-2ER has only one sync.
#
# Paul Makeev (mac@redline.ru)
#
if ($siftype{$index} eq 'ppp') {
if ($sifdesc{$index} eq 'ptpW1') {
$sifspeed{$index} = 128000;
} else {
$sifspeed{$index} = 76800;
}
} elsif ($siftype{$index} eq 'slip') {
$sifspeed{$index} = 38400;
} elsif ($siftype{$index} eq 'ethernetCsmacd') {
$sifspeed{$index} = 10000000;
}
}
### Move this section south so we know what type of
### circuit we're looking at before we retrieve
### the cisco interface alias.
###
### This whole cicso thing should be re-written, but since
### this script doesn't need to run quickly...
###
### - mjd 2/5/98
###
# Get the user configurable interface description entered in the config
# if it's a cisco-box
#
if ($ciscobox) {
my ($enoid, @descr);
$enoid = $snmpget::OIDS{"$cisco_descr_oid"} . "." . $index;
if ( $cisco_ver ge "11.2" or $siftype{$index} ne 'frame-relay' ) {
### This is either not a frame-relay sub-interface or
### this router is running IOS 11.2+ and interface
### type won't matter. In either of these cases, it's
### ok to try getting the ifAlias or ciscoLocIfDesc.
###
@descr = snmpget($router, $enoid);
} else {
### This is a frame-relay sub-interface *and* the router
### is running an IOS older than 11.2. Therefore, we can
### get neither ifAlias nor ciscoLocIfDesc. Do something
### useful.
###
@descr = ("Cisco PVCs descriptions require IOS 11.2+.");
} # end if else
### Put whatever I got into the array we'll use later to append the result
### of this operation onto the results from the ifDescr fetch.
###
push @ciscodescr, shift @descr;
} # end if ($ciscobox)
# especially since cisco does not return a if
# descr for each interface it has ...
## JB 2/8/97 - sometimes IOS inserts E1 controllers in the standard-MIB
## interface table, but not in the local interface table. This puts the
## local interface description table out-of-sync. the following
## modification skips over E1 cards as interfaces.
#
### I suspect that the mod I made above, to use the ifAlias
### oid if possible, may cause problems here. If it seems
### that your descriptions are out of sync, try commenting
### out the "if ( condition )" and it's closing right brace
### so that the "shift @ciscodescr" get executed for *all*
### iterations of this loop.
###
### - mjd 2/5/95
###
if ($ciscobox && $siftype{$index} ne 'ds1') {
$sciscodescr{$index} = "<BR>" . (shift @ciscodescr) if @ciscodescr;
}
}
foreach $index ( sort { $a <=> $b } keys %sifdesc) {
my $c;
my $speed = int($sifspeed{$index} / 8); # bits to byte
# LJG Change to report in Bits
# my $speed_str=&fmi($speed);
my $speed_str=&fmi($sifspeed{$index});
my $name="$sysNameL.$index";
my $namerr="$sysNameL.$index.err";
if (($sifadminstatus{$index} ne "up")
# this check added by Josh - don't query E1-stack controllers
|| ($siftype{$index} eq 'ds1')
|| ($siftype{$index} eq 'softwareLoopback')
|| ($speed == 0 )
# LJG Change to report all in Bits
# || ($speed > 400 * 10**6) #speeds of 400 MByte/s are not realistic
|| ($speed > 3200 * 10**6) #speeds of 400 MByte/s are not realistic
|| ($sifoperstatus{$index} eq 'down')
|| (($sifdesc{$index}=~ /Dialer/) && ($ciscobox))) {
print <<ECHO;
########
######## This Interface is one of the following
######## - administratively not UP
######## - it is in test mode
######## - it is a softwareLoopback interface
######## - has a unrealistic speed setting
######## It is commented out for this reason.
########
ECHO
$c="# ";
}else {
$c = '';
}
print <<ECHO;
${c}
${c}Target[$name]: `perl ovcvtfile $router $index 1`
${c}MaxBytes[$name]: $speed
${c}Title[$name]: $sysName ($iphost{$index}): $sifdesc{$index} $sifname{$index}
${c}Options[$name]: growright, gauge, bits
${c}PageTop[$name]: <H1>Traffic Analysis for $sifdesc{$index}
${c} $sciscodescr{$index}</H1>
${c} <TABLE>
${c} <TR><TD>System:</TD><TD>$sysName in $sysLocation</TD></TR>
${c} <TR><TD>Maintainer:</TD><TD>$sysContact</TD></TR>
${c} <TR><TD>Interface:</TD><TD>$sifdesc{$index} ($index - $sifname{$index})</TD></TR>
${c} <TR><TD>IP:</TD><TD>$iphost{$index} ($ipaddr{$index})</TD></TR>
${c} <TR><TD>Max Speed:</TD>
${c} <TD>$speed_str ($siftype{$index})</TD></TR>
${c} </TABLE>
${c}
#---------------------------------------------------------------
# In and Out Error Counts
${c}
${c}Target[$namerr]: `perl ovcvtfile $router $index 0`
${c}MaxBytes[$namerr]: 2147483600
${c}Title[$namerr]: $sysName ($iphost{$index}): $sifdesc{$index} $sifname{$index} I/O Errors
${c}Options[$namerr]: growright, gauge
${c}PageTop[$namerr]: <H1>I/O Error Analysis for $sifdesc{$index}
${c} $sciscodescr{$index}</H1>
${c}YLegend[$namerr]: Errors/Period
${c}Legend1[$namerr]: Inward Errors
${c}Legend2[$namerr]: Outward Errors
${c}Legend3[$namerr]:
${c}Legend4[$namerr]:
${c}LegendI[$namerr]: In :
${c}LegendO[$namerr]: Out :
${c}
#---------------------------------------------------------------
ECHO
}
}
main;
exit(0);
sub snmpget{
my($host,@vars) = @_;
my(@enoid, $var,$response, $bindings, $binding, $value, $inoid,$outoid,
$upoid,$oid,@retvals,$t1,$t2,@resp,$tempo);
my($hackcisco);
foreach $var (@vars) {
die "Unknown SNMP var $var\n"
unless $snmpget::OIDS{$var} || $var =~ /^\d+[\.\d+]*\.\d+$/;
if ($var =~ /^\d+[\.\d+]*\.\d+/) {
$value = $value.$var." ";
$hackcisco = 1;
} else {
$value = $value.$snmpget::OIDS{$var}." ";
$hackcisco = 0;
}
}
open(SNMPG, "snmpget $host $value |");
# print STDERR $value;
while ($tempo =<SNMPG>){
# print STDERR $tempo;
($t1, $t2, $tempo ) = split /:/ , $tempo, 3;
if (!$tempo){
if ($t2){
$t1 = $t1 .":".$t2;
}
$tempo = pop(@retvals)." ".$t1 ;
}
$tempo=~s/\t/ /g;
$tempo=~s/\n/ /g;
$tempo=~s/^\s+//;
$tempo=~s/\s+$//;
push @retvals, $tempo;
}
# print STDERR @retvals;
close (SNMPG);
return (@retvals);
}
sub snmpgettable{
my($host,$var) = @_;
my($next_oid,$enoid,$orig_oid,
$response, $bindings, $binding, $t1, $t2,$outoid,
$upoid,$oid,@table,$tempo);
die "Unknown SNMP var $var\n"
unless $snmpget::OIDS{$var};
$orig_oid = $snmpget::OIDS{$var}." ";
$enoid=$orig_oid;
open(SNMPG, "snmpwalk $host $orig_oid |");
# print STDERR $orig_oid;
while ($tempo =<SNMPG>){
# print STDERR $tempo;
($t1, $t2, $tempo ) = split /:/ , $tempo ,3;
if (!$tempo){
if ($t2){
$t1 = $t1 .":".$t2;
}
$tempo = pop(@table)." ".$t1 ;
}
$tempo=~s/\t/ /g;
$tempo=~s/\n/ /g;
$tempo=~s/^\s+//;
$tempo=~s/\s+$//;
push @table, $tempo;
}
close (SNMPG);
return (@table);
}
sub fmi {
my($number) = $_[0];
my(@short);
# LJG Change to report in Bits
# @short = ("Bytes/s","kBytes/s","MBytes/s","GBytes/s");
@short = ("Bits/s","kBits/s","MBits/s","GBits/s");
my $digits=length("".$number);
my $divm=0;
while ($digits-$divm*3 > 3) { $divm++; }
my $divnum = $number/10**($divm*3);
return sprintf("%1.1f %s",$divnum,$short[$divm]);
}