… | |
… | |
8 | |
8 | |
9 | my $ber = ber_decode $buf, $Convert::BER::XS::SNMP_PROFILE |
9 | my $ber = ber_decode $buf, $Convert::BER::XS::SNMP_PROFILE |
10 | or die "unable to decode SNMP message"; |
10 | or die "unable to decode SNMP message"; |
11 | |
11 | |
12 | # The above results in a data structure consisting of |
12 | # The above results in a data structure consisting of |
13 | # (class, tag, flags, data) |
13 | # (class, tag, flags, data) |
14 | # tuples. Below is such a message, SNMPv1 trap |
14 | # tuples. Below is such a message, SNMPv1 trap |
15 | # with a Cisco mac change notification. |
15 | # with a Cisco mac change notification. |
16 | # Did you know that Cisco is in the news almost |
16 | # Did you know that Cisco is in the news almost |
17 | # every week because of some backdoor password |
17 | # every week because of some backdoor password |
18 | # or other extremely stupid security bug? |
18 | # or other extremely stupid security bug? |
… | |
… | |
477 | To aid debugging, you cna call the C<ber_dump> function to print a "nice" |
477 | To aid debugging, you cna call the C<ber_dump> function to print a "nice" |
478 | representation to STDOUT. |
478 | representation to STDOUT. |
479 | |
479 | |
480 | =over |
480 | =over |
481 | |
481 | |
482 | =item Convert::BER::XS::ber_dump $tuple[, $profile[, $prefix]] |
482 | =item ber_dump $tuple[, $profile[, $prefix]] |
483 | |
483 | |
484 | In addition to specifying the BER C<$tuple> to dump, youc an also specify |
484 | In addition to specifying the BER C<$tuple> to dump, youc an also specify |
485 | a C<$profile> and a C<$prefix> string that is printed in front of each line. |
485 | a C<$profile> and a C<$prefix> string that is printed in front of each line. |
486 | |
486 | |
487 | If C<$profile> is C<$Convert::BER::XS::SNMP_PROFILE>, then C<ber_dump> |
487 | If C<$profile> is C<$Convert::BER::XS::SNMP_PROFILE>, then C<ber_dump> |
… | |
… | |
505 | | | SEQUENCE |
505 | | | SEQUENCE |
506 | | | | SEQUENCE |
506 | | | | SEQUENCE |
507 | | | | | OID oid 1.3.6.1.2.1.1.3.0 |
507 | | | | | OID oid 1.3.6.1.2.1.1.3.0 |
508 | | | | | TIMETICKS int 638085796 |
508 | | | | | TIMETICKS int 638085796 |
509 | |
509 | |
|
|
510 | =back |
|
|
511 | |
510 | =cut |
512 | =cut |
511 | |
513 | |
512 | # reverse enum, very slow and ugly hack |
514 | # reverse enum, very slow and ugly hack |
513 | sub _re { |
515 | sub _re { |
514 | my ($export_tag, $value) = @_; |
516 | my ($export_tag, $value) = @_; |
… | |
… | |
538 | my $type = _re const_ber_type => $profile->get ($ber->[BER_CLASS], $ber->[BER_TAG]); |
540 | my $type = _re const_ber_type => $profile->get ($ber->[BER_CLASS], $ber->[BER_TAG]); |
539 | my $data = $ber->[BER_DATA]; |
541 | my $data = $ber->[BER_DATA]; |
540 | |
542 | |
541 | if ($profile == $SNMP_PROFILE and $ber->[BER_CLASS] == ASN_APPLICATION) { |
543 | if ($profile == $SNMP_PROFILE and $ber->[BER_CLASS] == ASN_APPLICATION) { |
542 | $tag = _re const_snmp => $ber->[BER_TAG]; |
544 | $tag = _re const_snmp => $ber->[BER_TAG]; |
543 | $asn = 1; |
545 | } elsif (!$asn) { |
|
|
546 | $tag = "$class ($tag)"; |
544 | } |
547 | } |
545 | |
|
|
546 | $asn or $tag = "$class ($tag)"; |
|
|
547 | |
548 | |
548 | $class =~ s/^ASN_//; |
549 | $class =~ s/^ASN_//; |
549 | $tag =~ s/^(ASN_|SNMP_)//; |
550 | $tag =~ s/^(ASN_|SNMP_)//; |
550 | $type =~ s/^BER_TYPE_//; |
551 | $type =~ s/^BER_TYPE_//; |
551 | |
552 | |
552 | if ($ber->[BER_FLAGS]) { |
553 | if ($ber->[BER_FLAGS]) { |
553 | printf "$indent%-16.16s %-6.6s CONSTRUCTED\n", $tag, lc $type; |
554 | printf "$indent%-16.16s %-6.6s CONSTRUCTED\n", $tag, lc $type; |
554 | &_ber_dump ($_, $profile, "$indent| ") |
555 | &_ber_dump ($_, $profile, "$indent| ") |
555 | for @$data; |
556 | for @$data; |
556 | } else { |
557 | } else { |
557 | if ($data =~ y/\x20-\x7e//c > 10 or $data =~ /\x00./s) { |
558 | if ($data =~ y/\x20-\x7e//c / (length $data || 1) > 0.2 or $data =~ /\x00./s) { |
558 | # assume binary |
559 | # assume binary |
559 | $data = unpack "H*", $data; |
560 | $data = unpack "H*", $data; |
560 | substr $data, 40, 1e9, "..." if 40 < length $data; |
|
|
561 | } else { |
561 | } else { |
562 | $data =~ s/[^\x20-\x7e]/./g; |
562 | $data =~ s/[^\x20-\x7e]/./g; |
563 | $data = "\"$data\"" if $type =~ /string/i; |
563 | $data = "\"$data\"" if $type =~ /string/i || !length $data; |
564 | substr $data, 40, 1e9, "..." if 40 < length $data; |
|
|
565 | } |
564 | } |
|
|
565 | |
|
|
566 | substr $data, 40, 1e9, "..." if 40 < length $data; |
566 | |
567 | |
567 | printf "$indent%-16.16s %-6.6s %s\n", $tag, lc $type, $data; |
568 | printf "$indent%-16.16s %-6.6s %s\n", $tag, lc $type, $data; |
568 | } |
569 | } |
569 | } |
570 | } |
570 | } |
571 | } |
… | |
… | |
640 | |
641 | |
641 | Returns the BER type mapped to the given C<$class>/C<$tag> combination. |
642 | Returns the BER type mapped to the given C<$class>/C<$tag> combination. |
642 | |
643 | |
643 | =back |
644 | =back |
644 | |
645 | |
645 | =head2 BER TYPES |
646 | =head2 BER Types |
646 | |
647 | |
647 | This lists the predefined BER types - you can map any C<CLASS>/C<TAG> |
648 | This lists the predefined BER types. BER types are formatters used |
648 | combination to any C<BER_TYPE_*>. |
649 | internally to format and encode BER values. You can assign any C<BER_TYPE> |
|
|
650 | to any C<CLASS>/C<TAG> combination tgo change how that tag is decoded or |
|
|
651 | encoded. |
649 | |
652 | |
650 | =over |
653 | =over |
651 | |
654 | |
652 | =item C<BER_TYPE_BYTES> |
655 | =item C<BER_TYPE_BYTES> |
653 | |
656 | |
… | |
… | |
736 | $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT); |
739 | $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT); |
737 | |
740 | |
738 | =head2 LIMITATIONS/NOTES |
741 | =head2 LIMITATIONS/NOTES |
739 | |
742 | |
740 | This module can only en-/decode 64 bit signed and unsigned integers, and |
743 | This module can only en-/decode 64 bit signed and unsigned integers, and |
741 | only when your perl supports those. |
744 | only when your perl supports those. So no UUID OIDs for now (unless you |
|
|
745 | map the C<OBJECT IDENTIFIER> tag to something other than C<BER_TYPE_OID>). |
742 | |
746 | |
743 | This module does not generally care about ranges, i.e. it will happily |
747 | This module does not generally care about ranges, i.e. it will happily |
744 | de-/encode 64 bit integers into an C<ASN_INTEGER> value, or a negative |
748 | de-/encode 64 bit integers into an C<ASN_INTEGER> value, or a negative |
745 | number into an C<SNMP_COUNTER64>. |
749 | number into an C<SNMP_COUNTER64>. |
746 | |
750 | |
747 | OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is |
751 | OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is |
748 | much larger than e.g. the one imposed by SNMP or other protocols,a nd is |
752 | much larger than e.g. the one imposed by SNMP or other protocols, and is |
749 | about 4kB. |
753 | about 4kB. |
750 | |
754 | |
751 | Indefinite length encoding is not supported. |
755 | Indefinite length encoding is not supported. |
752 | |
756 | |
753 | Constructed strings are decoded just fine, but there should be a way to |
757 | Constructed strings are decoded just fine, but there should be a way to |
754 | join them for convenience. |
758 | join them for convenience. |
755 | |
759 | |
756 | REAL values are not supported and will currently croak. |
760 | REAL values are not supported and will currently croak. |
757 | |
761 | |
758 | The encoder and decoder tend to accept more formats than should be |
762 | The encoder and decoder tend to accept more formats than should be |
759 | strictly supported. |
763 | strictly supported - security sensitive applications are strongly advised |
|
|
764 | to review the code first. |
760 | |
765 | |
761 | This module has undergone little to no testing so far. |
766 | This module has undergone little to no testing so far. |
762 | |
767 | |
763 | =head2 ITHREADS SUPPORT |
768 | =head2 ITHREADS SUPPORT |
764 | |
769 | |