ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-BER-XS/XS.pm
(Generate patch)

Comparing Convert-BER-XS/XS.pm (file contents):
Revision 1.36 by root, Sun Apr 21 00:36:11 2019 UTC vs.
Revision 1.54 by root, Tue Apr 23 21:03:12 2019 UTC

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?
108 BER_CLASS BER_TAG BER_FLAGS BER_DATA 108 BER_CLASS BER_TAG BER_FLAGS BER_DATA
109 109
110=item C<:const_asn> 110=item C<:const_asn>
111 111
112ASN class values (these are C<0>, C<1>, C<2> and C<3>, respectively - 112ASN class values (these are C<0>, C<1>, C<2> and C<3>, respectively -
113exactly thw two topmost bits from the identifier octet shifted 6 bits to 113exactly the two topmost bits from the identifier octet shifted 6 bits to
114the right): 114the right):
115 115
116 ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE 116 ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE
117 117
118ASN tag values (some of which are aliases, such as C<ASN_OID>). Their 118ASN tag values (some of which are aliases, such as C<ASN_OID>). Their
296Also, since BER is self-delimited, this can be used to decode multiple BER 296Also, since BER is self-delimited, this can be used to decode multiple BER
297values joined together. 297values joined together.
298 298
299=item $bindata = ber_encode $tuple[, $profile] 299=item $bindata = ber_encode $tuple[, $profile]
300 300
301Encodes the BER tuple into a BER/DER data structure. AS with 301Encodes the BER tuple into a BER/DER data structure. As with
302Cyber_decode>, an optional profile can be given. 302Cyber_decode>, an optional profile can be given.
303 303
304The encoded data should be both BER and DER ("shortest form") compliant 304The encoded data should be both BER and DER ("shortest form") compliant
305unless the input says otherwise (e.g. it uses constructed strings). 305unless the input says otherwise (e.g. it uses constructed strings).
306 306
412use Exporter qw(import); 412use Exporter qw(import);
413 413
414our $VERSION; 414our $VERSION;
415 415
416BEGIN { 416BEGIN {
417 $VERSION = '1.0'; 417 $VERSION = 1.11;
418 XSLoader::load __PACKAGE__, $VERSION; 418 XSLoader::load __PACKAGE__, $VERSION;
419} 419}
420 420
421our %EXPORT_TAGS = ( 421our %EXPORT_TAGS = (
422 const_index => [qw( 422 const_index => [qw(
468 468
469$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS); 469$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
470$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT); 470$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
471$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT); 471$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
472$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT); 472$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
473$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS);
474 473
475=head2 DEBUGGING 474=head2 DEBUGGING
476 475
477To aid debugging, you cna call the C<ber_dump> function to print a "nice" 476To aid debugging, you cna call the C<ber_dump> function to print a "nice"
478representation to STDOUT. 477representation to STDOUT.
479 478
480=over 479=over
481 480
482=item Convert::BER::XS::ber_dump $tuple[, $profile[, $prefix]] 481=item ber_dump $tuple[, $profile[, $prefix]]
483 482
484In addition to specifying the BER C<$tuple> to dump, youc an also specify 483In addition to specifying the BER C<$tuple> to dump, you can also specify
485a C<$profile> and a C<$prefix> string that is printed in front of each line. 484a C<$profile> and a C<$prefix> string that is printed in front of each line.
486 485
487If C<$profile> is C<$Convert::BER::XS::SNMP_PROFILE>, then C<ber_dump> 486If C<$profile> is C<$Convert::BER::XS::SNMP_PROFILE>, then C<ber_dump>
488will try to improve its output for SNMP data. 487will try to improve its output for SNMP data.
489 488
496Example output: 495Example output:
497 496
498 SEQUENCE 497 SEQUENCE
499 | OCTET_STRING bytes 800063784300454045045400000001 498 | OCTET_STRING bytes 800063784300454045045400000001
500 | OCTET_STRING bytes 499 | OCTET_STRING bytes
501 | CONTEXT (7) bytes CONSTRUCTED 500 | CONTEXT (7) CONSTRUCTED
502 | | INTEGER int 1058588941 501 | | INTEGER int 1058588941
503 | | INTEGER int 0 502 | | INTEGER int 0
504 | | INTEGER int 0 503 | | INTEGER int 0
505 | | SEQUENCE 504 | | SEQUENCE
506 | | | SEQUENCE 505 | | | SEQUENCE
507 | | | | OID oid 1.3.6.1.2.1.1.3.0 506 | | | | OID oid 1.3.6.1.2.1.1.3.0
508 | | | | TIMETICKS int 638085796 507 | | | | TIMETICKS int 638085796
509 508
509=back
510
510=cut 511=cut
511 512
512# reverse enum, very slow and ugly hack 513# reverse enum, very slow and ugly hack
513sub _re { 514sub _re {
514 my ($export_tag, $value) = @_; 515 my ($export_tag, $value) = @_;
538 my $type = _re const_ber_type => $profile->get ($ber->[BER_CLASS], $ber->[BER_TAG]); 539 my $type = _re const_ber_type => $profile->get ($ber->[BER_CLASS], $ber->[BER_TAG]);
539 my $data = $ber->[BER_DATA]; 540 my $data = $ber->[BER_DATA];
540 541
541 if ($profile == $SNMP_PROFILE and $ber->[BER_CLASS] == ASN_APPLICATION) { 542 if ($profile == $SNMP_PROFILE and $ber->[BER_CLASS] == ASN_APPLICATION) {
542 $tag = _re const_snmp => $ber->[BER_TAG]; 543 $tag = _re const_snmp => $ber->[BER_TAG];
543 $asn = 1; 544 } elsif (!$asn) {
545 $tag = "$class ($tag)";
544 } 546 }
545
546 $asn or $tag = "$class ($tag)";
547 547
548 $class =~ s/^ASN_//; 548 $class =~ s/^ASN_//;
549 $tag =~ s/^(ASN_|SNMP_)//; 549 $tag =~ s/^(ASN_|SNMP_)//;
550 $type =~ s/^BER_TYPE_//; 550 $type =~ s/^BER_TYPE_//;
551 551
552 if ($ber->[BER_FLAGS]) { 552 if ($ber->[BER_FLAGS]) {
553 printf "$indent%-16.16s %-6.6s CONSTRUCTED\n", $tag, lc $type; 553 printf "$indent%-16.16s\n", $tag;
554 &_ber_dump ($_, $profile, "$indent| ") 554 &_ber_dump ($_, $profile, "$indent| ")
555 for @$data; 555 for @$data;
556 } else { 556 } else {
557 if ($data =~ y/\x20-\x7e//c > 10 or $data =~ /\x00./s) { 557 if ($data =~ y/\x20-\x7e//c / (length $data || 1) > 0.2 or $data =~ /\x00./s) {
558 # assume binary 558 # assume binary
559 $data = unpack "H*", $data; 559 $data = unpack "H*", $data;
560 substr $data, 40, 1e9, "..." if 40 < length $data;
561 } else { 560 } else {
562 $data =~ s/[^\x20-\x7e]/./g; 561 $data =~ s/[^\x20-\x7e]/./g;
563 $data = "\"$data\"" if $type =~ /string/i; 562 $data = "\"$data\"" if $tag =~ /string/i || !length $data;
564 substr $data, 40, 1e9, "..." if 40 < length $data;
565 } 563 }
564
565 substr $data, 40, 1e9, "..." if 40 < length $data;
566 566
567 printf "$indent%-16.16s %-6.6s %s\n", $tag, lc $type, $data; 567 printf "$indent%-16.16s %-6.6s %s\n", $tag, lc $type, $data;
568 } 568 }
569 } 569 }
570} 570}
640 640
641Returns the BER type mapped to the given C<$class>/C<$tag> combination. 641Returns the BER type mapped to the given C<$class>/C<$tag> combination.
642 642
643=back 643=back
644 644
645=head2 BER TYPES 645=head2 BER Types
646 646
647This lists the predefined BER types - you can map any C<CLASS>/C<TAG> 647This lists the predefined BER types. BER types are formatters used
648combination to any C<BER_TYPE_*>. 648internally to format and encode BER values. You can assign any C<BER_TYPE>
649to any C<CLASS>/C<TAG> combination tgo change how that tag is decoded or
650encoded.
649 651
650=over 652=over
651 653
652=item C<BER_TYPE_BYTES> 654=item C<BER_TYPE_BYTES>
653 655
730 732
731 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS); 733 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
732 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT); 734 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
733 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT); 735 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
734 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT); 736 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
735 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS); 737 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_BYTES);
736 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT); 738 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
737 739
738=head2 LIMITATIONS/NOTES 740=head2 LIMITATIONS/NOTES
739 741
740This module can only en-/decode 64 bit signed and unsigned integers, and 742This module can only en-/decode 64 bit signed and unsigned integers, and
741only when your perl supports those. 743only when your perl supports those. So no UUID OIDs for now (unless you
744map the C<OBJECT IDENTIFIER> tag to something other than C<BER_TYPE_OID>).
742 745
743This module does not generally care about ranges, i.e. it will happily 746This module does not generally care about ranges, i.e. it will happily
744de-/encode 64 bit integers into an C<ASN_INTEGER> value, or a negative 747de-/encode 64 bit integers into an C<ASN_INTEGER> value, or a negative
745number into an C<SNMP_COUNTER64>. 748number into an C<SNMP_COUNTER64>.
746 749
747OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is 750OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is
748much larger than e.g. the one imposed by SNMP or other protocols,a nd is 751much larger than e.g. the one imposed by SNMP or other protocols, and is
749about 4kB. 752about 4kB.
750 753
751Indefinite length encoding is not supported. 754Indefinite length encoding is not supported.
752 755
753Constructed strings are decoded just fine, but there should be a way to 756Constructed strings are decoded just fine, but there should be a way to
754join them for convenience. 757join them for convenience.
755 758
756REAL values are not supported and will currently croak. 759REAL values are not supported and will currently croak.
757 760
758The encoder and decoder tend to accept more formats than should be 761The encoder and decoder tend to accept more formats than should be
759strictly supported. 762strictly supported - security sensitive applications are strongly advised
763to review the code first.
760 764
761This module has undergone little to no testing so far. 765This module has undergone little to no testing so far.
762 766
763=head2 ITHREADS SUPPORT 767=head2 ITHREADS SUPPORT
764 768

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines