File Coverage

blib/lib/Net/SNMP/Mixin/Dot1abLldp.pm
Criterion Covered Total %
statement 81 144 56.2
branch 27 56 48.2
condition 3 12 25.0
subroutine 19 19 100.0
pod 4 4 100.0
total 134 235 57.0


line stmt bran cond sub pod time code
1             package Net::SNMP::Mixin::Dot1abLldp;
2              
3 4     4   304605 use strict;
  4         10  
  4         93  
4 4     4   17 use warnings;
  4         8  
  4         119  
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   16 use Carp ();
  4         5  
  4         77  
17 4     4   398 use Net::SNMP::Mixin::Util qw/normalize_mac idx2val push_error get_init_slot/;
  4         65555  
  4         27  
18              
19             #
20             # this module export config
21             #
22             my @mixin_methods;
23              
24             BEGIN {
25 4     4   1953 @mixin_methods = (
26             qw/
27             get_lldp_local_system_data
28             get_lldp_loc_port_table
29             get_lldp_rem_table
30             map_lldp_loc_portid2portnum
31             /
32             );
33             }
34              
35 4         51 use Sub::Exporter -setup => {
36             exports => [@mixin_methods],
37             groups => { default => [@mixin_methods], },
38 4     4   31 };
  4         8  
39              
40             #
41             # SNMP oid constants used in this module
42             #
43             # from lldpMIB
44             use constant {
45 4         3275 LLDP_LOCAL_SYSTEM_DATA => '1.0.8802.1.1.2.1.3',
46             LLDP_LOCAL_CASSIS_ID_SUBTYPE => '1.0.8802.1.1.2.1.3.1.0',
47             LLDP_LOCAL_CASSIS_ID => '1.0.8802.1.1.2.1.3.2.0',
48             LLDP_LOCAL_SYS_NAME => '1.0.8802.1.1.2.1.3.3.0',
49             LLDP_LOCAL_SYS_DESC => '1.0.8802.1.1.2.1.3.4.0',
50             LLDP_LOCAL_SYS_CAPA_SUP => '1.0.8802.1.1.2.1.3.5.0',
51             LLDP_LOCAL_SYS_CAPA_ENA => '1.0.8802.1.1.2.1.3.6.0',
52              
53             LLDP_LOC_PORT_TABLE => '1.0.8802.1.1.2.1.3.7',
54             LLDP_LOC_PORT_NUM => '1.0.8802.1.1.2.1.3.7.1.1',
55             LLDP_LOC_PORT_ID_SUBTYPE => '1.0.8802.1.1.2.1.3.7.1.2',
56             LLDP_LOC_PORT_ID => '1.0.8802.1.1.2.1.3.7.1.3',
57             LLDP_LOC_PORT_DESC => '1.0.8802.1.1.2.1.3.7.1.4',
58              
59             LLDP_REM_TABLE => '1.0.8802.1.1.2.1.4.1',
60             LLDP_REM_LOCAL_PORT_NUM => '1.0.8802.1.1.2.1.4.1.1.2',
61             LLDP_REM_CASSIS_ID_SUBTYPE => '1.0.8802.1.1.2.1.4.1.1.4',
62             LLDP_REM_CASSIS_ID => '1.0.8802.1.1.2.1.4.1.1.5',
63             LLDP_REM_PORT_ID_SUBTYPE => '1.0.8802.1.1.2.1.4.1.1.6',
64             LLDP_REM_PORT_ID => '1.0.8802.1.1.2.1.4.1.1.7',
65             LLDP_REM_PORT_DESC => '1.0.8802.1.1.2.1.4.1.1.8',
66             LLDP_REM_SYS_NAME => '1.0.8802.1.1.2.1.4.1.1.9',
67             LLDP_REM_SYS_DESC => '1.0.8802.1.1.2.1.4.1.1.10',
68             LLDP_REM_SYS_CAPA_SUP => '1.0.8802.1.1.2.1.4.1.1.11',
69             LLDP_REM_SYS_CAPA_ENA => '1.0.8802.1.1.2.1.4.1.1.12',
70 4     4   1862 };
  4         10  
