parse show lldp remote-device all
[dell-switch] / neighbors.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5
6 # ./sw-ip-name-mac.sh
7 # ./sw-names | xargs -i ./dell-switch.pl {} 'show lldp neighbors'
8
9 use Data::Dump qw(dump);
10
11 my $mac2ip;
12 my $mac2name;
13
14 open(my $f, '<'. '/dev/shm/sw-ip-name-mac');
15 while(<$f>) {
16         chomp;
17         my ( $ip, $name, $mac ) = split(/ /,$_);
18         $mac2ip->{$mac} = $ip;
19         $mac2name->{$mac} = $name;
20 }
21
22 warn "# mac2name = ",dump($mac2name);
23
24 foreach my $file ( glob('log/*lldp*') ) {
25         my ( undef, $name, undef ) = split(/_/, $file);
26         print "# $name $file\n";
27
28         my $line_regex;
29         my @ports;
30
31         open(my $f, '<', $file);
32         while(<$f>) {
33                 chomp;
34                 #print "## $_<--\n";
35                 next if ( /^$/ || /^\s+Port/ );
36                 if ( /^--+/ ) {
37                         $line_regex = $_;
38                         $line_regex =~ s/\s+$//;
39                         $line_regex =~ s/-/./g;
40                         $line_regex =~ s/^/(/g;
41                         $line_regex =~ s/ /) (/g;
42                         $line_regex =~ s/$/)/g;
43
44                         if ( $file =~ m/remote-device/ ) {
45                                 $line_regex =~ s{\) \(}{.)(}g;
46                                 $line_regex =~ s{\(\.+\)$}{(.+)}g;
47                         }
48
49                         print "## line_regex = $line_regex\n";
50                         next;
51                 }
52
53                 s{^\s+}{} if $file =~ m/remote-device/; # remote left-over from pager
54
55                 if ( defined($line_regex) &&  /$line_regex/ ) {
56                         # port, mac, remote_port, system_name, capabilities
57                         my @v = ( $1, $2, $3, $4, $5 );
58
59                         if ( $file =~ m/neighbors/ ) {
60
61                                 # show lldp neighbours
62                                 # Port       Device ID          Port ID          System Name     Capabilities 
63
64                         } elsif ( $file =~ m/remote-device/ ) {
65
66                                 # show lldp remote-device all
67                                 # Interface RemID   Chassis ID          Port ID           System Name
68
69                                 @v = ( $v[0], $v[2], $v[3], $v[4], '' );
70
71                                 # move overflow numbers from system name to port id
72                                 if ( $v[3] =~ s{^(\d+)}{} ) {
73                                         $v[2] .= $1;
74                                 }
75
76                         } else {
77                                 die "don't know how to parse $file";
78                         }
79
80                         print "# [$_] ",join('|',@v),$/;
81
82                         @v = map { s/^\s+//; s/\s+$//; $_ } @v;
83
84                         if ( length($v[1]) == 6 ) { # decode text mac
85                                 $v[1] = unpack('H*', $v[1]);
86                                 $v[1] =~ s/(..)/$1:/g;
87                                 $v[1] =~ s/:$//;
88                         }
89
90                         if ( exists $mac2name->{$v[1]} ) {
91                                 my $mac_name = $mac2name->{$v[1]};
92                                 if ( $v[3] eq '' ) {
93                                         $v[3] = $mac_name;
94                                 } else {
95                                         warn "ERROR: name different $v[3] != $mac_name" if $v[3] ne $mac_name;
96                                 }
97                         }
98
99                         #my ( $port, $device_id, $port_id, $system_name, $cap ) = @v;
100                         if ( @ports && $v[0] =~ m/^$/ ) {
101                                 my @old = @{ pop @ports };
102                                 foreach my $i ( 0 .. $#old ) {
103                                         $old[$i] .= $v[$i];
104                                 }
105                                 push @ports, [ @old ];
106                         } else {
107                                 push @ports, [ @v ];
108                         }
109                 } else {
110                         print "# $_<--\n";
111                 }
112         }
113
114         foreach my $p ( @ports ) {
115                 next if ( $p->[1] eq $p->[2] && $p->[3] eq '' ); # FIXME hosts?
116                 print "$name ", join(' | ', @$p ), "\n";
117         }
118 }