=head1 NAME Convert::BER::XS - I low level BER decoding =head1 SYNOPSIS use Convert::BER::XS ':all'; my $ber = ber_decode $buf or die "unable to decode SNMP v1/v2c Message"; # the above results in a data structure consisting of (class, tag, # constructed, data) tuples. here is such a message, SNMPv1 trap # with a cisoc mac change notification [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, [ [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 0 ], # snmp version 1 [ ASN_UNIVERSAL, 4, 0, "public" ], # community [ ASN_CONTEXT, 4, 1, # CHOICE, constructed [ [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.2" ], # enterprise oid [ ASN_APPLICATION, 0, 0, "\x0a\x00\x00\x01" ], # SNMP IpAddress, 10.0.0.1 [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 6 ], # generic trap [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 1 ], # specific trap [ ASN_APPLICATION, ASN_TIMETICKS, 0, 1817903850 ], # SNMP TimeTicks [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # the varbindlist [ [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # a single varbind, "key value" pair [ [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.1.1.8.1.2.1" ], # the oid [ ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "...data..." # the value ] ] ], ... # let's decode it a bit with some helper functions my $msg = ber_is_seq $ber or die "SNMP message does not start with a sequence"; ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER32, 0 or die "SNMP message does not start with snmp version\n"; # message is SNMP v1 or v2c? if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) { # message is v1 trap? if (ber_is $msg->[2], ASN_CONTEXT, 4, 1) { my $trap = $msg->[2][BER_DATA]; # check whether trap is a cisco mac notification mac changed message if ( (ber_is_oid $trap->[0], "1.3.6.1.4.1.9.9.215.2") # cmnInterfaceObjects and (ber_is_i32 $trap->[2], 6) and (ber_is_i32 $trap->[3], 1) # mac changed msg ) { ... and so on =head1 DESCRIPTION This module implements a I low level BER/DER decoder, and in the future, probably also an encoder (tell me if you want an encoder, this might speed up the process of getting one). If is tuned for low memory and high speed, while still maintaining some level of user-friendlyness. Currently, not much is documented, as this is an initial release to reserve CPAN namespace, stay tuned for a few days. =head2 RELATIONSHIP TO L and L This module is I the XS version of L, but a different take at doing the same thing. I imagine this module would be a good base for speeding up either fo these, or write a similar module, or write your own LDAP or SNMP module for example. =cut package Convert::BER::XS; use common::sense; use XSLoader (); use Exporter qw(import); our $VERSION = '0.0'; XSLoader::load __PACKAGE__, $VERSION; our %EXPORT_TAGS = ( all => [qw( ber_decode ber_is ber_is_seq ber_is_i32 ber_is_oid BER_CLASS BER_TAG BER_CONSTRUCTED BER_DATA ASN_BOOLEAN ASN_INTEGER32 ASN_BIT_STRING ASN_OCTET_STRING ASN_NULL ASN_OBJECT_IDENTIFIER ASN_TAG_BER ASN_TAG_MASK ASN_CONSTRUCTED ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE ASN_CLASS_MASK ASN_CLASS_SHIFT ASN_SEQUENCE ASN_IPADDRESS ASN_COUNTER32 ASN_UNSIGNED32 ASN_TIMETICKS ASN_OPAQUE ASN_COUNTER64 )], ); our @EXPORT_OK = map @$_, values %EXPORT_TAGS; 1; =head1 AUTHOR Marc Lehmann http://software.schmorp.de/pkg/Convert-BER-XS =cut