#!/usr/bin/perl -w ### ### cbqos-cfgmaker.pl - A perl script that interrogates cisco routers ### and generates per-queue, per-interface bit rate and drop-rate ### MRTG targets. ### Greg Volk 20091127 ### ### This program was based off of OIDs found in the following cisco ### mib files: ### CISCO-CLASS-BASED-QOS-MIB ### CISCO-CLASS-BASED-QOS-CAPABILITY ### ### The invocation syntax is ./cbqos_cfgmaker.pl @ > ### ./cbqos_cfgmaker.pl public@router > router.cfg ### ### This template is licensed under the GNU GPL. For more information, please ### see http://www.gnu.org/copyleft/gpl.html. ### ### Newer/older/different versions might be available at http://mrtg.gvolk.com ### use strict; use locale; use Socket; # Where are your mrtg (SNMP_util) libraries? use lib "/opt/ejnmrtg/usr/lib/mrtg2"; use SNMP_util; # Some important OIDs for finding port names, port descrs, QOS indexes, etc my %indexhash = ( "ifDescr" => ".1.3.6.1.2.1.2.2.1.2", "ifAlias" => ".1.3.6.1.2.1.31.1.1.1.18", "ifSpeed" => ".1.3.6.1.2.1.2.2.1.5", "cbQosIfIndex" => ".1.3.6.1.4.1.9.9.166.1.1.1.1.4", "cbQosCMName" => ".1.3.6.1.4.1.9.9.166.1.7.1.1.1", "cbQosCMDesc" => ".1.3.6.1.4.1.9.9.166.1.7.1.1.2", "cbQosMatchStmtName" => ".1.3.6.1.4.1.9.9.166.1.8.1.1.1", "cbQosConfigIndex" => ".1.3.6.1.4.1.9.9.166.1.5.1.1.2", "cbQosObjectType" => ".1.3.6.1.4.1.9.9.166.1.5.1.1.3", "cbQosParentObjectsIndex" => ".1.3.6.1.4.1.9.9.166.1.5.1.1.4" ); # OIDs for the stats that we want to collect my %stathash = ( "cbQosCMPrePolicyByte64" => ".1.3.6.1.4.1.9.9.166.1.15.1.1.6", "cbQosCMPostPolicyByte64" => ".1.3.6.1.4.1.9.9.166.1.15.1.1.10", "cbQosCMDropByte64" => ".1.3.6.1.4.1.9.9.166.1.15.1.1.17" ); # Some general use vars my ($element,@array,@data,$host,$community,$router,@cbqoscmname, @cbqosconfigindex,%classnum,@keys,$entry,$key,$class,$indexnum, $statname,$i,$oid,@cbqosifindex,@ifdescr,@ifalias,%descrhash,%aliashash, $subindex,%qosifindex,$portname,$portalias,$target_name,$classname, $router_connect,$oid1,$oid2,$fileid,$statname1,$statname2,@ifspeed, %speedhash,$portspeed,$qindex); # Need debug output? my $debug = 1; unless($ARGV[0]) { print STDERR "Need command line args (community\@router)\n"; print STDERR "Example usage is:\n"; print STDERR " ./cbqos-cfgmaker public\@router > router.cfg\n"; die; } # Get some command line args @array = split "\@",$ARGV[0]; $community = $array[0]; $router = $array[1]; # Add ":::::2" for snmp v2c 64 bit counters $host = "$community\@$router".":::::2"; $router_connect = $host; if ($debug) { print STDERR "\n\nGot command line args: @ARGV\n"; } # Walk the qos index OIDs if($debug) { print STDERR "Walking cbQosIfIndex on $host\n"; } (@cbqosifindex) = &snmpwalk("$host",$indexhash{'cbQosIfIndex'}); if($debug) { print STDERR "Found $#cbqosifindex enteries in cbQosIfIndex table\n"; } # Store the qos index OIDs in a hash table foreach $i (@cbqosifindex) { @array = split ":",$i; $qosifindex{$array[0]} = $array[1]; if($debug) { print STDERR "loaded qosifindex with $array[0] -> $array[1]\n"; } } # Walk the regular interfaces OIDs if($debug) { print STDERR "Walking ifDescr on $host\n"; } (@ifdescr) = &snmpwalk("$host",$indexhash{'ifDescr'}); if($debug) { print STDERR "Found $#ifdescr enteries in ifDescr table\n"; } # Store the ifdescr data in a hash table foreach $i (@ifdescr) { @array = split ":",$i; $descrhash{$array[0]} = $array[1]; } # Walk the ifalias table if($debug) { print STDERR "Walking ifAlias on $host\n"; } (@ifalias) = &snmpwalk("$host",$indexhash{'ifAlias'}); if($debug) { print STDERR "Found $#ifalias enteries in ifAlias table\n"; } # Store ifalias in a hash table foreach $i (@ifalias) { @array = split ":",$i; $aliashash{$array[0]} = $array[1]; } # Walk the ifSpeed table if($debug) { print STDERR "Walking ifSpeed on $host\n"; } (@ifspeed) = &snmpwalk("$host",$indexhash{'ifSpeed'}); if($debug) { print STDERR "Found $#ifspeed enteries in ifSpeed table\n"; } # Store ifspeed in a hash table foreach $i (@ifspeed) { @array = split ":",$i; $speedhash{$array[0]} = $array[1]; } # Get a list of qos class names, store in a hash table if($debug) { print STDERR "Walking cbQosCMName on $host\n"; } (@cbqoscmname) = &snmpwalk("$host",$indexhash{'cbQosCMName'}); foreach $element (@cbqoscmname) { @array = split ":",$element; $classnum{$array[0]} = $array[1]; } if($debug) { print STDERR "Found $#cbqoscmname enteries in cbqoscmname table\n"; @keys = keys %classnum; print STDERR "cbqoscmname values are: @cbqoscmname\n\n"; } # Get a list of qos index numbers if($debug) { print STDERR "Walking cbQosConfigIndex on $host\n"; } (@cbqosconfigindex) = &snmpwalk("$host",$indexhash{'cbQosConfigIndex'}); if($debug) { print STDERR "Found $#cbqosconfigindex enteries in cbQosConfigIndex table\n"; } if($#cbqosconfigindex < 1) { print STDERR "cbqosconfigindex less than 1, are you sure this is a cbqos-enabled host?\n"; die; } # Iterate over each class number foreach $class (keys %classnum) { print "\n\n"; # Iterate over each qos index number foreach $indexnum (@cbqosconfigindex) { # If class num = index num we are interested in building an oid if($indexnum =~ /$class$/) { # Break up the data, we need subindex to get ifdescr & ifalias data @array = split ":",$indexnum; @data = split /\./,$array[0]; $qindex = $data[1]; $subindex = $data[0]; # What stats are we looking for? $statname1 = "cbQosCMDropByte64"; $statname2 = "cbQosCMDropByte64"; $fileid = "drops"; # Build some oids $oid1 = "$stathash{$statname1}.$array[0]"; $oid2 = "$stathash{$statname2}.$array[0]"; # Define the class name $classname = $classnum{$class}; # Get the port name info if($descrhash{$qosifindex{$subindex}}) { $portname = $descrhash{$qosifindex{$subindex}}; } else { if($debug) { print STDERR "WARNING!!! Port name for $subindex -> $qosifindex{$subindex} ($classname) is not defined, skipping this target!\n"; } next; } # Get the ifspeed if($speedhash{$qosifindex{$subindex}}) { $portspeed = $speedhash{$qosifindex{$subindex}}; } else { if($debug) { print STDERR "WARNING!!! Speed for $subindex -> $qosifindex{$subindex} ($classname) is not defined, skipping this target!\n"; } next; } # Get the port alias info $portalias = $aliashash{$qosifindex{$subindex}}; # Create the config target name $target_name = $router."_".$portname."_".$classname."_".$fileid."_".$qindex; # Replace slashes with underscores $target_name =~ s/\//_/g; if($debug) { print STDERR "Generating config for $target_name\n";} print "ShortLegend[$target_name]: drops\n"; print "YLegend[$target_name]: drops\n"; print "Legend1[$target_name]: drops\n"; print "Legend2[$target_name]: drops\n"; print "Legend3[$target_name]: Max drops\n"; print "Legend4[$target_name]: Max drops\n"; print "LegendI[$target_name]: drops\n"; print "LegendO[$target_name]: drops\n"; print "Directory[$target_name]: $router\n"; print "WithPeak[$target_name]: ywm\n"; print "MaxBytes[$target_name]: $portspeed\n"; print "Options[$target_name]: growright, nopercent\n"; print "Title[$target_name]: $router $portname $classname.$qindex drops\n"; print "Target[$target_name]: $oid1&$oid2:$router_connect\n"; print "PageTop[$target_name]:

