diff options
author | root <root@frank.tg14.gathering.org> | 2014-04-15 17:12:03 +0200 |
---|---|---|
committer | root <root@frank.tg14.gathering.org> | 2014-04-15 17:12:03 +0200 |
commit | 46cb978bc54303a537a70397c006c977400f242a (patch) | |
tree | 669bcd52a6f1a35ce153de151a983620de680fe7 | |
parent | 46959e031175a33d9a7ab52501323f7b1f9873e5 (diff) |
Add a little script to find loopbacks and linknets.
-rwxr-xr-x | clients/build-linknets.pl | 104 | ||||
-rw-r--r-- | sql/nms.sql | 7 |
2 files changed, 111 insertions, 0 deletions
diff --git a/clients/build-linknets.pl b/clients/build-linknets.pl new file mode 100755 index 0000000..bc7374c --- /dev/null +++ b/clients/build-linknets.pl @@ -0,0 +1,104 @@ +#! /usr/bin/perl + +# sesse testing + +use strict; +use warnings; +use lib '../include'; +use nms; +use Net::CIDR; + +my $dbh = nms::db_connect(); + +my $coregws = $dbh->prepare("SELECT switch, ip, community, sysname FROM switches WHERE switchtype <> 'dlink3100'") + or die "Can't prepare query: $!"; +$coregws->execute; + +my %switch_id = (); # sysname -> switch database ID +my %loopbacks = (); # sysname -> primary address +my %map = (); # CIDR -> (sysname,ip)* +my %lldpneigh = (); # sysname -> sysname -> 1 + +while (my $ref = $coregws->fetchrow_hashref) { + my $sysname = $ref->{'sysname'}; + $switch_id{$sysname} = $ref->{'switch'}; + + print "$sysname...\n"; + my $snmp; + eval { + $snmp = nms::snmp_open_session($ref->{'ip'}, $ref->{'community'}); + }; + warn $@ if $@; + next if not $snmp; + + my $routes = $snmp->gettable('ipCidrRouteTable'); + my $ifs = $snmp->gettable('ifTable'); + my $addrs = $snmp->gettable('ipAddrTable'); + my $lldp = $snmp->gettable('lldpRemTable'); + + # Find all direct routes we have, and that we also have an address in. + # These are our linknet candidates. + for my $route (values %$routes) { + next if ($route->{'ipCidrRouteMask'} eq '255.255.255.255'); + next if ($route->{'ipCidrRouteNextHop'} ne '0.0.0.0'); + my $cidr = Net::CIDR::addrandmask2cidr($route->{'ipCidrRouteDest'}, $route->{'ipCidrRouteMask'}); + + for my $addr (values %$addrs) { + my $ip = $addr->{'ipAdEntAddr'}; + if (Net::CIDR::cidrlookup($ip, $cidr)) { + push @{$map{$cidr}}, [ $sysname, $ip ]; + } + } + } + + # Find the first loopback address. + my %loopbacks_this_switch = (); + for my $addr (values %$addrs) { + my $ifdescr = $ifs->{$addr->{'ipAdEntIfIndex'}}->{'ifDescr'}; + next unless $ifdescr =~ /^Loop/; + $loopbacks_this_switch{$ifdescr} = $addr->{'ipAdEntAddr'}; + } + for my $if (sort keys %loopbacks_this_switch) { + $loopbacks{$sysname} = $loopbacks_this_switch{$if}; + last; + } + + # Find all LLDP neighbors. + for my $neigh (values %$lldp) { + $lldpneigh{$sysname}{$neigh->{'lldpRemSysName'}} = 1; + } +} + +# print Dumper(\%switch_id); +# print Dumper(\%map); +# print Dumper(\%loopbacks); +# print Dumper(\%lldpneigh); + +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +# Update the switches we have loopback addresses fora +while (my ($sysname, $ip) = each %loopbacks) { + $dbh->do('UPDATE switches SET ip=? WHERE sysname=?', + undef, $ip, $sysname); +} + +# Now go through each linknet candidate, and see if we can find any +# direct LLDP neighbors. +$dbh->do('DELETE FROM linknets'); +while (my ($cidr, $devices) = each %map) { + for (my $i = 0; $i < scalar @$devices; ++$i) { + my $device_a = $devices->[$i]; + for (my $j = $i + 1; $j < scalar @$devices; ++$j) { + my $device_b = $devices->[$j]; + next if $device_a->[0] eq $device_b->[0]; + next unless exists($lldpneigh{$device_a->[0]}{$device_b->[0]}); + + $dbh->do('INSERT INTO linknets (switch1, addr1, switch2, addr2) VALUES (?,?,?,?)', + undef, + $switch_id{$device_a->[0]}, $device_a->[1], + $switch_id{$device_b->[0]}, $device_b->[1]); + } + } +} +$dbh->commit; diff --git a/sql/nms.sql b/sql/nms.sql index fe5f4b8..d5182fe 100644 --- a/sql/nms.sql +++ b/sql/nms.sql @@ -593,6 +593,13 @@ create table ping ( switch integer not null, updated timestamptz not null defaul create index updated_index on ping ( updated ); alter table public.ping owner to nms; +create table linknets ( linknet serial not null, switch1 integer not null, addr1 inet not null, switch2 integer not null, addr2 inet not null ); +alter table public.linknets owner to nms; + +create table linknet_ping ( linknet integer not null, updated timestamptz not null default current_timestamp, latency1_ms float, latency2_ms float ); +create index updated_index2 on linknet_ping ( updated ); +alter table public.linknet_ping owner to nms; + -- -- Data for Name: ap_poll; Type: TABLE DATA; Schema: public; Owner: nms -- |