5 use Data::Dump qw(dump);
7 if ( $ARGV[0] eq 'update' ) {
10 ./sw-names | xargs -i ./dell-switch.pl {} 'show lldp neighbors'
11 /home/dpavlin/mikrotik-switch/m-neighbour
18 my $debug = $ENV{DEBUG} || 0;
22 open(my $f, '<'. '/dev/shm/sw-name-mac');
25 #my ( $ip, $name, $mac ) = split(/ /,$_);
26 my ( $name, $mac ) = split(/ /,$_);
28 if ( defined $mac2name->{$mac} ) {
29 if ( $mac2name->{$mac} ne $name ) {
30 warn "ERROR: GOT $mac with $mac2name->{$mac} and now trying to overwrite it with $name\n";
33 $mac2name->{$mac} = $name;
38 my ( $mac, $name ) = @_;
39 return unless defined $mac;
43 if ( exists $mac2name->{$mac} ) {
44 my $mac_name = $mac2name->{$mac};
45 warn "ERROR: name different $name != $mac_name" if $name && $name ne $mac_name;
46 return ( $mac, $mac_name );
48 return ( $mac, $name );
51 warn "# mac2name = ",dump($mac2name) if $debug;
53 open(my $n_fh, '>', '/dev/shm/neighbors.tab');
54 open(my $html_fh, '>', '/var/www/neighbors.html');
55 print $html_fh qq{<table>\n};
57 # parse Dell switch lldp neighbors output
59 foreach my $file ( glob('log/*lldp*') ) {
60 my ( undef, $name, undef ) = split(/_/, $file);
61 print "# $name $file\n" if $debug;
66 open(my $f, '<', $file);
70 next if ( /^$/ || /^\s+Port/ );
73 $line_regex =~ s/\s+$//;
74 $line_regex =~ s/-/./g;
75 $line_regex =~ s/^/(/g;
76 $line_regex =~ s/ /) (/g;
77 $line_regex =~ s/$/)/g;
79 if ( $file =~ m/remote-device/ ) {
80 $line_regex =~ s{\) \(}{.)(}g;
81 $line_regex =~ s{\(\.+\)$}{(.+)}g;
84 print "## line_regex = $line_regex\n" if $debug;
88 s{^\s+}{} if $file =~ m/remote-device/; # remote left-over from pager
92 if ( defined($line_regex) && /$line_regex/ ) {
93 # port, mac, remote_port, system_name, capabilities
94 @v = ( $1, $2, $3, $4, $5 );
96 if ( $file =~ m/neighbors/ ) {
98 # show lldp neighbours
99 # Port Device ID Port ID System Name Capabilities
101 } elsif ( $file =~ m/remote-device/ ) {
103 # show lldp remote-device all
104 # Interface RemID Chassis ID Port ID System Name
106 @v = ( $v[0], $v[2], $v[3], $v[4], '' );
108 # move overflow numbers from system name to port id
109 if ( $v[3] =~ s{^(\d+)}{} ) {
114 die "don't know how to parse $file";
116 } elsif ( defined($line_regex) && $file =~ m/remote-device/ ) {
117 # if we don't have system name, line_regex is too long
118 my @s = split(/\s+/,$_);
119 @v = ( $s[0], $s[2], $s[3], '', '' ) if $#s == 3;
123 print "# [$_]<-- LINE IGNORED\n# [$l]\n",dump($_);
127 print "# [$_] ",join('|',@v),$/ if $debug;
129 @v = map { s/^\s+//; s/\s+$//; $_ } @v;
131 if ( length($v[1]) == 6 ) { # decode text mac
132 $v[1] = unpack('H*', $v[1]);
133 $v[1] =~ s/(..)/$1:/g;
137 ( $v[1], $v[3] ) = mac2name( $v[1], $v[3] );
140 #my ( $port, $device_id, $port_id, $system_name, $cap ) = @v;
141 if ( @ports && $v[0] =~ m/^$/ ) {
142 my @old = @{ pop @ports };
143 foreach my $i ( 0 .. $#old ) {
146 push @ports, [ @old ];
154 print "# [$_]<-- IGNORED no v\n# [$l]\n";
159 foreach my $p ( @ports ) {
160 next if ( $p->[1] eq lc($p->[2]) && $p->[3] eq '' ); # FIXME hosts?
161 print "$name ", join(' | ', @$p ), "\n";
162 print $n_fh "$name\t", join("\t", @$p ), "\n";
163 print $html_fh "<tr><td>$name</td><td>", join("</td><td>", @$p ), "</td></tr>\n";
167 # prase MikroTik /ip neighbor print detail terse
169 my $patt = 'ip neighbor print detail terse';
170 $patt =~ s{\s}{\\ }g; # escape spaces
171 my @files = ( map { $_ . '/*' . $patt } qw( ../mikrotik-switch/out/ ../tilera/out/ ));
172 @files = map { glob $_ } @files;
173 warn "XXX $patt files=",dump(\@files) if $debug;
175 foreach my $file ( @files ) {
176 my $name = $1 if $file =~ m{out/+([\w\-]+)\.ip neighbor};
177 print "## [$name] file $file\n" if $debug;
178 open(my $f, '<', $file);
182 s{^\s*\d+\s+}{}; # remote ordinal number
183 print "# $_\n" if $debug;
185 foreach my $kv ( split(/ /, $_) ) {
186 my ($k,$v) = split(/=/, $kv);
187 $l->{$k} = $v if ( defined($v) && $v ne '""' );
190 no warnings 'uninitialized';
192 #warn "## l=",dump($l),$/;
193 # Port Device ID Port ID System Name Capabilities
197 $l->{'interface-name'},
200 join(' ', $l->{address}, $l->{platform}, $l->{board}, $l->{version} ),
203 ( $v[1], $v[3] ) = mac2name( $v[1], $v[3] );
205 print "$name ", join(' | ', @v), $/;
206 print $n_fh "$name\t", join("\t", @v ), "\n";
207 print $html_fh "<tr><td>$name</td><td>", join("</td><td>", @v ), "</td></tr>\n";
211 print $html_fh qq{</table>\n};