3 ## IP Filter UCD-SNMP pass module
5 ## Allows read IP Filter's tables (In, Out, AccIn, AccOut),
6 ## fetching rules, hits and bytes (for accounting tables only).
8 ## Author: Yaroslav Terletsky <ts@polynet.lviv.ua>
9 ## Date: $ Tue Dec 1 10:24:08 EET 1998 $
12 # Put this file in /usr/local/bin/ipf-mod.pl and then add the following
13 # line to your snmpd.conf file (without the # at the front):
15 # pass .1.3.6.1.4.1.2021.13.2 /usr/local/bin/ipf-mod.pl
17 # enterprises.ucdavis.ucdExperimental.ipFilter = .1.3.6.1.4.1.2021.13.2
18 # ipfInTable.ipfInEntry.ipfInIndex integer = 1.1.1
19 # ipfInTable.ipfInEntry.ipfInRule string = 1.1.2
20 # ipfInTable.ipfInEntry.ipfInHits counter = 1.1.3
21 # ipfOutTable.ipfOutEntry.ipfOutIndex integer = 1.2.1
22 # ipfOutTable.ipfOutEntry.ipfOutRule string = 1.2.2
23 # ipfOutTable.ipfOutEntry.ipfOutHits counter = 1.2.3
24 # ipfAccInTable.ipfAccInEntry.ipfAccInIndex integer = 1.3.1
25 # ipfAccInTable.ipfAccInEntry.ipfAccInRule string = 1.3.2
26 # ipfAccInTable.ipfAccInEntry.ipfAccInHits counter = 1.3.3
27 # ipfAccInTable.ipfAccInEntry.ipfAccInBytes counter = 1.3.4
28 # ipfAccOutTable.ipfAccOutEntry.ipfAccOutIndex integer = 1.4.1
29 # ipfAccOutTable.ipfAccOutEntry.ipfAccOutRule string = 1.4.2
30 # ipfAccOutTable.ipfAccOutEntry.ipfAccOutHits counter = 1.4.3
31 # ipfAccOutTable.ipfAccOutEntry.ipfAccOutBytes counter = 1.4.4
34 %type = ('1.1.1', 'integer', '1.1.2', 'string', '1.1.3', 'counter',
35 '2.1.1', 'integer', '2.1.2', 'string', '2.1.3', 'counter',
36 '3.1.1', 'integer', '3.1.2', 'string', '3.1.3', 'counter',
38 '4.1.1', 'integer', '4.1.2', 'string', '4.1.3', 'counter',
42 %next = ('1.1.1', '1.1.2', '1.1.2', '1.1.3', '1.1.3', '2.1.1',
43 '2.1.1', '2.1.2', '2.1.2', '2.1.3', '2.1.3', '3.1.1',
44 '3.1.1', '3.1.2', '3.1.2', '3.1.3', '3.1.3', '3.1.4',
46 '4.1.1', '4.1.2', '4.1.2', '4.1.3', '4.1.3', '4.1.4');
48 # ipfilter's commands to fetch needed information
49 $ipfstat_comm="/sbin/ipfstat";
50 $ipf_in="$ipfstat_comm -ih 2>/dev/null";
51 $ipf_out="$ipfstat_comm -oh 2>/dev/null";
52 $ipf_acc_in="$ipfstat_comm -aih 2>/dev/null";
53 $ipf_acc_out="$ipfstat_comm -aoh 2>/dev/null";
56 $IPF_OID='.1.3.6.1.4.1.2021.13.2';
57 $IPF_OID_NO_DOTS='\.1\.3\.6\.1\.4\.1\.2021\.13\.2';
59 # exit if OID is not one of IPF-MIB's
60 exit if $OID !~ /^$IPF_OID_NO_DOTS(\D|$)/;
62 # get table, entry, column and row numbers
64 $tecr =~ s/^$IPF_OID_NO_DOTS(\D|$)//;
65 ($table, $entry, $col, $row, $rest) = split(/\./, $tecr);
69 # exit if OID is wrong specified
70 if(!defined $table or !defined $entry or !defined $col or !defined $row or defined $rest) {
71 print "[1] NO-SUCH NAME\n" if $d;
76 $value = &get_value($table, $entry, $col, $row);
77 print "value=$value\n" if $d;
79 # exit if OID does not exist
80 print "[2] NO-SUCH NAME\n" if $d and !defined $value;
81 exit if !defined $value;
83 # set ObjectID and reply with response
84 $tec = "$table.$entry.$col";
85 $ObjectID = "${IPF_OID}.${tec}.${row}";
89 # parse 'get-next' request
91 # set values if 0 or unspecified
92 $table = 1, $a = 1 if !$table or !defined $table;
93 $entry = 1, $a = 1 if !$entry or !defined $entry;
94 $col = 1, $a = 1 if !$col or !defined $col;
95 $row = 1, $a = 1 if !$row or !defined $row;
99 $value = &get_value($table, $entry, $col, $row);
100 print "value=$value\n" if $d;
102 # set ObjectID and reply with response
103 $tec = "$table.$entry.$col";
104 $ObjectID = "${IPF_OID}.${tec}.${row}";
108 # get next OID's value
110 $value = &get_value($table, $entry, $col, $row);
112 # choose new table/column if rows exceeded
113 if(!defined $value) {
114 $tec = "$table.$entry.$col";
115 $tec = $next{$tec} if !$a;
119 $table =~ s/\.\d\.\d$//;
120 $entry =~ s/^\d\.(\d)\.\d$/$1/;
121 $col =~ s/^\d\.\d\.//;
124 # get the OID's value
125 $value = &get_value($table, $entry, $col, $row);
126 print "value=$value\n" if $d;
129 # set ObjectID and reply with response
130 $tec = "$table.$entry.$col";
131 $ObjectID = "${IPF_OID}.${tec}.${row}";
135 ##############################################################################
137 # fetch values from 'ipfInTable' and 'ipfOutTable' tables
138 sub fetch_hits_n_rules {
139 local($row, $col, $ipf_output) = @_;
140 local($asdf, $i, @ipf_lines, $length);
142 # create an entry if no rule exists
143 $ipf_output = "0 empty list for ipfilter" if !$ipf_output;
145 @ipf_lines = split("\n", $ipf_output);
146 $length = $#ipf_lines + 1;
148 for($i = 1; $i < $length + 1; $i++) {
149 $hits{$i} = $ipf_lines[$i-1];
150 $hits{$i} =~ s/^(\d+).*$/$1/;
151 $rule{$i} = $ipf_lines[$i-1];
152 $rule{$i} =~ s/^\d+ //;
154 return $i if $col == 1;
155 return $rule{$i} if $col == 2;
156 return $hits{$i} if $col == 3;
159 # return undefined value
164 # fetch values from 'ipfAccInTable' and 'ipfAccOutTable' tables
165 sub fetch_hits_bytes_n_rules {
166 local($row, $col, $ipf_output) = @_;
167 local($asdf, $i, @ipf_lines, $length);
169 # create an entry if no rule exists
170 $ipf_output = "0 0 empty list for ipacct" if !$ipf_output;
172 @ipf_lines = split("\n", $ipf_output);
173 $length = $#ipf_lines + 1;
175 for($i = 1; $i < $length + 1; $i++) {
176 $hits{$i} = $ipf_lines[$i-1];
177 $hits{$i} =~ s/^(\d+) .*$/$1/;
178 $bytes{$i} = $ipf_lines[$i-1];
179 $bytes{$i} =~ s/^\d+ (\d+) .*/$1/;
180 $rule{$i} = $ipf_lines[$i-1];
181 $rule{$i} =~ s/^\d+ \d+ //;
183 return $i if $col == 1;
184 return $rule{$i} if $col == 2;
185 return $hits{$i} if $col == 3;
186 return $bytes{$i} if $col == 4;
189 # return undefined value
194 # get the values from ipfilter's tables
196 local($table, $entry, $col, $row) = @_;
199 # fetch ipfInTable data
200 $ipf_output = `$ipf_in`;
201 $value = &fetch_hits_n_rules($row, $col, $ipf_output);
202 } elsif($table == 2) {
203 # fetch ipfOutTable data
204 $ipf_output = `$ipf_out`;
205 $value = &fetch_hits_n_rules($row, $col, $ipf_output);
206 } elsif($table == 3) {
207 # fetch ipfAccInTable data
208 $ipf_output = `$ipf_acc_in`;
209 $value = &fetch_hits_bytes_n_rules($row, $col, $ipf_output);
210 } elsif($table == 4) {
211 # fetch ipfAccOutTable data
212 $ipf_output = `$ipf_acc_out`;
213 $value = &fetch_hits_bytes_n_rules($row, $col, $ipf_output);
218 # generate response to 'get' or 'get-next' request
220 # print ObjectID, its type and the value
221 if(defined $ObjectID and defined $type{$tec} and defined $value) {
223 print "$type{$tec}\n";