aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@frank.tg14.gathering.org>2014-04-15 17:12:03 +0200
committerroot <root@frank.tg14.gathering.org>2014-04-15 17:12:03 +0200
commit46cb978bc54303a537a70397c006c977400f242a (patch)
tree669bcd52a6f1a35ce153de151a983620de680fe7
parent46959e031175a33d9a7ab52501323f7b1f9873e5 (diff)
Add a little script to find loopbacks and linknets.
-rwxr-xr-xclients/build-linknets.pl104
-rw-r--r--sql/nms.sql7
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
--