0xfffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffe
####
const vlanPortIslVlansAllowed = " .1.3.6.1.4.1.9.5.1.9.3.1.5.1.1 "
const SNMPGETCMD2 = "f:\usr\bin\snmpget.exe -Ov -v 2c -c "
'************************************************************************
'FUNCTION: *
' enum_AllowedVLAN(strAgent) *
'Purpose: *
' enumerate the vlans configured on the switch. *
' *
'Inputs: *
' strAgent: management IP address of the switch *
' *
'Returns: *
' Array with each element containing a vlan number *
' *
'Calls: *
' SNMPGETCMD2 - constant defining the path to an external *
' program and options used to perform an snmp get operation. *
' fmtBinary - function to left pad a binary number with zeros *
' ToBinary - function to convert an integer to a binary string *
' *
'Comments: *
' CISCO-STACK-MIB is cisco specific. *
' Reference Cisco SNMP Object Navigator viewed at *
' http://tools.cisco.com/Support/SNMP/do/BrowseOID.do? *
' objectInput=vlanPortIslVlansAllowed&translate=Translate& *
' submitValue=SUBMIT&submitClicked=true *
' on 16/11/2006 *
'************************************************************************
function enum_AllowedVLAN(strAgent)
dim WshShell, oExec
dim re 'as regexp
dim matches
dim match, submatch
dim tempstr, stroutput, index, vlans
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec(SNMPGETCMD2 & SNMPREAD & " " & _
strAgent & " " & vlanPortIslVlansAllowed)
Do while Not oExec.StdOut.AtEndOfStream
stroutput = oExec.StdOut.readall
Loop
Do While oExec.Status <> 1
WScript.Sleep 100
Loop
tempstr = ""
set re = new regexp
re.global = True
re.multiline = True
'Pattern to capture the hex digits representing the allowed vlans.
re.pattern = "[0-9a-fA-F]{2}"
vlans = ""
if instr(1,stroutput, "Hex-STRING:") > 0 then
set matches = re.execute(stroutput)
for each match in matches
tempstr = tempstr & fmtBinary(ToBinary(cint("&H" & match)), 8)
next
tempstr = strreverse(tempstr)
index = 1
do
index = instr(index, tempstr, "1")
if index <> 0 then
vlans = vlans & " " & index - 1
index = index + 1
end if
loop until index = 0
end if
enum_AllowedVLAN = split(trim(vlans))
end function
'************************************************************************
'FUNCTION: *
' fmtBinary(strNumber, intLength) *
'PURPOSE: *
' function to left pad a binary number with zeros *
' *
'INPUTS: *
' strNumber: binary number to left pad with zeros *
' intLength: The desired bit length of the binary number *
' *
'RETURNS: *
' string containing the binary representation of the input. *
' *
'CALLS: *
' Nothing *
' *
'COMMENTS: *
'************************************************************************
function fmtBinary(strNumber, intLength)
fmtBinary = string(intLength - len(strNumber), "0") & strNumber
end function
'************************************************************************
'FUNCTION: *
' ToBinary(intNumber) *
' *
'PURPOSE: *
' convert an integer number to binary. *
' *
'Inputs: *
' intNumber: Number to convert to binary *
' *
'Returns: *
' string containing the binary representation of the input. *
' *
'Calls: *
' Nothing *
' *
'Comments: *
' note the use of \ (integer division operator) rather than / *
'************************************************************************
function ToBinary(intNumber)
if intNumber > 0 then
ToBinary = ToBinary(intNumber\2) & intNumber mod 2
end if
end function
####
use strict;
use Net::SNMP;
use Cisco::CopyConfig;
my($error,$session,$seed_oid,$oid_root,$community,$hostname,$seed_ip,$found,
$htype,$tftpsvr,$line,$key,$value,$sysname,$ssn);
my ($osysname,$ochassis,$ossn,$oifdesc,$ovlanallowed);#OID constants
my(%done,%devices,%ssndone, %shapes);
my(@todo, @lines, @hostinfo);
#The sysObjectID OID returns a vendor system identifier OID
#Read OIDs and descriptions from file to translate the OIDs
open (FH, "c:/CiscoSysObjIDs.csv");
while (){
chomp($_);
@lines = split ",", $_;
if ($lines[0]){
$devices{$lines[0]} = $lines[1];
}
}
close FH;
#Define OID constants
$osysname = "1.3.6.1.2.1.1.5.0";
$ochassis = "1.3.6.1.2.1.1.2.0";
$ossn = "1.3.6.1.2.1.47.1.1.1.1.11.1";
$oifdesc = "1.3.6.1.2.1.2.2.1.2";
#Vlan allowed OID will show only the VLANs not pruned.
#Administratively allowed VLANs is 1.3.6.1.4.1.9.5.1.9.3.1.5
$ovlanallowed = "1.3.6.1.4.1.9.9.46.1.6.1.1.4";
$done{"0.0.0.0"}=1;
#We need a starting point, get an IP from command line
die "usage: $0 seedip" unless ( @ARGV == 1 );
$seed_ip = $ARGV[0];
die "usage: $0 seedip" unless ($seed_ip =~ m{\d+\.\d+\.\d+\.\d+});
$tftpsvr = "xxx.xxx.xxx.xxx";
@todo=($seed_ip); #List of possible targets
$oid_root = "1.3.6.1.4.1.9.9.23.1.2.1.1";
$seed_oid = ("$oid_root".".3");
print "Host Name,Host IP,Host Type,Local Interface,Neighbor IP,Neighbor Name,Remote Interface,Neighbor Type,Vlans Allowed to Neighbor\n";
while(@todo){ #Grab a target and go to work
$hostname= shift(@todo);
$community = "comm1";
unless(exists $done{$hostname}){ #Make sure we haven't done this one yet
$done{$hostname}=1; #Remember that we checked this IP
#Open SNMP session
($session,$error) = Net::SNMP->session(Hostname => $hostname, Community => $community);
return unless($session);
$sysname = Get_SNMP_Info($osysname);
unless($sysname){
$community = "comm2";
Net::SNMP->session(Hostname => $hostname, Community => $community);
$sysname = Get_SNMP_Info($osysname);
}
unless($sysname){
$community = "comm3";
Net::SNMP->session(Hostname => $hostname, Community => $community);
$sysname = Get_SNMP_Info($osysname);
}
unless($sysname){$sysname = "Unknown device name";}
$htype =(Get_SNMP_Info($ochassis));
$htype =~ s/1\.3\.6\.1\.4\.1\.9\.1\.//;
if ($htype){
for my $key ( keys %devices ) {
if ($htype eq $key) {
$htype = $devices{$key}
;last;
}
}
}
else{$htype = "Unkown device type";}
$ssn = Get_SNMP_Info($ossn);
unless ($ssn){$ssn = "UknownSSN$found.$sysname.$hostname"};#Some devices do not support the entPhysical Table
$ssndone{$ssn}=1; #Remember that we checked this ssn
unless(exists $done{$ssn}){ #Make sure we haven't done this one yet
print "$sysname,$hostname,$htype\n";
$found++;
Get_Config($hostname,$community,$tftpsvr,$sysname.".cfg");
get_oids($seed_oid);#Get the SNMP info for this target
}
$session->close;
}
}
print $found."devices found\n";
#----------------------------------------------------------
#This sub finds out how many neighbors the target has
#and determines what oids we need to use to get the info that
#we want, then calls other subs to get that info
#----------------------------------------------------------
sub get_oids{
my($starting_oid , $new_oid , $unique_oid , $result , $crap, $index,$if_oid);
my($ip , $name , $port, $type);
$starting_oid = $_[0];
$new_oid = $starting_oid ;
while(Net::SNMP::oid_context_match($starting_oid,$new_oid)){
$result = $session->get_next_request(($new_oid));
return unless (defined $result);
($new_oid , $crap) = %$result;
if (Net::SNMP::oid_context_match($starting_oid,$new_oid)){
$unique_oid = $new_oid;
$unique_oid =~ s/$starting_oid//g;
$ip = (Convert_IP(Get_SNMP_Info("$oid_root".".4"."$unique_oid")));
$name = (Get_SNMP_Info("$oid_root".".6"."$unique_oid"));
$port = (Get_SNMP_Info("$oid_root".".7"."$unique_oid"));
$type = (Get_SNMP_Info("$oid_root".".8"."$unique_oid"));
$if_oid = $unique_oid;
$if_oid =~ s/\.\d+$//;
my $ifdescr = Get_SNMP_Info($oifdesc.$if_oid);
my $vlanallowed = Get_SNMP_Info($ovlanallowed.$if_oid);
if ($vlanallowed){
$vlanallowed = Vlans_Allowed_Format($vlanallowed);}
else{$vlanallowed = "Unavailable";}
unless (($type=~/phone/i)||($type=~/server/i)||($type=~/ata/i)){@todo=(@todo,$ip)}; #Ignore phones, servers, and ATA devices
unless (($type=~/phone/i)||($type=~/server/i)||($type=~/ata/i)){print ",,,$ifdescr,$ip,$name,$port,$type,\"$vlanallowed\"\n"};
get_oids($new_oid);
}
}
}
sub Convert_IP{ #This sub converts a hex IP to standard xxx.xxx.xxx.xxx format
my($ip , $result , $crap);
my($hex1 , $hex2 , $hex3 , $hex4);
my($oct1 , $oct2 , $oct3 , $oct4);
my($hex_ip) = $_[0] ;
if ((substr($hex_ip,0,1) eq "")|| ($hex_ip !~ /0x/)){
$ip = "0.0.0.0";
}
else{
$hex_ip =~ s/0x//g;
$hex1 = (substr $hex_ip,0,2);
$hex2 = (substr $hex_ip,2,2);
$hex3 = (substr $hex_ip,4,2);
$hex4 = (substr $hex_ip,6,2);
$oct1 = hex($hex1);
$oct2 = hex($hex2);
$oct3 = hex($hex3);
$oct4 = hex($hex4);
$ip = "$oct1\.$oct2\.$oct3\.$oct4";
}
return $ip;
}
sub Get_SNMP_Info{ #This sub gets the value of an oid
my($crap , $value , $result);
my($oid) = $_[0];
$result = $session->get_request("$oid");
return unless (defined $result);
($crap , $value) = %$result;
return $value;
}
sub Get_Config{
my ($hostip, $community, $tftp, $cfg_file, $copy);
$hostip = shift;
$community = shift;
$tftp = shift;
$cfg_file = shift;
unless ($cfg_file) {$cfg_file = $hostip};
$copy = Cisco::CopyConfig->new(Host => $hostip,
Comm => $community,
Tmout => 15,
Retry => 2);
$copy->copy($tftp, $cfg_file);
if ($copy->error){print "Couldn't get config for $hostip : ".$copy->error."\n"};
}
sub Convert_Octet_String{
my $octet_str = shift;
my $basePort = 0;
my ($index,$octet);
my @octet;
$octet_str = substr $octet_str, 2;
while ($octet_str) {
my $octet = hex substr $octet_str, 0, 2, '';
my $index = 0;
while ($octet) {
next unless $octet & 0x80;
push @octet, $basePort + $index;
} continue {
++$index;
$octet = ($octet << 1) & 0xff;
}
$basePort += 8;
}
return @octet;
}
sub Vlans_Allowed_Format{
my ($vlans,$octets,$bits,$return);
$vlans = shift;
$octets = From_Hex($vlans);
$bits = Reverse_Bit_Order($octets);
$return = Range_Format($bits);
if($return eq "1-1023"){
$return = "1-4094";#Assume the extended VLANs are allowed as well
return $return;
}
return $return;
}
sub From_Hex {
my ($hex) = @_ ;
$hex =~ s/^0x//i ;
return pack('H*', $hex) ;
}
sub Reverse_Bit_Order {
my ($octets) = @_ ;
return pack('B*', unpack('b*', $octets)) ;
}
sub Range_Format{
my $bits = shift;
my $r = undef;
my @s = ();
for my $vn (1..length($bits) * 8) {
if (vec($bits, $vn, 1)) {
if (!defined($r)) { push @s, "$vn" ; $r = 0 ; }
else { $r = $vn ; } ;
}
else {
if (defined($r)) {
if ($r) { $s[-1] .= "-$r" ; } ;
$r = undef ;
} ;
}
}
return join(', ',@s);
}