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.62 by root, Thu Feb 6 23:15:44 2020 UTC vs.
Revision 1.63 by root, Wed Mar 3 05:30:23 2021 UTC

4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use Convert::BER::XS ':all'; 7 use Convert::BER::XS ':all';
8 8
9 # decode a binary BER data structure using the SNMP profile
9 my $ber = ber_decode $buf, $Convert::BER::XS::SNMP_PROFILE 10 my $ber = ber_decode $buf, $Convert::BER::XS::SNMP_PROFILE
10 or die "unable to decode SNMP message"; 11 or die "unable to decode SNMP message";
11 12
12 # The above results in a data structure consisting of 13 # The above results in a data structure consisting of
13 # (class, tag, flags, data) 14 # (class, tag, flags, data)
14 # tuples. Below is such a message, SNMPv1 trap 15 # tuples. Below is such a message, an SNMPv1 trap
15 # with a Cisco mac change notification. 16 # with a Cisco mac change notification.
16 # Did you know that Cisco is in the news almost 17 # (Did you know that Cisco is in the news almost
17 # every week because of some backdoor password 18 # every week because of some backdoor password
18 # or other extremely stupid security bug? 19 # or other extremely stupid security bug?)
19 20
20 [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, 21 [ ASN_UNIVERSAL, ASN_SEQUENCE, 1,
21 [ 22 [
22 [ ASN_UNIVERSAL, ASN_INTEGER, 0, 0 ], # snmp version 1 23 [ ASN_UNIVERSAL, ASN_INTEGER, 0, 0 ], # snmp version 1
23 [ ASN_UNIVERSAL, 4, 0, "public" ], # community 24 [ ASN_UNIVERSAL, 4, 0, "public" ], # community
36 [ ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "...data..." # the value 37 [ ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "...data..." # the value
37 ] 38 ]
38 ] 39 ]
39 ], 40 ],
40 ... 41 ...
42
41 # let's dump it, for debugging 43 # let's dump the above structure, for debugging
42
43 ber_dump $ber, $Convert::BER::XS::SNMP_PROFILE; 44 ber_dump $ber, $Convert::BER::XS::SNMP_PROFILE;
44 45
45 # let's decode it a bit with some helper functions 46 # let's decode it a bit with some helper functions.
46 47 # first check whether it starts with a sequence
47 my $msg = ber_is_seq $ber 48 my $msg = ber_is_seq $ber
48 or die "SNMP message does not start with a sequence"; 49 or die "SNMP message does not start with a sequence";
49 50
51 # then check if its some kind of integer
50 ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER, 0 52 ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER, 0
51 or die "SNMP message does not start with snmp version\n"; 53 or die "SNMP message does not start with snmp version";
52 54
53 # message is SNMP v1 or v2c? 55 # message is SNMP v1 or v2c?
54 if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) { 56 if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) {
55 57
56 # message is v1 trap? 58 # message is v1 trap?
64 and (ber_is_int $trap->[3], 1) # mac changed msg 66 and (ber_is_int $trap->[3], 1) # mac changed msg
65 ) { 67 ) {
66 ... and so on 68 ... and so on
67 69
68 # finally, let's encode it again and hope it results in the same bit pattern 70 # finally, let's encode it again and hope it results in the same bit pattern
69
70 my $buf = ber_encode $ber, $Convert::BER::XS::SNMP_PROFILE; 71 my $buf = ber_encode $ber, $Convert::BER::XS::SNMP_PROFILE;
71 72
72=head1 DESCRIPTION 73=head1 DESCRIPTION
73 74
74This module implements a I<very> low level BER/DER en-/decoder. 75This module implements a I<very> low level BER/DER en-/decoder.
173This works because BER values are tagged with a type and a namespace, 174This works because BER values are tagged with a type and a namespace,
174and also have a flag that says whether a value consists of subvalues (is 175and also have a flag that says whether a value consists of subvalues (is
175"constructed") or not (is "primitive"). 176"constructed") or not (is "primitive").
176 177
177Tags are simple integers, and ASN.1 defines a somewhat weird assortment 178Tags are simple integers, and ASN.1 defines a somewhat weird assortment
178of those - for example, you have one integers and 16(!) different 179of those - for example, you have one integer but 16(!) different
179string types, but there is no Unsigned32 type for example. Different 180string types, but there is no Unsigned32 type for example. Different
180applications work around this in different ways, for example, SNMP defines 181applications work around this in different ways, for example, SNMP defines
181application-specific Gauge32, Counter32 and Unsigned32, which are mapped 182application-specific Gauge32, Counter32 and Unsigned32, which are mapped
182to two different tags: you can distinguish between Counter32 and the 183to two different tags: you can distinguish between Counter32 and the
183others, but not between Gause32 and Unsigned32, without the ASN.1 schema. 184others, but not between Gause32 and Unsigned32, without the ASN.1 schema.
466# additional SNMP application types 467# additional SNMP application types
467our $SNMP_PROFILE = new Convert::BER::XS::Profile; 468our $SNMP_PROFILE = new Convert::BER::XS::Profile;
468 469
469$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS); 470$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_IPADDRESS , BER_TYPE_IPADDRESS);
470$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT); 471$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER32 , BER_TYPE_INT);
472$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
471$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT); 473$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_UNSIGNED32, BER_TYPE_INT);
472$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT); 474$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_TIMETICKS , BER_TYPE_INT);
473 475
474# decodes REAL values according to ECMA-63 476# decodes REAL values according to ECMA-63
475# this is pretty strict, except it doesn't catch -0. 477# this is pretty strict, except it doesn't catch -0.
563 } 565 }
564 566
565 "($value)" 567 "($value)"
566} 568}
567 569
568$SNMP_PROFILE->set (ASN_APPLICATION, SNMP_COUNTER64 , BER_TYPE_INT);
569
570sub _ber_dump { 570sub _ber_dump {
571 my ($ber, $profile, $indent) = @_; 571 my ($ber, $profile, $indent) = @_;
572 572
573 if (my $seq = ber_is_seq $ber) { 573 if (my $seq = ber_is_seq $ber) {
574 printf "%sSEQUENCE\n", $indent; 574 printf "%sSEQUENCE\n", $indent;
648=item C<$Convert::BER::XS::SNMP_PROFILE> 648=item C<$Convert::BER::XS::SNMP_PROFILE>
649 649
650A profile with mappings for SNMP-specific application tags added. This is 650A profile with mappings for SNMP-specific application tags added. This is
651useful when de-/encoding SNMP data. 651useful when de-/encoding SNMP data.
652 652
653The L<Example Profile> section, below, shows how this profile is being
654constructed.
655
653Example: 656Example:
654 657
655 $ber = ber_decode $data, $Convert::BER::XS::SNMP_PROFILE; 658 $ber = ber_decode $data, $Convert::BER::XS::SNMP_PROFILE;
656 659
657=back 660=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines