… | |
… | |
7 | use Convert::BER::XS ':all'; |
7 | use Convert::BER::XS ':all'; |
8 | |
8 | |
9 | my $ber = ber_decode $buf |
9 | my $ber = ber_decode $buf |
10 | or die "unable to decode SNMP v1/v2c Message"; |
10 | or die "unable to decode SNMP v1/v2c Message"; |
11 | |
11 | |
|
|
12 | # the above results in a data structure consisting of (class, tag, |
|
|
13 | # constructed, data) tuples. here is such a message, SNMPv1 trap |
|
|
14 | # with a cisoc mac change notification |
|
|
15 | |
|
|
16 | [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, |
|
|
17 | [ |
|
|
18 | [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 0 ], # snmp version 1 |
|
|
19 | [ ASN_UNIVERSAL, 4, 0, "public" ], # community |
|
|
20 | [ ASN_CONTEXT, 4, 1, # CHOICE, constructed |
|
|
21 | [ |
|
|
22 | [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.2" ], # enterprise oid |
|
|
23 | [ ASN_APPLICATION, 0, 0, "\x0a\x00\x00\x01" ], # SNMP IpAddress, 10.0.0.1 |
|
|
24 | [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 6 ], # generic trap |
|
|
25 | [ ASN_UNIVERSAL, ASN_INTEGER32, 0, 1 ], # specific trap |
|
|
26 | [ ASN_APPLICATION, ASN_TIMETICKS, 0, 1817903850 ], # SNMP TimeTicks |
|
|
27 | [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # the varbindlist |
|
|
28 | [ |
|
|
29 | [ ASN_UNIVERSAL, ASN_SEQUENCE, 1, # a single varbind, "key value" pair |
|
|
30 | [ |
|
|
31 | [ ASN_UNIVERSAL, ASN_OBJECT_IDENTIFIER, 0, "1.3.6.1.4.1.9.9.215.1.1.8.1.2.1" ], # the oid |
|
|
32 | [ ASN_UNIVERSAL, ASN_OCTET_STRING, 0, "...data..." # the value |
|
|
33 | ] |
|
|
34 | ] |
|
|
35 | ], |
|
|
36 | ... |
|
|
37 | |
|
|
38 | # let's decode it a bit with some helper functions |
|
|
39 | |
12 | my $msg = ber_is_seq $ber |
40 | my $msg = ber_is_seq $ber |
13 | or die "SNMP message does not start with a sequence"; |
41 | or die "SNMP message does not start with a sequence"; |
14 | |
42 | |
15 | ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER32, 0 |
43 | ber_is $msg->[0], ASN_UNIVERSAL, ASN_INTEGER32, 0 |
16 | or die "SNMP message does not start with snmp version\n"; |
44 | or die "SNMP message does not start with snmp version\n"; |
17 | |
45 | |
|
|
46 | # message is SNMP v1 or v2c? |
18 | if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) { |
47 | if ($msg->[0][BER_DATA] == 0 || $msg->[0][BER_DATA] == 1) { |
19 | # message is SNMP v1 or v2c |
|
|
20 | |
48 | |
|
|
49 | # message is v1 trap? |
21 | if (ber_is $msg->[2], ASN_CONTEXT, 4, 1) { |
50 | if (ber_is $msg->[2], ASN_CONTEXT, 4, 1) { |
22 | # message is v1 trap |
|
|
23 | my $trap = $msg->[2][BER_DATA]; |
51 | my $trap = $msg->[2][BER_DATA]; |
24 | |
52 | |
25 | # check whether trap is a cisco mac notification mac changed message |
53 | # check whether trap is a cisco mac notification mac changed message |
26 | if ( |
54 | if ( |
27 | (ber_is_oid $trap->[0], "1.3.6.1.4.1.9.9.215.2") # cmnInterfaceObjects |
55 | (ber_is_oid $trap->[0], "1.3.6.1.4.1.9.9.215.2") # cmnInterfaceObjects |