1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#!/usr/local/bin/perl -w
## Print dot1dTpFdbTable from RFC 1493
use strict;
use SNMP_Session;
use BER;
my $dot1dTpFdbAddress = [1,3,6,1,2,1,17,4,3,1,1];
my $dot1dTpFdbPort = [1,3,6,1,2,1,17,4,3,1,2];
my $dot1dTpFdbStatus = [1,3,6,1,2,1,17,4,3,1,3];
my $host = shift @ARGV || die "Usage: $0 host [community]";
my $community = shift @ARGV || 'public';
my $session = SNMP_Session->open ($host, $community, 161)
|| die "open SNMP session to $community\@$host: $!";
$session->map_table ([$dot1dTpFdbPort, $dot1dTpFdbStatus],
sub () {
my ($addr, $port, $status) = @_;
$addr = ether_hex (hex_string_aux (pack ("C6", split ('\.', $addr))));
grep (defined $_ && ($_=pretty_print $_),
($port, $status));
note_fdb ($addr, $port, $status);
});
$session->close
|| warn "close SNMP session: $!";
list_fdbs ();
1;
my %all_fdbs;
sub fdb_addr ($) { defined $_[1] ? $_[0]->{addr} = $_[1] : $_[0]->{addr}; }
sub fdb_port ($) { defined $_[1] ? $_[0]->{port} = $_[1] : $_[0]->{port}; }
sub fdb_status ($) { defined $_[1] ? $_[0]->{status} = $_[1] : $_[0]->{status}; }
sub make_fdb ($@) {
my ($addr, $port, $status) = @_;
{
addr => $addr, port => $port, status => $status,
};
}
sub note_fdb ($$@) {
my ($addr, @other_args) = @_;
my $fdb = make_fdb ($addr, @other_args);
$all_fdbs{$addr} = $fdb;
$fdb;
}
sub list_fdbs () {
print_fdbs_table_header ();
foreach my $fdb (sort { $a->{port} <=> $b->{port} || $a->{addr} cmp $b->{addr} }
values %all_fdbs) {
my $addr = fdb_addr ($fdb);
my $port = fdb_port ($fdb);
my $status = fdb_status ($fdb);
printf STDOUT ("%4d %-20s %s\n",
$port, $addr, pretty_fdb_status ($status));
}
}
sub print_fdbs_table_header () {
printf STDOUT ("%-4s %-20s %s\n",
"port",
"MAC addr.",
"status");
print STDOUT (("=" x 35),"\n");
}
sub pretty_fdb_status ($) {
my ($status) = @_;
if ($status == 1) {
return "other";
} elsif ($status == 2) {
return "invalid";
} elsif ($status == 3) {
return "learned";
} elsif ($status == 4) {
return "self";
} elsif ($status == 5) {
return "mgmt";
} else {
return "ILLEGAL".$status;
}
}
sub ether_hex ($) {
my ($string) = @_;
$string =~ s/([0-9a-f][0-9a-f])/$1:/g;
$string =~ s/:$//;
$string;
}
sub hex_string_aux ($) {
my ($binary_string) = @_;
my ($c, $result);
$result = '';
for $c (unpack "C*", $binary_string) {
$result .= sprintf "%02x", $c;
}
$result;
}
|