Commit 4216a108 authored by Robert Ricci's avatar Robert Ricci

Add support for Intel and Nortel switches, so that I can run this on

the minibed.

Also, grab MACs from the control switch(es), too.
parent a9ec3b32
...@@ -59,13 +59,21 @@ if (@ARGV) { ...@@ -59,13 +59,21 @@ if (@ARGV) {
# have to worry about missing something, and don't have to get the user to # have to worry about missing something, and don't have to get the user to
# guess which switch they're using # guess which switch they're using
# #
my @switches = getTestSwitches(); my @test_switches = getTestSwitches();
if (!@switches) { if (!@test_switches) {
die "No experimental switches found - make sure they're in the nodes ". die "No experimental switches found - make sure they're in the nodes ".
"table!\n"; "table!\n";
} }
my @control_switches = getControlSwitches();
if (!@control_switches) {
warn "Warning - No control switches found - you probably want to add them " .
"to the nodes table\n";
}
my @switches = (@test_switches, @control_switches);
my $debug = 0; my $debug = 0;
sub DEBUG { sub DEBUG {
...@@ -77,6 +85,7 @@ sub DEBUG { ...@@ -77,6 +85,7 @@ sub DEBUG {
# #
# Loop through each switch indvidually # Loop through each switch indvidually
# #
SWITCHLOOP:
foreach my $switch (@switches) { foreach my $switch (@switches) {
DEBUG "Looking at switch $switch\n"; DEBUG "Looking at switch $switch\n";
...@@ -84,10 +93,21 @@ foreach my $switch (@switches) { ...@@ -84,10 +93,21 @@ foreach my $switch (@switches) {
# I have _no_ idea if this will work on other switches! # I have _no_ idea if this will work on other switches!
# #
my $type = getDeviceType($switch); my $type = getDeviceType($switch);
if ($switch !~ /^cisco/) { my ($snmpversion, $useindexing, $switchtype);
die "Sorry, only Cisco switches are supported!\n"; SWITCH:
for ($type) {
(/^cisco/) && do { $snmpversion = "2c"; $useindexing = 1;
$switchtype = "cisco"; last;};
(/^intel/) && do { $snmpversion = "1"; $useindexing = 0;
$switchtype = "intel"; last;};
(/^nortel/) && do { $snmpversion = "1"; $useindexing = 0;
$switchtype = "nortel"; last;};
warn "WARNING: Switch type $type is not supported for $switch!\n";
next SWITCHLOOP;
} }
# #
# Get the community string for this switch # Get the community string for this switch
# #
...@@ -95,6 +115,7 @@ foreach my $switch (@switches) { ...@@ -95,6 +115,7 @@ foreach my $switch (@switches) {
if ($MASTER_COMMUNITY) { if ($MASTER_COMMUNITY) {
$community = $MASTER_COMMUNITY; $community = $MASTER_COMMUNITY;
} }
my $stack = getSwitchStack($switch); my $stack = getSwitchStack($switch);
if (!$stack) { if (!$stack) {
die "No stack found for switch $switch\n"; die "No stack found for switch $switch\n";
...@@ -107,10 +128,20 @@ foreach my $switch (@switches) { ...@@ -107,10 +128,20 @@ foreach my $switch (@switches) {
DEBUG "Decided on community $community"; DEBUG "Decided on community $community";
# #
# Get a list of VLANS from the switch - we'll need them later # Get a list of VLANS from the switch - we'll need them later. But, only
# for some types of switches.
# #
my $device = new snmpit_cisco($switch,0,$community,0); my @vlanList;
my @vlanList = $device->listVlans(); my $device;
if ($useindexing) {
$device = new snmpit_cisco($switch,0,$community,0);
@vlanList = $device->listVlans();
} else {
#
# Make up a fake VLAN, just so we get into the loop below
#
@vlanList = ([0,0,[]]);
}
# #
# Loop through all VLANs - we have to start a new session for each one. # Loop through all VLANs - we have to start a new session for each one.
...@@ -126,20 +157,43 @@ foreach my $switch (@switches) { ...@@ -126,20 +157,43 @@ foreach my $switch (@switches) {
# is that?! (This abomination, BTW, is called 'Community String # is that?! (This abomination, BTW, is called 'Community String
# Indexing') # Indexing')
# #
my $session = new SNMP::Session(DestHost => $switch, Version => "2c", my $thiscommunity;
Community => "$community\@$vlan_number"); if ($useindexing) {
$thiscommunity = "$community\@$vlan_number";
} else {
$thiscommunity = $community;
}
my $session = new SNMP::Session(DestHost => $switch,
Version => "$snmpversion", Community => "$thiscommunity");
if (!$session) { if (!$session) {
die "Unable to open session to $switch $community\@$vlan_number\n"; die "Unable to open session to $switch $thiscommunity\n";
} }
# #
# Walk the table that contains the MACs for this VLAN # Walk the table that contains the MACs for this VLAN
# #
my ($rows) = $session->bulkwalk(0,32,["dot1dTpFdbTable"]); my $rows;
if ($snmpversion eq "2c") {
($rows) = $session->bulkwalk(0,32,["dot1dTpFdbTable"]);
} else {
my $oid = ["dot1dTpFdbTable",0];
$session->get($oid);
while ($$oid[0] =~ /^dot1dTpFdb/) {
push @$rows, [@$oid];
$session->getnext($oid);
}
}
my %MACs; my %MACs;
my %interfaces; my %interfaces;
my %bridgeports; my %bridgeports;
my %status; my %status;
my $firsttime = 1;
#
# What we loop on here depends on whether we're using bulkwalk with
# v2c, or the old, slow, getnext() walking with version 1
#
foreach my $rowref (@$rows) { foreach my $rowref (@$rows) {
my ($oid, $index, $value) = @$rowref; my ($oid, $index, $value) = @$rowref;
...@@ -186,6 +240,7 @@ foreach my $switch (@switches) { ...@@ -186,6 +240,7 @@ foreach my $switch (@switches) {
# #
# Just record for later use # Just record for later use
# #
DEBUG "Got status $value (index $index)\n";
$status{$index} = $value; $status{$index} = $value;
last SWITCH; last SWITCH;
}; };
...@@ -200,7 +255,17 @@ foreach my $switch (@switches) { ...@@ -200,7 +255,17 @@ foreach my $switch (@switches) {
# #
my %realports; my %realports;
if (keys %MACs) { if (keys %MACs) {
my ($rows) = $session->bulkwalk(0,32,["dot1dBasePortIfIndex"]); my $rows;
if ($snmpversion eq "2c") {
($rows) = $session->bulkwalk(0,32,["dot1dBasePortIfIndex"]);
} else {
my $oid = ["dot1dBasePortIfIndex",0];
$session->get($oid);
while ($$oid[0] =~ /^dot1dBasePortIfIndex/) {
push @$rows, [@$oid];
$session->getnext($oid);
}
}
my %ifIndexMap; my %ifIndexMap;
foreach my $rowref (@$rows) { foreach my $rowref (@$rows) {
my ($oid, $index, $value) = @$rowref; my ($oid, $index, $value) = @$rowref;
...@@ -216,9 +281,28 @@ foreach my $switch (@switches) { ...@@ -216,9 +281,28 @@ foreach my $switch (@switches) {
my $bridgeport = $bridgeports{$index}; my $bridgeport = $bridgeports{$index};
my $ifIndex = $ifIndexMap{$bridgeport}; my $ifIndex = $ifIndexMap{$bridgeport};
if (!$ifIndex) { if (!$ifIndex) {
die "ifIndex conversion failed for $bridgeport!\n"; if ($switchtype eq "nortel") {
#
# Bad hack for Nortel switches
#
$ifIndex = $bridgeport - 47;
} else {
DEBUG "ifIndex conversion failed for $bridgeport!\n";
next;
}
}
#
# If the device is a Cisco, we have to convert ifindex to a
# module.port number - for now, the other switches we support
# have only one module, and require no ifindex conversion.
#
my $modport;
if ($switchtype eq "cisco") {
my ($modport) = $device->convertPortFormat(2, $ifIndex);
} else {
$modport = "1.$ifIndex";
} }
my ($modport) = $device->convertPortFormat(2, $ifIndex);
my $switchport; my $switchport;
if ($modport) { if ($modport) {
$switchport = $switch . "/" . $modport; $switchport = $switch . "/" . $modport;
...@@ -241,7 +325,8 @@ foreach my $switch (@switches) { ...@@ -241,7 +325,8 @@ foreach my $switch (@switches) {
# off-switch (eg. a trunk port) # off-switch (eg. a trunk port)
# #
DEBUG "printing for index $index\n"; DEBUG "printing for index $index\n";
next unless ($status{$index} && $status{$index} eq "learned"); next unless ($status{$index} && ($status{$index} eq "learned" ||
$status{$index} == 3));
next if ($realports{$index} =~ /ifIndex/); next if ($realports{$index} =~ /ifIndex/);
print "$MACs{$index},$realports{$index},$vlan_number,". print "$MACs{$index},$realports{$index},$vlan_number,".
"$interfaces{$index}\n"; "$interfaces{$index}\n";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment