File Coverage

blib/lib/SNMP/Class/Varbind.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package SNMP::Class::Varbind;
2              
3             our $VERSION = '0.13';
4              
5 1     1   1870 use warnings;
  1         3  
  1         32  
6 1     1   6 use strict;
  1         2  
  1         32  
7 1     1   403 use SNMP;
  0            
  0            
8             use Carp qw(cluck carp croak confess);
9             use SNMP::Class::OID;
10             use Data::Dumper;
11             use Log::Log4perl qw(:easy);
12              
13             use SNMP::Class::Varbind::IpAddress;
14             use SNMP::Class::Varbind::SysUpTime;
15             use SNMP::Class::Varbind::IpForwarding;
16              
17             BEGIN {
18             eval {
19             require Time::HiRes;
20             import Time::HiRes qw(time);
21             };
22             warn "Time::HiRes not installed -- you only get the low granularity built in time function" if ($@);
23             }
24              
25             use overload
26             '""' => \&value,
27             fallback => 1
28             ;
29              
30             use base qw(SNMP::Class::OID);
31              
32             my %callback=();
33              
34              
35             =head2 new(oid=>$oid,type=>$type,value=>$value)
36              
37             Constructor. $oid can be either a string or an L. Normally this method should almost never be used, as the user rarely has to construct this kind of objects by hand.
38              
39             =cut
40            
41             sub new {
42             my $class = shift(@_) or croak "Incorrect call to new";
43             my $self;
44            
45             my %arg_h = (@_);
46            
47             if(defined($arg_h{varbind})) {
48             my $varbind = $arg_h{varbind};
49             croak "new was called with a varbind that was not an SNMP::Varbind." unless (eval { $varbind->isa("SNMP::Varbind") } );
50             my $object = SNMP::Class::OID->new($varbind->[0]);
51             my $instance = ((!exists($varbind->[1]))||($varbind->[1] eq ''))? SNMP::Class::OID->new('0.0') : SNMP::Class::OID->new($varbind->[1]);
52             $self = $object . $instance;#make sure that marginal cases produce correct overloaded '+' result
53             croak "Internal error. Self is not an SNMP::Class::OID object!" unless ($self->isa("SNMP::Class::OID"));
54             $self->{type} = $varbind->[3];
55             $self->{raw_value} = $varbind->[2];
56             #@#$self->{value} = $self->construct_value;
57              
58             }
59             else {
60             croak "Cannot create a new varbind without an oid" unless defined($arg_h{oid});
61            
62             if (eval { $arg_h{oid}->isa("SNMP::Class::OID") }) {
63             #we just keep it intact and continue
64             $self = $arg_h{oid};
65             }
66             else {
67             #let's assume that argument was a plain string
68             $self = $class->SUPER::new($arg_h{oid});
69             }
70             for my $field (qw(type value raw_value)) {
71             if(defined($arg_h{$field})) {
72             $self->{$field} = $arg_h{$field};
73             }
74             }
75             }
76            
77             #default fallback: value coincides with raw_value
78             #this may be freely modified later
79             if(defined($self->{raw_value})) {
80             $self->{value} = $self->{raw_value};
81             }
82            
83             #we now have an almost complete object. Let's see if there is any more functionality inside a callback
84             if(defined($self->{raw_value})&&$self->has_label&&defined($callback{label}->{$self->get_label})) {
85             DEBUG "There is a special callback for label ".$self->get_label;
86             bless $self,$callback{label}->{$self->get_label};
87             if($self->can("initialize_callback_object")) {
88             DEBUG "Calling initializing method for ".$callback{label}->{$self->get_label};
89             $self->initialize_callback_object;
90             }
91              
92             }
93             elsif(defined($self->{raw_value})&&$self->has_syntax&&defined($callback{syntax}->{$self->get_syntax})) {
94             DEBUG "There is a special callback for syntax ".$self->get_syntax;
95             bless $self,$callback{syntax}->{$self->get_syntax};
96             if($self->can("initialize_callback_object")) {
97             DEBUG "Calling initializing method for ".$callback{syntax}->{$self->get_syntax};
98             $self->initialize_callback_object;
99             }
100             }
101             else {
102             bless $self,$class;
103             }
104              
105             return $self;
106             }
107              
108             #user should not have to know about this method. Used internally.
109              
110             #sub new_from_varbind {
111             # my $class = shift(@_) or croak "Incorrect call to new_from_varbind";
112             # my $varbind = shift(@_) or croak "2nd argument (varbind) missing from call to new_from_varbind";
113             #
114             #
115             # #check that we were given a correct type of argument
116             # if(eval { $varbind->isa("SNMP::Varbind") } ) {
117             # #$self->{varbind} = $varbind;
118             # }
119             # else {
120             # croak "new_from_varbind was called with an argument that was not an SNMP::Varbind.";
121             # }
122             #
123             #
124             # $self->{object} = SNMP::Class::OID->new($varbind->[0]);
125             # $self->{instance} = ($varbind->[1] eq '')? SNMP::Class::OID->new('0.0') : SNMP::Class::OID->new($varbind->[1]);
126             # $self->{oid} = $self->object + $self->instance;#make sure that marginal cases produce correct overloaded '+' result
127             # $self->{type} = $varbind->[3];
128             # $self->{raw_value} = $varbind->[2];
129             # $self->{value} = $self->construct_value;
130             #
131             # return $self;
132             # #after completion, the SNMP::Varbind is thrown away. Better this way.
133             #}
134              
135              
136             #I am lazy + I don't want to repeat the same code over and over
137             #So, I construct these 6 methods by using this nifty trick
138             for my $item (qw(object instance type raw_value value)) {
139             no strict 'refs';#only temporarily
140             *{$item} = sub { return $_[0]->{$item} };
141             use strict;
142             }
143              
144             #this the opposite from new_from_varbind. You get the SNMP::Varbind. Warning, you only get the correct oid, but you shouldn't get types,values,etc.s
145             sub generate_varbind {
146             my $self = shift(@_);
147             croak "self appears to be undefined" unless ref $self;
148             #@#return SNMP::Varbind->new([$self->object->numeric]) or croak "Cannot invoke SNMP::Varbind::new method with ".$_[0]->numeric." \n";
149             return SNMP::Varbind->new([$self->numeric]) or croak "Cannot invoke SNMP::Varbind::new method with argument".$self->numeric." \n";
150             }
151              
152             #return the varbind
153             #sub get_varbind {
154             # my $ref_self = \ shift(@_) or croak "Incorrect call to get_varbind";
155             # return $$ref_self->{varbind};
156             #}
157              
158             #returns the object part of the varbind. (example: ifName or .1.2.3)
159             #The type of the object returned is SNMP::Class::OID
160             #sub get_object {
161             # my $ref_self = \ shift(@_) or croak "Incorrect call to get_object";
162             # return new SNMP::Class::OID($$ref_self->get_varbind->[0]);
163             #}
164              
165             #returns the instance part of the varbind. (example: 10.10.10.10)
166             #If the instance is '', it will return undef (surprise,surprise!)
167             #sub get_instance {
168             # my $ref_self = \ shift(@_) or croak "Incorrect call to get_instance";
169             # if ($$ref_self->get_varbind->[1] eq '') {
170             # #this is an ugly hack....
171             # #the SNMP library will occasionally return varbinds with a '' instance, which is, well, not good
172             # #if we find the instance empty, we'll just stick the zeroDotzero instance and return it instead of undef
173             # #this happens with e.g. the sysUpTimeInstance object
174             # return SNMP::Class::OID->new('0.0');
175             # }
176             # return SNMP::Class::OID->new($$ref_self->get_varbind->[1]);
177             #}
178              
179             #returns a string numeric representation of the instance
180             #sub instance_numeric {
181             # my $self = shift(@_);
182             # croak "self appears to be undefined" unless ref $self;
183             # #if(!$$ref_self->get_instance) {
184             # # return '';
185             # #}
186             # return $self->instance->numeric;
187             #}
188              
189             #returns the full oid of this varbind.
190             #type returned is SNMP::Class::OID
191             #also handles correctly the case where the instance is undef
192             #sub get_oid {
193             # my $ref_self = \ shift(@_) or croak "Incorrect call to get_oid";
194             # if(!$$ref_self->get_instance) {
195             # return $$ref_self->get_object;
196             # }
197             # return $$ref_self->get_object + $$ref_self->get_instance;
198             #}
199            
200             #sub get_value {
201             # my $ref_self = \ shift(@_);
202             # #my $self = shift(@_) or croak "Incorrect call to get_value";
203             # return SNMP::Class::Value->new($$ref_self->get_varbind->[2]);
204             #}
205              
206             =head2 dump
207              
208             Use this method with no arguments to get a human readable string representation of the object. Example:
209             "ifName.3 eth0 OCTET-STR"
210              
211             =cut
212              
213             sub dump {
214             my $self = shift(@_);
215             return $self->to_string." ".$self->value." ".$self->type;
216             }
217              
218             #this is a class method. Other modules wishing to register themselves as varbind handlers must use it.
219             sub register_handler {
220             my $type_of_callback = shift(@_);#type can be object,syntax
221             my $identifier = shift(@_);
222             my $callback = shift(@_);
223             $callback{$type_of_callback}->{$identifier} = $callback;
224             }
225            
226            
227              
228             sub construct_value {
229             my $self = shift(@_);
230             croak "self appears to be undefined" unless ref $self;
231              
232             #if it is an object id, then find the label
233             if ($self->type eq 'OBJECTID') {
234             ###$logger->debug("This is an objectid...I will try to translate it to a label");
235             return SNMP::Class::Utils::label_of($self->get_value);
236             }
237              
238             #if it is an enum, return the appr. item
239             my $enum;
240             if($enum = SNMP::Class::Utils::enums_of($self->object->to_string)) {
241             #we will make sure that the key actually exists in the enum
242             if(defined($enum->{$self->raw_value})) {
243             return $enum->{$self->raw_value};
244             }
245             WARN "WARNING: There is no corresponding enum for value=".$self->raw_value." in ".$self->object->to_string;
246             return "unknown";
247             }
248              
249             my $tc = SNMP::Class::Utils::textual_convention_of($self->object->to_string);
250             if (defined($tc)) {
251             if ($tc eq 'PhysAddress') {
252             return SNMP::Class::Value::MacAddress->new($self->raw_value);
253             }
254             }
255              
256             #fallback
257             return SNMP::Class::Value->new($self->raw_value);
258             }
259              
260             #sub get_type {
261             # my $ref_self = \ shift(@_) or croak "Incorrect call to get_type";
262             # return $$ref_self->get_varbind->[3];
263             #}
264              
265             #@#sub normalize {
266             #@# my $ref_self = \ shift(@_) or croak "Incorrect call to normalize";
267             #@# $$ref_self->get_varbind->[0] = $$ref_self->get_oid->numeric;
268             #@#}
269              
270            
271              
272             =head1 AUTHOR
273              
274             Athanasios Douitsis, C<< >>
275              
276             =head1 BUGS
277              
278             Please report any bugs or feature requests to
279             C, or through the web interface at
280             L.
281             I will be notified, and then you'll automatically be notified of progress on
282             your bug as I make changes.
283              
284             =head1 SUPPORT
285              
286             You can find documentation for this module with the perldoc command.
287              
288             perldoc SNMP::Class
289              
290             You can also look for information at:
291              
292             =over 4
293              
294             =item * AnnoCPAN: Annotated CPAN documentation
295              
296             L
297              
298             =item * CPAN Ratings
299              
300             L
301              
302             =item * RT: CPAN's request tracker
303              
304             L
305              
306             =item * Search CPAN
307              
308             L
309              
310             =back
311              
312             =head1 ACKNOWLEDGEMENTS
313              
314             =head1 COPYRIGHT & LICENSE
315              
316             Copyright 2007 Athanasios Douitsis, all rights reserved.
317              
318             This program is free software; you can redistribute it and/or modify it
319             under the same terms as Perl itself.
320              
321             =cut
322              
323             1; # End of SNMP::Class::Varbind