http://www.perlmonks.org?node_id=1020444


in reply to How to encode snmpv2 trap varbind

Are you trying to send SNMP (v2) traps? The Net::SNMP module does this for you without you needing to worry about the encoding yourself.

I've done some decoding work with Net::SNMPTrapd, but for that I used Convert::ASN1.

I would use Convert::ASN1 also for your task instead of the module you're currently trying with. The following works:

use strict; use warnings; use Convert::ASN1; my $asn = Convert::ASN1->new; $asn->prepare(" varbind SEQUENCE OF SEQUENCE { oid OBJECT IDENTIFIER, choice CHOICE { val_integer INTEGER, val_string STRING, val_OID OBJECT IDENTIFIER, val_IpAddr [APPLICATION 0] STRING, val_Counter32 [APPLICATION 1] INTEGER, val_Guage32 [APPLICATION 2] INTEGER, val_TimeTicks [APPLICATION 3] INTEGER, val_Opaque [APPLICATION 4] STRING, val_Counter64 [APPLICATION 6] INTEGER } } "); my $pdu = $asn->encode( varbind => [ { oid => '1.3.6.1.2.1.1.3.0', choice => { val_TimeTicks => 600 } }, { oid => '1.3.6.1.6.3.1.1.4.1.0', choice => { val_OID => '1.3.6.1.4.1.42767.64.1.1.5.1.40.1' } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.9', choice => { val_integer => 11, } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.10', choice => { val_OID => '1.3.6.1.2.1.26.2.1.1.3.1.9', } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.11', choice => { val_Counter32 => 10, } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.12', choice => { val_TimeTicks => time() } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.13', choice => { val_integer => 2, } }, { oid => '1.3.6.1.4.1.42767.64.1.1.3.1.14', choice => { val_string => '' } } ] ); Convert::ASN1::asn_dump($pdu);

And the output:

VinsWorldcom@C:\Users\VinsWorldcom\tmp> perl test.pl 0000 186: SEQUENCE { 0003 14: SEQUENCE { 0005 8: OBJECT ID = 1.3.6.1.2.1.1.3.0 000F 2: [APPLICATION 3] 0011 : 02 58 __ __ __ __ __ __ __ __ __ __ __ __ __ __ .X 0013 : } 0013 29: SEQUENCE { 0015 10: OBJECT ID = 1.3.6.1.6.3.1.1.4.1.0 0021 15: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.5.1.40.1 0032 : } 0032 19: SEQUENCE { 0034 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.9 0044 1: INTEGER = 11 0047 : } 0047 30: SEQUENCE { 0049 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.10 0059 12: OBJECT ID = 1.3.6.1.2.1.26.2.1.1.3.1.9 0067 : } 0067 19: SEQUENCE { 0069 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.11 0079 1: [APPLICATION 1] 007B : 0A __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ . 007C : } 007C 22: SEQUENCE { 007E 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.12 008E 4: [APPLICATION 3] 0090 : 51 2A C7 73 __ __ __ __ __ __ __ __ __ __ __ __ Q*.s 0094 : } 0094 19: SEQUENCE { 0096 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.13 00A6 1: INTEGER = 2 00A9 : } 00A9 18: SEQUENCE { 00AB 14: OBJECT ID = 1.3.6.1.4.1.42767.64.1.1.3.1.14 00BB 0: STRING = '' 00BD : } 00BD : }

Replies are listed 'Best First'.
Re^2: How to encode snmpv2 trap varbind
by ahm123 (Initiate) on Feb 25, 2013 at 06:04 UTC

    Hi,

    For my testing, I needed to send source IP spoofed traps to SNMP
    manager (NMS). I am able to send traps now with some dirty way.
    I have used Net::SNMP module to send traps. Modified the IPTABLES rule to change the source ip of trap packets.

    #!/usr/bin/perl
    use lib '/opt/perl_64/lib/site_perl/5.8.8/';
    use strict;
    use warnings;
    use Net::SNMP qw(:ALL);
    my $curr_time = (scalar time);
    print "IPTABLES Rule inserted\n";
    `iptables -t nat -A POSTROUTING -d 10.10.70.14 -p udp --dport 5286 -j SNAT --to 10.10.16.230`;
    my ($session, $error) = Net::SNMP->session(
    -hostname => '10.10.70.14',
    -port => '5286',
    -localaddr => '192.168.10.121',
    -localport => '1028',
    -version => 'snmpv2c',
    -community => 'PUBLIC',
    );
    if (!defined($session)) {
    printf("ERROR: %s.\n", $error);
    exit 1;
    }

    my $result = $session->snmpv2_trap(
    -varbindlist => [
    '1.3.6.1.2.1.1.3.0', , TIMETICKS, 600,
    '1.3.6.1.6.3.1.1.4.1.0',OBJECT_IDENTIFIER,'1.3.6.1.4.1.42767.64.1.1.5.1.40.1',
    '1.3.6.1.4.1.42767.64.1.1.3.1.9', INTEGER32, 11,
    '1.3.6.1.4.1.42767.64.1.1.3.1.10', OBJECT_IDENTIFIER, 1.3.6.1.2.1.26.2.1.1.3.1.9,
    '1.3.6.1.4.1.42767.64.1.1.3.1.11', COUNTER32, 10,
    '1.3.6.1.4.1.42767.64.1.1.3.1.12', TIMETICKS, $curr_time,
    '1.3.6.1.4.1.42767.64.1.1.3.1.13', INTEGER32, 2,
    '1.3.6.1.4.1.42767.64.1.1.3.1.14', OCTET_STRING, '' ]
    );

    if (!defined($result)) {
    printf("ERROR: %s.\n", $session->error());
    }
    else {
    printf("SNMPv2-Trap-PDU sent.\n");
    }

    $session->close();
    `iptables -t nat -D POSTROUTING -d 10.10.70.14 -p udp --dport 5286 -j SNAT --to 10.10.16.230`;
    print "IPTABLES rules removed\n";

      Are you sure they have to be spoofed?

      The reason I ask is because there may be a simpler way to accomplish this. Most network monitoring systems (unless they're brain-damaged) support SNMP-COMMUNITY-MIB::snmpTrapAddress (1.3.6.1.6.3.18.1.3 with a .0 as your instance identifier). This is an SNMPv2 varbind that you can pass that contains an IP address to signify that the NMS should treat that as the originating SNMP source (commonly used by SNMP trap relays and aggregators). The docs on it noted that it should be the second varbind sent after the sysUptime (http://tools.ietf.org/html/rfc2576).

      This variable serves roughly the same purpose as the agent-addr value in SNMPv1 traps. In fact, if your NMS supports SNMPv1, using that and setting agent-addr should be another viable option.

      I've used both of the above methods successfully to "spoof" traps to multiple NMS's in the past. It works correctly on nearly all of them. In fact, if any of them fail to treat the trap as if it had come from the snmpTrapAddress/agent-addr, I'd recommend filing a bug with the developer and get them to fix their application.

      I'd definitely recommend giving this a try. It may simplify things a great deal for you, and save you from the hassle and complexity of packet-level spoofing.

      If needed, I might be able to dig up some (working) code I've used to accomplish the above; however, I was using the Net-SNMP project's SNMP perl module (not Net::SNMP), so the syntax is quite different.

        Thanks topher ...I will include snmpTrapAddress also in the varbind and test. I will post my test results ..