use List::Util;
sub usage {
- die "Usage: $0 [--debug] [--mac] [--allmac] <ip-addr>\n";
+ die <<AMEN ;
+Usage: $0 [<options>] <ip-addr>
+
+Options:
+--debug Show debugging outputs
+--mac Show one MAC address learned per port
+--allmac Show all MAC addresses learned per port
+--force-v1 Use SNMPv1 (work-around for buggy switches)
+AMEN
}
my $debug = 0;
my $mac = 0;
my $all_mac = 0;
+my $force_v1 = 0;
GetOptions(
'debug' => \$debug,
'mac' => \$mac,
'allmac' => \$all_mac,
+ 'force-v1' => \$force_v1,
) or usage;
@ARGV == 1 or usage;
my ($snmp, $err) = Net::SNMP->session(
-hostname => $switch_ip,
- -version => '2c',
+ -version => ($force_v1 ? '1' : '2c'),
-community => $community,
);
$snmp or die "Cannot establish session: $err\n";
if ($mac) {
my $OID_1qTpFdbTable = '1.3.6.1.2.1.17.7.1.2.2';
- my $OID_1qPort = "$OID_1qTpFdbTable.1.2";
- my $OID_1qStatus = "$OID_1qTpFdbTable.1.3";
my $vlan_fdb_table = my_get_table({
- 'port' => $OID_1qPort,
- 'status' => $OID_1qStatus,
+ 'port' => "$OID_1qTpFdbTable.1.2",
+ 'status' => "$OID_1qTpFdbTable.1.3",
});
print Dumper($vlan_fdb_table) if $debug;
- for my $m (keys %$vlan_fdb_table) {
- my $fdb = $vlan_fdb_table->{$m};
- $fdb->{status} == 3 or next; # Only learned MACs
- my $port = $if_table->{$fdb->{port}} or die "Forwarding DB refers to unknown iface";
- my @m = split /\./, $m;
- my $vlan = shift @m;
- my $mac = join(':', map { sprintf('%02x', $_) } @m);
- push @{$port->{macs}}, $mac;
+ if (%$vlan_fdb_table) {
+ for my $m (keys %$vlan_fdb_table) {
+ my $fdb = $vlan_fdb_table->{$m};
+ $fdb->{status} == 3 or next; # Only learned MACs
+ my $port = $if_table->{$fdb->{port}} or die "Forwarding DB refers to unknown iface";
+ my @m = split /\./, $m;
+ my $vlan = shift @m;
+ my $mac = join(':', map { sprintf('%02x', $_) } @m);
+ push @{$port->{macs}}, $mac;
+ }
+ } else {
+ print "# Trying fall-fack to .1d FDB\n" if $debug;
+ my $OID_1dTpFdbTable = '1.3.6.1.2.1.17.4.3';
+ my $fdb_table = my_get_table({
+ 'port' => "$OID_1dTpFdbTable.1.2",
+ 'status' => "$OID_1dTpFdbTable.1.3",
+ });
+ print Dumper($fdb_table) if $debug;
+ for my $m (keys %$fdb_table) {
+ my $fdb = $fdb_table->{$m};
+ $fdb->{status} == 3 or next; # Only learned MACs
+ my $port = $if_table->{$fdb->{port}} or die "Forwarding DB refers to unknown iface";
+ my @m = split /\./, $m;
+ my $mac = join(':', map { sprintf('%02x', $_) } @m);
+ push @{$port->{macs}}, $mac;
+ }
}
+
for my $if (values %$if_table) {
$if->{macs} or next;
$if->{macs} = [ sort(List::Util::uniq(@{$if->{macs}})) ];