File Coverage

blib/lib/Net/Frame/Layer/SNMP.pm
Criterion Covered Total %
statement 183 261 70.1
branch 32 86 37.2
condition 20 63 31.7
subroutine 49 55 89.0
pod 20 20 100.0
total 304 485 62.6


line stmt bran cond sub pod time code
1             #
2             # $Id: SNMP.pm 49 2013-03-04 13:15:34Z VinsWorldcom $
3             #
4             package Net::Frame::Layer::SNMP;
5 10     10   106602 use strict; use warnings;
  10     10   26  
  10         349  
  10         54  
  10         21  
  10         724  
6              
7             our $VERSION = '1.01';
8              
9 10     10   11541 use Net::Frame::Layer qw(:consts :subs);
  10         941996  
  10         3126  
10 10     10   115 use Exporter;
  10         24  
  10         1411  
11             our @ISA = qw(Net::Frame::Layer Exporter);
12              
13             our %EXPORT_TAGS = (
14             consts => [qw(
15             NF_SNMP_VERSION_1
16             NF_SNMP_VERSION_2
17             NF_SNMP_PDUTYPE_GET
18             NF_SNMP_PDUTYPE_GETNEXT
19             NF_SNMP_PDUTYPE_RESPONSE
20             NF_SNMP_PDUTYPE_SET
21             NF_SNMP_PDUTYPE_TRAP
22             NF_SNMP_PDUTYPE_GETBULK
23             NF_SNMP_PDUTYPE_INFORM
24             NF_SNMP_PDUTYPE_V2TRAP
25             NF_SNMP_PDUTYPE_REPORT
26             NF_SNMP_GENERICTRAP_COLDSTART
27             NF_SNMP_GENERICTRAP_WARMSTART
28             NF_SNMP_GENERICTRAP_LINKDOWN
29             NF_SNMP_GENERICTRAP_LINKUP
30             NF_SNMP_GENERICTRAP_AUTHFAIL
31             NF_SNMP_GENERICTRAP_EGPNEIGHBORLOSS
32             NF_SNMP_GENERICTRAP_ENTERPRISESPECIFIC
33             NF_SNMP_VARBINDTYPE_INTEGER
34             NF_SNMP_VARBINDTYPE_STRING
35             NF_SNMP_VARBINDTYPE_OID
36             NF_SNMP_VARBINDTYPE_IPADDR
37             NF_SNMP_VARBINDTYPE_COUNTER32
38             NF_SNMP_VARBINDTYPE_GUAGE32
39             NF_SNMP_VARBINDTYPE_TIMETICKS
40             NF_SNMP_VARBINDTYPE_OPAQUE
41             NF_SNMP_VARBINDTYPE_COUNTER64
42             NF_SNMP_VARBINDTYPE_NULL
43             )],
44             subs => [qw(
45             varbinds
46             v2trap_varbinds
47             )],
48             );
49             our @EXPORT_OK = (
50             @{$EXPORT_TAGS{consts}},
51             @{$EXPORT_TAGS{subs}},
52             );
53              
54 10     10   62 use constant NF_SNMP_VERSION_1 => 0;
  10         22  
  10         587  
55 10     10   51 use constant NF_SNMP_VERSION_2 => 1;
  10         21  
  10         426  
56 10     10   49 use constant NF_SNMP_PDUTYPE_GET => 0;
  10         20  
  10         437  
57 10     10   51 use constant NF_SNMP_PDUTYPE_GETNEXT => 1;
  10         20  
  10         423  
58 10     10   49 use constant NF_SNMP_PDUTYPE_RESPONSE => 2;
  10         23  
  10         471  
59 10     10   148 use constant NF_SNMP_PDUTYPE_SET => 3;
  10         27  
  10         399  
60 10     10   45 use constant NF_SNMP_PDUTYPE_TRAP => 4;
  10         17  
  10         447  
61 10     10   46 use constant NF_SNMP_PDUTYPE_GETBULK => 5;
  10         17  
  10         394  
