net-snmp/local/snmpdump.pl

108 lines
2.7 KiB
Perl
Executable File

#!/usr/bin/perl
#
# Reformat 'snmpcmd -d' style raw dump output
# into something a little easier to understand.
#
sub parse_dump {
#
# Basic formatting technique:
# Display the contents of each nested SEQUENCE
# indented from the enclosing level.
# Individual data fields are all on one line
#
my @data = @_;
my $indent = shift( @data );
my $datalen = shift( @data );
while ( $datalen > 0 ) {
my ($tag, $tlen, $tmp);
my ($tag1, $tag2 );
$tag = shift( @data );
$tmp = shift( @data );
$tlen = hex($tmp);
#
# Handle 2-octet lengths
if ( $tlen >= 128 ) {
$tlen -= 128;
$tmp = shift( @data );
$tlen += hex($tmp);
}
$datalen -= ($tlen + 2 );
$tag1 = substr($tag, 0, 1);
$tag2 = substr($tag, 1, 1);
#
# Sequence-based tags - display and indent
#
if ( $tag1 eq 3 ) {
print " "x$indent, "$tag $tmp\n";
parse_dump( $indent+3, $tlen, @data );
}
elsif ( $tag1 eq "A" ) {
print " "x$indent, "$tag $tmp\n";
parse_dump( $indent+3, $tlen, @data );
}
#
# Leaf-data tags - just display
#
else {
$val = "";
while ( $tlen > 0 ) {
$val .= " ";
$val .= shift( @data );
$tlen--;
}
if ( $tag1 eq "0" ) { # leaf data
print " "x$indent, "$tag $tmp$val\n";
}
elsif ( $tag1 eq "8" ) { # exceptions
print " "x$indent, "$tag $tmp$val\n";
}
else { # unknown
print " "x$indent, "$tag $tmp$val\n";
}
}
}
}
$inpacket=0;
$rawdump="";
while (<>) {
if ( $inpacket ) {
#
# Strip off the extraneous junk, and join
# the raw dump output into a single line
#
if ( /^[0-9]*: / ) {
chomp;
s/^[0-9]*: //;
s/ .*$//;
s/ / /g;
$rawdump = "$rawdump $_";
} else {
#
# Once this line is complete, display the
# dump in a vaguely sensible layout
#
@rawdata = split( " ", $rawdump );
parse_dump( 3, $#rawdata, @rawdata );
$inpacket=0;
$rawdump="";
}
} else {
#
# Pass everything else through untouched
#
print;
if ( /^Sending / || /^Received / ) {
$inpacket=1;
$rawdump="";
}
}
}