8 # usage: NAME_MAC=/dev/shm/file-with-name-space-mac sbw-parse.pl [optional-switch-snmpbulkwalk-dump]
10 use Data::Dump qw(dump);
12 my $debug = $ENV{DEBUG} || 0;
14 my @cols = qw( ifName ifHighSpeed ifAdminStatus ifOperStatus ifType dot1dStpPortPathCost ifAlias );
18 foreach my $name_mac ( qw( /dev/shm/sw-name-mac /dev/shm/wap-name-mac ), $ENV{NAME_MAC} ) {
19 next unless -e $name_mac;
20 open(my $f, '<'. $name_mac);
23 #my ( $ip, $name, $mac ) = split(/ /,$_);
24 my ( $name, $mac ) = split(/ /,$_);
26 $mac2name->{$mac} = $name;
31 my ( $mac, $name ) = @_;
35 if ( exists $mac2name->{$mac} ) {
36 my $mac_name = $mac2name->{$mac};
37 warn "ERROR: name different $name != $mac_name" if $name && $name ne $mac_name;
38 return ( $mac, $mac_name );
40 return ( $mac, $name );
43 warn "# mac2name = ",dump($mac2name) if $debug;
51 $mac =~ s/^([0-9a-f]):/0$1:/;
52 while ( $mac =~ s/:([0-9a-f]):/:0$1:/g ) {};
53 $mac =~ s/:([0-9a-f])$/:0$1/;
58 sub sw_name_mac_port {
59 my ( $name, $mac, $port ) = @_;
61 if ( exists $mac2name->{$mac} ) {
62 my $sw_name = $mac2name->{$mac};
63 $sw->{$name}->{port_for_switch}->{$port}->{ $sw_name }++;
64 #print "## $name $port $sw_name\n";
69 @files = glob('snmpbulkwalk/*') unless @files;
71 foreach my $file ( @files ) {
72 my ( undef, $name ) = split(/\//, $file);
73 print "# $name $file\n" if $debug;
75 if ( -s "/dev/shm/$file" ) {
76 if ( -M $file < -M "/dev/shm/$file" ) {
77 warn "UPDATE $file\n";
78 system "cp -pv /dev/shm/$file $file";
80 $file="/dev/shm/$file";
82 warn "WARNING: using old file $file\n";
85 open(my $f, '<', $file);
88 if ( m/::(sysName|sysLocation|ipDefaultTTL|dot1dStpPriority|dot1dStpTopChanges|dot1dStpDesignatedRoot|dot1dStpRootCost|dot1dStpRootPort|dot1qNumVlans)\./ ) {
89 my ( undef, $v ) = split(/ = \w+: /,$_,2);
90 $sw->{$name}->{$1} = $v;
91 } elsif ( m/::(ifMtu|ifHighSpeed)\[(\d\d?)\] = (?:INTEGER|Gauge32): (\d+)/ ) {
92 $sw->{$name}->{$1}->[$2] = $3;
93 } elsif ( m/::(ifPhysAddress)\[(\d\d?)\] = STRING: ([0-9a-f:]+)/ ) {
94 $sw->{$name}->{$1}->[$2] = fix_mac($3);
95 } elsif ( m/::(ifName|ifAlias)\[(\d\d?)\] = STRING: (.+)/ ) {
96 $sw->{$name}->{$1}->[$2] = $3;
97 } elsif ( m/::(ifAdminStatus|ifOperStatus|ifType|dot3StatsDuplexStatus)\[(\d\d?)\] = INTEGER: (\w+)\(/ ) {
98 $sw->{$name}->{$1}->[$2] = $3;
99 } elsif ( m/::(dot1dStpPortPathCost)\[(\d\d?)\] = INTEGER: (\d+)/ ) {
100 $sw->{$name}->{$1}->[$2] = $3;
101 } elsif ( m/::(dot1dTpFdbPort)\[STRING: ([0-9a-f:]+)\] = INTEGER: (\d+)/ ) {
102 $sw->{$name}->{$1}->{ fix_mac($2) } = $3;
103 sw_name_mac_port( $name, $2, $3 );
104 } elsif ( m/::(dot1qTpFdbPort)\[(\d+)\]\[STRING: ([0-9a-f:]+)\] = INTEGER: (\d+)/ ) {
105 $sw->{$name}->{$1}->{ fix_mac($3) } = [ $4, $2 ]; # port, vlan
106 sw_name_mac_port( $name, $3, $4 );
109 # dot1qVlanCurrentEgressPorts
110 # dot1qVlanCurrentUntaggedPorts
111 # dot1qVlanStaticName
112 # dot1qVlanStaticEgressPorts
113 # dot1qVlanStaticUntaggedPorts
121 warn "# sw $name = ",dump($sw->{$name}) if $debug;
123 foreach my $port ( 1 .. $#{ $sw->{$name}->{ifName} } ) {
125 foreach my $oid ( @cols ) {
126 if ( $oid eq 'ifAlias' ) {
127 if ( defined( $sw->{$name}->{$oid}->[$port] ) ) {
128 print " [",$sw->{$name}->{$oid}->[$port],"]";
130 } elsif ( defined $sw->{$name}->{$oid}->[$port] ) {
131 print " ", $sw->{$name}->{$oid}->[$port];
134 #warn "MISSING $name $oid $port\n";
138 if ( exists( $sw->{$name}->{port_for_switch}->{ $port } ) ) {
139 print " ",join(',', sort keys %{ $sw->{$name}->{port_for_switch}->{ $port } } );