62 10     10   78 use constant NF_SNMP_PDUTYPE_INFORM => 6;
  10         24  
  10         462  
63 10     10   56 use constant NF_SNMP_PDUTYPE_V2TRAP => 7;
  10         17  
  10         455  
64 10     10   46 use constant NF_SNMP_PDUTYPE_REPORT => 8;
  10         19  
  10         412  
65 10     10   45 use constant NF_SNMP_GENERICTRAP_COLDSTART => 0;
  10         17  
  10         449  
66 10     10   68 use constant NF_SNMP_GENERICTRAP_WARMSTART => 1;
  10         20  
  10         457  
67 10     10   48 use constant NF_SNMP_GENERICTRAP_LINKDOWN => 1;
  10         17  
  10         459  
68 10     10   61 use constant NF_SNMP_GENERICTRAP_LINKUP => 3;
  10         27  
  10         433  
69 10     10   45 use constant NF_SNMP_GENERICTRAP_AUTHFAIL => 4;
  10         23  
  10         460  
70 10     10   47 use constant NF_SNMP_GENERICTRAP_EGPNEIGHBORLOSS => 5;
  10         17  
  10         516  
71 10     10   42 use constant NF_SNMP_GENERICTRAP_ENTERPRISESPECIFIC => 6;
  10         26  
  10         409  
72 10     10   48 use constant NF_SNMP_VARBINDTYPE_INTEGER => 0;
  10         17  
  10         448  
73 10     10   50 use constant NF_SNMP_VARBINDTYPE_STRING => 1;
  10         18  
  10         466  
74 10     10   46 use constant NF_SNMP_VARBINDTYPE_OID => 2;
  10         26  
  10         393  
75 10     10   45 use constant NF_SNMP_VARBINDTYPE_IPADDR => 3;
  10         23  
  10         416  
76 10     10   48 use constant NF_SNMP_VARBINDTYPE_COUNTER32 => 4;
  10         15  
  10         424  
77 10     10   45 use constant NF_SNMP_VARBINDTYPE_GUAGE32 => 5;
  10         17  
  10         520  
78 10     10   45 use constant NF_SNMP_VARBINDTYPE_TIMETICKS => 6;
  10         17  
  10         405  
79 10     10   46 use constant NF_SNMP_VARBINDTYPE_OPAQUE => 7;
  10         19  
  10         375  
80 10     10   47 use constant NF_SNMP_VARBINDTYPE_COUNTER64 => 8;
  10         160  
  10         413  
81 10     10   48 use constant NF_SNMP_VARBINDTYPE_NULL => 9;
  10         15  
  10         7994  
82              
83             our @AS = qw(
84             version
85             community
86             pdu_type
87             requestId
88             errorStatus
89             errorIndex
90             entOid
91             agentAddr
92             genericTrap
93             specificTrap
94             timeticks
95             nonRepeaters
96             maxRepetitions
97             );
98             our @AA = qw(
99             varbindlist
100             );
101             __PACKAGE__->cgBuildIndices;
102             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
103             __PACKAGE__->cgBuildAccessorsArray(\@AA);
104              
105             #no strict 'vars';
106              
107 10     10   1314 use Socket qw(inet_ntoa AF_INET IPPROTO_TCP);
  10         1428  
  10         3919  
108              
109             my $AF_INET6 = eval { Socket::AF_INET6() };
110             my $NI_NUMERICHOST = eval { Socket::NI_NUMERICHOST() };
111              
112 10     10   11017 use Convert::ASN1;
  10         472915  
  10         38320  
