dalbaranster has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone

I´m new with Perl and modules from CPAN. Currently I´m working in a project that extract the SNMP traps from a pcap file. I checked different modules from CPAN and I think I´m very close but I need your help and advice with a couple of doubts. This is the code I´m using (I added several modules but I´m not using all, is just for test purpose):

#!/usr/bin/perl use Net::TcpDumpLog; use NetPacket::Ethernet; use NetPacket::IP; use NetPacket::TCP; use strict; use warnings; use Net::Frame::Dump::Offline; use Net::Frame::Simple; use Net::Frame::Layer; use Net::Frame::Layer::UDP; use Mon::SNMP; # # Simple offline anaysis # my $fParse = "/home/my_file.cap"; my $oDump = Net::Frame::Dump::Offline->new( file => $fParse, filter => 'SNMP', ); $oDump->start; my $count = 1; while (my $h = $oDump->next) { my $f = Net::Frame::Simple->new( raw => $h->{raw}, firstLayer => $h->{firstLayer}, timestamp => $h->{timestamp}, ); my $len = length($h->{raw}); print 'o Frame number: '.$count++." (length: $len)\n"; print $f->print."\n"; } $oDump->stop;

Basically the idea is use the Net::Frame::Dump::Offline to read the .cap file and the Net::Frame::Simple help extracting the information from layers (at least for ETH, IPv4 and UDP) My problem is because the SNMP trap is in the payload for the last UDP layer. My question is how can I decode the payload information? I found other module called Mon::SNMP for decode snmp traps, but I´m not sure if this module can read the payload and decode it. If yes, how can I send the "payload" as an input in the Mon::SNMP?

$trap = new Mon::SNMP; $trap->buffer($snmptrap); %traphash = $trap->decode; print %traphash; foreach $oid (keys $traphash{"varbindlist"}) { $val = $traphash{"varbindlist"}{$oid}; print "oid($oid) = val($val)\n"; }

This is an example of the output that I have:

o Frame number: 41 (length: 401) ETH: dst:d8:d3:85:de:85:68 src:78:e7:d1:56:f7:a0 type:0x0800 IPv4: version:4 hlen:5 tos:0x00 length:387 id:0 IPv4: flags:0x02 offset:0 ttl:64 protocol:0x11 checksum:0xd8ee IPv4: src:172.19.4.58 dst:172.19.4.27 UDP: src:41665 dst:162 length:367 checksum:0x9443 UDP: payload:3082016302010104066573796d6163a782015402041560ae270201000 +2010030820144301006082b0601020101030043040cd6aeed3019060a2b0601060301 +01040100060b2b060104015e07010300023028060c2b060104015e070104020102041 +84950444f4d2d312f49504e452d392f49504e4549462d31363012060c2b060104015e +0701040201010202062f3018060c2b060104015e070104020103040807da090d0f2a2 +0013013060c2b060104015e070104020104020301e271302c060c2b060104015e0701 +04020105041c504f5254204f5220494e5445524641434520484153204641494c45443 +011060c2b060104015e070104020106020105302c060c2b060104015e070104020107 +041c506f7274206f7220696e7465726661636520686173206661696c65643012060c2 +b060104015e0701040201080202013b3011060c2b060104015e070104020109020104 +3012060c2b060104015e07010402010a02020b51

At the end my question is, how can I manipulate the payload that I´m getting from the first part of code and use it as the input for the SNMP module, do you think if is possible o which other advices can you give me, please, in order to get the SNMP information.

Replies are listed 'Best First'.
Re: How to parse SNMP traps from pcap file
by ig (Vicar) on Jun 14, 2011 at 19:57 UTC

    If you have a look in Net::SNMP or maybe Mon::SNMP you can see how they are parsing the packets from the network.

      That´s exactly I´m trying to do, but I don´t know how to send the extracted payload from the packets that I get from the object Net::Frame::Simple and use it as input to the buffer in the Mon::SNMP module

      From my code I have in $f the extracted package

      print $f->print."\n";

      how can I just "isolate" this part

      o Frame number: 41 (length: 401) ETH: dst:d8:d3:85:de:85:68 src:78:e7:d1:56:f7:a0 type:0x0800 IPv4: version:4 hlen:5 tos:0x00 length:387 id:0 IPv4: flags:0x02 offset:0 ttl:64 protocol:0x11 checksum:0xd8ee IPv4: src:172.19.4.58 dst:172.19.4.27 UDP: src:41665 dst:162 length:367 checksum:0x9443
      UDP: payload:3082016302010104066573796d6163a782015402041560ae2702010002010030820144301006082b0601020101030043040cd6aeed3019060a2b060106030101040100060b2b060104015e07010300023028060c2b060104015e07010402010204184950444f4d2d312f49504e452d392f49504e4549462d31363012060c2b060104015e0701040201010202062f3018060c2b060104015e070104020103040807da090d0f2a20013013060c2b060104015e070104020104020301e271302c060c2b060104015e070104020105041c504f5254204f5220494e5445524641434520484153204641494c45443011060c2b060104015e070104020106020105302c060c2b060104015e070104020107041c506f7274206f7220696e7465726661636520686173206661696c65643012060c2b060104015e0701040201080202013b3011060c2b060104015e0701040201090201043012060c2b060104015e07010402010a02020b51

      and use it as the value in the $snmptrap

      $trap->buffer($snmptrap);

      My apologies if this looks easy, but I´m still trying to understand how use this modules on my project.

        The UDP packet payload is available as binary data:

        my $payload = $f->ref->{UDP}->payload;
