Blame local/ipf-mod.pl

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