added files
[bcm963xx.git] / userapps / opensource / net-snmp / local / ipf-mod.pl
1 #!/usr/bin/perl -s
2 ##
3 ## IP Filter UCD-SNMP pass module
4 ##
5 ## Allows read IP Filter's tables (In, Out, AccIn, AccOut),
6 ## fetching rules, hits and bytes (for accounting tables only).
7 ##
8 ## Author: Yaroslav Terletsky <ts@polynet.lviv.ua>
9 ## Date: $ Tue Dec  1 10:24:08 EET 1998 $
10 ## Version: 1.1a
11
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):
14 #
15 #   pass .1.3.6.1.4.1.2021.13.2 /usr/local/bin/ipf-mod.pl
16
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
32
33 # variables types
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',
37          '3.1.4', 'counter',
38          '4.1.1', 'integer', '4.1.2', 'string', '4.1.3', 'counter',
39          '4.1.4', 'counter');
40
41 # getnext sequence
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',
45          '3.1.4', '4.1.1',
46          '4.1.1', '4.1.2', '4.1.2', '4.1.3', '4.1.3', '4.1.4');
47
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";
54
55 $OID=$ARGV[0];
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';
58
59 # exit if OID is not one of IPF-MIB's
60 exit if $OID !~ /^$IPF_OID_NO_DOTS(\D|$)/;
61
62 # get table, entry, column and row numbers
63 $tecr = $OID;
64 $tecr =~ s/^$IPF_OID_NO_DOTS(\D|$)//;
65 ($table, $entry, $col, $row, $rest) = split(/\./, $tecr);
66
67 # parse 'get' request
68 if($g) {
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;
72                 exit;
73         }
74
75         # get the OID's value
76         $value = &get_value($table, $entry, $col, $row);
77         print "value=$value\n" if $d;
78
79         # exit if OID does not exist
80         print "[2] NO-SUCH NAME\n" if $d and !defined $value;
81         exit if !defined $value;
82
83         # set ObjectID and reply with response
84         $tec = "$table.$entry.$col";
85         $ObjectID = "${IPF_OID}.${tec}.${row}";
86         &response;
87 }
88
89 # parse 'get-next' request
90 if($n) {
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;
96
97         if($a) {
98                 # get the OID's value
99                 $value = &get_value($table, $entry, $col, $row);
100                 print "value=$value\n" if $d;
101
102                 # set ObjectID and reply with response
103                 $tec = "$table.$entry.$col";
104                 $ObjectID = "${IPF_OID}.${tec}.${row}";
105                 &response;
106         }
107
108         # get next OID's value
109         $row++;
110         $value = &get_value($table, $entry, $col, $row);
111
112         # choose new table/column if rows exceeded
113         if(!defined $value) {
114                 $tec = "$table.$entry.$col";
115                 $tec = $next{$tec} if !$a;
116                 $table = $tec;
117                 $entry = $tec;
118                 $col = $tec;
119                 $table =~ s/\.\d\.\d$//;
120                 $entry =~ s/^\d\.(\d)\.\d$/$1/;
121                 $col =~ s/^\d\.\d\.//;
122                 $row = 1;
123
124                 # get the OID's value
125                 $value = &get_value($table, $entry, $col, $row);
126                 print "value=$value\n" if $d;
127         }
128
129         # set ObjectID and reply with response
130         $tec = "$table.$entry.$col";
131         $ObjectID = "${IPF_OID}.${tec}.${row}";
132         &response;
133 }
134
135 ##############################################################################
136
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);
141
142         # create an entry if no rule exists
143         $ipf_output = "0 empty list for ipfilter" if !$ipf_output;
144
145         @ipf_lines = split("\n", $ipf_output);
146         $length = $#ipf_lines + 1;
147
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+ //;
153                 if($i == $row) {
154                         return $i if $col == 1;
155                         return $rule{$i} if $col == 2;
156                         return $hits{$i} if $col == 3;
157                 }
158         }
159         # return undefined value
160         undef $asdf;
161         return $asdf;
162 }
163
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);
168
169         # create an entry if no rule exists
170         $ipf_output = "0 0 empty list for ipacct" if !$ipf_output;
171
172         @ipf_lines = split("\n", $ipf_output);
173         $length = $#ipf_lines + 1;
174
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+ //;
182                 if($i == $row) {
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;
187                 }
188         }
189         # return undefined value
190         undef $asdf;
191         return $asdf;
192 }
193
194 # get the values from ipfilter's tables
195 sub get_value {
196         local($table, $entry, $col, $row) = @_;
197
198         if($table == 1) {
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);
214         }
215         return $value;
216 }
217
218 # generate response to 'get' or 'get-next' request
219 sub response {
220         # print ObjectID, its type and the value
221         if(defined $ObjectID and defined $type{$tec} and defined $value) {
222                 print "$ObjectID\n";
223                 print "$type{$tec}\n";
224                 print "$value\n";
225         }
226         exit;
227 }