Selaa lähdekoodia

add script for update switch port desription
add script for backup switch config's
rewrite sync_mikrotik script

Dmitriev Roman 5 vuotta sitten
vanhempi
sitoutus
586883120c

+ 4 - 1
docs/wiki/update_auth_wiki.pl

@@ -15,6 +15,9 @@ use strict;
 use warnings;
 use File::Find;
 use File::Basename;
+use Fcntl qw(:flock);
+open(SELF,"<",$0) or die "Cannot open $0 - $!";
+flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
 
 if (!$config_ref{wiki_path}) { exit; }
 
@@ -51,7 +54,7 @@ exit;
 sub wanted {
 my $filename = $File::Find::name;
 my $dev_name = basename($filename);
-if ($filename =~/\.txt$/ and $dev_name=~/^(Device|Switch|Router|Gateway)/) {
+if ($filename =~/\.txt$/ and $dev_name=~/^(Device|Switch|Router|Gateway|Ups|Sensor)/) {
     $dev_name=~s/\.txt$//;
     $content{$dev_name}=$filename;
     }

+ 3 - 0
docs/wiki/update_wiki.pl

@@ -15,6 +15,9 @@ use strict;
 use warnings;
 use File::Find;
 use File::Basename;
+use Fcntl qw(:flock);
+open(SELF,"<",$0) or die "Cannot open $0 - $!";
+flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
 
 if (!$config_ref{wiki_path}) { exit; }
 

+ 728 - 2
scripts/Rstat/cmd.pm

@@ -14,14 +14,28 @@ use Data::Dumper;
 use Rstat::config;
 use Rstat::main;
 use Net::Telnet;
+use Net::SSH::Expect;
 
 @ISA = qw(Exporter);
-@EXPORT = qw( log_cmd log_cmd2 log_cmd3 log_cmd4 flush_telnet run_command);
+@EXPORT = qw(
+log_cmd
+log_cmd2
+log_cmd3
+log_cmd4
+flush_telnet
+run_command
+netdev_login
+netdev_cmd
+netdev_backup
+netdev_set_port_descr
+netdev_set_hostname
+netdev_set_enable
+netdev_wr_mem
+);
 
 BEGIN
 {
 
-
 #---------------------------------------------------------------------------------
 # Execute command and wait answer from device
 # Args: t - telnet session, $command - command string, $sleep - pause after execute command (enabled by default)
@@ -235,5 +249,717 @@ if ($@) { log_error("Abort: $@"); return 0; };
 return 1;
 }
 
+#---------------------------------------------------------------------------------
+
+sub netdev_login {
+my $device = shift;
+#skip unknown vendor
+if (!$switch_auth{$device->{vendor_id}}) { return; }
+if (!$switch_auth{$device->{vendor_id}}{proto}) { $switch_auth{$device->{vendor_id}}{proto} = 'telnet'; }
+
+my $t;
+
+if ($switch_auth{$device->{vendor_id}}{proto} eq 'telnet') {
+    if (!$device->{port}) { $device->{port} = '23'; }
+    log_info("Try login to $device->{device_name} ip: $device->{ip} by telnet...");
+
+    #zyxel patch
+    if ($device->{vendor_id} eq '4') {
+        eval {
+            my $t1 = new Net::Telnet (Timeout => 30, Port => $device->{port}, Max_buffer_length=>10240000, Prompt =>"/$switch_auth{$device->{vendor_id}}{prompt}/");
+            $t1->open($device->{ip}) or return;
+            if (exists $switch_auth{$device->{vendor_id}}{login}) { $t1->waitfor("/$switch_auth{$device->{vendor_id}}{login}/"); }
+            $t1->print($device->{login});
+            if (exists $switch_auth{$device->{vendor_id}}{password}) { $t1->waitfor("/$switch_auth{$device->{vendor_id}}{password}/"); }
+            $t1->print($device->{password});
+            $t1->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/");
+            $t1->cmd("exit");
+            $t1->close;
+            };
+        }
+
+    eval {
+#        $t = new Net::Telnet (Timeout => 30, Port => $device->{port}, Max_buffer_length=>10240000, Prompt =>"/$switch_auth{$device->{vendor_id}}{prompt}/", Dump_Log=>'/tmp/1');
+        $t = new Net::Telnet (Timeout => 30, Port => $device->{port}, Max_buffer_length=>10240000, Prompt =>"/$switch_auth{$device->{vendor_id}}{prompt}/");
+        $t->open($device->{ip}) or return;
+        if (exists $switch_auth{$device->{vendor_id}}{login}) { $t->waitfor("/$switch_auth{$device->{vendor_id}}{login}/"); }
+        if ($device->{vendor_id} eq '9') { $t->print($device->{login}.'+ct400w'); } else { $t->print($device->{login}); }
+        if (exists $switch_auth{$device->{vendor_id}}{password}) { $t->waitfor("/$switch_auth{$device->{vendor_id}}{password}/"); }
+        $t->print($device->{password});
+        $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/");
+        if (exists $switch_auth{$device->{vendor_id}}{enable}) {
+            $t->print($switch_auth{$device->{vendor_id}}{enable});
+            $t->print($device->{enable_password});
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/");
+            }
+        if ($device->{vendor_id} eq '2') {
+            log_cmd($t,"terminal datadump");
+            log_cmd($t,"no logging console");
+            }
+        if ($device->{vendor_id} eq '5') { log_cmd($t,"terminal page-break disable"); }
+        if ($device->{vendor_id} eq '6') { log_cmd($t,"terminal length 0"); }
+        if ($device->{vendor_id} eq '9') { log_cmd($t,"/system note set show-at-login=no"); }
+        if ($device->{vendor_id} eq '16') { log_cmd($t,"terminal width 0"); }
+        if ($device->{vendor_id} eq '17') {
+            log_cmd($t,"more displine 50");
+            log_cmd($t,"more off");
+            }
+        if ($device->{vendor_id} eq '38') {
+            log_cmd($t,"disable cli prompting");
+            log_cmd($t,"disable clipaging");
+            }
+        };
+    if ($@) { log_error("Login to $device->{device_name} ip: $device->{ip} by telnet aborted: $@"); } else { log_info("Login to $device->{device_name} ip: $device->{ip} by telnet success!"); }
+    }
+
+if ($switch_auth{$device->{vendor_id}}{proto} eq 'ssh') {
+    if (!$device->{port}) { $device->{port} = '22'; }
+    log_info("Try login to $device->{device_name} ip: $device->{ip} by ssh...");
+    eval {
+        $t  = Net::SSH::Expect->new (
+            host=>$device->{ip},
+            port=>$device->{port},
+            user=>$device->{login},
+            password=>$device->{password},
+            timeout=>1,
+            raw_pty=>1,
+            ssh_option=>'-o PubkeyAcceptedKeyTypes=+ssh-dss \
+            -o KexAlgorithms=+diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 \
+            -o HostKeyAlgorithms=+ssh-dss \
+            -o LogLevel=quiet \
+            -o UserKnownHostsFile=/dev/null \
+            -o StrictHostKeyChecking=no'
+            );
+
+        $t->run_ssh() or die "SSH process couldn't start: $!";
+
+        my $retry_count = 0;
+        my $max_retry_count = 30;
+        my $rc;
+        while(1){
+            $rc = eval{$t->login($switch_auth{$device->{vendor_id}}{login},$switch_auth{$device->{vendor_id}}{password},0);};
+            last if defined $rc;
+            return if $retry_count >= $max_retry_count;
+            $retry_count++;
+            sleep 1;
+            }
+
+        if ($rc !~ /$switch_auth{$device->{vendor_id}}{prompt}/) { return; }
+
+        if (exists $switch_auth{$device->{vendor_id}}{enable}) {
+            $t->send($switch_auth{$device->{vendor_id}}{enable}."\n");
+#            $t->print($device->{enable_password});
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+
+        if ($device->{vendor_id} eq '2') {
+            $t->send("terminal datadump");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            $t->send("no logging console");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '5') { 
+            $t->send("terminal page-break disable"); 
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '6') { 
+            $t->send("terminal length 0"); 
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '9') { 
+            $t->send("/system note set show-at-login=no"); 
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '16') { 
+            $t->send("terminal width 0"); 
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '17') {
+            $t->send("more displine 50");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            $t->send("more off");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        if ($device->{vendor_id} eq '38') {
+            $t->send("disable cli prompting");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            $t->send("disable clipaging");
+            $t->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/",1);
+            }
+        };
+    if ($@) { log_error("Login to $device->{device_name} ip: $device->{ip} by telnet aborted: $@"); } else { log_info("Login to $device->{device_name} ip: $device->{ip} by ssh success!"); }
+    }
+
+return $t;
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_set_enable {
+my $session = shift;
+my $device = shift;
+return if (!exists $switch_auth{$device->{vendor_id}}{enable});
+my $cmd = "$switch_auth{$device->{vendor_id}}{enable}
+SLEEP 5
+$device->{enable_password}
+";
+netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_cmd {
+my ($device,$session,$proto,$cmd,$telnet_version)=@_;
+my @result=();
+if ($proto eq 'ssh') {
+    my @tmp=();
+    if (ref($cmd) eq 'ARRAY') { @tmp = @{$cmd}; } else { push(@tmp,$cmd); }
+    eval {
+    foreach my $run_cmd (@tmp) {
+        next if (!$run_cmd);
+        if ($run_cmd =~ /SLEEP/i) {
+            if ($run_cmd =~ /SLEEP\s+(\d+)/i) { log_session('WAIT:'." $1 sec."); sleep($1); } else { log_session('WAIT:'." 10 sec."); sleep(10); };
+            next;
+            }
+        log_session('Send:'.$cmd);
+        $session->send($cmd."\n");
+        my $line;
+        while ( defined ($line = $session->read_line()) ) { push(@result,$line); }
+        select(undef, undef, undef, 0.25);
+        $session->waitfor($switch_auth{$device->{vendor_id}}{prompt}, 1);
+        }
+    log_session('Get:'.Dumper(\@result));
+    };
+    if ($@) { log_error("Abort: $@"); return 0; };
+    }
+if ($proto eq 'telnet') {
+    my @tmp=();
+    if (!$telnet_version) { $telnet_version = 1; }
+    if (ref($cmd) eq 'ARRAY') { @tmp = @{$cmd}; } else { push(@tmp,$cmd); }
+    eval {
+    foreach my $run_cmd (@tmp) {
+        next if (!$run_cmd);
+        my @ret=();
+        @ret=log_cmd($session,$run_cmd) if ($telnet_version == 1);
+        @ret=log_cmd2($session,$run_cmd) if ($telnet_version == 2);
+        @ret=log_cmd3($session,$run_cmd) if ($telnet_version == 3);
+        @ret=log_cmd4($session,$run_cmd) if ($telnet_version == 4);
+        if (scalar @ret) { push(@result,@ret); }
+        select(undef, undef, undef, 0.25);
+        }
+    };
+    if ($@) { log_error("Abort: $@"); return 0; };
+    }
+return @result;
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_backup {
+my $device = shift;
+my $tftp_ip = shift;
+
+#eltex
+if ($device->{vendor_id} eq '2') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "upload startup-config tftp $tftp_ip $device->{device_name}.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+#huawei
+if ($device->{vendor_id} eq '3') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "tftp $tftp_ip put vrpcfg.zip $device->{device_name}.zip";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
+        };
+    }
+
+#zyxel
+if ($device->{vendor_id} eq '4') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "copy running-config tftp $tftp_ip $device->{device_name}.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+#raisecom
+if ($device->{vendor_id} eq '5') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "upload startup-config tftp $tftp_ip $device->{device_name}.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+#SNR
+if ($device->{vendor_id} eq '6') {
+    eval {
+        my $session = netdev_login($device);
+my $cmd = "copy running-config tftp://$tftp_ip/$device->{device_name}.cfg
+Y
+";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
+        };
+    }
+
+#Dlink
+if ($device->{vendor_id} eq '7') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "upload cfg_toTFTP $tftp_ip dest_file $device->{device_name}.cfg src_file config.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+#allied telesys x210,x610
+if ($device->{device_model_id} ~~ [50..53]) {
+    eval {
+        my $session = netdev_login($device);
+my $cmd = "copy running-config tftp
+SLEEP 2
+$tftp_ip
+SLEEP 2
+$device->{device_name}.cfg
+SLEEP 5
+";
+    netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,2);
+    };
+    }
+#allied telesys 8000
+if ($device->{device_model_id} eq '3') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "copy running-config tftp://$tftp_ip/$device->{device_name}.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,2);
+        };
+    }
+#allied telesys 8100
+if ($device->{device_model_id} eq '4') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "copy flash tftp $tftp_ip boot.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,2);
+        rename $tftp_dir."/boot.cfg",$tftp_dir."/$device->{device_name}".".cfg";
+        };
+    }
+
+#mikrotik
+if ($device->{vendor_id} eq '9') {
+    eval {
+        my $session = netdev_login($device);
+        log_cmd($session,"/system note set show-at-login=no",1,$session->prompt);
+        my $cmd = "/export";
+        my @netdev_cfg = netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,4);
+        write_to_file($tftp_dir."/$device->{device_name}.cfg","Config for $device->{device_name}",0);
+        foreach my $row (@netdev_cfg) { write_to_file($tftp_dir."/$device->{device_name}.cfg",$row,1); }
+        };
+    }
+
+#cisco
+if ($device->{vendor_id} eq '16') {
+    eval {
+        my $session = netdev_login($device);
+my $cmd = "
+copy system:/running-config tftp:
+SLEEP 2
+$tftp_ip
+SLEEP 2
+$device->{device_name}.cfg
+SLEEP 5
+";
+    netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,2);
+    };
+    }
+
+#maipu
+if ($device->{vendor_id} eq '17') {
+    eval {
+        my $session = netdev_login($device);
+my $cmd = "
+filesystem
+copy running-config tftp $tftp_ip $device->{device_name}.cfg
+SLEEP 5
+exit
+";
+    netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+    };
+    }
+
+#Qtech
+if ($device->{vendor_id} eq '38') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "upload configuration tftp $tftp_ip $device->{device_name}.cfg";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+#Extreme
+if ($device->{vendor_id} eq '39') {
+    eval {
+        my $session = netdev_login($device);
+        my $cmd = "upload configuration $tftp_ip $device->{device_name}.cfg vr \"VR-Default\"";
+        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
+        };
+    }
+
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_set_port_descr {
+my $session = shift;
+my $device = shift;
+my $port = shift;
+my $port_num = shift;
+my $descr = shift;
+
+my $cmd;
+my $telnet_cmd_mode = 4;
+
+#eltex
+if ($device->{vendor_id} eq '2') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+
+#huawei
+if ($device->{vendor_id} eq '3') {
+    if (!$descr) { $descr = "undo description"; } else { $descr = "description $descr"; }
+$cmd = "
+interface $port
+$descr
+quit";
+    }
+
+#zyxel
+if ($device->{vendor_id} eq '4') {
+    if (!$descr) { $descr = "name "; } else { $descr = "name $descr"; }
+$cmd = "
+conf t
+interface port-channel $port_num
+$descr
+exit
+exit";
+    }
+
+#raisecom
+if ($device->{vendor_id} eq '5') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+interface $port_num
+$descr
+exit
+exit";
+    }
+
+#SNR
+if ($device->{vendor_id} eq '6') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+
+#Dlink
+if ($device->{vendor_id} eq '7') {
+    if (!$descr) { $descr = "clear_description"; } else { $descr = "description $descr"; }
+    $cmd = "config ports $port $descr";
+    }
+
+#allied telesys x210,x610
+if ($device->{vendor_id} eq '8') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+    $telnet_cmd_mode = 2;
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+#allied telesys 8000
+if ($device->{device_model_id} eq '3') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+    $telnet_cmd_mode = 2;
+$cmd = "
+conf
+interface ethernet $port
+$descr
+exit
+exit";
+    }
+#allied telesys 8100
+if ($device->{device_model_id} eq '4') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+    $telnet_cmd_mode = 2;
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+
+#mikrotik
+if ($device->{vendor_id} eq '9') {
+$cmd = "/interface ethernet
+set [ find default-name=$port ] comment=$descr
+";
+    }
+
+#cisco
+if ($device->{vendor_id} eq '16') {
+    if (!$descr) { $descr = 'description ""'; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+
+#maipu
+if ($device->{vendor_id} eq '17') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+port $port
+$descr
+exit
+exit";
+    }
+
+#Qtech
+if ($device->{vendor_id} eq '38') {
+    if (!$descr) { $descr = "no description"; } else { $descr = "description $descr"; }
+$cmd = "
+conf t
+interface $port
+$descr
+exit
+exit";
+    }
+
+#Extreme
+if ($device->{vendor_id} eq '39') {
+    if ($descr) {
+        $cmd = "configure port $port_num display $descr";
+        } else {
+        $cmd = "unconfigure port $port_num display";
+        }
+    }
+
+netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,$telnet_cmd_mode);
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_set_hostname {
+my $session = shift;
+my $device = shift;
+
+my $cmd;
+my $telnet_cmd_mode = 4;
+
+#eltex
+if ($device->{vendor_id} eq '2') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+}
+
+#huawei
+if ($device->{vendor_id} eq '3') {
+    $cmd = "sysname $device->{device_name}";
+    }
+
+#zyxel
+if ($device->{vendor_id} eq '4') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+    }
+
+#raisecom
+if ($device->{vendor_id} eq '5') {
+    $cmd = "hostname $device->{device_name}";
+    }
+
+#SNR
+if ($device->{vendor_id} eq '6') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+}
+
+#Dlink
+if ($device->{vendor_id} eq '7') {
+    $cmd = "config hostname $device->{device_name}";
+    }
+
+#allied telesys x210,x610 - default
+if ($device->{vendor_id} eq '8') {
+$telnet_cmd_mode = 2;
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+}
+
+#allied telesys 8000
+if ($device->{device_model_id} eq '3') {
+$telnet_cmd_mode = 2;
+$cmd = "
+conf
+hostname $device->{device_name}
+exit";
+}
+
+#allied telesys 8100
+if ($device->{device_model_id} eq '4') {
+$telnet_cmd_mode = 2;
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+}
+
+#mikrotik
+if ($device->{vendor_id} eq '9') {
+$cmd = "/system identity
+set name=$device->{device_name}
+";
+    }
+
+#cisco
+if ($device->{vendor_id} eq '16') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+    }
+
+#maipu
+if ($device->{vendor_id} eq '17') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+    }
+
+#Qtech
+if ($device->{vendor_id} eq '38') {
+$cmd = "
+conf t
+hostname $device->{device_name}
+exit";
+    }
+
+#Extreme
+if ($device->{vendor_id} eq '39') {
+    $cmd = "configure snmp sysName $device->{device_name}";
+    }
+
+netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,$telnet_cmd_mode);
+}
+
+#---------------------------------------------------------------------------------
+
+sub netdev_wr_mem {
+my $session = shift;
+my $device = shift;
+
+my $cmd;
+my $telnet_cmd_mode = 4;
+
+#eltex
+if ($device->{vendor_id} eq '2') {
+$cmd = "wr
+Y";
+}
+
+#huawei
+if ($device->{vendor_id} eq '3') {
+$cmd = "quit
+save
+Y
+";
+}
+
+#zyxel
+if ($device->{vendor_id} eq '4') { $cmd = "wr mem"; }
+
+#raisecom
+if ($device->{vendor_id} eq '5') { $cmd = "wr"; }
+
+#SNR
+if ($device->{vendor_id} eq '6') {
+$cmd="copy running-config startup-config
+Y";
+}
+
+#Dlink
+if ($device->{vendor_id} eq '7') { $cmd="save"; }
+
+#allied telesys x210,x610
+if ($device->{vendor_id} eq '8') {
+$cmd = "wr
+Y";
+    }
+#allied telesys 8000
+if ($device->{device_model_id} eq '3') {
+$telnet_cmd_mode=2;
+$cmd = "copy running-config startup-config
+Y
+";
+    }
+#allied telesys 8100
+if ($device->{device_model_id} eq '4') {
+$cmd = "wr
+Y";
+    }
+
+#cisco
+if ($device->{vendor_id} eq '16') { $cmd="wr_mem"; }
+
+#maipu
+if ($device->{vendor_id} eq '17') {
+$cmd = "wr
+Yes
+";
+    }
+
+#Qtech
+if ($device->{vendor_id} eq '38') {
+$cmd = "copy running-config startup-config
+Y
+";
+    }
+
+#Extreme
+if ($device->{vendor_id} eq '39') { $cmd="save configuration primary"; }
+
+netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,$telnet_cmd_mode);
+}
+
+#---------------------------------------------------------------------------------
+
 1;
 }