Re: How to parse SNMP traps from pcap file
by VinsWorldcom (Prior) on Jun 15, 2011 at 01:26 UTC

    For decoding SNMP traps, use Net::SNMPTrapd

    You can take your payload and use it directly like:

    #!/usr/bin/perl use strict; use warnings; use Net::SNMPTrapd; my $snmptrap = '3082016302[...]0b51'; # where [...] is you really, really long string my $trap = Net::SNMPTrapd->dump(pack "H*", $snmptrap); #DONE! # OR ... # for a nicely formatted output ... $trap = Net::SNMPTrapd->process_trap(pack "H*", $snmptrap); printf "Version = %i\n", $trap->version; printf "Community = %s\n", $trap->community, printf "PDU Type = %s\n", $trap->pdu_type; if ($trap->version == 1) { printf "Ent. OID = %s\n", $trap->ent_OID; printf "Agent Addr = %s\n", $trap->agentaddr; printf "Generic = %s\n", $trap->generic_trap; printf "Specific = %s\n", $trap->specific_trap; printf "Timeticks = %s\n", $trap->timeticks } else { printf "Request ID = %s\n", $trap->request_ID; printf "Error Stat = %s\n", $trap->error_status; printf "Error Idx = %s\n", $trap->error_index } print "Varbinds:\n"; for my $varbind (@{$trap->varbinds}) { for (keys(%{$varbind})) { printf "%s: %s\n", $_, $varbind->{$_} } }

    Output is as follows:

    VinsWorldcom@C:\Users\VinsWorldcom\tmp> script.pl 0000 355: SEQUENCE { 0004 1: INTEGER = 1 0007 6: STRING = 'esymac' 000F 340: [CONTEXT 7] { 0013 4: INTEGER = 358657575 0019 1: INTEGER = 0 001C 1: INTEGER = 0 001F 324: SEQUENCE { 0023 16: SEQUENCE { 0025 8: OBJECT ID = 1.3.6.1.2.1.1.3.0 002F 4: [APPLICATION 3] 0031 : 0C D6 AE ED __ __ __ __ __ __ __ __ __ __ __ __ . +... 0035 : } 0035 25: SEQUENCE { 0037 10: OBJECT ID = 1.3.6.1.6.3.1.1.4.1.0 0043 11: OBJECT ID = 1.3.6.1.4.1.94.7.1.3.0.2 0050 : } 0050 40: SEQUENCE { 0052 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.2 0060 24: STRING = 'IPDOM-1/IPNE-9/IPNEIF-16' 007A : } 007A 18: SEQUENCE { 007C 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.1 008A 2: INTEGER = 1583 008E : } 008E 24: SEQUENCE { 0090 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.3 009E 8: STRING 00A0 : 07 DA 09 0D 0F 2A 20 01 __ __ __ __ __ __ __ __ . +....* . 00A8 : } 00A8 19: SEQUENCE { 00AA 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.4 00B8 3: INTEGER = 123505 00BD : } 00BD 44: SEQUENCE { 00BF 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.5 00CD 28: STRING = 'PORT OR INTERFACE HAS FAILED' 00EB : } 00EB 17: SEQUENCE { 00ED 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.6 00FB 1: INTEGER = 5 00FE : } 00FE 44: SEQUENCE { 0100 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.7 010E 28: STRING = 'Port or interface has failed' 012C : } 012C 18: SEQUENCE { 012E 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.8 013C 2: INTEGER = 315 0140 : } 0140 17: SEQUENCE { 0142 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.9 0150 1: INTEGER = 4 0153 : } 0153 18: SEQUENCE { 0155 12: OBJECT ID = 1.3.6.1.4.1.94.7.1.4.2.1.10 0163 2: INTEGER = 2897 0167 : } 0167 : } 0167 : } 0167 : } 30 82 01 63 02 01 01 04 06 65 73 79 6D 61 63 A7 0..c.....esymac. 82 01 54 02 04 15 60 AE 27 02 01 00 02 01 00 30 ..T...`.'......0 82 01 44 30 10 06 08 2B 06 01 02 01 01 03 00 43 ..D0...+.......C 04 0C D6 AE ED 30 19 06 0A 2B 06 01 06 03 01 01 .....0...+...... 04 01 00 06 0B 2B 06 01 04 01 5E 07 01 03 00 02 .....+....^..... 30 28 06 0C 2B 06 01 04 01 5E 07 01 04 02 01 02 0(..+....^...... 04 18 49 50 44 4F 4D 2D 31 2F 49 50 4E 45 2D 39 ..IPDOM-1/IPNE-9 2F 49 50 4E 45 49 46 2D 31 36 30 12 06 0C 2B 06 /IPNEIF-160...+. 01 04 01 5E 07 01 04 02 01 01 02 02 06 2F 30 18 ...^........./0. 06 0C 2B 06 01 04 01 5E 07 01 04 02 01 03 04 08 ..+....^........ 07 DA 09 0D 0F 2A 20 01 30 13 06 0C 2B 06 01 04 .....* .0...+... 01 5E 07 01 04 02 01 04 02 03 01 E2 71 30 2C 06 .^..........q0,. 0C 2B 06 01 04 01 5E 07 01 04 02 01 05 04 1C 50 .+....^........P 4F 52 54 20 4F 52 20 49 4E 54 45 52 46 41 43 45 ORT OR INTERFACE 20 48 41 53 20 46 41 49 4C 45 44 30 11 06 0C 2B HAS FAILED0...+ 06 01 04 01 5E 07 01 04 02 01 06 02 01 05 30 2C ....^.........0, 06 0C 2B 06 01 04 01 5E 07 01 04 02 01 07 04 1C ..+....^........ 50 6F 72 74 20 6F 72 20 69 6E 74 65 72 66 61 63 Port or interfac 65 20 68 61 73 20 66 61 69 6C 65 64 30 12 06 0C e has failed0... 2B 06 01 04 01 5E 07 01 04 02 01 08 02 02 01 3B +....^.........; 30 11 06 0C 2B 06 01 04 01 5E 07 01 04 02 01 09 0...+....^...... 02 01 04 30 12 06 0C 2B 06 01 04 01 5E 07 01 04 ...0...+....^... 02 01 0A 02 02 0B 51 __ __ __ __ __ __ __ __ __ ......Q Version = 2 PDU Type = SNMPv2-Trap Community = esymac Request ID = 358657575 Error Stat = 0 Error Idx = 0 Varbinds: 1.3.6.1.2.1.1.3.0: 215396077 1.3.6.1.6.3.1.1.4.1.0: 1.3.6.1.4.1.94.7.1.3.0.2 1.3.6.1.4.1.94.7.1.4.2.1.2: IPDOM-1/IPNE-9/IPNEIF-16 1.3.6.1.4.1.94.7.1.4.2.1.1: 1583 ☼* ☺6.1.4.1.94.7.1.4.2.1.3: ┌ 1.3.6.1.4.1.94.7.1.4.2.1.4: 123505 1.3.6.1.4.1.94.7.1.4.2.1.5: PORT OR INTERFACE HAS FAILED 1.3.6.1.4.1.94.7.1.4.2.1.6: 5 1.3.6.1.4.1.94.7.1.4.2.1.7: Port or interface has failed 1.3.6.1.4.1.94.7.1.4.2.1.8: 315 1.3.6.1.4.1.94.7.1.4.2.1.9: 4 1.3.6.1.4.1.94.7.1.4.2.1.10: 2897

    UPDATE: code and output