#!/opt/gnu/bin/perl
# -*- mode: Perl -*-
##################################################################
# Config file creator
##################################################################
# Cloned form cfgmaker Mark Trettin <mkt@lucent.com>
# Created by Tobias Oetiker <oetiker@ee.ethz.ch>
# this produces a config file for one router, by bulling info
# off the router via snmp
#################################################################
#
# Distributed under the GNU copyleft
#
# $Id: atmmaker,v 1.1.1.1 2002/02/26 10:16:31 oetiker Exp $
#
use SNMP_Session;
use BER;
use Socket;
use strict;
%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',
# asx port group info
'asxPortAdmnStat' => '1.3.6.1.4.1.326.2.2.2.1.2.2.1.2',
'asxPortOperStat' => '1.3.6.1.4.1.326.2.2.2.1.2.2.1.3',
'asxPortRemoteIpAddress'=> '1.3.6.1.4.1.326.2.2.2.1.2.2.1.6',
'asxPortILMIRemoteIpAddress' => '1.3.6.1.4.1.326.2.2.2.1.2.2.1.22',
'asxPortMaxBandwidthIn' => '1.3.6.1.4.1.326.2.2.2.1.2.2.1.9',
'asxhwPortName' => '1.3.6.1.4.1.326.2.2.1.1.2.3.1.13',
'asxPortNumber' => '1.3.6.1.4.1.326.2.2.2.1.2.2.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($community,$router) = split /\@/, $ARGV[0];
die <<USAGE unless $community && $router;
USAGE: cfgmaker 'community'\@'router'
EXAMPLE: cfgmaker public\@ezwf7.ethz.ch >>mrtg.cfg
USAGE
my($sysDescr,$sysContact,$sysName,$sysLocation,$ifNumber,$sysObjectID) =
snmpget($router,$community,
'sysDescr','sysContact','sysName', 'sysLocation', 'ifNumber',
'sysObjectID');
$sysDescr =~ s/\r/<BR>/g; # Change returns to <BR>
my($cisco_router_sysid) = '1\.3\.6\.1\.4\.1\.9';
my($ciscobox) = ($sysObjectID =~ /^$cisco_router_sysid/);
my($foreasx_switch_sysid) = '1\.3\.6\.1\.4\.1\.326';
my($foreasx) = ($sysObjectID =~ /^$foreasx_switch_sysid/);
print <<ECHO;
######################################################################
# Description: $sysDescr
# Contact: $sysContact
# System Name: $sysName
# Location: $sysLocation
#.....................................................................
ECHO
my @ipadent = snmpgettable($router,$community, 'ipAdEntAddr');
my @ipadentif = snmpgettable($router,$community, 'ipAdEntIfIndex');
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} = 'No hostname defined for IP address';
}
}
my(@ifdescr) = snmpgettable($router,$community, 'ifDescr');
my(@iftype) = snmpgettable($router,$community, 'ifType');
my(@ifspeed) = snmpgettable($router,$community, 'ifSpeed');
my(@ifadminstatus) = snmpgettable($router,$community, 'ifAdminStatus');
my(@ifoperstatus) = snmpgettable($router,$community, 'ifOperStatus');
my(@ifindex) = snmpgettable($router,$community, 'ifIndex');
# Get the user configurable interface description entered in the config
# if it's a cisco-box
my @ciscodescr;
if ($ciscobox) {
@ciscodescr = snmpgettable($router,$community, 'CiscolocIfDescr');
}
if ($foreasx) {
# Get the FORE ATM Switch port configurations
# if it's a ASX Switch
my @asxipaddress;
my @asxilmiaddress;
my @asxifadminstatus;
my @asxifoperstatus;
my @asxifilmiaddress;
my @asxifipaddress;
my @asxmaxbandwidthin;
my @asxhwportname;
my @asxportnumber;
@asxportnumber = snmpgettable($router,$community, 'asxPortNumber');
@asxhwportname = snmpgettable($router,$community, 'asxhwPortName');
@asxipaddress = snmpgettable($router,$community, 'asxPortRemoteIpAddress');
@asxilmiaddress = snmpgettable($router,$community, 'asxPortILMIRemoteIpAddress');
@asxmaxbandwidthin = snmpgettable($router,$community, 'asxPortMaxBandwidthIn');
@asxifadminstatus = snmpgettable($router,$community, 'asxPortAdmnStat');
@asxifoperstatus = snmpgettable($router,$community, 'asxPortOperStat');
my(%ipaddr, %iphost,%ipiladdr, %ipilhost);
my(%sportnumber, %sportname, %sifadminstatus, %sifoperstatus, %smaxbandwidth);
while (scalar @asxportnumber) {
$index = shift @asxportnumber;
$sportnumber{$index} = $index;
$sportname{$index} = shift @asxhwportname;
$smaxbandwidth{$index} = shift @asxmaxbandwidthin;
$sifadminstatus{$index} = shift @asxifadminstatus;
$sifoperstatus{$index} = shift @asxifoperstatus;
$ipaddr{$index} = shift @asxipaddress;
$ipiladdr{$index} = shift @asxilmiaddress;
$iphost{$index} =
gethostbyaddr(pack('C4',split(/\./,$ipaddr{$index})), AF_INET);
if ($iphost{$index} eq ''){
$iphost{$index} = $ipaddr{$index};
}
$ipilhost{$index} =
gethostbyaddr(pack('C4',split(/\./,$ipiladdr{$index})), AF_INET);
if ($ipilhost{$index} eq ''){
$ipilhost{$index} = $ipiladdr{$index};
}
}
foreach $index (keys %sportnumber) {
my $c;
my $speed = int($smaxbandwidth{$index}*53); # cells to bytes
my $speed_str=&fmi($speed);
my $name="$router.$index";
if (($sifoperstatus{$index} != 1)
&& ($sifadminstatus{$index} == 3)) {
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]: CellsRcvd.$index&CellsTrans.$index:$community\@$router \* 53
${c}MaxBytes[$name]: $speed
${c}Options[$name]: growright
${c}WithPeak[$name]: dwmy
${c}Title[$name]: $sysName ($iphost{$index}): $sportname{$index}
${c}PageTop[$name]: <H1>Traffic Analysis for $sportname{$index}
${c} </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>$sportname{$index} ($index)</TD></TR>
ECHO
print <<ECHO if $iphost{$index}!="255.255.255.255";
${c} <TR><TD>Remote IP:</TD><TD>$iphost{$index} ($ipaddr{$index})</TD></TR>
ECHO
print <<ECHO if $ipilhost{$index}!="255.255.255.255";
${c} <TR><TD>Remote ILMI IP:</TD><TD>$ipilhost{$index} ($ipiladdr{$index})</TD></TR>
ECHO
print <<ECHO;
${c} <TR><TD>Max Speed:</TD>
${c} <TD>$speed_str (Sonet)</TD></TR>
${c} </TABLE>
${c}
#---------------------------------------------------------------
ECHO
}
}
else {
my(%sifdesc,%siftype,%sifspeed,%sifadminstatus,%sifoperstatus,%sciscodescr);
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;
$siftype{$index} = shift @iftype;
print STDERR $siftype{$index};
$sifspeed{$index} = shift @ifspeed;
$sifadminstatus{$index} = shift @ifadminstatus;
$sifoperstatus{$index} = shift @ifoperstatus;
# especially since cisco does not return a if
# descr for each interface it has ...
$sciscodescr{$index} = "<BR>" . (shift @ciscodescr) if @ciscodescr;
}
foreach $index (keys %sifdesc) {
my $c;
my $speed = int($sifspeed{$index} / 8); # bits to byte
my $speed_str=&fmi($speed);
my $name="$router.$index";
if (($sifadminstatus{$index} != 1)
|| ($siftype{$index} == 24)
|| ($speed == 0 )
|| ($speed > 400 * 10**6) #speeds of 400 MByte/s are not realistic
|| ($sifoperstatus{$index} == 3)) {
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]: $index:$community\@$router
${c}MaxBytes[$name]: $speed
${c}Options[$name]: growright
${c}WithPeak[$name]: dwmy
${c}Title[$name]: $sysName ($iphost{$index}): $sifdesc{$index}
${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)</TD></TR>
${c} <TR><TD>IP:</TD><TD>$iphost{$index} ($ipaddr{$index})</TD></TR>
${c} <TR><TD>Max Speed:</TD>
${c} <TD>$speed_str ($ifType_d{$siftype{$index}})</TD></TR>
${c} </TABLE>
${c}
#---------------------------------------------------------------
ECHO
}
}
}
main;
exit(0);
sub snmpget{
my($host,$community,@vars) = @_;
my(@enoid, $var,$response, $bindings, $binding, $value, $inoid,$outoid,
$upoid,$oid,@retvals);
foreach $var (@vars) {
die "Unknown SNMP var $var\n"
unless $snmpget::OIDS{$var};
push @enoid, encode_oid((split /\./, $snmpget::OIDS{$var}));
}
srand();
my $session = SNMP_Session->open ($host ,
$community,
161);
if ($session->get_request_response(@enoid)) {
$response = $session->pdu_buffer;
($bindings) = $session->decode_get_response ($response);
$session->close ();
while ($bindings) {
($binding,$bindings) = decode_sequence ($bindings);
($oid,$value) = decode_by_template ($binding, "%O%@");
my $tempo = pretty_print($value);
$tempo=~s/\t/ /g;
$tempo=~s/\n/ /g;
$tempo=~s/^\s+//;
$tempo=~s/\s+$//;
push @retvals, $tempo;
}
return (@retvals);
} else {
die "No answer from $ARGV[0]. You may be using the wrong community\n";
}
}
sub snmpgettable{
my($host,$community,$var) = @_;
my($next_oid,$enoid,$orig_oid,
$response, $bindings, $binding, $value, $inoid,$outoid,
$upoid,$oid,@table,$tempo);
die "Unknown SNMP var $var\n"
unless $snmpget::OIDS{$var};
$orig_oid = encode_oid(split /\./, $snmpget::OIDS{$var});
$enoid=$orig_oid;
srand();
my $session = SNMP_Session->open ($host ,
$community,
161);
for(;;) {
if ($session->getnext_request_response(($enoid))) {
$response = $session->pdu_buffer;
($bindings) = $session->decode_get_response ($response);
($binding,$bindings) = decode_sequence ($bindings);
($next_oid,$value) = decode_by_template ($binding, "%O%@");
# quit once we are outside the table
last unless BER::encoded_oid_prefix_p($orig_oid,$next_oid);
$tempo = pretty_print($value);
#print "$var: '$tempo'\n";
$tempo=~s/\t/ /g;
$tempo=~s/\n/ /g;
$tempo=~s/^\s+//;
$tempo=~s/\s+$//;
push @table, $tempo;
} else {
die "No answer from $ARGV[0]\n";
}
$enoid=$next_oid;
}
$session->close ();
return (@table);
}
sub fmi {
my($number) = $_[0];
my(@short);
@short = ("Bytes/s","kBytes/s","MBytes/s","GBytes/s","TBytes/s");
my $digits=length("".$number);
my $divm=0;
while ($digits-$divm*3 > 4) { $divm++; }
my $divnum = $number/10**($divm*3);
return sprintf("%1.1f %s",$divnum,$short[$divm]);
}