6f752236a4f8a9fe442cebd7d786dafde82bbd62
[dell-switch] / sbw-parse.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5
6 # ./sw-name-mac.sh
7
8 use Data::Dump qw(dump);
9
10 my $debug = $ENV{DEBUG} || 0;
11
12 my @cols = qw( ifName ifHighSpeed ifAdminStatus ifOperStatus ifType dot1dStpPortPathCost ifAlias );
13
14 my $mac2name;
15
16 open(my $f, '<'. '/dev/shm/sw-name-mac');
17 while(<$f>) {
18         chomp;
19         #my ( $ip, $name, $mac ) = split(/ /,$_);
20         my ( $name, $mac ) = split(/ /,$_);
21         $mac = lc($mac);
22         $mac2name->{$mac} = $name;
23 }
24
25 sub mac2name {
26         my ( $mac, $name ) = @_;
27
28         $mac = lc($mac);
29
30         if ( exists $mac2name->{$mac} ) {
31                 my $mac_name = $mac2name->{$mac};
32                 warn "ERROR: name different $name != $mac_name" if $name && $name ne $mac_name;
33                 return ( $mac, $mac_name );
34         }
35         return ( $mac, $name );
36 }
37
38 warn "# mac2name = ",dump($mac2name) if $debug;
39
40
41 my $sw;
42
43 sub fix_mac {
44         my $mac = shift;
45         $mac = lc($mac);
46         $mac =~ s/^([0-9a-f]):/0$1:/;
47         while ( $mac =~ s/:([0-9a-f]):/:0$1:/g ) {};
48         $mac =~ s/:([0-9a-f])$/:0$1/;
49 #       warn "# $mac\n";
50         return $mac;
51 }
52
53 sub sw_name_mac_port {
54         my ( $name, $mac, $port ) = @_;
55         $mac = fix_mac($mac);
56         if ( exists $mac2name->{$mac} ) {
57                 my $sw_name = $mac2name->{$mac};
58                 $sw->{$name}->{port_for_switch}->{$port}->{ $sw_name }++;
59                 #print "## $name $port $sw_name\n";
60         }
61 }
62
63 my @files = @ARGV;
64 @files = glob('snmpbulkwalk/*') unless @files;
65
66 foreach my $file ( @files ) {
67         my ( undef, $name ) = split(/\//, $file);
68         print "# $name $file\n" if $debug;
69
70         if ( -s "/dev/shm/$file" ) {
71                 if ( -M $file < -M "/dev/shm/$file" ) {
72                         warn "UPDATE $file\n";
73                         system "cp -pv /dev/shm/$file $file";
74                 }
75                 $file="/dev/shm/$file";
76         } else {
77                 warn "WARNING: using old file $file\n";
78         }
79
80         open(my $f, '<', $file);
81         while(<$f>) {
82                 chomp;
83                 if ( m/::(sysName|sysLocation|ipDefaultTTL|dot1dStpPriority|dot1dStpTopChanges|dot1dStpDesignatedRoot|dot1dStpRootCost|dot1dStpRootPort|dot1qNumVlans)\./ ) {
84                         my ( undef, $v ) = split(/ = \w+: /,$_,2);
85                         $sw->{$name}->{$1} = $v;
86                 } elsif ( m/::(ifMtu|ifHighSpeed)\[(\d\d?)\] = (?:INTEGER|Gauge32): (\d+)/ ) {
87                         $sw->{$name}->{$1}->[$2] = $3;
88                 } elsif ( m/::(ifPhysAddress)\[(\d\d?)\] = STRING: ([0-9a-f:]+)/ ) {
89                         $sw->{$name}->{$1}->[$2] = fix_mac($3);
90                 } elsif ( m/::(ifName|ifAlias)\[(\d\d?)\] = STRING: (.+)/ ) {
91                         $sw->{$name}->{$1}->[$2] = $3;
92                 } elsif ( m/::(ifAdminStatus|ifOperStatus|ifType|dot3StatsDuplexStatus)\[(\d\d?)\] = INTEGER: (\w+)\(/ ) {
93                         $sw->{$name}->{$1}->[$2] = $3;
94                 } elsif ( m/::(dot1dStpPortPathCost)\[(\d\d?)\] = INTEGER: (\d+)/ ) {
95                         $sw->{$name}->{$1}->[$2] = $3;
96                 } elsif ( m/::(dot1dTpFdbPort)\[STRING: ([0-9a-f:]+)\] = INTEGER: (\d+)/ ) {
97                         $sw->{$name}->{$1}->{ fix_mac($2) } = $3;
98                         sw_name_mac_port( $name, $2, $3 );
99                 } elsif ( m/::(dot1qTpFdbPort)\[(\d+)\]\[STRING: ([0-9a-f:]+)\] = INTEGER: (\d+)/ ) {
100                         $sw->{$name}->{$1}->{ fix_mac($3) } = [ $4, $2 ]; # port, vlan
101                         sw_name_mac_port( $name, $3, $4 );
102                 }
103
104                 # dot1qVlanCurrentEgressPorts
105                 # dot1qVlanCurrentUntaggedPorts
106                 # dot1qVlanStaticName
107                 # dot1qVlanStaticEgressPorts
108                 # dot1qVlanStaticUntaggedPorts
109                 # dot1qPvid
110
111                 # entPhysicalDescr
112                 # entPhysicalClass
113
114                 #print "## $_<--\n";
115         }
116         warn "# sw $name = ",dump($sw->{$name}) if $debug;
117
118         foreach my $port ( 1 .. $#{ $sw->{$name}->{ifName} } ) {
119                 print "$name $port";
120                 foreach my $oid ( @cols ) {
121                         if ( $oid eq 'ifAlias' ) {
122                                 if ( defined( $sw->{$name}->{$oid}->[$port] ) ) {
123                                         print " [",$sw->{$name}->{$oid}->[$port],"]";
124                                 }
125                         } elsif ( defined $sw->{$name}->{$oid}->[$port] ) {
126                                 print " ", $sw->{$name}->{$oid}->[$port];
127                         } else {
128                                 print " ?";
129                                 #warn "MISSING $name $oid $port\n";
130                         }
131
132                 }
133                 if ( exists( $sw->{$name}->{port_for_switch}->{ $port } ) ) {
134                         print " ",join(',', sort keys %{ $sw->{$name}->{port_for_switch}->{ $port } } );
135                 }
136                 print "\n";
137         }}
138
139 # fix ifPhysAddress
140