$router $portname $classname.$qindex drops

\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
\n"; print "
System:$router
Description:$router $portname $classname.$qindex drops
ifType:counter
Resource:
\n"; print " $router $portname $classname.$qindex drops
\n"; print " $statname1 ($oid1) & $statname2.$qindex ($oid2)
\n"; print "
\n"; print "\n\n"; # What stats are we looking for? $statname1 = "cbQosCMPrePolicyByte64"; $statname2 = "cbQosCMPostPolicyByte64"; $fileid = "prepostrate"; # Build some oids $oid1 = "$stathash{$statname1}.$array[0]"; $oid2 = "$stathash{$statname2}.$array[0]"; # Define the class name $classname = $classnum{$class}; # Get the port name info if($descrhash{$qosifindex{$subindex}}) { $portname = $descrhash{$qosifindex{$subindex}}; } else { if($debug) { print STDERR "WARNING!!! Port name for $subindex -> $qosifindex{$subindex} ($classname) is not defined, skipping this target!\n"; } next; } # Get the ifspeed if($speedhash{$qosifindex{$subindex}}) { $portspeed = $speedhash{$qosifindex{$subindex}}; } else { if($debug) { print STDERR "WARNING!!! Speed for $subindex -> $qosifindex{$subindex} ($classname) is not defined, skipping this target!\n"; } next; } # Get the port alias info $portalias = $aliashash{$qosifindex{$subindex}}; # Create the config target name $target_name = $router."_".$portname."_".$classname."_".$fileid."_".$qindex; # Replace slashes with underscores $target_name =~ s/\//_/g; if($debug) { print STDERR "Generating config for $target_name\n";} print "ShortLegend[$target_name]: b/s\n"; print "YLegend[$target_name]: bits\n"; print "Legend1[$target_name]: cbQosCMPrePolicy\n"; print "Legend2[$target_name]: cbQosCMPostPolicy\n"; print "Legend3[$target_name]: Max cbQosCMPrePolicy\n"; print "Legend4[$target_name]: Max cbQosCMPostPolicy\n"; print "LegendI[$target_name]: cbQosCMPrePolicy\n"; print "LegendO[$target_name]: cbQosCMPostPolicy\n"; print "Directory[$target_name]: $router\n"; print "WithPeak[$target_name]: ywm\n"; print "MaxBytes[$target_name]: $portspeed\n"; print "Options[$target_name]: growright, nopercent, bits\n"; print "Title[$target_name]: $router $portname $classname.$qindex Pre/Post Policy bit rate\n"; print "Target[$target_name]: $oid1&$oid2:$router_connect\n"; print "PageTop[$target_name]:

$router $portname $classname.$qindex Pre/Post Policy bit rate

\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
\n"; print "
System:$router
Description:$router $portname $classname.$qindex Pre/Post Policy bit rate
ifType:counter
Resource:
\n"; print " $router $portname $classname.$qindex Pre/Post Policy bit rate
\n"; print " $statname1 ($oid1) & $statname2 ($oid2)
\n"; print "
\n"; print "\n\n"; } } } if($debug) { print STDERR "Finished with cfg generation for $router\n"; }