NAME_MAC=/path to read additional names
[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 # usage: NAME_MAC=/dev/shm/file-with-name-space-mac sbw-parse.pl [optional-switch-snmpbulkwalk-dump]
9
10 use Data::Dump qw(dump);
11
12 my $debug = $ENV{DEBUG} || 0;
13
14 my @cols = qw( ifName ifHighSpeed ifAdminStatus ifOperStatus ifType dot1dStpPortPathCost ifAlias );
15
16 my $mac2name;
17
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);
21         while(<$f>) {
22                 chomp;
23                 #my ( $ip, $name, $mac ) = split(/ /,$_);
24                 my ( $name, $mac ) = split(/ /,$_);
25                 $mac = lc($mac);
26                 $mac2name->{$mac} = $name;
27         }
28 }
29
30 sub mac2name {
31         my ( $mac, $name ) = @_;
32
33         $mac = lc($mac);
34
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 );
39         }
40         return ( $mac, $name );
41 }
42
43 warn "# mac2name = ",dump($mac2name) if $debug;
44
45
46 my $sw;
47
48 sub fix_mac {
49         my $mac = shift;
50         $mac = lc($mac);
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/;
54 #       warn "# $mac\n";
55         return $mac;
56 }
57
58 sub sw_name_mac_port {
59         my ( $name, $mac, $port ) = @_;
60         $mac = fix_mac($mac);
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";
65         }
66 }
67
68 my @files = @ARGV;
69 @files = glob('snmpbulkwalk/*') unless @files;
70
71 foreach my $file ( @files ) {
72         my ( undef, $name ) = split(/\//, $file);
73         print "# $name $file\n" if $debug;
74
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";
79                 }
80                 $file="/dev/shm/$file";
81         } else {
82                 warn "WARNING: using old file $file\n";
83         }
84
85         open(my $f, '<', $file);
86         while(<$f>) {
87                 chomp;
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 );
107                 }
108
109                 # dot1qVlanCurrentEgressPorts
110                 # dot1qVlanCurrentUntaggedPorts
111                 # dot1qVlanStaticName
112                 # dot1qVlanStaticEgressPorts
113                 # dot1qVlanStaticUntaggedPorts
114                 # dot1qPvid
115
116                 # entPhysicalDescr
117                 # entPhysicalClass
118
119                 #print "## $_<--\n";
120         }
121         warn "# sw $name = ",dump($sw->{$name}) if $debug;
122
123         foreach my $port ( 1 .. $#{ $sw->{$name}->{ifName} } ) {
124                 print "$name $port";
125                 foreach my $oid ( @cols ) {
126                         if ( $oid eq 'ifAlias' ) {
127                                 if ( defined( $sw->{$name}->{$oid}->[$port] ) ) {
128                                         print " [",$sw->{$name}->{$oid}->[$port],"]";
129                                 }
130                         } elsif ( defined $sw->{$name}->{$oid}->[$port] ) {
131                                 print " ", $sw->{$name}->{$oid}->[$port];
132                         } else {
133                                 print " ?";
134                                 #warn "MISSING $name $oid $port\n";
135                         }
136
137                 }
138                 if ( exists( $sw->{$name}->{port_for_switch}->{ $port } ) ) {
139                         print " ",join(',', sort keys %{ $sw->{$name}->{port_for_switch}->{ $port } } );
140                 }
141                 print "\n";
142         }}
143
144 # fix ifPhysAddress
145