|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/local/src/munin-1.2.6/node/node.d.linux/ |
Upload File : |
#!@@PERL@@
# -*- perl -*-
#
# Wildcard-script to monitor network port usage. To monitor a
# port, link port_<service> to this file. E.g.
#
# ln -s /usr/share/munin/node/plugins-auto/port_ /etc/munin/node.d/port_www
#
# ...will monitor www connections. Services are those listed in
# /etc/services.
#
# Parameters:
#
# config (required)
# autoconf (optional - used by munin-config)
# suggest (optional - used by munin-config)
#
# Magic markers (optional - used by munin-config and some installation
# scripts):
#%# family=manual
#%# capabilities=autoconf suggest
use constant {
ST_ESTABLISHED => 1,
ST_LISTEN => 10,
};
sub cache_open
{
my ($fd, $file) = @_;
my $cache_dir = "@@PLUGSTATE@@";
my $cache = $file;
$cache =~ s:/:_:g;
$cache = "$cache_dir/$cache";
my $ttl = $ENV{'cache_ttl'};
$ttl = 60 unless (defined $ttl);
# The user can disable caching by setting cache_ttl to something
# other than a positive integer.
if ($ttl !~ /^\d+$/ || $ttl == 0)
{
return open($fd, $file);
}
if (-e $cache && -M _ < $ttl / 86400)
{
return open($fd, $cache);
}
unless (-d $cache_dir)
{
mkdir($cache_dir) || die "$cache_dir: mkdir: $!\n";
}
my $retval;
$retval = open(CACHE_INPUT, $file);
return $retval unless ($retval);
my $tmpfile = "$cache.$$";
open(CACHE_OUTPUT, ">$tmpfile") || die "$tmpfile: open: $!\n";
while (<CACHE_INPUT>)
{
print CACHE_OUTPUT;
}
close(CACHE_OUTPUT) || die "$tmpfile: close: $!\n";
close(CACHE_INPUT);
rename($tmpfile, $cache) || die "$cache: rename: $!\n";
# Okay, we have a fresh copy in our cache.
return open($fd, $cache);
}
if ($ARGV[0] and $ARGV[0] =~ /^\s*autoconf\s*$/i)
{
if (-r "/proc/net/tcp" or -r "/proc/net/tcp6")
{
print "yes\n";
exit 0;
}
else
{
print "no\n";
exit 1;
}
}
sub count_tcp_ports
{
my ($state, $ports) = @_;
cache_open("NETSTAT", "/proc/net/tcp") or exit 1;
my $header = <NETSTAT>;
$header =~ /^(.*\s)local_address\s/;
# 32/4 + 1 corresponds to the IP address in hex + ":"
my $local_port_offset = length($1) + 32/4 + 1;
$header =~ /^(.*\s)st\s/;
my $state_offset = length($1);
while (<NETSTAT>)
{
next unless (hex(substr($_, $state_offset, 2)) == $state);
++$ports->{hex(substr($_, $local_port_offset, 4))};
}
close NETSTAT;
}
sub count_tcp6_ports
{
my ($state, $ports) = @_;
cache_open("NETSTAT", "/proc/net/tcp6") or exit 1;
my $header = <NETSTAT>;
$header =~ /^(.*\s)local_address\s/;
# 128/4 + 1 corresponds to the IP address in hex + ":"
my $local_port_offset = length($1) + 128/4 + 1;
$header =~ /^(.*\s)st\s/;
my $state_offset = length($1);
while (<NETSTAT>)
{
next unless (hex(substr($_, $state_offset, 2)) == $state);
++$ports->{hex(substr($_, $local_port_offset, 4))};
}
close(NETSTAT);
}
if ($ARGV[0] and $ARGV[0] =~ /^\s*suggest\s*$/i)
{
if (-r "/proc/net/tcp" or -r "/proc/net/tcp6")
{
my %ports = ();
count_tcp_ports(ST_LISTEN, \%ports) if (-r "/proc/net/tcp");
count_tcp6_ports(ST_LISTEN, \%ports) if (-r "/proc/net/tcp6");
foreach my $port (keys %ports)
{
my $p = (getservbyport($port, "tcp"))[0];
print $p || $port, "\n";
}
exit 0;
}
exit 1;
}
my ($name, $port);
if ($0 =~ /port_(.+)*$/) {
$name = $port = $1;
if ($port =~ /\D/) {
$port = (getservbyname ($name, "tcp"))[2];
}
} else {
exit 2;
}
if ($ARGV[0] and $ARGV[0] =~ /^\s*config\s*$/i)
{
if (int($name)) {
print "graph_title TCP port $name connection count\n";
} else {
print "graph_title $name connection count\n";
}
print "graph_args --base 1000 -l 0\n";
print "graph_vlabel concurrent connections\n";
print "graph_category network\n";
print "count.label $name\n";
exit 0;
}
my %ports = ();
count_tcp_ports(ST_ESTABLISHED, \%ports) if (-r "/proc/net/tcp");
count_tcp6_ports(ST_ESTABLISHED, \%ports) if (-r "/proc/net/tcp6");
# If there aint any the right answer is 0 no blank or U
$ports{$port} = 0 if $ports{$port} == '';
print "count.value ", $ports{$port}, "\n";
# vim:syntax=perl