71              
72             =head1 NAME
73              
74             Net::SNMP::Mixin::Dot1abLldp - mixin class for the Link Layer Discovery Protocol
75              
76             =cut
77              
78             our $VERSION = '0.17';
79              
80             =head1 SYNOPSIS
81              
82             A Net::SNMP mixin class for LLDP (Link Layer Discovery Protocol) based info.
83              
84             use Net::SNMP;
85             use Net::SNMP::Mixin;
86              
87             #...
88              
89             my $session = Net::SNMP->session( -hostname => 'foo.bar.com' );
90              
91             $session->mixer('Net::SNMP::Mixin::Dot1abLldp');
92             $session->init_mixins;
93             snmp_dispatcher();
94             $session->init_ok();
95             die $session->errors if $session->errors;
96              
97             printf "Local ChassisID: %s\n",
98             $session->get_lldp_local_system_data->{lldpLocChassisId};
99              
100             $lldp_loc_port_tbl = $session->get_lldp_loc_port_table;
101             $lldp_rem_tbl = $session->get_lldp_rem_table;
102              
103             foreach $lport ( keys %$lldp_rem_tbl ) {
104             foreach $idx ( keys %{ $lldp_rem_tbl->{$lport} } ) {
105             my $lldpRemSysName = $lldp_rem_tbl->{$lport}{$idx}{lldpRemSysName};
106             my $lldpRemPortId = $lldp_rem_tbl->{$lport}{$idx}{lldpRemPortId};
107             my $lldpRemPortDesc = $lldp_rem_tbl->{$lport}{$idx}{lldpRemPortDesc};
108             my $lldpRemChassisId = $lldp_rem_tbl->{$lport}{$idx}{lldpRemChassisId};
109             my $ldesc = $lldp_loc_port_tbl->{$lport}{lldpLocPortDesc};
110              
111             printf "$lport:$ldesc => $lldpRemSysName:$lldpRemPortId:$lldpRemPortDesc:$lldpRemChassisId\n";
112             }
113             }
114              
115             =cut
116              
117             =head1 DESCRIPTION
118              
119             With this mixin it's simple to explore the Layer-2 topologie of the network.
120              
121             The LLDP (Link Layer Discovery Protocol) is an IEEE (Draft?) standard for vendor-independent Layer-2 discovery, similar to the proprietary CDP (Cisco Discovery Protocol) from Cisco. It's defined in the IEEE 802.1AB documents, therefore the name of this module.
122              
123             This mixin reads data from the B<< lldpLocalSystemData >>, B<< lldpLocPortTable >> and the B<< lldpRemTable >> out of the LLDP-MIB. At least these values are in the mandatory set of the LLDP-MIB.
124              
125             =head1 MIXIN METHODS
126              
127             =head2 B<< OBJ->get_lldp_local_system_data() >>
128              
129             Returns the LLDP lldpLocalSystemData group as a hash reference:
130              
131             {
132             lldpLocChassisIdSubtype => Integer,
133             lldpLocChassisId => OCTET_STRING,
134             lldpLocSysName => OCTET_STRING,
135             lldpLocSysDesc => OCTET_STRING,
136             lldpLocSysCapSupported => BITS,
137             lldpLocSysCapEnabled => BITS,
138             }
139              
140             =cut
141              
142             sub get_lldp_local_system_data {
143 1     1 1 22980 my $session = shift;
144 1         6 my $agent = $session->hostname;
145              
146 1 50       13 Carp::croak "$agent: '$prefix' not initialized,"
147             unless $session->init_ok($prefix);
148              
149             # just a shallow copy for shallow values
150 0         0 my $result = { %{ $session->{$prefix}{locSysData} } };
  0         0  
151              
152             # if the chassisIdSubtype has the enumeration 'macAddress(4)'
153             # we normalize the MacAddress
154             $result->{lldpLocChassisId} = normalize_mac( $result->{lldpLocChassisId} )
155 0 0 0     0 if defined $result->{lldpLocChassisIdSubtype} && $result->{lldpLocChassisIdSubtype} == 4;
156              
157 0         0 return $result;
158             }
159              
160             =head2 B<< OBJ->get_lldp_loc_port_table() >>
161              
162             Returns the LLDP lldp_loc_port_table as a hash reference. The table is indexed by the LLDP local port numbers:
163              
164             {
165             lldpLocPortNum => {
166             lldpLocPortIdSubtype => INTEGER,
167             lldpLocPortId => OCTET_STRING,
168             lldpLocPortDesc => OCTET_STRING,
169             }
170             }
171              
172             The LLDP portnumber isn't necessarily the ifIndex of the switch. See the TEXTUAL-CONVENTION from the LLDP-MIB:
173              
174             "A port number has no mandatory relationship to an
175             InterfaceIndex object (of the interfaces MIB, IETF RFC 2863).
176             If the LLDP agent is a IEEE 802.1D, IEEE 802.1Q bridge, the
177             LldpPortNumber will have the same value as the dot1dBasePort
178             object (defined in IETF RFC 1493) associated corresponding
179             bridge port. If the system hosting LLDP agent is not an
180             IEEE 802.1D or an IEEE 802.1Q bridge, the LldpPortNumber
181             will have the same value as the corresponding interface's
182             InterfaceIndex object."
183              
184             See also the L<< Net::SNMP::Mixin::Dot1dBase >> for a mixin to get the mapping between the ifIndexes and the dot1dBasePorts if needed.
185              
186             =cut
187              
188              
189             sub get_lldp_loc_port_table {
190 1     1 1 618 my $session = shift;
191 1         6 my $agent = $session->hostname;
192              
193 1 50       8 Carp::croak "$agent: '$prefix' not initialized,"
194             unless $session->init_ok($prefix);
195              
196             # stash for return values
197 0         0 my $result = {};
198              
199             #
200             # the MIB tables are stored in {column}{row}{value} order
201             # but we return {row}{column}{value}
202             #
203             # grab all rows from one choosen column
204 0         0 my @rows = keys %{ $session->{$prefix}{lldpLocPortTbl}{lldpLocPortId} };
  0         0  
205              
206 0         0 foreach my $row (@rows) {
207              
208             # loop over all columns
209 0         0 foreach my $column ( keys %{ $session->{$prefix}{lldpLocPortTbl} } ) {
  0         0  
210              
211             # rebuild in reverse order: result(row,column) = stash(column,row)
212             # side effect: make a shallow copy for shallow values
213              
214             $result->{$row}{$column} =
215 0         0 $session->{$prefix}{lldpLocPortTbl}{$column}{$row};
216             }
217              
218             }
219              
220 0         0 return $result;
221             }
222              
223             =head2 B<< OBJ->map_lldp_loc_portid2portnum() >>
224              
225             Returns a hash reference with local portIds to local portNums:
226              
227             {
228             ...
229             Te5/32 => 234,
230             ...
231             }
232              
233             =cut
234              
235             sub map_lldp_loc_portid2portnum {
236 1     1 1 594 my $session = shift;
237 1         5 my $agent = $session->hostname;
238              
239 1 50       9 Carp::croak "$agent: '$prefix' not initialized,"
240             unless $session->init_ok($prefix);
241              
242             # stash for return values
243 0         0 my $result = {};
244              
245 0         0 foreach my $portNum ( keys %{ $session->{$prefix}{lldpLocPortTbl}{lldpLocPortId} } ) {
  0         0  
246 0         0 my $portId = $session->{$prefix}{lldpLocPortTbl}{lldpLocPortId}{$portNum};
247 0         0 $result->{$portId} = $portNum;
248             }
249              
250 0         0 return $result;
251             }
252              
253             =head2 B<< OBJ->get_lldp_rem_table() >>
254              
255             Returns the LLDP lldp_rem_table as a hash reference. The table is indexed by the LLDP local port numbers on which the remote system information is received and an index for multiple neighbors on one port:
256              
257             {
258             lldpRemLocalPortNum => {
259             lldpRemIndex => {
260             lldpRemChassisIdSubtype => INTEGER,
261             lldpRemChassisId => OCTET_STRING,
262             lldpRemPortIdSubtype => INTEGER,
263             lldpRemPortId => OCTET_STRING,
264             lldpRemPortDesc => OCTET_STRING,
265             lldpRemSysName => OCTET_STRING,
266             lldpRemSysDesc => OCTET_STRING,
267             lldpRemSysCapSupported => BITS,
268             lldpRemSysCapEnabled => BITS,
269             }
270             }
271             }
272              
273             =cut
274              
275             sub get_lldp_rem_table {
276 1     1 1 577 my $session = shift;
277 1         14 my $agent = $session->hostname;
278              
279 1 50       8 Carp::croak "$agent: '$prefix' not initialized,"
280             unless $session->init_ok($prefix);
281              
282             # stash for return values
283 0         0 my $result = {};
284              
285             # the MIB tables are stored in {column}{row}{value} order
286             # but we return {row}{column}{value}
287             #
288             # grab all rows from one random choosen column
289 0         0 my @rows = keys %{ $session->{$prefix}{lldpRemTbl}{lldpRemPortId} };
  0         0  
290              
291 0         0 foreach my $row (@rows) {
292              
293             # the rows are the concatenation of 'lldpRemLocalPortNum.lldpRemIndex'
294             # split them into separate values
295 0         0 my ( $lldpRemLocalPortNum, $lldpRemIndex ) = split /\./, $row;
296              
297             # loop over all columns
298 0         0 foreach my $column ( keys %{ $session->{$prefix}{lldpRemTbl} } ) {
  0         0  
299              
300             # rebuild in reverse order: result(row,column) = stash(column,row)
301             # side effect: make a shallow copy for shallow values
302             # side effect: entangle the row 'lldpRemLocalPortNum.lldpRemIndex'
303              
304             $result->{$lldpRemLocalPortNum}{$lldpRemIndex}{$column} =
305 0         0 $session->{$prefix}{lldpRemTbl}{$column}{$row};
306             }
307              
308             # if the chassisIdSubtype has the enumeration 'macAddress(4)'
309             # we normalize the MacAddress
310             my $chassisIdSubtype =
311 0         0 $result->{$lldpRemLocalPortNum}{$lldpRemIndex}{lldpRemChassisIdSubtype};
312              
313 0 0 0     0 if ( defined $chassisIdSubtype && $chassisIdSubtype == 4 ) {
314             $result->{$lldpRemLocalPortNum}{$lldpRemIndex}{lldpRemChassisId} =
315 0         0 normalize_mac( $result->{$lldpRemLocalPortNum}{$lldpRemIndex}{lldpRemChassisId} );
316             }
317              
318             }
319              
320 0         0 return $result;
321             }
322              
323             =head1 INITIALIZATION
324              
325             =head2 B<< OBJ->_init($reload) >>
326              
327             Fetch the LLDP related snmp values from the host. Don't call this method direct!
328              
329             =cut
330              
331             #
332             # due to the asynchron nature, we don't know what init job is really the last, we decrement
333             # the value after each callback
334             #
335 4     4   27 use constant THIS_INIT_JOBS => 3;
  4         10  
  4         3998  
