ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-BER-XS/XS.pm
Revision: 1.33
Committed: Sat Apr 20 17:23:21 2019 UTC (5 years, 1 month ago) by root
Branch: MAIN
Changes since 1.32: +4 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Convert::BER::XS - I<very> low level BER en-/decoding
4
5 =head1 SYNOPSIS
6
7 use Convert::BER::XS ':all';
8
9 my $ber = ber_decode $buf, $Convert::BER::XS::SNMP_PROFILE
10 or die "unable to decode SNMP message";
11
12 # The above results in a data structure consisting of
13 # (class, tag, flags, data)
14 # tuples. Below is such a message, SNMPv1 trap
15 # with a Cisco mac change notification.
16 # Did you know that Cisco is in the news almost
17 # every week because of some backdoor password
18 # or other extremely stupid security bug?
19
20 [ ASN_UNIVERSAL, ASN_SEQUENCE, 1,
21 [
22 [ ASN_UNIVERSAL, ASN_INTEGER, 0, 0 ], # snmp version 1
23 [ ASN_UNIVERSAL, 4, 0, "public" ], # community
24 [ ASN_CONTEXT, 4, 1, # CHOICE, constructed - trap PDU
25 [
26 [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.2" ], # enterprise oid
27 [ ASN_APPLICATION, SNMP_IPADDRESS, 0, "10.0.0.1" ], # SNMP IpAddress
28 [ ASN_UNIVERSAL, ASN_INTEGER, 0, 6 ], # generic trap
29 [ ASN_UNIVERSAL, ASN_INTEGER, 0, 1 ], # specific trap
30 [ ASN_APPLICATION, SNMP_TIMETICKS, 0, 1817903850 ], # SNMP TimeTicks
31 [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # the varbindlist
32 [
33 [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # a single varbind, "key value" pair
34 [
35 [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.1.1.8.1.2.1" ],
36 [ ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "...data..." # the value
37 ]
38 ]
39 ],
40 ...
41
42 # let's decode it a bit with some helper functions
43
44 my $msg = ber_is_seq $ber
45 or die "SNMP message does not start with a sequence";
46
47 ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER, 0
48 or die "SNMP message does not start with snmp version\n";
49
50 # message is SNMP v1 or v2c?
51 if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) {
52
53 # message is v1 trap?
54 if (ber_is $msg->[2], ASN_CONTEXT, 4, 1) {
55 my $trap = $msg->[2][BER_DATA];
56
57 # check whether trap is a cisco mac notification mac changed message
58 if (
59 (ber_is_oid $trap->[0], "1.3.6.1.4.1.9.9.215.2") # cmnInterfaceObjects
60 and (ber_is_int $trap->[2], 6)
61 and (ber_is_int $trap->[3], 1) # mac changed msg
62 ) {
63 ... and so on
64
65 # finally, let's encode it again and hope it results in the same bit pattern
66
67 my $buf = ber_encode $ber, $Convert::BER::XS::SNMP_PROFILE;
68
69 =head1 DESCRIPTION
70
71 WARNING: Before release 1.0, the API is not considered stable in any way.
72
73 This module implements a I<very> low level BER/DER en-/decoder.
74
75 It is tuned for low memory and high speed, while still maintaining some
76 level of user-friendlyness.
77
78 =head2 EXPORT TAGS AND CONSTANTS
79
80 By default this module doesn't export any symbols, but if you don't want
81 to break your keyboard, editor or eyesight with extremely long names, I
82 recommend importing the C<:all> tag. Still, you can selectively import
83 things.
84
85 =over
86
87 =item C<:all>
88
89 All of the below. Really. Recommended for at least first steps, or if you
90 don't care about a few kilobytes of wasted memory (and namespace).
91
92 =item C<:const>
93
94 All of the strictly ASN.1-related constants defined by this module, the
95 same as C<:const_asn :const_index>. Notably, this does not contain
96 C<:const_ber_type> and C<:const_snmp>.
97
98 A good set to get everything you need to decode and match BER data would be
99 C<:decode :const>.
100
101 =item C<:const_index>
102
103 The BER tuple array index constants:
104
105 BER_CLASS BER_TAG BER_FLAGS BER_DATA
106
107 =item C<:const_asn>
108
109 ASN class values (these are C<0>, C<1>, C<2> and C<3>, respectively -
110 exactly thw two topmost bits from the identifier octet shifted 6 bits to
111 the right):
112
113 ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE
114
115 ASN tag values (some of which are aliases, such as C<ASN_OID>). Their
116 numerical value corresponds exactly to the numbers used in BER/X.690.
117
118 ASN_BOOLEAN ASN_INTEGER ASN_BIT_STRING ASN_OCTET_STRING ASN_NULL ASN_OBJECT_IDENTIFIER
119 ASN_OBJECT_DESCRIPTOR ASN_OID ASN_EXTERNAL ASN_REAL ASN_SEQUENCE ASN_ENUMERATED
120 ASN_EMBEDDED_PDV ASN_UTF8_STRING ASN_RELATIVE_OID ASN_SET ASN_NUMERIC_STRING
121 ASN_PRINTABLE_STRING ASN_TELETEX_STRING ASN_T61_STRING ASN_VIDEOTEX_STRING ASN_IA5_STRING
122 ASN_ASCII_STRING ASN_UTC_TIME ASN_GENERALIZED_TIME ASN_GRAPHIC_STRING ASN_VISIBLE_STRING
123 ASN_ISO646_STRING ASN_GENERAL_STRING ASN_UNIVERSAL_STRING ASN_CHARACTER_STRING ASN_BMP_STRING
124
125 =item C<:const_ber_type>
126
127 The BER type constants, explained in the PROFILES section.
128
129 BER_TYPE_BYTES BER_TYPE_UTF8 BER_TYPE_UCS2 BER_TYPE_UCS4 BER_TYPE_INT
130 BER_TYPE_OID BER_TYPE_RELOID BER_TYPE_NULL BER_TYPE_BOOL BER_TYPE_REAL
131 BER_TYPE_IPADDRESS BER_TYPE_CROAK
132
133 =item C<:const_snmp>
134
135 Constants only relevant to SNMP. These are the tag values used by SNMP in
136 the C<ASN_APPLICATION> namespace and have the exact numerical value as in
137 BER/RFC 2578.
138
139 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_UNSIGNED32 SNMP_GAUGE32
140 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64
141
142 =item C<:decode>
143
144 C<ber_decode> and the match helper functions:
145
146 ber_decode ber_is ber_is_seq ber_is_int ber_is_oid
147
148 =item C<:encode>
149
150 C<ber_encode> and the construction helper functions:
151
152 ber_encode ber_int
153
154 =back
155
156 =head2 ASN.1/BER/DER/... BASICS
157
158 ASN.1 is a strange language that can be used to describe protocols and
159 data structures. It supports various mappings to JSON, XML, but most
160 importantly, to a various binary encodings such as BER, that is the topic
161 of this module, and is used in SNMP, LDAP or X.509 for example.
162
163 While ASN.1 defines a schema that is useful to interpret encoded data,
164 the BER encoding is actually somewhat self-describing: you might not know
165 whether something is a string or a number or a sequence or something else,
166 but you can nevertheless decode the overall structure, even if you end up
167 with just a binary blob for the actual value.
168
169 This works because BER values are tagged with a type and a namespace,
170 and also have a flag that says whether a value consists of subvalues (is
171 "constructed") or not (is "primitive").
172
173 Tags are simple integers, and ASN.1 defines a somewhat weird assortment
174 of those - for example, you have one integers and 16(!) different
175 string types, but there is no Unsigned32 type for example. Different
176 applications work around this in different ways, for example, SNMP defines
177 application-specific Gauge32, Counter32 and Unsigned32, which are mapped
178 to two different tags: you can distinguish between Counter32 and the
179 others, but not between Gause32 and Unsigned32, without the ASN.1 schema.
180
181 Ugh.
182
183 =head2 DECODED BER REPRESENTATION
184
185 This module represents every BER value as a 4-element tuple (actually an
186 array-reference):
187
188 [CLASS, TAG, FLAGS, DATA]
189
190 For example:
191
192 [ASN_UNIVERSAL, ASN_INTEGER, 0, 177] # the integer 177
193 [ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "john"] # the string "john"
194 [ASN_UNIVERSAL, ASN_OID, 0, "1.3.6.133"] # some OID
195 [ASN_UNIVERSAL, ASN_SEQUENCE, 1, [ [ASN_UNIVERSAL... # a sequence
196
197 To avoid non-descriptive hardcoded array index numbers, this module
198 defines symbolic constants to access these members: C<BER_CLASS>,
199 C<BER_TAG>, C<BER_FLAGS> and C<BER_DATA>.
200
201 Also, the first three members are integers with a little caveat: for
202 performance reasons, these are readonly and shared, so you must not modify
203 them (increment, assign to them etc.) in any way. You may modify the
204 I<DATA> member, and you may re-assign the array itself, e.g.:
205
206 $ber = ber_decode $binbuf;
207
208 # the following is NOT legal:
209 $ber->[BER_CLASS] = ASN_PRIVATE; # ERROR, CLASS/TAG/FLAGS are READ ONLY(!)
210
211 # but all of the following are fine:
212 $ber->[BER_DATA] = "string";
213 $ber->[BER_DATA] = [ASN_UNIVERSAL, ASN_INTEGER, 0, 123];
214 @$ber = (ASN_APPLICATION, SNMP_TIMETICKS, 0, 1000);
215
216 I<CLASS> is something like a namespace for I<TAG>s - there is the
217 C<ASN_UNIVERSAL> namespace which defines tags common to all ASN.1
218 implementations, the C<ASN_APPLICATION> namespace which defines tags for
219 specific applications (for example, the SNMP C<Unsigned32> type is in this
220 namespace), a special-purpose context namespace (C<ASN_CONTEXT>, used e.g.
221 for C<CHOICE>) and a private namespace (C<ASN_PRIVATE>).
222
223 The meaning of the I<TAG> depends on the namespace, and defines a
224 (partial) interpretation of the data value. For example, SNMP defines
225 extra tags in the C<ASN_APPLICATION> namespace, and to take full advantage
226 of these, you need to tell this module how to handle those via profiles.
227
228 The most common tags in the C<ASN_UNIVERSAL> namespace are
229 C<ASN_INTEGER>, C<ASN_BIT_STRING>, C<ASN_NULL>, C<ASN_OCTET_STRING>,
230 C<ASN_OBJECT_IDENTIFIER>, C<ASN_SEQUENCE>, C<ASN_SET> and
231 C<ASN_IA5_STRING>.
232
233 The most common tags in SNMP's C<ASN_APPLICATION> namespace are
234 C<SNMP_COUNTER32>, C<SNMP_UNSIGNED32>, C<SNMP_TIMETICKS> and
235 C<SNMP_COUNTER64>.
236
237 The I<FLAGS> value is really just a boolean at this time (but might
238 get extended) - if it is C<0>, the value is "primitive" and contains
239 no subvalues, kind of like a non-reference perl scalar. If it is C<1>,
240 then the value is "constructed" which just means it contains a list of
241 subvalues which this module will en-/decode as BER tuples themselves.
242
243 The I<DATA> value is either a reference to an array of further tuples
244 (if the value is I<FLAGS>), some decoded representation of the value, if
245 this module knows how to decode it (e.g. for the integer types above) or
246 a binary string with the raw octets if this module doesn't know how to
247 interpret the namespace/tag.
248
249 Thus, you can always decode a BER data structure and at worst you get a
250 string in place of some nice decoded value.
251
252 See the SYNOPSIS for an example of such an encoded tuple representation.
253
254 =head2 DECODING AND ENCODING
255
256 =over
257
258 =item $tuple = ber_decoded $bindata[, $profile]
259
260 Decodes binary BER data in C<$bindata> and returns the resulting BER
261 tuple. Croaks on any decoding error, so the returned C<$tuple> is always
262 valid.
263
264 How tags are interpreted is defined by the second argument, which must
265 be a C<Convert::BER::XS::Profile> object. If it is missing, the default
266 profile will be used (C<$Convert::BER::XS::DEFAULT_PROFILE>).
267
268 In addition to rolling your own, this module provides a
269 C<$Convert::BER::XS::SNMP_PROFILE> that knows about the additional SNMP
270 types.
271
272 Example: decode a BER blob using the default profile - SNMP values will be
273 decided as raw strings.
274
275 $tuple = ber_decode $data;
276
277 Example: as above, but use the provided SNMP profile.
278
279 $tuple = ber_encode $data, $Convert::BER::XS::SNMP_PROFILE;
280
281 =item $bindata = ber_encode $tuple[, $profile]
282
283 Encodes the BER tuple into a BER/DER data structure. AS with
284 Cyber_decode>, an optional profile can be given.
285
286 The encoded data should be both BER and DER ("shortest form") compliant
287 unless the input says otherwise (e.g. it uses constructed strings).
288
289 =back
290
291 =head2 HELPER FUNCTIONS
292
293 Working with a 4-tuple for every value can be annoying. Or, rather, I<is>
294 annoying. To reduce this a bit, this module defines a number of helper
295 functions, both to match BER tuples and to construct BER tuples:
296
297 =head3 MATCH HELPERS
298
299 These functions accept a BER tuple as first argument and either partially
300 or fully match it. They often come in two forms, one which exactly matches
301 a value, and one which only matches the type and returns the value.
302
303 They do check whether valid tuples are passed in and croak otherwise. As
304 a ease-of-use exception, they usually also accept C<undef> instead of a
305 tuple reference, in which case they silently fail to match.
306
307 =over
308
309 =item $bool = ber_is $tuple, $class, $tag, $flags, $data
310
311 This takes a BER C<$tuple> and matches its elements against the provided
312 values, all of which are optional - values that are either missing or
313 C<undef> will be ignored, the others will be matched exactly (e.g. as if
314 you used C<==> or C<eq> (for C<$data>)).
315
316 Some examples:
317
318 ber_is $tuple, ASN_UNIVERSAL, ASN_SEQUENCE, 1
319 orf die "tuple is not an ASN SEQUENCE";
320
321 ber_is $tuple, ASN_UNIVERSAL, ASN_NULL
322 or die "tuple is not an ASN NULL value";
323
324 ber_is $tuple, ASN_UNIVERSAL, ASN_INTEGER, 0, 50
325 or die "BER integer must be 50";
326
327 =item $seq = ber_is_seq $tuple
328
329 Returns the sequence members (the array of subvalues) if the C<$tuple> is
330 an ASN SEQUENCE, i.e. the C<BER_DATA> member. If the C<$tuple> is not a
331 sequence it returns C<undef>. For example, SNMP version 1/2c/3 packets all
332 consist of an outer SEQUENCE value:
333
334 my $ber = ber_decode $snmp_data;
335
336 my $snmp = ber_is_seq $ber
337 or die "SNMP packet invalid: does not start with SEQUENCE";
338
339 # now we know $snmp is a sequence, so decode the SNMP version
340
341 my $version = ber_is_int $snmp->[0]
342 or die "SNMP packet invalid: does not start with version number";
343
344 =item $bool = ber_is_int $tuple, $int
345
346 Returns a true value if the C<$tuple> represents an ASN INTEGER with
347 the value C<$int>.
348
349 =item $int = ber_is_int $tuple
350
351 Returns true (and extracts the integer value) if the C<$tuple> is an
352 C<ASN_INTEGER>. For C<0>, this function returns a special value that is 0
353 but true.
354
355 =item $bool = ber_is_oid $tuple, $oid_string
356
357 Returns true if the C<$tuple> represents an ASN_OBJECT_IDENTIFIER
358 that exactly matches C<$oid_string>. Example:
359
360 ber_is_oid $tuple, "1.3.6.1.4"
361 or die "oid must be 1.3.6.1.4";
362
363 =item $oid = ber_is_oid $tuple
364
365 Returns true (and extracts the OID string) if the C<$tuple> is an ASN
366 OBJECT IDENTIFIER. Otherwise, it returns C<undef>.
367
368 =back
369
370 =head3 CONSTRUCTION HELPERS
371
372 =over
373
374 =item $tuple = ber_int $value
375
376 Constructs a new C<ASN_INTEGER> tuple.
377
378 =back
379
380 =head2 RELATIONSHIP TO L<Convert::BER> and L<Convert::ASN1>
381
382 This module is I<not> the XS version of L<Convert::BER>, but a different
383 take at doing the same thing. I imagine this module would be a good base
384 for speeding up either of these, or write a similar module, or write your
385 own LDAP or SNMP module for example.
386
387 =cut
388
389 package Convert::BER::XS;
390
391 use common::sense;
392
393 use XSLoader ();
394 use Exporter qw(import);
395
396 our $VERSION;
397
398 BEGIN {
399 $VERSION = 0.9;
400 XSLoader::load __PACKAGE__, $VERSION;
401 }
402
403 our %EXPORT_TAGS = (
404 const_index => [qw(
405 BER_CLASS BER_TAG BER_FLAGS BER_DATA
406 )],
407 const_asn => [qw(
408 ASN_BOOLEAN ASN_INTEGER ASN_BIT_STRING ASN_OCTET_STRING ASN_NULL ASN_OBJECT_IDENTIFIER
409 ASN_OBJECT_DESCRIPTOR ASN_OID ASN_EXTERNAL ASN_REAL ASN_SEQUENCE ASN_ENUMERATED
410 ASN_EMBEDDED_PDV ASN_UTF8_STRING ASN_RELATIVE_OID ASN_SET ASN_NUMERIC_STRING
411 ASN_PRINTABLE_STRING ASN_TELETEX_STRING ASN_T61_STRING ASN_VIDEOTEX_STRING ASN_IA5_STRING
412 ASN_ASCII_STRING ASN_UTC_TIME ASN_GENERALIZED_TIME ASN_GRAPHIC_STRING ASN_VISIBLE_STRING
413 ASN_ISO646_STRING ASN_GENERAL_STRING ASN_UNIVERSAL_STRING ASN_CHARACTER_STRING ASN_BMP_STRING
414
415 ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE
416 )],
417 const_ber_type => [qw(
418 BER_TYPE_BYTES BER_TYPE_UTF8 BER_TYPE_UCS2 BER_TYPE_UCS4 BER_TYPE_INT
419 BER_TYPE_OID BER_TYPE_RELOID BER_TYPE_NULL BER_TYPE_BOOL BER_TYPE_REAL
420 BER_TYPE_IPADDRESS BER_TYPE_CROAK
421 )],
422 const_snmp => [qw(
423 SNMP_IPADDRESS SNMP_COUNTER32 SNMP_GAUGE32 SNMP_UNSIGNED32
424 SNMP_TIMETICKS SNMP_OPAQUE SNMP_COUNTER64
425 )],
426 decode => [qw(
427 ber_decode
428 ber_is ber_is_seq ber_is_int ber_is_oid
429 )],
430 encode => [qw(
431 ber_encode
432 ber_int
433 )],
434 );
435
436 our @EXPORT_OK = map @$_, values %EXPORT_TAGS;
437
438 $EXPORT_TAGS{all} = \@EXPORT_OK;
439 $EXPORT_TAGS{const} = [map @{ $EXPORT_TAGS{$_} }, qw(const_index const_asn)];
440
441 =head1 PROFILES
442
443 While any BER data can be correctly encoded and decoded out of the box, it
444 can be inconvenient to have to manually decode some values into a "better"
445 format: for instance, SNMP TimeTicks values are decoded into the raw octet
446 strings of their BER representation, which is quite hard to decode. With
447 profiles, you can change which class/tag combinations map to which decoder
448 function inside C<ber_decode> (and of course also which encoder functions
449 are used in C<ber_encode>).
450
451 This works by mapping specific class/tag combinations to an internal "ber
452 type".
453
454 The default profile supports the standard ASN.1 types, but no
455 application-specific ones. This means that class/tag combinations not in
456 the base set of ASN.1 are decoded into their raw octet strings.
457
458 C<Convert::BER::XS> defines two profile variables you can use out of the box:
459
460 =over
461
462 =item C<$Convert::BER::XS::DEFAULT_PROFILE>
463
464 This is the default profile, i.e. the profile that is used when no
465 profile is specified for de-/encoding.
466
467 You can modify it, but remember that this modifies the defaults for all
468 callers that rely on the default profile.
469
470 =item C<$Convert::BER::XS::SNMP_PROFILE>
471
472 A profile with mappings for SNMP-specific application tags added. This is
473 useful when de-/encoding SNMP data.
474
475 Example:
476
477 $ber = ber_decode $data, $Convert::BER::XS::SNMP_PROFILE;
478
479 =back
480
481 =head2 The Convert::BER::XS::Profile class
482
483 =over
484
485 =item $profile = new Convert::BER::XS::Profile
486
487 Create a new profile. The profile will be identical to the default
488 profile.
489
490 =item $profile->set ($class, $tag, $type)
491
492 Sets the mapping for the given C<$class>/C<$tag> combination to C<$type>,
493 which must be one of the C<BER_TYPE_*> constants.
494
495 Note that currently, the mapping is stored in a flat array, so large
496 values of C<$tag> will consume large amounts of memory.
497
498 Example:
499
500 $profile = new Convert::BER::XS::Profile;
501 $profile->set (ASN_APPLICATION, SNMP_COUNTER32, BER_TYPE_INT);
502 $ber = ber_decode $data, $profile;
503
504 =item $type = $profile->get ($class, $tag)
505
506 Returns the BER type mapped to the given C<$class>/C<$tag> combination.
507
508 =back
509
510 =head2 BER TYPES
511
512 This lists the predefined BER types - you can map any C<CLASS>/C<TAG>
513 combination to any C<BER_TYPE_*>.
514
515 =over
516
517 =item C<BER_TYPE_BYTES>
518
519 The raw octets of the value. This is the default type for unknown tags and
520 de-/encodes the value as if it were an octet string, i.e. by copying the
521 raw bytes.
522
523 =item C<BER_TYPE_UTF8>
524
525 Like C<BER_TYPE_BYTES>, but decodes the value as if it were a UTF-8 string
526 (without validation!) and encodes a perl unicode string into a UTF-8 BER
527 string.
528
529 =item C<BER_TYPE_UCS2>
530
531 Similar to C<BER_TYPE_UTF8>, but treats the BER value as UCS-2 encoded
532 string.
533
534 =item C<BER_TYPE_UCS4>
535
536 Similar to C<BER_TYPE_UTF8>, but treats the BER value as UCS-4 encoded
537 string.
538
539 =item C<BER_TYPE_INT>
540
541 Encodes and decodes a BER integer value to a perl integer scalar. This
542 should correctly handle 64 bit signed and unsigned values.
543
544 =item C<BER_TYPE_OID>
545
546 Encodes and decodes an OBJECT IDENTIFIER into dotted form without leading
547 dot, e.g. C<1.3.6.1.213>.
548
549 =item C<BER_TYPE_RELOID>
550
551 Same as C<BER_TYPE_OID> but uses relative object identifier
552 encoding: ASN.1 has this hack of encoding the first two OID components
553 into a single integer in a weird attempt to save an insignificant amount
554 of space in an otherwise wasteful encoding, and relative OIDs are
555 basically OIDs without this hack. The practical difference is that the
556 second component of an OID can only have the values 1..40, while relative
557 OIDs do not have this restriction.
558
559 =item C<BER_TYPE_NULL>
560
561 Decodes an C<ASN_NULL> value into C<undef>, and always encodes a
562 C<ASN_NULL> type, regardless of the perl value.
563
564 =item C<BER_TYPE_BOOL>
565
566 Decodes an C<ASN_BOOLEAN> value into C<0> or C<1>, and encodes a perl
567 boolean value into an C<ASN_BOOLEAN>.
568
569 =item C<BER_TYPE_REAL>
570
571 Decodes/encodes a BER real value. NOT IMPLEMENTED.
572
573 =item C<BER_TYPE_IPADDRESS>
574
575 Decodes/encodes a four byte string into an IPv4 dotted-quad address string
576 in Perl. Given the obsolete nature of this type, this is a low-effort
577 implementation that simply uses C<sprintf> and C<sscanf>-style conversion,
578 so it won't handle all string forms supported by C<inet_aton> for example.
579
580 =item C<BER_TYPE_CROAK>
581
582 Always croaks when encountered during encoding or decoding - the
583 default behaviour when encountering an unknown type is to treat it as
584 C<BER_TYPE_BYTES>. When you don't want that but instead prefer a hard
585 error for some types, then C<BER_TYPE_CROAK> is for you.
586
587 =back
588
589 =head2 Example Profile
590
591 The following creates a profile suitable for SNMP - it's exactly identical
592 to the C<$Convert::BER::XS::SNMP_PROFILE> profile.
593
594 our $SNMP_PROFILE = new Convert::BER::XS::Profile;
595
596 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
597 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
598 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
599 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
600 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS);
601 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
602
603 =cut
604
605 our $DEFAULT_PROFILE = new Convert::BER::XS::Profile;
606
607 $DEFAULT_PROFILE->_set_default;
608
609 # additional SNMP application types
610 our $SNMP_PROFILE = new Convert::BER::XS::Profile;
611
612 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
613 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
614 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
615 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
616 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_OPAQUE , BER_TYPE_IPADDRESS);
617 $SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
618
619 1;
620
621 =head2 LIMITATIONS/NOTES
622
623 This module can only en-/decode 64 bit signed and unsigned integers, and
624 only when your perl supports those.
625
626 This module does not generally care about ranges, i.e. it will happily
627 de-/encode 64 bit integers into an C<ASN_INTEGER> value, or a negative
628 number into an C<SNMP_COUNTER64>.
629
630 OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is
631 much larger than e.g. the one imposed by SNMP or other protocols,a nd is
632 about 4kB.
633
634 Indefinite length encoding is not supported.
635
636 Constructed strings are decoded just fine, but there should be a way to
637 join them for convenience.
638
639 REAL values are not supported and will currently croak.
640
641 The encoder and decoder tend to accept more formats than should be
642 strictly supported.
643
644 This module has undergone little to no testing so far.
645
646 =head2 ITHREADS SUPPORT
647
648 This module is unlikely to work when the (officially discouraged) ithreads
649 are in use.
650
651 =head1 AUTHOR
652
653 Marc Lehmann <schmorp@schmorp.de>
654 http://software.schmorp.de/pkg/Convert-BER-XS
655
656 =cut
657