--- Convert-BER-XS/XS.pm 2019/04/19 16:23:00 1.2 +++ Convert-BER-XS/XS.pm 2019/04/19 16:49:02 1.3 @@ -9,17 +9,45 @@ 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 SNMP v1 or v2c + # message is v1 trap? if (ber_is $msg->[2], ASN_CONTEXT, 4, 1) { - # message is v1 trap my $trap = $msg->[2][BER_DATA]; # check whether trap is a cisco mac notification mac changed message