File Coverage

blib/lib/Net/SNMP/Mixin/Dot1dBase.pm
Criterion Covered Total %
statement 48 70 68.5
branch 17 28 60.7
condition 1 3 33.3
subroutine 15 15 100.0
pod 3 3 100.0
total 84 119 70.5


line stmt bran cond sub pod time code
1             package Net::SNMP::Mixin::Dot1dBase;
2              
3 4     4   495281 use strict;
  4         8  
  4         164  
4 4     4   20 use warnings;
  4         10  
  4         160  
5              
6             #
7             # store this package name in a handy variable,
8             # used for unambiguous prefix of mixin attributes
9             # storage in object hash
10             #
11             my $prefix = __PACKAGE__;
12              
13             #
14             # this module import config
15             #
16 4     4   21 use Carp ();
  4         11  
  4         94  
17 4     4   3952 use Net::SNMP::Mixin::Util qw/idx2val normalize_mac/;
  4         146579  
  4         40  
18              
19             #
20             # this module export config
21             #
22             my @mixin_methods;
23              
24             BEGIN {
25 4     4   1475 @mixin_methods = (
26             qw/
27             get_dot1d_base_group
28             map_bridge_ports2if_indexes
29             map_if_indexes2bridge_ports
30             /
31             );
32             }
33              
34 4         37 use Sub::Exporter -setup => {
35             exports => [@mixin_methods],
36             groups => { default => [@mixin_methods], },
37 4     4   35 };
  4         9  
38              
39             #
40             # SNMP oid constants used in this module
41             #
42             use constant {
43 4         4419 DOT1D_BASE_BRIDGE_ADDRESS => '1.3.6.1.2.1.17.1.1.0',
44             DOT1D_BASE_NUM_PORTS => '1.3.6.1.2.1.17.1.2.0',
45             DOT1D_BASE_TYPE => '1.3.6.1.2.1.17.1.3.0',
46              
47             DOT1D_BASE_PORT_IF_INDEX => '1.3.6.1.2.1.17.1.4.1.2',
48 4     4   1995 };
  4         9  
