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.27 by root, Sat Apr 20 15:27:28 2019 UTC vs.
Revision 1.34 by root, Sat Apr 20 18:38:33 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, # constructed, 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?
100 100
101=item C<:const_index> 101=item C<:const_index>
102 102
103The BER tuple array index constants: 103The BER tuple array index constants:
104 104
105 BER_CLASS BER_TAG BER_CONSTRUCTED BER_DATA 105 BER_CLASS BER_TAG BER_FLAGS BER_DATA
106 106
107=item C<:const_asn> 107=item C<:const_asn>
108 108
109ASN class values (these are C<0>, C<1>, C<2> and C<3>, respectively - 109ASN class values (these are C<0>, C<1>, C<2> and C<3>, respectively -
110exactly thw two topmost bits from the identifier octet shifted 6 bits to 110exactly thw two topmost bits from the identifier octet shifted 6 bits to
134 134
135Constants only relevant to SNMP. These are the tag values used by SNMP in 135Constants only relevant to SNMP. These are the tag values used by SNMP in
136the C<ASN_APPLICATION> namespace and have the exact numerical value as in 136the C<ASN_APPLICATION> namespace and have the exact numerical value as in
137BER/RFC 2578. 137BER/RFC 2578.
138 138
139 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_UNSIGNED32 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64 139 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_UNSIGNED32 SNMP_GAUGE32
140 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64
140 141
141=item C<:decode> 142=item C<:decode>
142 143
143C<ber_decode> and the match helper functions: 144C<ber_decode> and the match helper functions:
144 145
146 ber_decode ber-decode_prefix
145 ber_decode ber_is ber_is_seq ber_is_int ber_is_oid 147 ber_is ber_is_seq ber_is_int ber_is_oid
146 148
147=item C<:encode> 149=item C<:encode>
148 150
149C<ber_encode> and the construction helper functions: 151C<ber_encode> and the construction helper functions:
150 152
151 ber_encode ber_int 153 ber_encode
154 ber_int
152 155
153=back 156=back
154 157
155=head2 ASN.1/BER/DER/... BASICS 158=head2 ASN.1/BER/DER/... BASICS
156 159
182=head2 DECODED BER REPRESENTATION 185=head2 DECODED BER REPRESENTATION
183 186
184This module represents every BER value as a 4-element tuple (actually an 187This module represents every BER value as a 4-element tuple (actually an
185array-reference): 188array-reference):
186 189
187 [CLASS, TAG, CONSTRUCTED, DATA] 190 [CLASS, TAG, FLAGS, DATA]
188 191
189For example: 192For example:
190 193
191 [ASN_UNIVERSAL, ASN_INTEGER, 0, 177] # the integer 177 194 [ASN_UNIVERSAL, ASN_INTEGER, 0, 177] # the integer 177
192 [ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "john"] # the string "john" 195 [ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "john"] # the string "john"
193 [ASN_UNIVERSAL, ASN_OID, 0, "1.3.6.133"] # some OID 196 [ASN_UNIVERSAL, ASN_OID, 0, "1.3.6.133"] # some OID
194 [ASN_UNIVERSAL, ASN_SEQUENCE, 1, [ [ASN_UNIVERSAL... # a sequence 197 [ASN_UNIVERSAL, ASN_SEQUENCE, 1, [ [ASN_UNIVERSAL... # a sequence
195 198
196To avoid non-descriptive hardcoded array index numbers, this module 199To avoid non-descriptive hardcoded array index numbers, this module
197defines symbolic constants to access these members: C<BER_CLASS>, 200defines symbolic constants to access these members: C<BER_CLASS>,
198C<BER_TAG>, C<BER_CONSTRUCTED> and C<BER_DATA>. 201C<BER_TAG>, C<BER_FLAGS> and C<BER_DATA>.
199 202
200Also, the first three members are integers with a little caveat: for 203Also, the first three members are integers with a little caveat: for
201performance reasons, these are readonly and shared, so you must not modify 204performance reasons, these are readonly and shared, so you must not modify
202them (increment, assign to them etc.) in any way. You may modify the 205them (increment, assign to them etc.) in any way. You may modify the
203I<DATA> member, and you may re-assign the array itself, e.g.: 206I<DATA> member, and you may re-assign the array itself, e.g.:
204 207
205 $ber = ber_decode $binbuf; 208 $ber = ber_decode $binbuf;
206 209
207 # the following is NOT legal: 210 # the following is NOT legal:
208 $ber->[BER_CLASS] = ASN_PRIVATE; # ERROR, CLASS/TAG/CONSTRUCTED are READ ONLY(!) 211 $ber->[BER_CLASS] = ASN_PRIVATE; # ERROR, CLASS/TAG/FLAGS are READ ONLY(!)
209 212
210 # but all of the following are fine: 213 # but all of the following are fine:
211 $ber->[BER_DATA] = "string"; 214 $ber->[BER_DATA] = "string";
212 $ber->[BER_DATA] = [ASN_UNIVERSAL, ASN_INTEGER, 0, 123]; 215 $ber->[BER_DATA] = [ASN_UNIVERSAL, ASN_INTEGER, 0, 123];
213 @$ber = (ASN_APPLICATION, SNMP_TIMETICKS, 0, 1000); 216 @$ber = (ASN_APPLICATION, SNMP_TIMETICKS, 0, 1000);
231 234
232The most common tags in SNMP's C<ASN_APPLICATION> namespace are 235The most common tags in SNMP's C<ASN_APPLICATION> namespace are
233C<SNMP_COUNTER32>, C<SNMP_UNSIGNED32>, C<SNMP_TIMETICKS> and 236C<SNMP_COUNTER32>, C<SNMP_UNSIGNED32>, C<SNMP_TIMETICKS> and
234C<SNMP_COUNTER64>. 237C<SNMP_COUNTER64>.
235 238
236The I<CONSTRUCTED> flag is really just a boolean - if it is false, 239The I<FLAGS> value is really just a boolean at this time (but might
237the value is "primitive" and contains no subvalues, kind of like a 240get extended) - if it is C<0>, the value is "primitive" and contains
238non-reference perl scalar. If it is true, then the value is "constructed" 241no subvalues, kind of like a non-reference perl scalar. If it is C<1>,
239which just means it contains a list of subvalues which this module will 242then the value is "constructed" which just means it contains a list of
240en-/decode as BER tuples themselves. 243subvalues which this module will en-/decode as BER tuples themselves.
241 244
242The I<DATA> value is either a reference to an array of further tuples (if 245The I<DATA> value is either a reference to an array of further tuples
243the value is I<CONSTRUCTED>), some decoded representation of the value, 246(if the value is I<FLAGS>), some decoded representation of the value, if
244if this module knows how to decode it (e.g. for the integer types above) 247this module knows how to decode it (e.g. for the integer types above) or
245or a binary string with the raw octets if this module doesn't know how to 248a binary string with the raw octets if this module doesn't know how to
246interpret the namespace/tag. 249interpret the namespace/tag.
247 250
248Thus, you can always decode a BER data structure and at worst you get a 251Thus, you can always decode a BER data structure and at worst you get a
249string in place of some nice decoded value. 252string in place of some nice decoded value.
250 253
252 255
253=head2 DECODING AND ENCODING 256=head2 DECODING AND ENCODING
254 257
255=over 258=over
256 259
257=item $tuple = ber_decoded $bindata[, $profile] 260=item $tuple = ber_decode $bindata[, $profile]
258 261
259Decodes binary BER data in C<$bindata> and returns the resulting BER 262Decodes binary BER data in C<$bindata> and returns the resulting BER
260tuple. Croaks on any decoding error, so the returned C<$tuple> is always 263tuple. Croaks on any decoding error, so the returned C<$tuple> is always
261valid. 264valid.
262 265
275 278
276Example: as above, but use the provided SNMP profile. 279Example: as above, but use the provided SNMP profile.
277 280
278 $tuple = ber_encode $data, $Convert::BER::XS::SNMP_PROFILE; 281 $tuple = ber_encode $data, $Convert::BER::XS::SNMP_PROFILE;
279 282
283=item ($tuple, $bytes) = ber_decode_prefix $bindata[, $profile]
284
285Works like C<ber_decode>, except it doesn't croak when there is data after
286the BER data, but instead returns the decoded value and the number of
287bytes it decoded.
288
289This is useful when you have BER data at the start of a buffer and other
290data after, and you need to find the length.
291
292Also, since BER is self-delimited, this can be used to decode multiple BER
293values joined together.
294
280=item $bindata = ber_encode $tuple[, $profile] 295=item $bindata = ber_encode $tuple[, $profile]
281 296
282Encodes the BER tuple into a BER/DER data structure. AS with 297Encodes the BER tuple into a BER/DER data structure. AS with
283Cyber_decode>, an optional profile can be given. 298Cyber_decode>, an optional profile can be given.
299
300The encoded data should be both BER and DER ("shortest form") compliant
301unless the input says otherwise (e.g. it uses constructed strings).
284 302
285=back 303=back
286 304
287=head2 HELPER FUNCTIONS 305=head2 HELPER FUNCTIONS
288 306
300a ease-of-use exception, they usually also accept C<undef> instead of a 318a ease-of-use exception, they usually also accept C<undef> instead of a
301tuple reference, in which case they silently fail to match. 319tuple reference, in which case they silently fail to match.
302 320
303=over 321=over
304 322
305=item $bool = ber_is $tuple, $class, $tag, $constructed, $data 323=item $bool = ber_is $tuple, $class, $tag, $flags, $data
306 324
307This takes a BER C<$tuple> and matches its elements against the provided 325This takes a BER C<$tuple> and matches its elements against the provided
308values, all of which are optional - values that are either missing or 326values, all of which are optional - values that are either missing or
309C<undef> will be ignored, the others will be matched exactly (e.g. as if 327C<undef> will be ignored, the others will be matched exactly (e.g. as if
310you used C<==> or C<eq> (for C<$data>)). 328you used C<==> or C<eq> (for C<$data>)).
390use Exporter qw(import); 408use Exporter qw(import);
391 409
392our $VERSION; 410our $VERSION;
393 411
394BEGIN { 412BEGIN {
395 $VERSION = 0.8; 413 $VERSION = 0.9;
396 XSLoader::load __PACKAGE__, $VERSION; 414 XSLoader::load __PACKAGE__, $VERSION;
397} 415}
398 416
399our %EXPORT_TAGS = ( 417our %EXPORT_TAGS = (
400 const_index => [qw( 418 const_index => [qw(
401 BER_CLASS BER_TAG BER_CONSTRUCTED BER_DATA 419 BER_CLASS BER_TAG BER_FLAGS BER_DATA
402 )], 420 )],
403 const_asn => [qw( 421 const_asn => [qw(
404 ASN_BOOLEAN ASN_INTEGER ASN_BIT_STRING ASN_OCTET_STRING ASN_NULL ASN_OBJECT_IDENTIFIER 422 ASN_BOOLEAN ASN_INTEGER ASN_BIT_STRING ASN_OCTET_STRING ASN_NULL ASN_OBJECT_IDENTIFIER
405 ASN_OBJECT_DESCRIPTOR ASN_OID ASN_EXTERNAL ASN_REAL ASN_SEQUENCE ASN_ENUMERATED 423 ASN_OBJECT_DESCRIPTOR ASN_OID ASN_EXTERNAL ASN_REAL ASN_SEQUENCE ASN_ENUMERATED
406 ASN_EMBEDDED_PDV ASN_UTF8_STRING ASN_RELATIVE_OID ASN_SET ASN_NUMERIC_STRING 424 ASN_EMBEDDED_PDV ASN_UTF8_STRING ASN_RELATIVE_OID ASN_SET ASN_NUMERIC_STRING
414 BER_TYPE_BYTES BER_TYPE_UTF8 BER_TYPE_UCS2 BER_TYPE_UCS4 BER_TYPE_INT 432 BER_TYPE_BYTES BER_TYPE_UTF8 BER_TYPE_UCS2 BER_TYPE_UCS4 BER_TYPE_INT
415 BER_TYPE_OID BER_TYPE_RELOID BER_TYPE_NULL BER_TYPE_BOOL BER_TYPE_REAL 433 BER_TYPE_OID BER_TYPE_RELOID BER_TYPE_NULL BER_TYPE_BOOL BER_TYPE_REAL
416 BER_TYPE_IPADDRESS BER_TYPE_CROAK 434 BER_TYPE_IPADDRESS BER_TYPE_CROAK
417 )], 435 )],
418 const_snmp => [qw( 436 const_snmp => [qw(
419 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_UNSIGNED32 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64 437 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_GAUGE32 SNMP_UNSIGNED32
438 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64
420 )], 439 )],
421 decode => [qw( 440 decode => [qw(
422 ber_decode 441 ber_decode ber_decode_prefix
423 ber_is ber_is_seq ber_is_int ber_is_oid 442 ber_is ber_is_seq ber_is_int ber_is_oid
424 )], 443 )],
425 encode => [qw( 444 encode => [qw(
426 ber_encode 445 ber_encode
427 ber_int 446 ber_int
579C<BER_TYPE_BYTES>. When you don't want that but instead prefer a hard 598C<BER_TYPE_BYTES>. When you don't want that but instead prefer a hard
580error for some types, then C<BER_TYPE_CROAK> is for you. 599error for some types, then C<BER_TYPE_CROAK> is for you.
581 600
582=back 601=back
583 602
603=head2 Example Profile
604
605The following creates a profile suitable for SNMP - it's exactly identical
606to the C<$Convert::BER::XS::SNMP_PROFILE> profile.
607
608 our $SNMP_PROFILE = new Convert::BER::XS::Profile;
609
610 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
611 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
612 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
613 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
614 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS);
615 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
616
584=cut 617=cut
585 618
586our $DEFAULT_PROFILE = new Convert::BER::XS::Profile; 619our $DEFAULT_PROFILE = new Convert::BER::XS::Profile;
587our $SNMP_PROFILE = new Convert::BER::XS::Profile; 620
621$DEFAULT_PROFILE->_set_default;
588 622
589# additional SNMP application types 623# additional SNMP application types
624our $SNMP_PROFILE = new Convert::BER::XS::Profile;
625
590$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS); 626$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
591$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT); 627$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
592$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT); 628$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
593$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT); 629$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
594$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS); 630$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS);
595$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT); 631$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
596 632
597$DEFAULT_PROFILE->_set_default;
598
5991; 6331;
600 634
601=head2 LIMITATIONS/NOTES 635=head2 LIMITATIONS/NOTES
602 636
603This module can only en-/decode 64 bit signed and unsigned integers, and 637This module can only en-/decode 64 bit signed and unsigned integers, and
609 643
610OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is 644OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is
611much larger than e.g. the one imposed by SNMP or other protocols,a nd is 645much larger than e.g. the one imposed by SNMP or other protocols,a nd is
612about 4kB. 646about 4kB.
613 647
648Indefinite length encoding is not supported.
649
650Constructed strings are decoded just fine, but there should be a way to
651join them for convenience.
652
614REAL values are not supported and will currently croak. 653REAL values are not supported and will currently croak.
654
655The encoder and decoder tend to accept more formats than should be
656strictly supported.
615 657
616This module has undergone little to no testing so far. 658This module has undergone little to no testing so far.
617 659
618=head2 ITHREADS SUPPORT 660=head2 ITHREADS SUPPORT
619 661

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines