Files
conetadm 5718e70f15 init
2024-11-14 21:11:06 +01:00

392 lines
15 KiB
Perl
Executable File

#!/usr/bin/perl
use v5.10;
use strict;
use DBI;
use experimental qw( switch );
our $FUNC_STATEMENT_HANDLE;
my @entry;
my %conf;
#read_config ("config.txt");
$conf{'DB_TYPE'}="mysql";
$conf{'DB_NAME'}="routes";
$conf{'DB_HOST'}="10.99.0.199";
$conf{'DB_PORT'}="3306";
$conf{'DB_USER'}="conetadm";
$conf{'DB_PASS'}="Conet12#";
my @hostnames = read_hostnames ();
my %hostname;
foreach my $entry (@hostnames) {
$hostname{"$entry->[1]"} = "$entry->[0]";
}
my @protocols = read_protocols ();
my %protocol;
foreach my $entry (@protocols) {
$protocol{"$entry->[1]"} = "$entry->[0]";
}
# flush all routes from db
flush_routes ();
# Zeilen lesen
# wenn Hostname nicht in DB, hinzufügen
#my @files=`ls /home/rancid/var/rancid/network/configs | egrep "(asa|router|switch.*sp.*).*"`;
#my @files=`cat /home/rancid/var/rancid/network/router.db | awk -F';' '{print $1}' | egrep "(asa|router|switch.*sp.*).*"`;
#my @files=`ls /home/rancid/var/rancid/network/configs | egrep "switch-sp-1"`;
my @files=`cat /home/rancid/var/rancid/network/router.db | awk -F';' '{print \$1}' | egrep "^(asa|router|switch.*sp.*).*"`;
foreach my $host (@files) {
chomp $host;
print "$host\n";
add_router_db($host);
# get routes from asa
if ($host =~ /^asa-/) {
my $ol; # oldline for EIGRP, multiple entries for same dest possible
my @routing = `clogin -u $ENV{'SSHUSER'} -p $ENV{'SSHPASS'} -c "sh route" $host | egrep '^(S |B |D |E |O |I |C | )'`;
foreach my $route (@routing) {
chomp $route;
$route =~ tr/\r//d;
# check which protocol D, S, B
if ($route =~ /^B/) {
print "B";
$ol="";
my $prot = "BGP";
#B 192.168.50.0 255.255.255.248 [200/0] via 10.120.1.187, 7w0d
my ($n,$m,$g) = $route =~ /^B\s+([0-9.]*) ([0-9.]*) .*via ([0-9.]*),.*$/;
#print "host: $host ($hostname{$host}) net: $n, mask: $m, gw: $g, proto: $prot ($protocol{$prot})\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,'na','');
}
elsif ($route =~ /^C/) {
print "C";
$ol="";
my $prot = "CONNECTED";
#C 10.127.12.0 255.255.255.128 is directly connected, LCH_CPS
my ($n,$m,$i) = $route =~ /^C\s+([0-9.]*) ([0-9.]*) .*is directly connected, (.*)$/;
#print "###\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: 'na', int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,'na',$i,'');
}
elsif ($route =~ /^D/) {
print "D";
$ol="";
# can be shown on two or more lines, therefore myn routes lost ($n ne "")
my $prot = "EIGRP";
#D EX 100.65.0.0 255.255.0.0 [170/537856] via 10.120.1.242, 7w0d, FITS
my (undef,$n,$m,$g,$i) = $route =~ /^D([EX ]*) ([0-9.]*) ([0-9.]*) .*via ([0-9.]*),.*, (.*)$/;
#print "###\n$route\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
if ($n ne "") {
print "+";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'');
}
else {
print ".";
$ol=$route;
}
}
elsif ($route =~ /^S/) {
print "S";
$ol="";
my $prot = "STATIC";
#S 92.1.253.131 255.255.255.255 [1/0] via 92.254.20.22, DBS_ZOS
my ($n,$m,$g,$i) = $route =~ /^S\s+([0-9.]*) ([0-9.]*) .*via ([0-9.]*),\s+(.*)$/;
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'');
}
elsif ($route =~ /^ *\[/) {
print "!";
# here we are, now $ol needed
my $line = $ol . $route;
my $prot = "EIGRP";
#D EX 10.1.1.0 255.255.255.0 [170/28416] via 172.31.254.11, 7w0d, OFFICE_XFER
my (undef,$n,$m,$g,$i) = $line =~ /^D([EX ]*) ([0-9.]*) ([0-9.]*) .*via ([0-9.]*),.*, (.*)$/;
#print "###\n$line\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'');
}
}
print "\n\n";
}
if ($host =~ /^router/) {
my @routing = `clogin -u $ENV{'SSHUSER'} -p $ENV{'SSHPASS'} -c "sh ip route" $host | egrep '^(S |B |D |E |O |I |C | )'`;
my $ol; # oldline for EIGRP, multiple entries for same dest possible
foreach my $route (@routing) {
chomp $route;
$route =~ tr/\r//d;
# check which protocol D, S, B
if ($route =~ /^B/) {
print "B";
$ol="";
my $prot = "BGP";
#B 192.168.50.0 255.255.255.248 [200/0] via 10.120.1.187, 7w0d
my ($n,$m,$g) = $route =~ /^B\s+([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*),.*$/;
#print "host: $host ($hostname{$host}) net: $n, mask: $m, gw: $g, proto: $prot ($protocol{$prot})\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,'na','');
}
elsif ($route =~ /^C/) {
print "C";
$ol="";
my $prot = "CONNECTED";
#C 10.127.12.0 255.255.255.128 is directly connected, LCH_CPS
my ($n,$m,$i) = $route =~ /^C\s+([0-9.]*)(\/[0-9]*| ).*is directly connected, (.*)$/;
#print "###\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: 'na', int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,'na',$i,'');
}
elsif ($route =~ /^D/) {
print "D";
$ol="";
# can be shown on two or more lines, therefore myn routes lost ($n ne "")
my $prot = "EIGRP";
#D EX 2.104.55.0 [170/538112] via 10.127.12.126, 7w0d, Vlan2027
my (undef,$n,$m,$g,$i) = $route =~ /^D([EX ]*) ([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*),.*, (.*)$/;
#print "###\n$route\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
if ($n ne "") {
print "+";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'');
}
else {
print ".";
$ol=$route;
}
}
elsif ($route =~ /^S/) {
print "S";
$ol="";
my $prot = "STATIC";
#S 208.134.161.0/24 [1/0] via 10.101.2.1
my ($n,$m,$g,$i) = $route =~ /^S\s+([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*)$/;
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'');
}
elsif ($route =~ /^ *\[/) {
print "!";
# here we are, now $ol needed
my $line = $ol . $route;
my $prot = "EIGRP";
#D EX 10.1.1.0 255.255.255.0 [170/28416] via 172.31.254.11, 7w0d, OFFICE_XFER
my (undef,$n,$m,$g,$i) = $line =~ /^D([EX ]*) ([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*),.*, (.*)$/;
#print "###\n$line\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,'') if ($n ne "");
}
}
print "\n\n";
}
if ($host =~ /^switch-/) {
my @vrfs = `clogin -u $ENV{'SSHUSER'} -p $ENV{'SSHPASS'} -c "sh run" $host | egrep "^ip vrf|vrf definition" | awk '{print \$3}'`;
push @vrfs, "NONE";
foreach my $vrf (@vrfs) {
chomp $vrf;
$vrf =~ tr/\r//d;
my $str;
$str = "sh ip route vrf $vrf" if ($vrf ne "NONE");
$str = "sh ip route" if ($vrf eq "NONE");
my @routing = `clogin -u $ENV{'SSHUSER'} -p $ENV{'SSHPASS'} -c "$str" $host | egrep '^(S |B |D |E |O |I |C | )'`;
my $ol; # oldline for EIGRP, multiple entries for same dest possible
foreach my $route (@routing) {
chomp $route;
$route =~ tr/\r//d;
# check which protocol D, S, B
if ($route =~ /^B/) {
print "B";
$ol="";
my $prot = "BGP";
#B 192.168.50.0 255.255.255.248 [200/0] via 10.120.1.187, 7w0d
my ($n,$m,$g) = $route =~ /^B\s+([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*),.*$/;
#print "host: $host ($hostname{$host}) net: $n, mask: $m, gw: $g, proto: $prot ($protocol{$prot})\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,'na',$vrf);
}
elsif ($route =~ /^C/) {
print "C";
$ol="";
my $prot = "CONNECTED";
#C 10.127.12.0 255.255.255.128 is directly connected, LCH_CPS
my ($n,$m,$i) = $route =~ /^C\s+([0-9.]*)(\/[0-9]*| ).*is directly connected, (.*)$/;
#print "###\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: 'na', int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,'na',$i,$vrf);
}
elsif ($route =~ /^D/) {
print "D";
$ol="";
# can be shown on two or more lines, therefore myn routes lost ($n ne "")
my $prot = "EIGRP";
#D EX 2.104.55.0 [170/538112] via 10.127.12.126, 7w0d, Vlan2027
#my (undef,$n,$m,$g,$i) = $route =~ /^D([EX ]*) ([0-9.]*)(\/[0-9]*| )\[.*via ([0-9.]*),.*, (.*)$/;
my (undef,$n,$m,$g,$i) = $route =~ /^D ([XIANE12]*) *([0-9.]*[0-9.]*[0-9.]*[0-9])(\/[0-9]*|) .*via ([0-9.]*[0-9.]*[0-9.]*[0-9]),.*, (.*)$/;
#print "###\n$route\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
if ($n ne "") {
print "+";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,$vrf);
$ol=$route;
}
else {
print ".";
$ol=$route;
}
}
elsif ($route =~ /^O/) {
print "O";
#O E2 2.104.55.0 [110/20] via 172.17.157.21, 2w1d, Vlan3
#O E2 192.168.213.0/24 [110/10000] via 10.120.1.241, 7w0d, Vlan2006
my $prot = "OSPF";
#my (undef,$n,$m,$g,$i) = $route =~ /^O([IANE12 ]*) ([0-9.]*)(\/[0-9]*| )\[.*via ([0-9.]*),.*, (.*)$/;
my (undef,$n,$m,$g,$i) = $route =~ /^O ([XIANE12]*) *([0-9.]*[0-9.]*[0-9.]*[0-9])(\/[0-9]*|) .*via ([0-9.]*[0-9.]*[0-9.]*[0-9]),.*, (.*)$/;
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,$vrf);
}
elsif ($route =~ /^S/) {
print "S";
$ol="";
my $prot = "STATIC";
#S 208.134.161.0/24 [1/0] via 10.101.2.1
my ($n,$m,$g,$i) = $route =~ /^S\s+([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*)$/;
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,$vrf);
}
elsif ($route =~ /^ *\[/) {
print "!";
# here we are, now $ol needed
my $prot = "EIGRP";
#D EX 160.92.34.32/27 [170/768256] via 10.127.12.130, 1w2d, Vlan2028
# [170/768256] via 10.127.12.2, 1w2d, Vlan2027
my (undef,$n,$m,$g,$i) = $ol =~ /^D([EX ]*) ([0-9.]*)(\/[0-9]*| ).*via ([0-9.]*),.*, (.*)$/;
($g,$i) = $route =~ /via ([0-9.]*),.*, (.*)$/;
#print "###\n$line\n host: $host ($hostname{$host}), net: $n, mask: $m, gw: $g, int: $i, proto: $prot ($protocol{$prot})\n####\n";
insert_route ($hostname{$host},$protocol{$prot},$n,$m,$g,$i,$vrf);
}
}
print "\n\n";
}
}
}
print "\nende\n";
sub insert_route () {
my ($h,$p,$n,$m,$g,$i,$v) = @_;
return 1 if ($n eq "");
my $DBH;
db_connect($DBH, $conf{'DB_TYPE'}, $conf{'DB_NAME'}, $conf{'DB_HOST'}, $conf{'DB_PORT'}, $conf{'DB_USER'}, $conf{'DB_PASS'});
db_exec($DBH, "insert into routes set hostname_id='$h', destination='$n', netmask='$m', gateway='$g', interface='$i', protocol_id='$p', vrf='$v'");
db_disconnect($DBH);
}
sub flush_routes () {
my $DBH;
db_connect($DBH, $conf{'DB_TYPE'}, $conf{'DB_NAME'}, $conf{'DB_HOST'}, $conf{'DB_PORT'}, $conf{'DB_USER'}, $conf{'DB_PASS'});
db_exec($DBH, "delete from routes");
db_disconnect($DBH);
}
sub add_router_db () {
my $rtr = $_[0];
my $DBH;
db_connect($DBH, $conf{'DB_TYPE'}, $conf{'DB_NAME'}, $conf{'DB_HOST'}, $conf{'DB_PORT'}, $conf{'DB_USER'}, $conf{'DB_PASS'});
my @res = db_select($DBH, "select id from hostnames where hostname = '$rtr'");
if ($res[0][0] eq "") {
my @res = db_exec($DBH, "insert into hostnames set hostname = '$rtr'");
}
db_disconnect($DBH);
}
sub read_hostnames {
my $DBH;
db_connect($DBH, $conf{'DB_TYPE'}, $conf{'DB_NAME'}, $conf{'DB_HOST'}, $conf{'DB_PORT'}, $conf{'DB_USER'}, $conf{'DB_PASS'});
my @res = db_select($DBH, "select id,hostname from hostnames");
db_disconnect($DBH);
return @res;
}
sub read_protocols {
my $DBH;
db_connect($DBH, $conf{'DB_TYPE'}, $conf{'DB_NAME'}, $conf{'DB_HOST'}, $conf{'DB_PORT'}, $conf{'DB_USER'}, $conf{'DB_PASS'});
my @res = db_select($DBH, "select id,protocol from protocols");
db_disconnect($DBH);
return @res;
}
sub db_connect (@) {
my $ok = eval {
$_[0] = DBI->connect("dbi:$_[1]:$_[2]:$_[3]:$_[4]", "$_[5]", "$_[6]");
return 0 if (!$_[0]);
return 1;
};
return $ok;
}
sub db_disconnect (@) {
$_[0]->disconnect();
}
sub db_exec (@) {
$FUNC_STATEMENT_HANDLE = $_[0]->prepare ("$_[1]");
$FUNC_STATEMENT_HANDLE->execute();
$FUNC_STATEMENT_HANDLE->finish();
}
sub db_select (@) {
my @data;
my $i;
my $j;
my @ret;
$FUNC_STATEMENT_HANDLE = $_[0]->prepare ("$_[1]");
$FUNC_STATEMENT_HANDLE->execute();
$i=0;
while (@data = $FUNC_STATEMENT_HANDLE->fetchrow_array()) {
$j=0;
foreach (@data) {
$ret[$i][$j]=$_;
$j++;
}
$i++;
}
return @ret;
}
sub read_config {
my $configfile=shift;
my $vd=':'; # trennt var von wert
my $ad=';'; # trennt werte im array bzw. wertpaare im hash
my $hd='#'; # trennt wert von key im hash
open CF,"$configfile";
foreach (<CF>) {
chomp;
if ($_ =~ /require/) {
my ($f) = $_ =~ /require "(.*)"/;
read_config($f);
}
else {
my ($k,$v) = split /$vd/,$_; # trennung zwischen var-name und werten
if ($k =~ /^@/) { # array variable
my @val=split /$ad/,$v;
foreach (@val) {
push @{$conf{"$k"}},$_;
}
}
if ($k =~ /^%/) { # hash variable
my @val=split /$ad/,$v;
foreach my $vp (@val) {
my ($k1,$v1) = split /$hd/,$vp;
$conf{"$k"}{"$k1"}=$v1;
}
}
else {
$conf{"$k"} = $v;
}
}
}
close CF;
}