+ 21 - 0
scripts/Rstat/config.pm

@@ -101,7 +101,10 @@ $vpn_networks
 @free_network_list
 @vpn_network_list
 %config_ref
+%switch_auth
 $last_refresh_config
+$tftp_dir
+$tftp_server
 );
 
 BEGIN
@@ -245,9 +248,27 @@ our $domain_name;
 our $connections_history;
 our $dbh;
 our $urgent_sync = 0;
+our $tftp_dir=$Config->{_}->{tftp_dir} || '/var/lib/tftpboot';
+our $tftp_server=$Config->{_}->{tftp_server} || '';
 
 our $last_refresh_config = time();
 
+our %switch_auth = (
+'8'=>{'vendor'=>'Allied Telesis','enable'=>'en','proto'=>'telnet','login'=> '(login|User Name):','password'=>'Password:','prompt'=>qr/(\010\013){0,5}(([-\w]+|[-\w(config)+])\#|[-\w]+\>)/},
+'3'=>{'vendor'=>'Huawei','proto'=>'ssh','enable'=>'system-view','login'=> 'login as:','password'=>'Password: ','prompt'=>qr/(\<.*\>|\[.*\])/},
+'16'=>{'vendor'=>'Cisco','proto'=>'telnet','enable'=>'en','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'5'=>{'vendor'=>'Raisecom','proto'=>'telnet','enable'=>'en','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'6'=>{'vendor'=>'SNR','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'7'=>{'vendor'=>'Dlink','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/[-\w]+\#$/},
+#'15'=>{'vendor'=>'HP','proto'=>'telnet','enable'=>'system-view','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'2'=>{'vendor'=>'Eltex','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'17'=>{'vendor'=>'Maipu','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'4'=>{'vendor'=>'Zyxel','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'38'=>{'vendor'=>'Qtech','proto'=>'telnet','enable'=>'en','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
+'9'=>{'vendor'=>'Mikrotik','proto'=>'telnet','login'=> 'Login:','password'=>'Password:','prompt'=>qr/\[(.*)+\@(.*)+\]\s+> $/},
+'39'=>{'vendor'=>'Extreme','proto'=>'telnet','login'=> 'login:','password'=>'Password:','prompt'=>qr/[-\w]+\s\#\s/},
+);
+
 mkdir $LOG_DIR unless (-d $LOG_DIR);
 
 1;

+ 69 - 0
scripts/backupcfg.pl

@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+
+#
+# Copyright (C) Roman Dmitiriev, rnd@rajven.ru
+#
+
+use FindBin '$Bin';
+use lib "$Bin";
+use strict;
+use Time::Local;
+use FileHandle;
+use Data::Dumper;
+use Rstat::config;
+use Rstat::main;
+use Rstat::mysql;
+use Rstat::net_utils;
+use Rstat::cmd;
+use Fcntl qw(:flock);
+
+open(SELF,"<",$0) or die "Cannot open $0 - $!";
+flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
+
+$|=1;
+
+my $debug = 1;
+
+if ($ARGV[0]) {
+    my $device=get_record_sql($dbh,'SELECT * FROM devices WHERE id='.$ARGV[0]);
+    print "Backup switch $device->{device_name} ip: $device->{ip} ...";
+    #router
+    if ($device->{device_type} eq '2') {
+        #mikrotik
+        if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+        $device->{login}=$router_login;
+        $device->{password}=$router_password;
+        }
+    #switch
+    if ($device->{device_type} eq '1') {
+        #mikrotik
+        if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+        $device->{login}='admin';
+        $device->{password}=$sw_password;
+        }
+    netdev_backup($device,$tftp_server);
+    print " end.\n";
+    } else {
+    my @devices=get_records_sql($dbh,'SELECT * FROM devices WHERE deleted=0 and (vendor_id=3 or vendor_id=8 or vendor_id=9)');
+    foreach my $device (@devices) {
+        print "Backup switch $device->{device_name} ip: $device->{ip} ...";
+        #router
+        if ($device->{device_type} eq '2') {
+            #mikrotik
+            if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+            $device->{login}=$router_login;
+            $device->{password}=$router_password;
+            }
+        #switch
+        if ($device->{device_type} eq '1') {
+            #mikrotik
+            if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+            $device->{login}='admin';
+            $device->{password}=$sw_password;
+            }
+        netdev_backup($device,$tftp_server);
+        print " end.\n";
+	}
+    }
+
+exit 0;

+ 167 - 0
scripts/set_port_descr.pl

@@ -0,0 +1,167 @@
+#!/usr/bin/perl
+
+#
+# Copyright (C) Roman Dmitiriev, rnd@rajven.ru
+#
+
+use FindBin '$Bin';
+use lib "$Bin/";
+use strict;
+use Time::Local;
+use FileHandle;
+use Data::Dumper;
+use Rstat::config;
+use Rstat::main;
+use Rstat::net_utils;
+use Rstat::mysql;
+use Rstat::snmp;
+use Rstat::cmd;
+use Net::SNMP qw(:snmp);
+use Fcntl qw(:flock);
+open(SELF,"<",$0) or die "Cannot open $0 - $!";
+flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
+
+my @auth_list = get_records_sql($dbh,"SELECT A.id,A.ip,A.mac,A.dns_name,A.comments,A.dhcp_hostname,A.WikiName,K.login,K.ou_id FROM User_auth as A, User_list as K WHERE K.id=A.user_id AND A.deleted=0 ORDER BY A.id");
+
+my %auth_ref;
+foreach my $auth (@auth_list) {
+$auth_ref{$auth->{id}}{id}=$auth->{id};
+$auth_ref{$auth->{id}}{ou_id}=$auth->{ou_id};
+$auth_ref{$auth->{id}}{ip}=$auth->{ip};
+$auth_ref{$auth->{id}}{mac}=$auth->{mac};
+$auth_ref{$auth->{id}}{dns_name}=$auth->{dns_name};
+$auth_ref{$auth->{id}}{comments}=$auth->{comments};
+$auth_ref{$auth->{id}}{dhcp_hostname}=$auth->{dhcp_hostname};
+$auth_ref{$auth->{id}}{WikiName}=$auth->{WikiName};
+$auth_ref{$auth->{id}}{login}=$auth->{login};
+if ($auth->{dns_name}) { $auth_ref{$auth->{id}}{description} = $auth->{dns_name}; }
+if (!$auth_ref{$auth->{id}}{description} and $auth->{WikiName}) { $auth_ref{$auth->{id}}{description} = $auth->{WikiName}; }
+if (!$auth_ref{$auth->{id}}{description} and $auth->{comments}) { $auth_ref{$auth->{id}}{description} = translit($auth->{comments}); }
+if (!$auth_ref{$auth->{id}}{description} and $auth->{dhcp_hostname}) { $auth_ref{$auth->{id}}{description} = $auth->{dhcp_hostname}; }
+if (!$auth_ref{$auth->{id}}{description}) { $auth_ref{$auth->{id}}{description} = translit($auth->{login})."_".$auth->{ip}; }
+$auth_ref{$auth->{id}}{description}=~s/\./-/g;
+$auth_ref{$auth->{id}}{description}=~s/\(/_/g;
+$auth_ref{$auth->{id}}{description}=~s/\)/_/g;
+}
+
+my %port_info;
+
+my $d_sql="SELECT DP.id, D.ip, D.device_name, D.device_model_id, DP.port, DP.snmp_index, DP.comment, D.community, D.snmp_version, DP.target_port_id, D.vendor_id, D.device_type
+FROM devices AS D, device_ports AS DP
+WHERE D.snmp_version>0 and D.id = DP.device_id AND D.community IS NOT NULL AND (D.device_type = 1 OR D.device_type=2) AND D.deleted=0
+ORDER BY D.device_name,DP.port";
+
+my @port_list = get_records_sql($dbh,$d_sql);
+
+foreach my $port (@port_list) {
+$port_info{$port->{id}}{id}=$port->{id};
+$port_info{$port->{id}}{device_name}=$port->{device_name};
+$port_info{$port->{id}}{ip}=$port->{ip};
+$port_info{$port->{id}}{device_model_id}=$port->{device_model_id};
+$port_info{$port->{id}}{port}=$port->{port};
+$port_info{$port->{id}}{snmp_index}=$port->{snmp_index};
+$port_info{$port->{id}}{community}=$port->{community};
+$port_info{$port->{id}}{comment}=$port->{comment};
+$port_info{$port->{id}}{snmp_version}=$port->{snmp_version};
+$port_info{$port->{id}}{target_port_id}=$port->{target_port_id};
+$port_info{$port->{id}}{vendor_id}=$port->{vendor_id};
+$port_info{$port->{id}}{device_type}=$port->{device_type};
+}
+
+my %conn_info;
+
+$d_sql="SELECT C.id, C.port_id, C.auth_id FROM connections AS C, User_auth as A WHERE A.id=C.auth_id AND A.deleted=0 ORDER BY C.id";
+my @conn_list = get_records_sql($dbh,$d_sql);
+
+foreach my $conn (@conn_list) {
+$conn_info{$conn->{id}}{id}=$conn->{id};
+$conn_info{$conn->{id}}{port_id}=$conn->{port_id};
+if ($conn->{auth_id}) {
+    $conn_info{$conn->{id}}{auth_id}=$conn->{auth_id};
+    $conn_info{$conn->{id}}{description}=$auth_ref{$conn->{auth_id}}->{description}."==ID:".$conn->{auth_id};
+    $conn_info{$conn->{id}}{ou_id}=$auth_ref{$conn->{auth_id}}->{ou_id};
+    }
+}
+
+
+foreach my $conn_id (keys %conn_info) {
+if (exists $port_info{$conn_info{$conn_id}{port_id}}{count}) {
+    $port_info{$conn_info{$conn_id}{port_id}}{count}++;
+    if ($conn_info{$conn_id}{ou_id}~~[7,10,12,28] and $conn_info{$conn_id}{description}) {
+        $port_info{$conn_info{$conn_id}{port_id}}{description} = $conn_info{$conn_id}{description};
+        }
+    next;
+    } else { $port_info{$conn_info{$conn_id}{port_id}}{count}=1; }
+
+if (!exists $port_info{$conn_info{$conn_id}{port_id}}{description} and $conn_info{$conn_id}{description}) {
+    $port_info{$conn_info{$conn_id}{port_id}}{description} = $conn_info{$conn_id}{description};
+    }
+}
+
+my %devices;
+
+foreach my $port_id (keys %port_info) {
+if ($port_info{$port_id}{target_port_id}) {
+    $port_info{$port_id}{description}=$port_info{$port_info{$port_id}{target_port_id}}{device_name}."-port-".$port_info{$port_info{$port_id}{target_port_id}}{port};
+    }
+if (!$port_info{$port_id}{description} and $port_info{$port_id}{comment}) { $port_info{$port_id}{description}=translit($port_info{$port_id}{comment}); }
+$devices{$port_info{$port_id}{device_name}}{ports}{$port_info{$port_id}{port}}{description}=$port_info{$port_id}{description};
+$devices{$port_info{$port_id}{device_name}}{ports}{$port_info{$port_id}{port}}{snmp_index}=$port_info{$port_id}{snmp_index};
+$devices{$port_info{$port_id}{device_name}}{device_name}=$port_info{$port_id}{device_name};
+$devices{$port_info{$port_id}{device_name}}{ip}=$port_info{$port_id}{ip};
+$devices{$port_info{$port_id}{device_name}}{device_model_id}=$port_info{$port_id}{device_model_id};
+$devices{$port_info{$port_id}{device_name}}{vendor_id}=$port_info{$port_id}{vendor_id};
+$devices{$port_info{$port_id}{device_name}}{device_type}=$port_info{$port_id}{device_type};
+$devices{$port_info{$port_id}{device_name}}{community}=$port_info{$port_id}{community};
+$devices{$port_info{$port_id}{device_name}}{snmp_version}=$port_info{$port_id}{snmp_version};
+}
+
+foreach my $device_name (keys %devices) {
+my $device = $devices{$device_name};
+
+#skip unknown vendor
+next if (!$switch_auth{$device->{vendor_id}});
+
+#museum patch - at & huawei
+next if !($device->{vendor_id} eq '8' or $device->{vendor_id} eq '3');
+
+my $ip = $device->{ip};
+my $community = $device->{community};
+my $snmp_version = $device->{snmp_version};
+
+print "Device: $device_name IP: $ip community: $community version: $snmp_version\n";
+
+#get interface names
+my $int = get_interfaces($ip,$community,$snmp_version,0);
+
+#router
+if ($device->{device_type} eq '2') {
+    #mikrotik
+    if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+    $device->{login}=$router_login;
+    $device->{password}=$router_password;
+    }
+
+#switch
+if ($device->{device_type} eq '1') {
+    #mikrotik
+    if ($device->{vendor_id} eq '9') { $device->{port}='60023'; }
+    $device->{login}='admin';
+    $device->{password}=$sw_password;
+    }
+
+my $session = netdev_login($device);
+
+if ($session) {
+    netdev_set_hostname($session,$device);
+    foreach my $port (sort  { $a <=> $b } keys %{$device->{ports}}) {
+        my $descr = $device->{ports}{$port}{description};
+        my $index = $device->{ports}{$port}{snmp_index};
+        print "Port: $port index: $index Descr: $descr\n";
+        netdev_set_port_descr($session,$device,$int->{$index}->{name},$port,$descr);
+        }
+    netdev_wr_mem($session,$device);
+    }
+}
+
+exit;

+ 46 - 51
scripts/sync_mikrotik.pl

@@ -12,7 +12,6 @@ use FileHandle;
 use Data::Dumper;
 use Rstat::config;
 use Rstat::main;
-use Rstat::mikrotik;
 use Rstat::cmd;
 use Net::Patricia;
 use Date::Parse;
@@ -22,6 +21,9 @@ use DBI;
 use utf8;
 use open ":encoding(utf8)";
 use Fcntl qw(:flock);
+
+#$debug = 1;
+
 open(SELF,"<",$0) or die "Cannot open $0 - $!";
 flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
 
@@ -76,7 +78,24 @@ if ($l3->{'interface_type'} eq '1') { push(@wan_int,$l3->{'name'}); }
 
 my @cmd_list=();
 
-my $t = Login_Mikrotik($router_ip);
+#router
+if ($gate->{device_type} eq '2') {
+    #mikrotik
+    if ($gate->{vendor_id} eq '9') { $gate->{port}='60023'; }
+    $gate->{login}=$router_login;
+    $gate->{password}=$router_password;
+    }
+
+#switch
+if ($gate->{device_type} eq '1') {
+    #mikrotik
+    if ($gate->{vendor_id} eq '9') { $gate->{port}='60023'; }
+    $gate->{login}='admin';
+    $gate->{password}=$sw_password;
+    }
+
+my $t = netdev_login($gate);
+log_cmd($t,"/system note set show-at-login=no",1,$t->prompt);
 
 foreach my $int (@lan_int) { #interface dhcp loop
 next if (!$int);
@@ -284,81 +303,57 @@ AND User_list.blocked =0
 AND User_auth.user_id <> $hotspot_user_id
 ORDER BY ip_int";
 
-my $user_auth_list = $dbh->prepare($user_auth_sql);
-if ( !defined $user_auth_list ) { die "Cannot prepare statement: $DBI::errstr\n"; }
-$user_auth_list->execute;
-# user auth list
-my $authlist_ref = $user_auth_list->fetchall_arrayref();
-$user_auth_list->finish();
+my @authlist_ref = get_records_sql($dbh,$user_auth_sql);
 
 my %users;
 my %lists;
-my @squid_users=();
 
-foreach my $row (@$authlist_ref) {
+foreach my $row (@authlist_ref) {
 if ($connected_users_only) {
-    next if (!$connected_users->match_string($row->[0]));
+    next if (!$connected_users->match_string($row->{ip}));
     }
-$users{'group_'.$row->[1]}->{$row->[0]}=1;
-$users{'group_all'}->{$row->[0]}=1;
-$lists{'group_'.$row->[1]}=1;
-if ($row->[2]) { $users{'queue_'.$row->[2]}->{$row->[0]}=1; }
+$users{'group_'.$row->{filter_group_id}}->{$row->{ip}}=1;
+$users{'group_all'}->{$row->{ip}}=1;
+$lists{'group_'.$row->{filter_group_id}}=1;
+if ($row->{queue_id}) { $users{'queue_'.$row->{queue_id}}->{$row->{ip}}=1; }
 }
 
 #full list
 $lists{'group_all'}=1;
 
 #get queue list
-my $queue_list = $dbh->prepare( "SELECT id,queue_name,Download,Upload FROM Queue_list" );
-if ( !defined $queue_list ) { die "Cannot prepare statement: $DBI::errstr\n"; }
-$queue_list->execute;
-# user auth list
-my $queuelist_ref = $queue_list->fetchall_arrayref();
-$queue_list->finish();
+my @queuelist_ref = get_records_sql($dbh,"SELECT * FROM Queue_list");
 
 my %queues;
-foreach my $row (@$queuelist_ref) {
-$lists{'queue_'.$row->[0]}=1;
-next if ((!$row->[2]) and !($row->[3]));
-$queues{'queue_'.$row->[0]}{id}=$row->[0];
-$queues{'queue_'.$row->[0]}{down}=$row->[2];
-$queues{'queue_'.$row->[0]}{up}=$row->[3];
+foreach my $row (@queuelist_ref) {
+$lists{'queue_'.$row->{id}}=1;
+next if ((!$row->{Download}) and !($row->{Upload}));
+$queues{'queue_'.$row->{id}}{id}=$row->{id};
+$queues{'queue_'.$row->{id}}{down}=$row->{Download};
+$queues{'queue_'.$row->{id}}{up}=$row->{Upload};
 }
 
 #print Dumper(\%users) if ($debug);
 
-#get filters
-my $filter_list = $dbh->prepare( "SELECT id,name,proto,dst,dstport,action FROM Filter_list where type=0" );
-if ( !defined $filter_list ) { die "Cannot prepare statement: $DBI::errstr\n"; }
-$filter_list->execute;
-# user auth list
-my $filterlist_ref = $filter_list->fetchall_arrayref();
-$filter_list->finish();
+my @filterlist_ref = get_records_sql($dbh,"SELECT * FROM Filter_list where type=0");
 
 my %filters;
-foreach my $row (@$filterlist_ref) {
-$filters{$row->[0]}->{id}=$row->[0];
-$filters{$row->[0]}->{proto}=$row->[2];
-$filters{$row->[0]}->{dst}=$row->[3];
-$filters{$row->[0]}->{port}=$row->[4];
-$filters{$row->[0]}->{action}=$row->[5];
+foreach my $row (@filterlist_ref) {
+$filters{$row->{id}}->{id}=$row->{id};
+$filters{$row->{id}}->{proto}=$row->{proto};
+$filters{$row->{id}}->{dst}=$row->{dst};
+$filters{$row->{id}}->{port}=$row->{dstport};
+$filters{$row->{id}}->{action}=$row->{action};
 }
 
 #print Dumper(\%filters) if ($debug);
 
-#get groups
-my $group_list = $dbh->prepare( "SELECT group_id,filter_id,Group_filters.order FROM Group_filters order by Group_filters.group_id,Group_filters.order" );
-if ( !defined $group_list ) { die "Cannot prepare statement: $DBI::errstr\n"; }
-$group_list->execute;
-# user auth list
-my $grouplist_ref = $group_list->fetchall_arrayref();
-$group_list->finish();
+my @grouplist_ref = get_records_sql($dbh,"SELECT group_id,filter_id,Group_filters.order FROM Group_filters order by Group_filters.group_id,Group_filters.order");
 
 my %group_filters;
 my $index=1;
-foreach my $row (@$grouplist_ref) {
-#{group-name}->{filter_id}=order
-$group_filters{'group_'.$row->[0]}->{$index}=$row->[1];
+foreach my $row (@grouplist_ref) {
+$group_filters{'group_'.$row->{group_id}}->{$index}=$row->{filter_id};
 $index++;
 }
 
@@ -399,7 +394,7 @@ foreach my $group_name (keys %cur_users) {
     }
 }
 
-
+die;
 timestamp;
 
 #sync firewall rules