49              
50             =head1 NAME
51              
52             Net::SNMP::Mixin::Dot1dBase - mixin class for the switch dot1d base values
53              
54             =head1 VERSION
55              
56             Version 0.04
57              
58             =cut
59              
60             our $VERSION = '0.04';
61              
62             =head1 SYNOPSIS
63              
64             A Net::SNMP mixin class for Dot1d base info.
65              
66             use Net::SNMP;
67             use Net::SNMP::Mixin qw/mixer init_mixins/;
68              
69             # class based mixin
70             Net::SNMP->mixer('Net::SNMP::Mixin::Dot1dBase');
71              
72             # ...
73              
74             my $session = Net::SNMP->session( -hostname => 'foo.bar.com' );
75              
76             $session->mixer('Net::SNMP::Mixin::Dot1dBase');
77             $session->init_mixins;
78             snmp_dispatcher() if $session->nonblocking;
79             die $session->error if $session->error;
80              
81             my $base_group = $session->get_dot1d_base_group;
82              
83             printf "BridgeAddr: %s NumPorts: %d Type: %d\n",
84             $base_group->{dot1dBaseBridgeAddress},
85             $base_group->{dot1dBaseNumPorts},
86             $base_group->{dot1dBaseType};
87              
88             my $map = $session->map_bridge_ports2if_indexes;
89              
90             foreach my $bridge_port ( sort {$a <=> $b} keys %$map ) {
91             my $if_index = $map->{$bridge_port};
92             printf "bridgePort: %4d -> ifIndex: %4\n", $bridge_port, $if_index;
93             }
94              
95              
96             =head1 DESCRIPTION
97              
98             A mixin class for basic switch information from the BRIDGE-MIB.
99              
100             Besides the bridge address and the number of bridge ports, it's primary use is the mapping between dot1dBasePorts and ifIndexes.
101              
102             =head1 MIXIN METHODS
103              
104             =head2 B<< OBJ->get_dot1d_base_group() >>
105              
106             Returns the dot1dBase group as a hash reference:
107              
108             {
109             dot1dBaseBridgeAddress => MacAddress,
110             dot1dBaseNumPorts => INTEGER,
111             dot1dBaseType => INTEGER,
112             }
113              
114             =cut
115              
116             sub get_dot1d_base_group {
117 1     1 1 47091 my $session = shift;
118 1 50       107 Carp::croak "'$prefix' not initialized,"
119             unless $session->{$prefix}{__initialized};
120              
121 0         0 my $result = { %{ $session->{$prefix}{dot1dBase} } };
  0         0  
122              
123             # normalize the MAC address
124 0         0 $result->{dot1dBaseBridgeAddress} =
125             normalize_mac( $result->{dot1dBaseBridgeAddress} );
126              
127 0         0 return $result;
128             }
129              
130             =head2 B<< OBJ->map_bridge_ports2if_indexes() >>
131              
132             Returns a reference to a hash with the following entries:
133              
134             {
135             # INTEGER INTEGER
136             dot1dBasePort => dot1dBasePortIfIndex,
137             }
138              
139             =cut
140              
141             sub map_bridge_ports2if_indexes {
142 1     1 1 420 my ( $session, ) = @_;
143 1 50       101 Carp::croak "'$prefix' not initialized,"
144             unless $session->{$prefix}{__initialized};
145              
146             # datastructure:
147             # $session->{$prefix}{dot1dBasePortIfIndex}{$dot1d_base_port} = ifIndex
148             #
149              
150 0         0 my $result = {};
151              
152 0         0 while ( my ( $bridge_port, $if_index ) =
  0         0  
153             each %{ $session->{$prefix}{dot1dBasePortIfIndex} } )
154             {
155 0         0 $result->{$bridge_port} = $if_index;
156             }
157              
158 0         0 return $result;
159             }
160              
161             =head2 B<< OBJ->map_if_indexes2bridge_ports() >>
162              
163             Returns a reference to a hash with the following entries:
164              
165             {
166             # INTEGER INTEGER
167             dot1dBasePortIfIndex => dot1dBasePort ,
168             }
169              
170             =cut
171              
172             sub map_if_indexes2bridge_ports {
173 1     1 1 431 my ( $session, ) = @_;
174 1 50       96 Carp::croak "'$prefix' not initialized,"
175             unless $session->{$prefix}{__initialized};
176              
177             # datastructure:
178             # $session->{$prefix}{dot1dBasePortIfIndex}{$dot1d_base_port} = ifIndex
179             #
180              
181 0         0 my $result = {};
182              
183 0         0 while ( my ( $bridge_port, $if_index ) =
  0         0  
184             each %{ $session->{$prefix}{dot1dBasePortIfIndex} } )
185             {
186 0         0 $result->{$if_index} = $bridge_port;
187             }
188              
189 0         0 return $result;
190             }
191              
192             =head1 INITIALIZATION
193              
194             =cut
195              
196             =head2 B<< OBJ->_init($reload) >>
197              
198             Fetch the dot1d base related snmp values from the host. Don't call this method direct!
199              
200             =cut
201              
202             sub _init {
203 4     4   16571 my ($session, $reload) = @_;
204              
205 4 50 33     35 die "$prefix already initalized and reload not forced.\n"
206             if $session->{$prefix}{__initialized} && not $reload;
207              
208             # initialize the object for dot1dbase infos
209 4         12 _fetch_dot1d_base($session);
210 4 100       43 return if $session->error;
211              
212             # LLDP, Dot1Q, STP, LLDP, ... tables are indexed
213             # by dot1dbaseports and not ifIndexes
214             # table to map between dot1dBasePort <-> ifIndex
215              
216 2         18 _fetch_dot1d_base_ports($session);
217 2 50       14 return if $session->error;
218              
219 2         16 return 1;
220             }
221              
222             =head1 PRIVATE METHODS
223              
224             Only for developers or maintainers.
225              
226             =head2 B<< _fetch_dot1d_base($session) >>
227              
228             Fetch values from the dot1dBase group once during object initialization.
229              
230             =cut
231              
232             sub _fetch_dot1d_base {
233 4     4   8 my $session = shift;
234 4         6 my $result;
235              
236             # fetch the dot1dBase group
237 4 100       38 $result = $session->get_request(
238             -varbindlist => [
239              
240             DOT1D_BASE_BRIDGE_ADDRESS,
241             DOT1D_BASE_NUM_PORTS,
242             DOT1D_BASE_TYPE,
243             ],
244              
245             # define callback if in nonblocking mode
246             $session->nonblocking ? ( -callback => \&_dot1d_base_cb ) : (),
247             );
248              
249 4 100       2010075 return unless defined $result;
250 2 50       8 return 1 if $session->nonblocking;
251              
252             # call the callback function in blocking mode by hand
253 0         0 _dot1d_base_cb($session);
254              
255             }
256              
257             =head2 B<< _dot1d_base_cb($session) >>
258              
259             The callback for _fetch_dot1d_base.
260              
261             =cut
262              
263             sub _dot1d_base_cb {
264 2     2   2004567 my $session = shift;
265 2         15 my $vbl = $session->var_bind_list;
266              
267 2 50       37 return unless defined $vbl;
268              
269 0         0 $session->{$prefix}{dot1dBase}{dot1dBaseBridgeAddress} =
270             $vbl->{DOT1D_BASE_BRIDGE_ADDRESS()};
271              
272 0         0 $session->{$prefix}{dot1dBase}{dot1dBaseNumPorts} =
273             $vbl->{DOT1D_BASE_NUM_PORTS()};
274              
275 0         0 $session->{$prefix}{dot1dBase}{dot1dBaseType} =
276             $vbl->{DOT1D_BASE_TYPE() };
277              
278 0         0 $session->{$prefix}{__initialized}++;
279             }
280              
281             =head2 B<< _fetch_dot1d_base_ports($session) >>
282              
283             Populate the object with the dot1dBasePorts.
284              
285             =cut
286              
287             sub _fetch_dot1d_base_ports {
288 2     2   4 my $session = shift;
289 2         4 my $result;
290              
291             # fetch the dot1dBasePorts, in blocking or nonblocking mode
292 2 50       11 $result = $session->get_entries(
293             -columns => [DOT1D_BASE_PORT_IF_INDEX,],
294              
295             # define callback if in nonblocking mode
296             $session->nonblocking ? ( -callback => \&_dot1d_base_ports_cb ) : (),
297             );
298              
299 2 50       1865 return unless defined $result;
300 2 50       8 return 1 if $session->nonblocking;
301              
302             # call the callback funktion in blocking mode by hand
303 0         0 _dot1d_base_ports_cb($session);
304              
305             }
306              
307             =head2 B<< _dot1d_base_ports_cb($session) >>
308              
309             The callback for _fetch_dot1d_base_ports.
310              
311             =cut
312              
313             sub _dot1d_base_ports_cb {
314 2     2   734 my $session = shift;
315 2         8 my $vbl = $session->var_bind_list;
316              
317 2 50       20 return unless defined $vbl;
318              
319             # mangle result table to get plain idx->value
320              
321 0           $session->{$prefix}{dot1dBasePortIfIndex} =
322             idx2val( $vbl, DOT1D_BASE_PORT_IF_INDEX );
323              
324 0           $session->{$prefix}{__initialized}++;
325             }
326              
327             =head1 REQUIREMENTS
328              
329             L<< Net::SNMP >>, L<< Net::SNMP::Mixin >>
330              
331             =head1 BUGS, PATCHES & FIXES
332              
333             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.
334              
335             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 .
336              
337             RT: http://rt.cpan.org/Public/Dist/Display.html?Name=Net-SNMP-Mixin-Dot1dBase
338              
339             =head1 AUTHOR
340              
341             Karl Gaissmaier
342              
343             =head1 COPYRIGHT & LICENSE
344              
345             Copyright 2008 Karl Gaissmaier, all rights reserved.
346              
347             This program is free software; you can redistribute it and/or modify it
348             under the same terms as Perl itself.
349              
350             =cut
351              
352             unless ( caller() ) {
353             print "$prefix compiles and initializes successful.\n";
354             }
355              
356             1;
357              
358             # vim: sw=2