-
#!/usr/bin/perl -w
-
-
# $Id: pf-to-mrtg.pl 831 2008-09-07 13:45:27Z remko $
-
#
-
# (c) 2005 Remko Lodder <remko@elvandar.org>
-
# (c) 2008 Remko Lodder <remko@FreeBSD.org>
-
# Based upon ipf.pl by Ronald Florence <ron@18james.com>
-
# last modified remko@elvandar.org, 05 Sept 2009
-
# Made the script working again.
-
-
# Example output from pfctl -si
-
#Interface Stats for fxp0 IPv4 IPv6
-
# Bytes In 156041 0
-
# Bytes Out 1895602 0
-
# Packets In
-
# Passed 1504 0
-
# Blocked 256 0
-
# Packets Out
-
# Passed 1756 0
-
# Blocked 0 0
-
#
-
#State Table Total Rate
-
# current entries 33
-
# searches 8865 10.7/s
-
# inserts 204 0.2/s
-
# removals 171 0.2/s
-
#Counters
-
# match 460 0.6/s
-
# bad-offset 0 0.0/s
-
# fragment 0 0.0/s
-
# short 0 0.0/s
-
# normalize 0 0.0/s
-
# memory 0 0.0/s
-
-
use strict;
-
use Getopt::Std;
-
-
# prototype variables.
-
my($inp,$outp) = 0;
-
-
my ($out,$in,$uptime,$firewall);
-
my(@pfctl);
-
my(%option);
-
-
# define some variables upfront
-
my $scriptname = __FILE__;
-
my $version = "2.0";
-
-
# Index our options
-
getopts("bBfimMnpsS", \%option);
-
-
my $pass_flag = 1 if $option{p};
-
my $block_flag = 1 if $option{b};
-
my $bytes_flag = 1 if $option{B};
-
my $state_flag =
1 if $option{s};
-
my $search_flag = 1 if $option{S};
-
my $inres_flag = 1 if $option{i};
-
my $match_flag =
1 if $option{m};
-
my $frag_flag = 1 if $option{f};
-
my $short_flag = 1 if $option{n};
-
my $memory_flag = 1 if $option{M};
-
-
@pfctl=`/sbin/pfctl -si`;
-
-
foreach my $packetfilter (@pfctl) {
-
if ($pass_flag || $block_flag) {
-
if ($packetfilter =~ /Packets In/) { $in = 1; $out = 0; }
-
if ($packetfilter =~ /Packets Out/) { $in = 0; $out = 1; }
-
if ($pass_flag) {
-
if ($packetfilter =~ /Passed\
s+
(\d+
)/
) { if ($in) { $inp += $
1;
} }
-
if ($packetfilter =~ /Passed\
s+
(\d+
)/
) { if ($out) { $outp += $
1;
} }
-
}
-
if ($block_flag) {
-
if ($packetfilter =~ /Blocked\
s+
(\d+
)/
) { if ($in) { $inp += $
1;
} }
-
if ($packetfilter =~ /Blocked\
s+
(\d+
)/
) { if ($out) { $outp += $
1;
} }
-
}
-
}
-
-
elsif ($bytes_flag) {
-
if ($packetfilter =~ /Bytes\sIn\
s+
(\d+
)/
) { $inp += $
1;
}
-
if ($packetfilter =~ /Bytes\sOut\
s+
(\d+
)/
) { $outp += $
1;
}
-
}
-
elsif ($state_flag) {
-
if ($packetfilter =~ /current entries\
s+
(\d+
)/
) { $inp += $
1 }
-
$outp = 0;
-
}
-
elsif ($search_flag) {
-
if ($packetfilter =~ /searches\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /searches\
s+\d+\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
elsif ($inres_flag) {
-
if ($packetfilter =~ /inserts\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /removals\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
elsif ($match_flag) {
-
if ($packetfilter =~ /match\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /match\
s+\d+\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
elsif ($frag_flag) {
-
if ($packetfilter =~ /bad-offset\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /fragment\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
elsif ($short_flag) {
-
if ($packetfilter =~ /short\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /normalize\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
elsif ($memory_flag) {
-
if ($packetfilter =~ /memory\
s+
(\d+
)/
) { $inp += $
1 }
-
if ($packetfilter =~ /memory\
s+\d+\
s+
(\d+
)/
) { $outp += $
1 }
-
}
-
else {
-
print("Usage:\t$scriptname [ -b ] [ -B ] [ -f ] [ -i ] [ -m ] [ -M ] [ -n ] [ -p ] [ -s ] [ -S ]
-
\t-b\tIndex blocked packets incoming and outgoing.
-
\t-B\tIndex bytes incoming and outgoing
-
\t-f\tIndex bad-offsets and fragments
-
\t-i\tIndex inserts and removals
-
\t-m\tIndex matched packets current values and usage rate
-
\t-M\tIndex memory usage current values and usage rate
-
\t-n\tIndex short packets and normalized packets
-
\t-p\tIndex passed packets incoming and outgoing.
-
\t-s\tIndex states other value will be zero (0)
-
\t-S\tIndex searches current searches and search rate
-
Version: $version
-
Originally written by Remko Lodder <remko\@FreeBSD.org>.\n");
-
-
}
-
}
-
-
-
"$outp\n";
-
-
$_ = `/usr/bin/uptime`;
-
($uptime) = /up\
s+
(.*
),\
s+.+user/;
-
$uptime =~
s/
(^
1\
s+day
)\
s/
1/;
-
-
chop($firewall = `uname -nm`
);
-
-
-
__END__
-
-
=head1 NAME
-
-
pf-to-mrtg.pl - generates statistics for use with MRTG
-
-
=head1 SYNOPSIS
-
-
Two example configuration options for MRTG:
-
-
Target[connections]: `/path/to/pf-to-mrtg.pl -p`
-
Options[connections]: growright, perhour
-
MaxBytes[connections]: 50000
-
Title[connections]: Firewall Connections
-
PageTop[connections]: <h3>Firewall Connections</h3>
-
YLegend[connections]: packets/hr
-
ShortLegend[connections]: pkts/h
-
Legend1[connections]: Incoming Connections
-
Legend2[connections]: Outgoing Connections
-
-
Target
[state
]: `/path/to/pf-to-mrtg.pl -
s`
-
Options[state]: growright, gauge, integer
-
MaxBytes[state]: 2048
-
Title[state]: State Table
-
PageTop[state]: <h3>NAT & IP state tables</h3>
-
YLegend[state]: states
-
ShortLegend[state]: states
-
Legend1[state]: NAT states
-
Legend2[state]: IP states
-
LegendI[state]: nat:
-
LegendO[state]: ip:
-
-
Other available targets are `pf-to-mrtg.pl -b`
-
`pf-to-mrtg.pl -B`
-
`pf-to-mrtg.pl -f`
-
`pf-to-mrtg.pl -i`
-
-
`pf-to-mrtg.pl -M`
-
`pf-to-mrtg.pl -n`
-
`pf-to-mrtg.pl -p`
-
-
`pf-to-mrtg.pl -S`
-
-
See the instructions in the help to see what they represent.
-
-
=head1 DESCRIPTION
-
-
The purpose of this script is to be able to create statistics
-
from various PF counters. By using this script you will be
-
able to see what your firewall does, how it behaves, and see
-
trends. Note: Due to MRTG's nature you will get spikes after
-
rebooting the machine.
-
=head1 LICENSE
-
This module is licensed under the BSD license.
-
=head1 AUTHOR
-
Remko Lodder <remko@FreeBSD.org> with additional help from
-
Mattieu Arnold <mat@FreeBSD.org> and Pasi Hirvonen.
-
Originally based on work from Ron James (before this was entirely rewritten).
-
=cut