392 lines
15 KiB
Perl
Executable File
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;
|
|
}
|