aboutsummaryrefslogtreecommitdiffstats
path: root/include/nms.pm
diff options
context:
space:
mode:
Diffstat (limited to 'include/nms.pm')
-rwxr-xr-xinclude/nms.pm186
1 files changed, 186 insertions, 0 deletions
diff --git a/include/nms.pm b/include/nms.pm
new file mode 100755
index 0000000..2ec922b
--- /dev/null
+++ b/include/nms.pm
@@ -0,0 +1,186 @@
+#! /usr/bin/perl
+use strict;
+use warnings;
+use DBI;
+use Net::OpenSSH;
+use Net::Telnet;
+use Data::Dumper;
+use FileHandle;
+use JSON;
+package nms;
+
+use base 'Exporter';
+our @EXPORT = qw(switch_disconnect switch_connect_ssh switch_connect_dlink switch_exec switch_exec_json switch_timeout db_connect);
+
+BEGIN {
+ require "config.pm";
+ eval {
+ require "config.local.pm";
+ };
+}
+
+
+sub db_connect {
+ my $connstr = "dbi:Pg:dbname=" . $nms::config::db_name;
+ $connstr .= ";host=" . $nms::config::db_host unless (!defined($nms::config::db_host));
+
+ my $dbh = DBI->connect($connstr,
+ $nms::config::db_username,
+ $nms::config::db_password, {AutoCommit => 0})
+ or die "Couldn't connect to database";
+ return $dbh;
+}
+
+sub switch_connect_ssh($) {
+ my ($ip) = @_;
+ my $ssh = Net::OpenSSH->new($ip,
+ user => $nms::config::tacacs_user,
+ password => $nms::config::tacacs_pass,
+ master_opts => [ "-o", "StrictHostKeyChecking=no" ]);
+ my ($pty, $pid) = $ssh->open2pty({stderr_to_stdout => 1})
+ or die "unable to start remote shell: " . $ssh->error;
+
+ my $dumplog = FileHandle->new;
+ $dumplog->open(">>/tmp/dumplog-queue") or die "/tmp/dumplog-queue: $!";
+ #$dumplog->print("\n\nConnecting to " . $ip . "\n\n");
+
+ my $inputlog = FileHandle->new;
+ $inputlog->open(">>/tmp/inputlog-queue") or die "/tmp/inputlog-queue: $!";
+ #$inputlog->print("\n\nConnecting to " . $ip . "\n\n");
+
+ my $telnet = Net::Telnet->new(-fhopen => $pty,
+ -timeout => $nms::config::telnet_timeout,
+ -dump_log => $dumplog,
+ -input_log => $inputlog,
+ -prompt => '/.*\@[a-z0-9-]+[>#] /',
+ -telnetmode => 0,
+ -cmd_remove_mode => 1,
+ -output_record_separator => "\r");
+ $telnet->waitfor(-match => $telnet->prompt,
+ -errmode => "return")
+ or die "login failed: " . $telnet->lastline;
+
+ $telnet->cmd("set cli screen-length 0");
+
+ return { telnet => $telnet, ssh => $ssh, pid => $pid, pty => $pty };
+}
+
+sub switch_connect_dlink($) {
+ my ($ip) = @_;
+
+ my $dumplog = FileHandle->new;
+ $dumplog->open(">>/tmp/dumplog-queue") or die "/tmp/dumplog-queue: $!";
+ $dumplog->print("\n\nConnecting to " . $ip . "\n\n");
+
+ my $inputlog = FileHandle->new;
+ $inputlog->open(">>/tmp/inputlog-queue") or die "/tmp/inputlog-queue: $!";
+ $inputlog->print("\n\nConnecting to " . $ip . "\n\n");
+
+ my $conn = new Net::Telnet( Timeout => $nms::config::telnet_timeout,
+ Dump_Log => $dumplog,
+ Input_Log => $inputlog,
+ Errmode => 'return',
+ Prompt => '/[\S\-\_]+[#>]/');
+ my $ret = $conn->open( Host => $ip);
+ if (!$ret || $ret != 1) {
+ return (undef);
+ }
+ # Handle login with and without password
+ print "Logging in without password\n";
+ $conn->waitfor('/User ?Name:/');
+ $conn->print('admin');
+ my (undef, $match) = $conn->waitfor('/DGS-3100#|Password:/');
+ die 'Unexpected prompt after login attempt' if (not defined $match);
+ if ($match eq 'Password:') {
+ $conn->print('gurbagurba'); # Dette passordet skal feile
+ $conn->waitfor('/User ?Name:/');
+ $conn->print($nms::config::tacacs_user);
+ my (undef, $match) = $conn->waitfor('/DGS-3100#|Password:/');
+ if ($match eq 'Password:') {
+ $conn->cmd($nms::config::tacacs_pass);
+ }
+ }
+ return { telnet => $conn };
+}
+
+# Send a command to switch and return the data recvied from the switch
+sub switch_exec {
+ my ($cmd, $conn, $print) = @_;
+
+ sleep 1; # don't overload the D-Link
+
+ # Send the command and get data from switch
+ my @data;
+ if (defined($print)) {
+ $conn->print($cmd);
+ return;
+ } else {
+ @data = $conn->cmd($cmd);
+ print "ERROR: " . $conn->errmsg . "\n" if $conn->errmsg;
+ }
+ return @data;
+}
+
+sub switch_exec_json($$) {
+ my ($cmd, $conn) = @_;
+ my @json = switch_exec("$cmd | display json", $conn);
+ pop @json; # Remove the banner at the end of the output
+ return ::decode_json(join("", @json));
+}
+
+sub switch_timeout {
+ my ($timeout, $conn) = @_;
+
+ $conn->timeout($timeout);
+ return ('Set timeout to ' . $timeout);
+}
+
+sub switch_disconnect($) {
+ my ($struct) = @_;
+ my $conn = $struct->{telnet};
+ $conn->close();
+ if ($struct->{pid}) {
+ waitpid($struct->{pid}, 0);
+ }
+}
+# A few utilities to convert from SNMP binary address format to human-readable.
+
+sub convert_mac {
+ return join(':', map { sprintf "%02x", $_ } unpack('C*', shift));
+}
+
+sub convert_ipv4 {
+ return join('.', map { sprintf "%d", $_ } unpack('C*', shift));
+}
+
+sub convert_ipv6 {
+ return join(':', map { sprintf "%x", $_ } unpack('n*', shift));
+}
+
+sub convert_addr {
+ my ($data, $type) = @_;
+ if ($type == 1) {
+ return convert_ipv4($data);
+ } elsif ($type == 2) {
+ return convert_ipv6($data);
+ } else {
+ die "Unknown address type $type";
+ }
+}
+
+# Convert raw binary SNMP data to list of bits.
+sub convert_bytelist {
+ return split //, unpack("B*", shift);
+}
+
+sub convert_lldp_caps {
+ my ($caps_data, $data) = @_;
+
+ my @caps = convert_bytelist($caps_data);
+ my @caps_names = qw(other repeater bridge ap router telephone docsis stationonly);
+ for (my $i = 0; $i < scalar @caps && $i < scalar @caps_names; ++$i) {
+ $data->{'cap_enabled_' . $caps_names[$i]} = $caps[$i];
+ }
+}
+
+1;