228 lines
6.5 KiB
Perl
Executable File
228 lines
6.5 KiB
Perl
Executable File
#!/usr/bin/perl -s
|
|
##
|
|
## IP Filter UCD-SNMP pass module
|
|
##
|
|
## Allows read IP Filter's tables (In, Out, AccIn, AccOut),
|
|
## fetching rules, hits and bytes (for accounting tables only).
|
|
##
|
|
## Author: Yaroslav Terletsky <ts@polynet.lviv.ua>
|
|
## Date: $ Tue Dec 1 10:24:08 EET 1998 $
|
|
## Version: 1.1a
|
|
|
|
# Put this file in /usr/local/bin/ipf-mod.pl and then add the following
|
|
# line to your snmpd.conf file (without the # at the front):
|
|
#
|
|
# pass .1.3.6.1.4.1.2021.13.2 /usr/local/bin/ipf-mod.pl
|
|
|
|
# enterprises.ucdavis.ucdExperimental.ipFilter = .1.3.6.1.4.1.2021.13.2
|
|
# ipfInTable.ipfInEntry.ipfInIndex integer = 1.1.1
|
|
# ipfInTable.ipfInEntry.ipfInRule string = 1.1.2
|
|
# ipfInTable.ipfInEntry.ipfInHits counter = 1.1.3
|
|
# ipfOutTable.ipfOutEntry.ipfOutIndex integer = 1.2.1
|
|
# ipfOutTable.ipfOutEntry.ipfOutRule string = 1.2.2
|
|
# ipfOutTable.ipfOutEntry.ipfOutHits counter = 1.2.3
|
|
# ipfAccInTable.ipfAccInEntry.ipfAccInIndex integer = 1.3.1
|
|
# ipfAccInTable.ipfAccInEntry.ipfAccInRule string = 1.3.2
|
|
# ipfAccInTable.ipfAccInEntry.ipfAccInHits counter = 1.3.3
|
|
# ipfAccInTable.ipfAccInEntry.ipfAccInBytes counter = 1.3.4
|
|
# ipfAccOutTable.ipfAccOutEntry.ipfAccOutIndex integer = 1.4.1
|
|
# ipfAccOutTable.ipfAccOutEntry.ipfAccOutRule string = 1.4.2
|
|
# ipfAccOutTable.ipfAccOutEntry.ipfAccOutHits counter = 1.4.3
|
|
# ipfAccOutTable.ipfAccOutEntry.ipfAccOutBytes counter = 1.4.4
|
|
|
|
# variables types
|
|
%type = ('1.1.1', 'integer', '1.1.2', 'string', '1.1.3', 'counter',
|
|
'2.1.1', 'integer', '2.1.2', 'string', '2.1.3', 'counter',
|
|
'3.1.1', 'integer', '3.1.2', 'string', '3.1.3', 'counter',
|
|
'3.1.4', 'counter',
|
|
'4.1.1', 'integer', '4.1.2', 'string', '4.1.3', 'counter',
|
|
'4.1.4', 'counter');
|
|
|
|
# getnext sequence
|
|
%next = ('1.1.1', '1.1.2', '1.1.2', '1.1.3', '1.1.3', '2.1.1',
|
|
'2.1.1', '2.1.2', '2.1.2', '2.1.3', '2.1.3', '3.1.1',
|
|
'3.1.1', '3.1.2', '3.1.2', '3.1.3', '3.1.3', '3.1.4',
|
|
'3.1.4', '4.1.1',
|
|
'4.1.1', '4.1.2', '4.1.2', '4.1.3', '4.1.3', '4.1.4');
|
|
|
|
# ipfilter's commands to fetch needed information
|
|
$ipfstat_comm="/sbin/ipfstat";
|
|
$ipf_in="$ipfstat_comm -ih 2>/dev/null";
|
|
$ipf_out="$ipfstat_comm -oh 2>/dev/null";
|
|
$ipf_acc_in="$ipfstat_comm -aih 2>/dev/null";
|
|
$ipf_acc_out="$ipfstat_comm -aoh 2>/dev/null";
|
|
|
|
$OID=$ARGV[0];
|
|
$IPF_OID='.1.3.6.1.4.1.2021.13.2';
|
|
$IPF_OID_NO_DOTS='\.1\.3\.6\.1\.4\.1\.2021\.13\.2';
|
|
|
|
# exit if OID is not one of IPF-MIB's
|
|
exit if $OID !~ /^$IPF_OID_NO_DOTS(\D|$)/;
|
|
|
|
# get table, entry, column and row numbers
|
|
$tecr = $OID;
|
|
$tecr =~ s/^$IPF_OID_NO_DOTS(\D|$)//;
|
|
($table, $entry, $col, $row, $rest) = split(/\./, $tecr);
|
|
|
|
# parse 'get' request
|
|
if($g) {
|
|
# exit if OID is wrong specified
|
|
if(!defined $table or !defined $entry or !defined $col or !defined $row or defined $rest) {
|
|
print "[1] NO-SUCH NAME\n" if $d;
|
|
exit;
|
|
}
|
|
|
|
# get the OID's value
|
|
$value = &get_value($table, $entry, $col, $row);
|
|
print "value=$value\n" if $d;
|
|
|
|
# exit if OID does not exist
|
|
print "[2] NO-SUCH NAME\n" if $d and !defined $value;
|
|
exit if !defined $value;
|
|
|
|
# set ObjectID and reply with response
|
|
$tec = "$table.$entry.$col";
|
|
$ObjectID = "${IPF_OID}.${tec}.${row}";
|
|
&response;
|
|
}
|
|
|
|
# parse 'get-next' request
|
|
if($n) {
|
|
# set values if 0 or unspecified
|
|
$table = 1, $a = 1 if !$table or !defined $table;
|
|
$entry = 1, $a = 1 if !$entry or !defined $entry;
|
|
$col = 1, $a = 1 if !$col or !defined $col;
|
|
$row = 1, $a = 1 if !$row or !defined $row;
|
|
|
|
if($a) {
|
|
# get the OID's value
|
|
$value = &get_value($table, $entry, $col, $row);
|
|
print "value=$value\n" if $d;
|
|
|
|
# set ObjectID and reply with response
|
|
$tec = "$table.$entry.$col";
|
|
$ObjectID = "${IPF_OID}.${tec}.${row}";
|
|
&response;
|
|
}
|
|
|
|
# get next OID's value
|
|
$row++;
|
|
$value = &get_value($table, $entry, $col, $row);
|
|
|
|
# choose new table/column if rows exceeded
|
|
if(!defined $value) {
|
|
$tec = "$table.$entry.$col";
|
|
$tec = $next{$tec} if !$a;
|
|
$table = $tec;
|
|
$entry = $tec;
|
|
$col = $tec;
|
|
$table =~ s/\.\d\.\d$//;
|
|
$entry =~ s/^\d\.(\d)\.\d$/$1/;
|
|
$col =~ s/^\d\.\d\.//;
|
|
$row = 1;
|
|
|
|
# get the OID's value
|
|
$value = &get_value($table, $entry, $col, $row);
|
|
print "value=$value\n" if $d;
|
|
}
|
|
|
|
# set ObjectID and reply with response
|
|
$tec = "$table.$entry.$col";
|
|
$ObjectID = "${IPF_OID}.${tec}.${row}";
|
|
&response;
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
# fetch values from 'ipfInTable' and 'ipfOutTable' tables
|
|
sub fetch_hits_n_rules {
|
|
local($row, $col, $ipf_output) = @_;
|
|
local($asdf, $i, @ipf_lines, $length);
|
|
|
|
# create an entry if no rule exists
|
|
$ipf_output = "0 empty list for ipfilter" if !$ipf_output;
|
|
|
|
@ipf_lines = split("\n", $ipf_output);
|
|
$length = $#ipf_lines + 1;
|
|
|
|
for($i = 1; $i < $length + 1; $i++) {
|
|
$hits{$i} = $ipf_lines[$i-1];
|
|
$hits{$i} =~ s/^(\d+).*$/$1/;
|
|
$rule{$i} = $ipf_lines[$i-1];
|
|
$rule{$i} =~ s/^\d+ //;
|
|
if($i == $row) {
|
|
return $i if $col == 1;
|
|
return $rule{$i} if $col == 2;
|
|
return $hits{$i} if $col == 3;
|
|
}
|
|
}
|
|
# return undefined value
|
|
undef $asdf;
|
|
return $asdf;
|
|
}
|
|
|
|
# fetch values from 'ipfAccInTable' and 'ipfAccOutTable' tables
|
|
sub fetch_hits_bytes_n_rules {
|
|
local($row, $col, $ipf_output) = @_;
|
|
local($asdf, $i, @ipf_lines, $length);
|
|
|
|
# create an entry if no rule exists
|
|
$ipf_output = "0 0 empty list for ipacct" if !$ipf_output;
|
|
|
|
@ipf_lines = split("\n", $ipf_output);
|
|
$length = $#ipf_lines + 1;
|
|
|
|
for($i = 1; $i < $length + 1; $i++) {
|
|
$hits{$i} = $ipf_lines[$i-1];
|
|
$hits{$i} =~ s/^(\d+) .*$/$1/;
|
|
$bytes{$i} = $ipf_lines[$i-1];
|
|
$bytes{$i} =~ s/^\d+ (\d+) .*/$1/;
|
|
$rule{$i} = $ipf_lines[$i-1];
|
|
$rule{$i} =~ s/^\d+ \d+ //;
|
|
if($i == $row) {
|
|
return $i if $col == 1;
|
|
return $rule{$i} if $col == 2;
|
|
return $hits{$i} if $col == 3;
|
|
return $bytes{$i} if $col == 4;
|
|
}
|
|
}
|
|
# return undefined value
|
|
undef $asdf;
|
|
return $asdf;
|
|
}
|
|
|
|
# get the values from ipfilter's tables
|
|
sub get_value {
|
|
local($table, $entry, $col, $row) = @_;
|
|
|
|
if($table == 1) {
|
|
# fetch ipfInTable data
|
|
$ipf_output = `$ipf_in`;
|
|
$value = &fetch_hits_n_rules($row, $col, $ipf_output);
|
|
} elsif($table == 2) {
|
|
# fetch ipfOutTable data
|
|
$ipf_output = `$ipf_out`;
|
|
$value = &fetch_hits_n_rules($row, $col, $ipf_output);
|
|
} elsif($table == 3) {
|
|
# fetch ipfAccInTable data
|
|
$ipf_output = `$ipf_acc_in`;
|
|
$value = &fetch_hits_bytes_n_rules($row, $col, $ipf_output);
|
|
} elsif($table == 4) {
|
|
# fetch ipfAccOutTable data
|
|
$ipf_output = `$ipf_acc_out`;
|
|
$value = &fetch_hits_bytes_n_rules($row, $col, $ipf_output);
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
# generate response to 'get' or 'get-next' request
|
|
sub response {
|
|
# print ObjectID, its type and the value
|
|
if(defined $ObjectID and defined $type{$tec} and defined $value) {
|
|
print "$ObjectID\n";
|
|
print "$type{$tec}\n";
|
|
print "$value\n";
|
|
}
|
|
exit;
|
|
}
|