diff options
Diffstat (limited to 'clients/snmpfetch.pl')
| -rwxr-xr-x | clients/snmpfetch.pl | 256 | 
1 files changed, 0 insertions, 256 deletions
| diff --git a/clients/snmpfetch.pl b/clients/snmpfetch.pl deleted file mode 100755 index a13ef3f..0000000 --- a/clients/snmpfetch.pl +++ /dev/null @@ -1,256 +0,0 @@ -#! /usr/bin/perl -use DBI; -use POSIX; -use Time::HiRes; -use Net::Telnet; -use strict; -use warnings; - -use lib '../include'; -use nms; -use threads; - -our $running = 0; - -our $dbh = nms::db_connect(); -$dbh->{AutoCommit} = 0; -$dbh->{RaiseError} = 1; - -# normal mode: fetch switches from the database -# instant mode: poll the switches specified on the command line -my $instant = defined($ARGV[0]); - -my $qualification; -if ($instant) { -	$qualification = "sysname LIKE ?"; -} else { -	$qualification = <<"EOF"; -(last_updated IS NULL OR now() - last_updated > poll_frequency) -AND (locked='f' OR now() - last_updated > '5 minutes'::interval) -AND ip is not null -EOF -} - -our $qswitch = $dbh->prepare(<<"EOF") -SELECT  -  *, -  DATE_TRUNC('second', now() - last_updated - poll_frequency) AS overdue -FROM -  switches -  NATURAL LEFT JOIN switchtypes -WHERE $qualification -ORDER BY -  priority DESC, -  overdue DESC -LIMIT 1 -FOR UPDATE OF switches -EOF -	or die "Couldn't prepare qswitch"; -our $qlock = $dbh->prepare("UPDATE switches SET locked='t', last_updated=now() WHERE switch=?") -	or die "Couldn't prepare qlock"; -our $qunlock = $dbh->prepare("UPDATE switches SET locked='f', last_updated=now() WHERE switch=?") -	or die "Couldn't prepare qunlock"; -our $qpoll = $dbh->prepare("INSERT INTO polls (time, switch, port, bytes_in, bytes_out, errors_in, errors_out, official_port,operstatus,ifdescr) VALUES (timeofday()::timestamp,?,?,?,?,?,?,true,?,?)") -	or die "Couldn't prepare qpoll"; - -poll_loop(@ARGV); -while ($running > 0) { -	SNMP::MainLoop(0.1); -} - -sub poll_loop { -	my @switches = @_; -	my $instant = (scalar @switches > 0); -	my $timeout = 15; - -	while (1) { -		my $sysname; -		if ($instant) { -			$sysname = shift @ARGV; -			return if (!defined($sysname)); -			$qswitch->execute('%'.$sysname.'%') -				or die "Couldn't get switch"; -		} else { -			# Find a switch to grab -			$qswitch->execute() -				or die "Couldn't get switch"; -		} -		my $switch = $qswitch->fetchrow_hashref(); - -		if (!defined($switch)) { -			$dbh->commit; - -			if ($instant) { -				mylog("No such switch $sysname available, quitting."); -				return; -			} else {	 -				mylog("No available switches in pool, sleeping."); -				SNMP::MainLoop(1.0); -				next; -			} -		} - -		$qlock->execute($switch->{'switch'}) -			or die "Couldn't lock switch"; -		$dbh->commit; - -		if ($switch->{'locked'}) { -			mylog("WARNING: Lock timed out on $switch->{'ip'}, breaking lock"); -		} - -		my $msg; -		if (defined($switch->{'overdue'})) { -			$msg = sprintf "Polling ports %s on %s (%s), %s overdue.", -				$switch->{'ports'}, $switch->{'ip'}, $switch->{'sysname'}, $switch->{'overdue'}; -		} else { -			$msg = sprintf "Polling ports %s on %s (%s), never polled before.", -				$switch->{'ports'}, $switch->{'ip'}, $switch->{'sysname'}; -		} -		mylog($msg); - -		my $ip = $switch->{'ip'}; -		if ($ip eq '127.0.0.1') { -			mylog("Polling disabled for this switch, skipping."); -			$qunlock->execute($switch->{'switch'}) -				or die "Couldn't unlock switch"; -			$dbh->commit; -			next; -		} - -		my $community = $switch->{'community'}; -		my $start = [Time::HiRes::gettimeofday]; -		my $session; -		eval { -			$session = nms::snmp_open_session($ip, $community, 1); -		}; -		if ($@) { -			warn "Couldn't open session (even an async one!) to $ip: $!"; -			$qunlock->execute($switch->{'switch'}) -				or die "Couldn't unlock switch"; -			$dbh->commit; -			next; -		}; -		my @ports = expand_ports($switch->{'ports'}); - -		my $switch_status = { -			session => $session, -			ip => $switch->{'ip'}, -			sysname => $switch->{'sysname'}, -			switch => $switch->{'switch'}, -			num_ports => scalar @ports, -			num_done => 0, -			start => $start, -		};	 - -		for my $port (@ports) { -			my @vars = (); -			push @vars, ["ifInOctets", $port]; -			push @vars, ["ifOutOctets", $port]; -			push @vars, ["ifInErrors", $port]; -			push @vars, ["ifDescr", $port]; -			push @vars, ["ifOutErrors", $port]; -			push @vars, ["ifOperStatus", $port]; -			my $varlist = SNMP::VarList->new(@vars); -			$session->get($varlist, [ \&callback, $switch_status, $port ]); -		} -		$running++; - -		$dbh->rollback; -	} -} - -sub expand_ports { -	my $in = shift; -	my @ranges = split /,/, $in; -	my @ret = (); - -	for my $range (@ranges) { -		if ($range =~ /^\d+$/) { -			push @ret, $range; -		} elsif ($range =~ /^(\d+)-(\d+)$/) { -			for my $i ($1..$2) { -				push @ret, $i; -			} -		} else { -			die "Couldn't understand '$range' in ports"; -		} -	} - -	return (sort { $a <=> $b } @ret);  -} - -sub mylog { -	my $msg = shift; -	my $time = POSIX::ctime(time); -	$time =~ s/\n.*$//; -	printf STDERR "[%s] %s\n", $time, $msg; -} - -sub callback { -	my ($switch, $port, $vars) = @_; - -	my ($in, $out, $ine, $oute) = (undef, undef, undef, undef); -	my $operstatus = 2; -	my $ifdescr = undef; - -	for my $var (@$vars) { -		if ($port != $var->[1]) { -			die "Response for unknown OID $var->[0].$var->[1] (expected port $port)"; -		} -		if ($var->[0] eq 'ifInOctets') { -			$in = $var->[2]; -		} elsif ($var->[0] eq 'ifOutOctets') { -			$out = $var->[2]; -		} elsif ($var->[0] eq 'ifInErrors') { -			$ine = $var->[2]; -		} elsif ($var->[0] eq 'ifOutErrors') { -			$oute = $var->[2]; -		} elsif ($var->[0] eq 'ifOperStatus') { -			$operstatus = $var->[2]; -		} elsif ($var->[0] eq 'ifDescr') { -			$ifdescr = $var->[2]; -		} else { -			die "Response for unknown OID $var->[0].$var->[1]"; -		} -	} - -	my $ok = 1; -	if (!defined($in) || $in !~ /^\d+$/) { -		if (defined($ine)) { -			warn $switch->{'sysname'}.":$port: failed reading in ($ine)" . (defined($in) ? ": $in" : ""); -		} -		$ok = 0; -	} -	if (!defined($out) || $out !~ /^\d+$/) { -		if (defined($oute)) { -			warn $switch->{'sysname'}.":$port: failed reading out ($oute)" . (defined($out) ? ": $out" : ""); -		} -		$ok = 0; -	} -	if (!defined($ifdescr)) { -		warn $switch->{'sysname'}.":$port: failed reading ifdescr"; -		$ok = 0; -	} elsif ($ifdescr =~ m/\./) { -		# Skip virtual ports -		$ok = 0; -	} - -	if ($ok) { -		$qpoll->execute($switch->{'switch'}, $port, $in, $out, $ine, $oute,$operstatus,$ifdescr) || die "%s:%s: %s\n", $switch->{'switch'}, $port, $in; -		$dbh->commit; -	} else { -		warn $switch->{'sysname'} . " failed to OK."; -	} - -	if (++$switch->{'num_done'} == $switch->{'num_ports'}) { -		--$running; -		 -		my $elapsed = Time::HiRes::tv_interval($switch->{'start'}); -		my $msg = sprintf "Polled $switch->{'ip'} in %5.3f seconds.", $elapsed;		 -		mylog($msg); - -		$qunlock->execute($switch->{'switch'}) -			or warn "Couldn't unlock switch"; -		$dbh->commit; -	} -} | 
