#!/usr/bin/perl

use Socket;
use strict;

sub disp{
    my $str = $_[0];
    my $len = length($str) / 2;
    my ($line,$lstr,$lchr,$i,$b);
    for ($line = 0; 1 ; $line++){
        $lstr = substr($str,$line*32,32) or last;
        printf "%04x : ",($line * 16);
        $lchr = '';
        for ($i = 0;$i < 16 ;$i++){
            $b = substr($lstr, $i*2 , 2) || '--';
            if ($b ge '20' and $b le '7e'){
                $lchr .= pack("H*", $b);
            }elsif ($b ne '--'){
                $lchr .= '_';
            }
            print "$b ";
            print " " if $i == 7;
        }
        print ": $lchr\n";
    }
}
1;

my ($host,$cname,$oid);
my @oid;
my $pd;
my ($port,$ip,$addr);
my ($snd,$rcv,$rin);

($host,$cname,$oid) = @ARGV;

$oid or die "Usage:perl snmpget.pl ipaddr public .1.3.6.1.2.1.1.5.0";

if ($oid !~ /^\./){
    $oid = '.1.3.6.1.2.1.' . $oid;
}
@oid = split(/\./,$oid);
shift(@oid);
$pd = sprintf("%02x", (shift(@oid)*40 + shift(@oid)) );
foreach (@oid){
    $pd .= sprintf("%02x", $_);
}
$pd = '06' . sprintf("%02x",(length($pd) / 2)) . $pd . '0500';
$pd = '30' . sprintf("%02x",(length($pd) / 2)) . $pd;
$pd = '30' . sprintf("%02x",(length($pd) / 2)) . $pd;
$pd = '020101020100020100' . $pd;
$pd = 'a0' . sprintf("%02x",(length($pd) / 2)) . $pd;
#$pd = 'a0' . sprintf("%02x",(length($pd) / 2)) . $pd;
$pd = sprintf("%02x",length($cname)) . unpack("H*",$cname) . $pd;
$pd = '02010004' . $pd;
$pd = '30' . sprintf("%02x",(length($pd) / 2)) . $pd;


$snd = pack "H*", $pd;

#socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "Socket error.\n";
socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "Socket error.\n";
bind(SOCKET, sockaddr_in(0, INADDR_ANY)) or die "Bind error.\n";
setsockopt(SOCKET, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt: $!";

print "snd.\n";
&disp($pd);
print "\n";

$port = 161;
$ip = inet_aton($host);
$addr = sockaddr_in($port, $ip);
send(SOCKET,$snd,0,$addr);

$rin = '';
vec($rin,fileno(SOCKET),1) = 1;
select($rin, undef, undef, 5) or die "Request timeout.\n";

recv(SOCKET,$rcv,1000,0);

close(SOCKET);

print "rcv.\n";
&disp(unpack "H*", $rcv);

exit;
