| #!/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; |
| } |