336              
337             sub _init {
338 4     4   7568 my ($session, $reload) = @_;
339 4         10 my $agent = $session->hostname;
340              
341             die "$agent: $prefix already initialized and reload not forced.\n"
342             if exists get_init_slot($session)->{$prefix}
343 4 50 66     23 && get_init_slot($session)->{$prefix} == 0
      33        
344             && not $reload;
345              
346             # set number of async init jobs for proper initialization
347 4         99 get_init_slot($session)->{$prefix} = THIS_INIT_JOBS;
348              
349             # populate the object with needed mib values
350             #
351             # initialize the object for LLDP infos
352 4         40 _fetch_lldp_local_system_data($session);
353 4 100       23 return if $session->error;
354              
355 2         18 _fetch_lldp_loc_port_tbl($session);
356 2 50       12 return if $session->error;
357              
358 2         13 _fetch_lldp_rem_tbl($session);
359 2 50       12 return if $session->error;
360              
361 2         12 return 1;
362             }
363              
364             =head1 PRIVATE METHODS
365              
366             Only for developers or maintainers.
367              
368             =head2 B<< _fetch_lldp_local_system_data($session) >>
369              
370             Fetch the local system data from the lldpMIB once during object initialization.
371              
372             =cut
373              
374             sub _fetch_lldp_local_system_data {
375 4     4   8 my $session = shift;
376 4         17 my $result;
377              
378             # use get_entries instead of get_request since the
379             # result will be true in case of missing values
380             # the values are just noSuchObject
381             # with get_entries() we get error messages for free
382            
383 4 100       24 $result = $session->get_entries(
384             -columns => [ LLDP_LOCAL_SYSTEM_DATA, ],
385             -endindex => '6.0', # LLDP_LOCAL_SYS_CAPA_ENA
386              
387             # define callback if in nonblocking mode
388             $session->nonblocking ? ( -callback => \&_lldp_local_system_data_cb ) : (),
389              
390             );
391              
392 4 100       2009447 unless (defined $result) {
393 2 50       12 if (my $err_msg = $session->error) {
394 2         45 push_error($session, "$prefix: $err_msg");
395             };
396 2         63 return;
397             }
398              
399             # in nonblocking mode the callback will be called asynchronously
400 2 50       8 return 1 if $session->nonblocking;
401              
402             # ok we are in synchronous mode, call the result mangling function
403             # by hand
404 0         0 _lldp_local_system_data_cb($session);
405             }
406              
407             =head2 B<< _lldp_local_system_data_cb($session) >>
408              
409             The callback for _fetch_lldp_local_system_data.
410              
411             =cut
412              
413             sub _lldp_local_system_data_cb {
414 2     2   2004705 my $session = shift;
415 2         7 my $vbl = $session->var_bind_list;
416              
417 2 50       27 unless (defined $vbl) {
418 2 50       11 if (my $err_msg = $session->error) {
419 2         29 push_error($session, "$prefix: $err_msg");
420             };
421 2         60 return;
422             }
423              
424             $session->{$prefix}{locSysData}{lldpLocChassisIdSubtype} =
425 0         0 $vbl->{ LLDP_LOCAL_CASSIS_ID_SUBTYPE() };
426              
427             $session->{$prefix}{locSysData}{lldpLocChassisId} =
428 0         0 $vbl->{ LLDP_LOCAL_CASSIS_ID() };
429              
430             $session->{$prefix}{locSysData}{lldpLocSysName} =
431 0         0 $vbl->{ LLDP_LOCAL_SYS_NAME() };
432              
433             $session->{$prefix}{locSysData}{lldpLocSysDesc} =
434 0         0 $vbl->{ LLDP_LOCAL_SYS_DESC() };
435              
436             $session->{$prefix}{locSysData}{lldpLocSysCapSupported} =
437 0         0 $vbl->{ LLDP_LOCAL_SYS_CAPA_SUP() };
438              
439             $session->{$prefix}{locSysData}{lldpLocSysCapEnabled} =
440 0         0 $vbl->{ LLDP_LOCAL_SYS_CAPA_ENA() };
441              
442             # this init job is finished
443 0         0 get_init_slot($session)->{$prefix}--;
444              
445 0         0 return 1;
446             }
447              
448             =head2 B<< _fetch_lldp_loc_port_tbl($session) >>
449              
450             Fetch the lldpLocPortTable once during object initialization.
451              
452             =cut
453              
454             sub _fetch_lldp_loc_port_tbl {
455 2     2   5 my $session = shift;
456 2         4 my $result;
457              
458             # fetch the lldpLocPortTable
459 2 50       7 $result = $session->get_table(
460             -baseoid => LLDP_LOC_PORT_TABLE,
461              
462             # define callback if in nonblocking mode
463             $session->nonblocking ? ( -callback => \&_lldp_loc_port_tbl_cb ) : (),
464             );
465              
466 2 50       1683 unless (defined $result) {
467 0 0       0 if (my $err_msg = $session->error) {
468 0         0 push_error($session, "$prefix: $err_msg");
469             };
470 0         0 return;
471             }
472              
473             # in nonblocking mode the callback will be called asynchronously
474 2 50       7 return 1 if $session->nonblocking;
475              
476             # ok we are in synchronous mode, call the result mangling function
477             # by hand
478 0         0 _lldp_loc_port_tbl_cb($session);
479              
480             }
481              
482             =head2 B<< _lldp_loc_port_tbl_cb($session) >>
483              
484             The callback for _fetch_lldp_loc_port_tbl_cb().
485              
486             =cut
487              
488             sub _lldp_loc_port_tbl_cb {
489 2     2   751 my $session = shift;
490 2         8 my $vbl = $session->var_bind_list;
491              
492              
493 2 50       21 unless (defined $vbl) {
494 2 50       9 if (my $err_msg = $session->error) {
495 2         19 push_error($session, "$prefix: $err_msg");
496             };
497 2         51 return;
498             }
499              
500             # mangle result table to get plain idx->value
501              
502             $session->{$prefix}{lldpLocPortTbl}{lldpLocPortIdSubtype} =
503 0         0 idx2val( $vbl, LLDP_LOC_PORT_ID_SUBTYPE );
504              
505             $session->{$prefix}{lldpLocPortTbl}{lldpLocPortId} =
506 0         0 idx2val( $vbl, LLDP_LOC_PORT_ID );
507              
508             $session->{$prefix}{lldpLocPortTbl}{lldpLocPortDesc} =
509 0         0 idx2val( $vbl, LLDP_LOC_PORT_DESC );
510              
511             # this init job is finished
512 0         0 get_init_slot($session)->{$prefix}--;
513              
514 0         0 return 1;
515             }
516              
517             =head2 B<< _fetch_lldp_rem_tbl($session) >>
518              
519             Fetch the lldpRemTable once during object initialization.
520              
521             =cut
522              
523             sub _fetch_lldp_rem_tbl {
524 2     2   5 my $session = shift;
525 2         2 my $result;
526              
527             # fetch the lldpRemTable
528 2 50       7 $result = $session->get_table(
529             -baseoid => LLDP_REM_TABLE,
530              
531             # define callback if in nonblocking mode
532             $session->nonblocking ? ( -callback => \&_lldp_rem_tbl_cb ) : (),
533             );
534              
535 2 50       1674 unless (defined $result) {
536 0 0       0 if (my $err_msg = $session->error) {
537 0         0 push_error($session, "$prefix: $err_msg");
538             };
539 0         0 return;
540             }
541              
542             # in nonblocking mode the callback will be called asynchronously
543 2 50       7 return 1 if $session->nonblocking;
544              
545             # ok we are in synchronous mode, call the result mangling function
546             # by hand
547 0         0 _lldp_rem_tbl_cb($session);
548              
549             }
550              
551             =head2 B<< _lldp_rem_tbl_cb($session) >>
552              
553             The callback for _fetch_lldp_rem_tbl_cb().
554              
555             =cut
556              
557             sub _lldp_rem_tbl_cb {
558 2     2   1097 my $session = shift;
559 2         8 my $vbl = $session->var_bind_list;
560              
561 2 50       20 unless (defined $vbl) {
562 2 50       6 if (my $err_msg = $session->error) {
563 2         21 push_error($session, "$prefix: $err_msg");
564             }
565 2         46 return;
566             }
567              
568             # mangle result table to get plain idx->value
569             #---------------------------------------------------------------
570             # the tableIndex is a little bit tricky, please see the LLDP-MIB
571             #---------------------------------------------------------------
572             #
573             # .1.0.8802.1.1.2.1.4.1.1.11[.0.20.1]
574             # ^ ^ ^
575             # | | |
576             # lldpRemTimeMark---/ | |
577             # | |
578             # lldpRemLocalPortNum--/ |
579             # |
580             # lldpRemIndex-----------/
581             #
582             #---------------------------------------------------------------
583             # lldpRemEntry OBJECT-TYPE
584             # SYNTAX LldpRemEntry
585             # MAX-ACCESS not-accessible
586             # STATUS current
587             # DESCRIPTION
588             # "Information about a particular physical network connection.
589             # Entries may be created and deleted in this table by the agent,
590             # if a physical topology discovery process is active."
591             # INDEX {
592             # lldpRemTimeMark,
593             # lldpRemLocalPortNum,
594             # lldpRemIndex
595             # }
596             # ::= { lldpRemTable 1 }
597             # -----------------------------------------------
598              
599             # mangle result table to get plain idx->value
600             # cut off the variable lldpRemTimeMark as pre
601             #
602             # result hashes: lldpRemLocalPortNum.lldpRemIndex => values
603             #
604              
605             $session->{$prefix}{lldpRemTbl}{lldpRemChassisIdSubtype} =
606 0           idx2val( $vbl, LLDP_REM_CASSIS_ID_SUBTYPE, 1, undef, );
607              
608             $session->{$prefix}{lldpRemTbl}{lldpRemChassisId} =
609 0           idx2val( $vbl, LLDP_REM_CASSIS_ID, 1, undef, );
610              
611             $session->{$prefix}{lldpRemTbl}{lldpRemPortIdSubtype} =
612 0           idx2val( $vbl, LLDP_REM_PORT_ID_SUBTYPE, 1, undef, );
613              
614             $session->{$prefix}{lldpRemTbl}{lldpRemPortId} =
615 0           idx2val( $vbl, LLDP_REM_PORT_ID, 1, undef, );
616              
617             $session->{$prefix}{lldpRemTbl}{lldpRemPortDesc} =
618 0           idx2val( $vbl, LLDP_REM_PORT_DESC, 1, undef, );
619              
620             $session->{$prefix}{lldpRemTbl}{lldpRemSysName} =
621 0           idx2val( $vbl, LLDP_REM_SYS_NAME, 1, undef, );
622              
623             $session->{$prefix}{lldpRemTbl}{lldpRemSysDesc} =
624 0           idx2val( $vbl, LLDP_REM_SYS_DESC, 1, undef, );
625              
626             $session->{$prefix}{lldpRemTbl}{lldpRemSysCapSupported} =
627 0           idx2val( $vbl, LLDP_REM_SYS_CAPA_SUP, 1, undef, );
628              
629             $session->{$prefix}{lldpRemTbl}{lldpRemSysCapEnabled} =
630 0           idx2val( $vbl, LLDP_REM_SYS_CAPA_ENA, 1, undef, );
631              
632             # this init job is finished
633 0           get_init_slot($session)->{$prefix}--;
634              
635 0           return 1;
636             }
637              
638             unless ( caller() ) {
639             print "$prefix compiles and initializes successful.\n";
640             }
641              
642             =head1 SEE ALSO
643              
644             L<< Net::SNMP::Mixin::Dot1dBase >>
645              
646             =head1 REQUIREMENTS
647              
648             L<< Net::SNMP >>, L<< Net::SNMP::Mixin >>
649              
650             =head1 BUGS, PATCHES & FIXES
651              
652             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.
653              
654             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 .
655              
656             RT: http://rt.cpan.org/Public/Dist/Display.html?Name=Net-SNMP-Mixin-Dot1abLldp
657              
658              
659             =head1 AUTHOR
660              
661             Karl Gaissmaier
662              
663             =head1 COPYRIGHT & LICENSE
664              
665             Copyright 2008-2018 Karl Gaissmaier, all rights reserved.
666              
667             This program is free software; you can redistribute it and/or modify it
668             under the same terms as Perl itself.
669              
670             =cut
671              
672             1;
673              
674             # vim: sw=2