113              
114             our $asn = Convert::ASN1->new;
115             $asn->prepare("
116             Message ::= SEQUENCE {
117             version INTEGER,
118             community STRING,
119             pdu_type PDUs
120             }
121             PDUs ::= CHOICE {
122             get_request GetRequest_PDU,
123             get_next_request GetNextRequest_PDU,
124             response Response_PDU,
125             set_request SetRequest_PDU,
126             trap Trap_PDU,
127             get_bulk_request GetBulkRequest_PDU,
128             inform_request InformRequest_PDU,
129             snmpV2_trap SNMPv2_Trap_PDU,
130             report Report_PDU
131             }
132             GetRequest_PDU ::= [0] IMPLICIT PDU
133             GetNextRequest_PDU ::= [1] IMPLICIT PDU
134             Response_PDU ::= [2] IMPLICIT PDU
135             SetRequest_PDU ::= [3] IMPLICIT PDU
136             Trap_PDU ::= [4] IMPLICIT TrapPDU
137             GetBulkRequest_PDU ::= [5] IMPLICIT BulkPDU
138             InformRequest_PDU ::= [6] IMPLICIT PDU
139             SNMPv2_Trap_PDU ::= [7] IMPLICIT PDU
140             Report_PDU ::= [8] IMPLICIT PDU
141              
142             IPAddress ::= [APPLICATION 0] STRING
143             Counter32 ::= [APPLICATION 1] INTEGER
144             Guage32 ::= [APPLICATION 2] INTEGER
145             TimeTicks ::= [APPLICATION 3] INTEGER
146             Opaque ::= [APPLICATION 4] STRING
147             Counter64 ::= [APPLICATION 6] INTEGER
148              
149             PDU ::= SEQUENCE {
150             requestId INTEGER,
151             errorStatus INTEGER,
152             errorIndex INTEGER,
153             varbindlist VARBINDS
154             }
155             TrapPDU ::= SEQUENCE {
156             entOid OBJECT IDENTIFIER,
157             agentAddr IPAddress,
158             genericTrap INTEGER,
159             specificTrap INTEGER,
160             timeticks TimeTicks,
161             varbindlist VARBINDS
162             }
163             BulkPDU ::= SEQUENCE {
164             requestId INTEGER,
165             nonRepeaters INTEGER,
166             maxRepetitions INTEGER,
167             varbindlist VARBINDS
168             }
169             VARBINDS ::= SEQUENCE OF SEQUENCE {
170             oid OBJECT IDENTIFIER,
171             value CHOICE {
172             integer INTEGER,
173             string STRING,
174             oid OBJECT IDENTIFIER,
175             ipaddr IPAddress,
176             counter32 Counter32,
177             guage32 Guage32,
178             timeticks TimeTicks,
179             opaque Opaque,
180             counter64 Counter64,
181             null NULL
182             }
183             }
184             ");
185             our $snmpasn = $asn->find('Message');
186             our @PDUTYPES = qw(get_request get_next_request response set_request trap get_bulk_request inform_request snmpV2_trap report);
187             our %PDUTYPES;
188             for (0..$#PDUTYPES) {
189             $PDUTYPES{$PDUTYPES[$_]} = $_
190             }
191             our @VARBINDTYPES = qw(integer string oid ipaddr counter32 guage32 timeticks opaque counter64 null);
192              
193             $Net::Frame::Layer::UDP::Next->{161} = "SNMP";
194             $Net::Frame::Layer::UDP::Next->{162} = "SNMP";
195              
196             sub new {
197             shift->SUPER::new(
198 1     1 1 25 version => NF_SNMP_VERSION_2,
199             community => 'public',
200             requestId => getRandom16bitsInt(),
201             errorStatus => 0,
202             errorIndex => 0,
203             varbindlist => [],
204             @_,
205             pdu_type => NF_SNMP_PDUTYPE_GET,
206             );
207             }
208              
209             sub Get {
210             shift->SUPER::new(
211 1     1 1 534 version => NF_SNMP_VERSION_2,
212             community => 'public',
213             requestId => getRandom16bitsInt(),
214             errorStatus => 0,
215             errorIndex => 0,
216             varbindlist => [],
217             @_,
218             pdu_type => NF_SNMP_PDUTYPE_GET,
219             );
220             }
221              
222             sub GetNext {
223             shift->SUPER::new(
224 1     1 1 617 version => NF_SNMP_VERSION_2,
225             community => 'public',
226             requestId => getRandom16bitsInt(),
227             errorStatus => 0,
228             errorIndex => 0,
229             varbindlist => [],
230             @_,
231             pdu_type => NF_SNMP_PDUTYPE_GETNEXT,
232             );
233             }
234              
235             sub Response {
236             shift->SUPER::new(
237 0     0 1 0 version => NF_SNMP_VERSION_2,
238             community => 'public',
239             requestId => getRandom16bitsInt(),
240             errorStatus => 0,
241             errorIndex => 0,
242             varbindlist => [],
243             @_,
244             pdu_type => NF_SNMP_PDUTYPE_RESPONSE,
245             );
246             }
247              
248             sub Set {
249             shift->SUPER::new(
250 1     1 1 649 version => NF_SNMP_VERSION_2,
251             community => 'public',
252             requestId => getRandom16bitsInt(),
253             errorStatus => 0,
254             errorIndex => 0,
255             varbindlist => [],
256             @_,
257             pdu_type => NF_SNMP_PDUTYPE_SET,
258             );
259             }
260              
261             sub Trap {
262             shift->SUPER::new(
263 1     1 1 598 version => NF_SNMP_VERSION_1,
264             community => 'public',
265             entOid => '1.3.6.1.4.1.50000',
266             agentAddr => '127.0.0.1',
267             genericTrap => NF_SNMP_GENERICTRAP_ENTERPRISESPECIFIC,
268             specificTrap => 1,
269             timeticks => time(),
270             varbindlist => [],
271             @_,
272             pdu_type => NF_SNMP_PDUTYPE_TRAP,
273             );
274             }
275              
276             sub GetBulk {
277             shift->SUPER::new(
278 1     1 1 565 version => NF_SNMP_VERSION_2,
279             community => 'public',
280             requestId => getRandom16bitsInt(),
281             nonRepeaters => 0,
282             maxRepetitions => 0,
283             varbindlist => [],
284             @_,
285             pdu_type => NF_SNMP_PDUTYPE_GETBULK,
286             );
287             }
288              
289             sub Inform {
290             shift->SUPER::new(
291 1     1 1 583 version => NF_SNMP_VERSION_2,
292             community => 'public',
293             requestId => getRandom16bitsInt(),
294             errorStatus => 0,
295             errorIndex => 0,
296             varbindlist => [],
297             @_,
298             pdu_type => NF_SNMP_PDUTYPE_INFORM,
299             );
300             }
301              
302             sub V2Trap {
303             shift->SUPER::new(
304 1     1 1 625 version => NF_SNMP_VERSION_2,
305             community => 'public',
306             requestId => getRandom16bitsInt(),
307             errorStatus => 0,
308             errorIndex => 0,
309             varbindlist => [],
310             @_,
311             pdu_type => NF_SNMP_PDUTYPE_V2TRAP,
312             );
313             }
314              
315             sub Report {
316             shift->SUPER::new(
317 0     0 1 0 version => NF_SNMP_VERSION_2,
318             community => 'public',
319             requestId => getRandom16bitsInt(),
320             errorStatus => 0,
321             errorIndex => 0,
322             varbindlist => [],
323             @_,
324             pdu_type => NF_SNMP_PDUTYPE_REPORT,
325             );
326             }
327              
328             sub match {
329 0     0 1 0 my $self = shift;
330 0         0 my ($with) = @_;
331 0         0 my $sPduType = $self->pdu_type;
332 0         0 my $sReqId = $self->requestId;
333 0         0 my $wPduType = $with->pdu_type;
334 0         0 my $wReqId = $with->requestId;
335 0 0 0     0 if ((($sPduType == NF_SNMP_PDUTYPE_GET)
      0        
      0        
336             || ($sPduType == NF_SNMP_PDUTYPE_GETNEXT)
337             || ($sPduType == NF_SNMP_PDUTYPE_SET)
338             || ($sPduType == NF_SNMP_PDUTYPE_GETBULK)
339             || ($sPduType == NF_SNMP_PDUTYPE_INFORM))
340              
341             && ($wPduType == NF_SNMP_PDUTYPE_RESPONSE)
342             && ($sReqId == $wReqId)) {
343 0         0 return 1;
344             }
345 0         0 0;
346             }
347              
348             # XXX: may be better, by keying on type also
349 0     0 1 0 sub getKey { shift->layer }
350 0     0 1 0 sub getKeyReverse { shift->layer }
351              
352             sub getLength {
353 0     0 1 0 my $self = shift;
354              
355 0         0 return length($self->raw)
356             }
357              
358             sub pack {
359 1     1 1 467 my $self = shift;
360              
361 1         4 my $raw;
362 1 50 33     7 if (($self->pdu_type == NF_SNMP_PDUTYPE_GET)
    0 33        
    0 0        
      0        
      0        
      0        
363             || ($self->pdu_type == NF_SNMP_PDUTYPE_GETNEXT)
364             || ($self->pdu_type == NF_SNMP_PDUTYPE_RESPONSE)
365             || ($self->pdu_type == NF_SNMP_PDUTYPE_SET)
366             || ($self->pdu_type == NF_SNMP_PDUTYPE_INFORM)
367             || ($self->pdu_type == NF_SNMP_PDUTYPE_V2TRAP)
368             || ($self->pdu_type == NF_SNMP_PDUTYPE_REPORT)) {
369 1         42 $raw = $snmpasn->encode(
370             version => $self->version,
371             community => $self->community,
372             pdu_type => {
373             $PDUTYPES[$self->pdu_type] => {
374             requestId => $self->requestId,
375             errorStatus => $self->errorStatus,
376             errorIndex => $self->errorIndex,
377             varbindlist => [$self->varbindlist]
378             }
379             }
380             );
381 1 50       540 if (defined($snmpasn->error)) {
382 0         0 print $snmpasn->error;
383             return
384 0         0 }
385             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_TRAP) {
386 0         0 my $agent_addr;
387 0 0       0 if ($self->agent_addr =~ /:/) {
388 0         0 $agent_addr = inet6Aton($self->agent_addr)
389             } else {
390 0         0 $agent_addr = inetAton($self->agent_addr)
391             }
392 0         0 $raw = $snmpasn->encode(
393             version => $self->version,
394             community => $self->community,
395             pdu_type => {
396             $PDUTYPES[$self->pdu_type] => {
397             entOid => $self->entOid,
398             agentAddr => $agent_addr,
399             genericTrap => $self->genericTrap,
400             specificTrap => $self->specificTrap,
401             timeticks => $self->timeticks,
402             varbindlist => [$self->varbindlist]
403             }
404             }
405             );
406 0 0       0 if (defined($snmpasn->error)) {
407 0         0 print $snmpasn->error;
408             return
409 0         0 }
410             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_GETBULK) {
411 0         0 $raw = $snmpasn->encode(
412             version => $self->version,
413             community => $self->community,
414             pdu_type => {
415             $PDUTYPES[$self->pdu_type] => {
416             requestId => $self->requestId,
417             nonRepeaters => $self->nonRepeaters,
418             maxRepetitions => $self->maxRepetitions,
419             varbindlist => [$self->varbindlist]
420             }
421             }
422             );
423 0 0       0 if (defined($snmpasn->error)) {
424 0         0 print $snmpasn->error;
425             return
426 0         0 }
427             }
428              
429 1         23 return $self->raw($raw);
430             }
431              
432             sub unpack {
433 1     1 1 18 my $self = shift;
434              
435 1         5 my $pdu = $snmpasn->decode($self->raw);
436 1 50       469 if (defined($snmpasn->error)) {
437 0         0 print $snmpasn->error;
438             return
439 0         0 }
440              
441 1         11 $self->version($pdu->{version});
442 1         15 $self->community($pdu->{community});
443 1         10 my $pdutype = sprintf "%s", keys(%{$pdu->{pdu_type}});
  1         7  
444 1         6 $self->pdu_type($PDUTYPES{$pdutype});
445 1 50 33     23 if (($self->pdu_type == NF_SNMP_PDUTYPE_GET)
    0 33        
    0 0        
      0        
      0        
      0        
446             || ($self->pdu_type == NF_SNMP_PDUTYPE_GETNEXT)
447             || ($self->pdu_type == NF_SNMP_PDUTYPE_RESPONSE)
448             || ($self->pdu_type == NF_SNMP_PDUTYPE_SET)
449             || ($self->pdu_type == NF_SNMP_PDUTYPE_INFORM)
450             || ($self->pdu_type == NF_SNMP_PDUTYPE_V2TRAP)
451             || ($self->pdu_type == NF_SNMP_PDUTYPE_REPORT)) {
452 1         24 $self->requestId($pdu->{pdu_type}->{$pdutype}->{requestId});
453 1         14 $self->errorStatus($pdu->{pdu_type}->{$pdutype}->{errorStatus});
454 1         14 $self->errorIndex($pdu->{pdu_type}->{$pdutype}->{errorIndex});
455 1         13 $self->varbindlist($pdu->{pdu_type}->{$pdutype}->{varbindlist});
456             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_TRAP) {
457 0         0 $self->entOid($pdu->{pdu_type}->{$pdutype}->{entOid});
458 0         0 $self->agentAddr(_inetNtoa($pdu->{pdu_type}->{$pdutype}->{agentAddr}));
459 0         0 $self->genericTrap($pdu->{pdu_type}->{$pdutype}->{genericTrap});
460 0         0 $self->specificTrap($pdu->{pdu_type}->{$pdutype}->{specificTrap});
461 0         0 $self->timeticks($pdu->{pdu_type}->{$pdutype}->{timeticks});
462 0         0 $self->varbindlist($pdu->{pdu_type}->{$pdutype}->{varbindlist});
463             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_GETBULK) {
464 0         0 $self->requestId($pdu->{pdu_type}->{$pdutype}->{requestId});
465 0         0 $self->nonRepeaters($pdu->{pdu_type}->{$pdutype}->{nonRepeaters});
466 0         0 $self->maxRepetitions($pdu->{pdu_type}->{$pdutype}->{maxRepetitions});
467 0         0 $self->varbindlist($pdu->{pdu_type}->{$pdutype}->{varbindlist});
468             }
469              
470 1         19 return $self;
471             }
472              
473             sub encapsulate {
474 1     1 1 8 my $self = shift;
475              
476 1 50       17 return $self->nextLayer if $self->nextLayer;
477              
478 1 50       20 if ($self->payload) {
479 0         0 return 'SNMP';
480             }
481              
482 1         16 NF_LAYER_NONE;
483             }
484              
485             sub print {
486 15     15 1 3877 my $self = shift;
487              
488 15         93 my $l = $self->layer;
489              
490 15         219 my $buf = sprintf
491             "$l: version:%d community:%s pdu:%s\n",
492             $self->version, $self->community, $PDUTYPES[$self->pdu_type];
493              
494 15 100 100     713 if (($self->pdu_type == NF_SNMP_PDUTYPE_GET)
    100 66        
    50 100        
      100        
      100        
      66        
495             || ($self->pdu_type == NF_SNMP_PDUTYPE_GETNEXT)
496             || ($self->pdu_type == NF_SNMP_PDUTYPE_RESPONSE)
497             || ($self->pdu_type == NF_SNMP_PDUTYPE_SET)
498             || ($self->pdu_type == NF_SNMP_PDUTYPE_INFORM)
499             || ($self->pdu_type == NF_SNMP_PDUTYPE_V2TRAP)
500             || ($self->pdu_type == NF_SNMP_PDUTYPE_REPORT)) {
501 11         578 $buf .= sprintf
502             "$l: requestId:%d errorStatus:%d errorIndex:%d\n".
503             "$l: varbindlist:",
504             $self->requestId, $self->errorStatus, $self->errorIndex;
505 11 50       362 if ($self->varbindlist != 0) {
506 0         0 for my $varbind ($self->varbindlist) {
507 0         0 $buf .= sprintf "\n$l: %s = ", $varbind->{oid};
508 0         0 my $valueType = sprintf "%s", keys(%{$varbind->{value}});
  0         0  
509 0 0       0 if ($valueType eq 'ipaddr') {
    0          
    0          
510 0         0 $buf .= sprintf "%s (%s)", _inetNtoa($varbind->{value}->{$valueType}), $valueType
511             } elsif ($valueType eq 'null') {
512 0         0 $buf .= sprintf "(%s)", $valueType
513             } elsif ($varbind->{value}->{$valueType} =~ /[\x00-\x1f\x7f-\xff]/s) {
514 0         0 $buf .= sprintf "0x%s ([hex]%s)", CORE::unpack ("H*", $varbind->{value}->{$valueType}), $valueType
515             } else {
516 0         0 $buf .= sprintf "%s (%s)", $varbind->{value}->{$valueType}, $valueType
517             }
518             }
519             }
520             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_TRAP) {
521 2         223 $buf .= sprintf
522             "$l: entOid:%s agentAddr:%s genericTrap:%s\n".
523             "$l: specificTrap:%d timeTicks:%d\n".
524             "$l: varbindlist:",
525             $self->entOid, $self->agentAddr, $self->genericTrap,
526             $self->specificTrap, $self->timeticks;
527 2 50       98 if ($self->varbindlist != 0) {
528 0         0 for my $varbind ($self->varbindlist) {
529 0         0 $buf .= sprintf "\n$l: %s = ", $varbind->{oid};
530 0         0 my $valueType = sprintf "%s", keys(%{$varbind->{value}});
  0         0  
531 0 0       0 if ($valueType eq 'ipaddr') {
    0          
    0          
532 0         0 $buf .= sprintf "%s (%s)", _inetNtoa($varbind->{value}->{$valueType}), $valueType
533             } elsif ($valueType eq 'null') {
534 0         0 $buf .= sprintf "(%s)", $valueType
535             } elsif ($varbind->{value}->{$valueType} =~ /[\x00-\x1f\x7f-\xff]/s) {
536 0         0 $buf .= sprintf "0x%s ([hex]%s)", CORE::unpack ("H*", $varbind->{value}->{$valueType}), $valueType
537             } else {
538 0         0 $buf .= sprintf "%s (%s)", $varbind->{value}->{$valueType}, $valueType
539             }
540             }
541             }
542             } elsif ($self->pdu_type == NF_SNMP_PDUTYPE_GETBULK) {
543 2         186 $buf .= sprintf
544             "$l: requestId:%d nonRepeaters:%d maxRepetitions:%d\n".
545             "$l: varbindlist:",
546             $self->requestId, $self->nonRepeaters, $self->maxRepetitions;
547 2 50       46 if ($self->varbindlist != 0) {
548 0         0 for my $varbind ($self->varbindlist) {
549 0         0 $buf .= sprintf "\n$l: %s = ", $varbind->{oid};
550 0         0 my $valueType = sprintf "%s", keys(%{$varbind->{value}});
  0         0  
551 0 0       0 if ($valueType eq 'ipaddr') {
    0          
    0          
552 0         0 $buf .= sprintf "%s (%s)", _inetNtoa($varbind->{value}->{$valueType}), $valueType
553             } elsif ($valueType eq 'null') {
554 0         0 $buf .= sprintf "(%s)", $valueType
555             } elsif ($varbind->{value}->{$valueType} =~ /[\x00-\x1f\x7f-\xff]/s) {
556 0         0 $buf .= sprintf "0x%s ([hex]%s)", CORE::unpack ("H*", $varbind->{value}->{$valueType}), $valueType
557             } else {
558 0         0 $buf .= sprintf "%s (%s)", $varbind->{value}->{$valueType}, $valueType
559             }
560             }
561             }
562             }
563              
564 15         3771 return $buf;
565             }
566              
567             ####
568              
569             sub varbinds {
570 11     11 1 4140 my $self = shift;
571              
572 11         147 my %params = (
573             oid => '1.3.6.1.4.1.50000',
574             type => $VARBINDTYPES[NF_SNMP_VARBINDTYPE_INTEGER],
575             value => 1,
576             );
577 11 50       31 if (@_ == 1) {
578             return(undef)
579 0         0 } else {
580 11         39 my %cfg = @_;
581 11         33 for (keys(%cfg)) {
582 33 100       162 if (/^-?oid$/i) {
    100          
    50          
583 11         41 $params{'oid'} = $cfg{$_}
584             } elsif (/^-?type$/i) {
585 11 50       23 if (defined($VARBINDTYPES[$cfg{$_}])) {
586 11         36 $params{'type'} = $VARBINDTYPES[$cfg{$_}]
587             } else {
588 0         0 print "$cfg{$_}\n";
589             return undef
590 0         0 }
591             } elsif (/^-?value$/i) {
592 11         35 $params{'value'} = $cfg{$_}
593             }
594             }
595             }
596              
597 11 100       182 if ($params{'type'} eq 'ipaddr') {
598 1         9 $params{'value'} = inetAton $params{'value'}
599             }
600              
601 11 100       53 if ($params{'type'} eq 'null') {
602 1         3 $params{'value'} = 1
603             }
604              
605 11         51 my %hash = (
606             oid => $params{'oid'},
607             value => {
608             $params{'type'} => $params{'value'}
609             }
610             );
611              
612 11         54 return \%hash;
613             }
614              
615             sub v2trap_varbinds {
616 1     1 1 324 my $self = shift;
617              
618 1         10 my %params = (
619             oid => '1.3.6.1.4.1.50000',
620             timeticks => time(),
621             );
622 1 50       4 if (@_ == 1) {
623             return(undef)
624 0         0 } else {
625 1         3 my %cfg = @_;
626 1         5 for (keys(%cfg)) {
627 2 100       14 if (/^-?oid$/i) {
    50          
628 1         4 $params{'oid'} = $cfg{$_}
629             } elsif (/^-?time(?:ticks)?$/i) {
630 1         4 $params{'timeticks'} = $cfg{$_}
631             }
632             }
633             }
634              
635 1         7 my %hash1 = (
636             oid => '1.3.6.1.2.1.1.3.0',
637             value => {
638             timeticks => $params{'timeticks'}
639             }
640             );
641              
642 1         17 my %hash2 = (
643             oid => '1.3.6.1.6.3.1.1.4.1.0',
644             value => {
645             oid => $params{'oid'}
646             }
647             );
648              
649 1         3 my @varbinds;
650 1         10 push @varbinds, \%hash1;
651 1         2 push @varbinds, \%hash2;
652              
653 1         6 return @varbinds;
654             }
655              
656             sub _inetNtoa {
657 1     1   434 my ($addr) = @_;
658              
659 1 50       10 if ($Socket::VERSION >= 1.94) {
660 1         2 my $name;
661 1 50       4 if (length($addr) == 4) {
662 1         7 $name = Socket::pack_sockaddr_in(0, $addr)
663             } else {
664 0         0 $name = Socket::pack_sockaddr_in6(0, $addr)
665             }
666 1         1510 my ($err, $address) = Socket::getnameinfo($name, $NI_NUMERICHOST);
667 1 50       11 if (defined($address)) {
668 1         9 return $address
669             } else {
670             # print "getnameinfo($addr) failed - $err";
671             return undef
672 0           }
673             } else {
674 0 0         if (length($addr) == 4) {
675 0           return inet_ntoa($addr)
676             } else {
677             # Poor man's IPv6
678 0           return join ':', (CORE::unpack '(a4)*', CORE::unpack ('H*', $addr))
679             }
680             }
681             }
682              
683             1;
684              
685             __END__