line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::SNMP::Mixin::Util; |
2
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
133808
|
use strict; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
240
|
|
4
|
5
|
|
|
5
|
|
30
|
use warnings; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
190
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# this module import config |
8
|
|
|
|
|
|
|
# |
9
|
5
|
|
|
5
|
|
1533
|
use Net::SNMP (); |
|
5
|
|
|
|
|
119975
|
|
|
5
|
|
|
|
|
191
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# |
12
|
|
|
|
|
|
|
# this module export config |
13
|
|
|
|
|
|
|
# |
14
|
5
|
|
|
|
|
80
|
use Sub::Exporter -setup => |
15
|
5
|
|
|
5
|
|
6879
|
{ exports => [qw/idx2val hex2octet normalize_mac push_error/], }; |
|
5
|
|
|
|
|
21081
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 NAME |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Net::SNMP::Mixin::Util - helper class for Net::SNMP mixins |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 VERSION |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Version 0.12 |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=cut |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
our $VERSION = '0.12'; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 SYNOPSIS |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
A helper class for Net::SNMP mixins. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
use Net::SNMP::Mixin::Util qw/idx2val hex2octet normalize_mac/; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 EXPORTS |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
The following routines are exported by request: |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=over 2 |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=item B<< idx2val($var_bind_list, $base_oid, [$pre], [$tail]) >> |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
convert a var_bind_list into a index => value form, |
44
|
|
|
|
|
|
|
removing the base_oid from oid. |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
e.g. if base_oid is '1.3.6.1.2.1.17.1.4.1.2', |
47
|
|
|
|
|
|
|
convert from: |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
'1.3.6.1.2.1.17.1.4.1.2.1' => 'foo' |
50
|
|
|
|
|
|
|
'1.3.6.1.2.1.17.1.4.1.2.2' => 'bar' |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
to: |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
'1' => 'foo' |
55
|
|
|
|
|
|
|
'2' => 'bar' |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
or if base_oid is '1.0.8802.4.1.1.12' and pre == 1 and tail == 2, |
58
|
|
|
|
|
|
|
convert from: |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
'1.0.8802.4.1.1.12.0.10.0.0.2.99.185' => 'foo', |
61
|
|
|
|
|
|
|
'1.0.8802.4.1.1.12.0.10.0.0.3.99.186' => 'bar', |
62
|
|
|
|
|
|
|
'1.0.8802.4.1.1.12.0.10.0.0.4.99.187' => 'baz', |
63
|
|
|
|
|
|
|
^ ^ ^ ^ ^ ^ ^ |
64
|
|
|
|
|
|
|
|.....base_oid....|.|.index..|.tail.| |value| |
65
|
|
|
|
|
|
|
^ |
66
|
|
|
|
|
|
|
pre ---------------| |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
to: |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
'10.0.0.2' => 'foo', |
71
|
|
|
|
|
|
|
'10.0.0.3' => 'bar', |
72
|
|
|
|
|
|
|
'10.0.0.4' => 'baz', |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
Returns the hash reference with index => value. Dies on error. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=cut |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub idx2val { |
79
|
10
|
|
|
10
|
1
|
1461
|
my ( $var_bind_list, $base_oid, $pre, $tail ) = @_; |
80
|
|
|
|
|
|
|
|
81
|
10
|
100
|
|
|
|
41
|
die "missing attribute 'var_bind_list'," unless defined $var_bind_list; |
82
|
9
|
100
|
|
|
|
9669
|
die "missing attribute 'base_oid'," unless defined $base_oid; |
83
|
|
|
|
|
|
|
|
84
|
8
|
|
100
|
|
|
38
|
$pre ||= 0; |
85
|
8
|
|
100
|
|
|
26
|
$tail ||= 0; |
86
|
|
|
|
|
|
|
|
87
|
8
|
100
|
|
|
|
35
|
die "wrong format for 'pre'," if $pre < 0; |
88
|
7
|
100
|
|
|
|
25
|
die "wrong format for 'tail'," if $tail < 0; |
89
|
|
|
|
|
|
|
|
90
|
6
|
|
|
|
|
12
|
my $idx; |
91
|
6
|
|
|
|
|
16
|
my $idx2val = {}; |
92
|
6
|
|
|
|
|
27
|
foreach my $oid ( keys %$var_bind_list ) { |
93
|
23
|
100
|
|
|
|
80
|
next unless Net::SNMP::oid_base_match( $base_oid, $oid ); |
94
|
|
|
|
|
|
|
|
95
|
18
|
|
|
|
|
818
|
$idx = $oid; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# cutoff leading and trailing whitespace, bloody SNMP agents! |
98
|
18
|
|
|
|
|
74
|
$idx =~ s/^\s*//; |
99
|
18
|
|
|
|
|
108
|
$idx =~ s/\s*$//; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# cutoff the basoid, get the idx |
102
|
18
|
|
|
|
|
152
|
$idx =~ s/^$base_oid//; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# if the idx isn't at the front of the index |
105
|
|
|
|
|
|
|
# cut off the n fold pre |
106
|
18
|
100
|
|
|
|
541
|
$idx =~ s/^\.?(\d+\.?){$pre}// if $pre > 0; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# if the idx isn't at the end of the oid |
109
|
|
|
|
|
|
|
# cut off the n fold tail |
110
|
18
|
100
|
|
|
|
182
|
$idx =~ s/(\d+\.?){$tail}$// if $tail > 0; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# cut off remaining dangling '.' |
113
|
18
|
|
|
|
|
38
|
$idx =~ s/^\.//; |
114
|
18
|
|
|
|
|
43
|
$idx =~ s/\.$//; |
115
|
|
|
|
|
|
|
|
116
|
18
|
|
|
|
|
73
|
$idx2val->{$idx} = $var_bind_list->{$oid}; |
117
|
|
|
|
|
|
|
} |
118
|
6
|
|
|
|
|
154
|
return $idx2val; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=item B<< hex2octet($hex_string) >> |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Sometimes it's importend that the returned SNMP values were untranslated by Net::SNMP. If already translated, we must reconvert it to pure OCTET_STRINGs for some calculations. Returns the input parameter untranslated if it's no string in the form /^0x[0-9a-f]+$/i . |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=cut |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub hex2octet { |
128
|
3
|
|
|
3
|
1
|
7
|
my $hex_string = shift; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# don't touch, it's no hex_string |
131
|
3
|
100
|
|
|
|
121
|
return $hex_string unless $hex_string =~ m/^0x[0-9a-f]+$/i; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# remove '0x' in front |
134
|
1
|
|
|
|
|
3
|
$hex_string = substr( $hex_string, 2 ); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# return octet_string |
137
|
1
|
|
|
|
|
11
|
return pack 'H*', $hex_string; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=item B<< normalize_mac($mac_address) >> |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
normalize MAC addresses to the IEEE form XX:XX:XX:XX:XX:XX |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
normalize the different formats like, |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
x:xx:x:xx:Xx:xx to XX:XX:XX:XX:XX:XX |
147
|
|
|
|
|
|
|
or xxxxxx-xxxxxx to XX:XX:XX:XX:XX:XX |
148
|
|
|
|
|
|
|
or xx-xx-xx-xx-xx-xx to XX:XX:XX:XX:XX:XX |
149
|
|
|
|
|
|
|
or xxxx.xxxx.xxxx to XX:XX:XX:XX:XX:XX |
150
|
|
|
|
|
|
|
or 0x xxxxxxxxxxxx to XX:XX:XX:XX:XX:XX |
151
|
|
|
|
|
|
|
or plain packed '6C' to XX:XX:XX:XX:XX:XX |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
or returns undef for format errors. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=cut |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub normalize_mac { |
158
|
20
|
|
|
20
|
1
|
8473
|
my ($mac) = @_; |
159
|
20
|
100
|
|
|
|
61
|
return unless defined $mac; |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# translate this OCTET_STRING to hexadecimal, unless already translated |
162
|
19
|
100
|
|
|
|
56
|
if ( length $mac == 6 ) { |
163
|
1
|
|
|
|
|
8
|
$mac = unpack 'H*', $mac; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# to upper case |
167
|
19
|
|
|
|
|
39
|
my $norm_address = uc($mac); |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# remove '-' in bloody Microsoft format |
170
|
19
|
|
|
|
|
38
|
$norm_address =~ s/-//g; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# remove '.' in bloody Cisco format |
173
|
19
|
|
|
|
|
30
|
$norm_address =~ s/\.//g; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# remove '0X' in front of, we are already upper case |
176
|
19
|
|
|
|
|
30
|
$norm_address =~ s/^0X//; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# we are already upper case |
179
|
19
|
|
|
|
|
142
|
my $hex_digit = qr/[A-F,0-9]/; |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# insert leading 0 in bloody Sun format |
182
|
19
|
|
|
|
|
192
|
$norm_address =~ s/\b($hex_digit)\b/0$1/g; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# insert ':' aabbccddeeff -> aa:bb:cc:dd:ee:ff |
185
|
19
|
|
|
|
|
225
|
$norm_address =~ s/($hex_digit{2})(?=$hex_digit)/$1:/g; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# wrong format |
188
|
19
|
100
|
|
|
|
201
|
return unless $norm_address =~ m /^($hex_digit{2}:){5}$hex_digit{2}$/; |
189
|
|
|
|
|
|
|
|
190
|
12
|
|
|
|
|
104
|
return $norm_address; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=item B<< push_error($session, $error_msg) >> |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
Net::SNMP has only one slot for errors. During nonblocking calls it's possible that an error followed by a successful transaction is cleared before the user gets the chance to see the error. At least for the mixin modules we use an array buffer for all seen errors until they are explicit cleared. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
This utility routine helps the mixin authors to push an error into the buffer without the knowledge of the buffer internas. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Dies if session isn't a Net::SNMP object or error_msg is missing. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=back |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=cut |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
sub push_error { |
206
|
3
|
|
|
3
|
1
|
5384
|
my ( $session, $error_msg ) = @_; |
207
|
|
|
|
|
|
|
|
208
|
3
|
100
|
|
|
|
25
|
die "missing attribute 'session'," unless defined $session; |
209
|
2
|
100
|
|
|
|
16
|
die "missing attribute 'error_msg'," unless defined $error_msg; |
210
|
|
|
|
|
|
|
|
211
|
1
|
50
|
33
|
|
|
22
|
die "'session' isn't a Net::SNMP object," |
212
|
|
|
|
|
|
|
unless ref $session && $session->isa('Net::SNMP'); |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# prepare the error buffer if not already done |
215
|
1
|
|
50
|
|
|
10
|
$session->{'Net::SNMP::Mixin'}{errors} ||= []; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# store the error_msg at the buffer end |
218
|
1
|
|
|
|
|
2
|
push @{ $session->{'Net::SNMP::Mixin'}{errors} }, $error_msg; |
|
1
|
|
|
|
|
7
|
|
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
unless ( caller() ) { |
222
|
|
|
|
|
|
|
print __PACKAGE__ . " compiles and initializes successful.\n"; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head1 REQUIREMENTS |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
L, L |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head1 BUGS, PATCHES & FIXES |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
There are no known bugs at the time of this release. However, if you spot a bug or are experiencing difficulties that are not explained within the POD documentation, please submit a bug to the RT system (see link below). However, it would help greatly if you are able to pinpoint problems or even supply a patch. |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Fixes are dependant upon their severity and my availablity. Should a fix not be forthcoming, please feel free to (politely) remind me by sending an email to gaissmai@cpan.org . |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
RT: http://rt.cpan.org/Public/Dist/Display.html?Name=Net-SNMP-Mixin |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head1 AUTHOR |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Karl Gaissmaier |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
Copyright 2008 Karl Gaissmaier, all rights reserved. |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
246
|
|
|
|
|
|
|
under the same terms as Perl itself. |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=cut |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
1; |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# vim: sw=2 |