ITエンジニアの技術メモ

神奈川在住のITエンジニアの備忘録です。主にプログラミング(Perl, Java など)やネットワーク技術について、自分の中で整理するためにゆるゆると書いています。誰かのご参考になれば幸いです。

SNMP Trap を受信するスクリプト

SNMP Trapを受信し、受信した内容を標準出力に出すperlスクリプト receiveTrap.pl を作成した。
perl receiveTrap.pl」と実行すると、終了するまでSNMP Trapを受信して表示し続ける。終了するには、実行したターミナル上で ctrl + c を実行する。

use strict;
use warnings;
use Socket;

my $TRAP_PORT = 162;
my $BUF_SIZE  = 65535;

my $socket;
socket($socket, PF_INET, SOCK_DGRAM, 0) or die "Failed to create socket. $!\n";
bind($socket, pack_sockaddr_in($TRAP_PORT, INADDR_ANY)) or die "Failed to bind socket. $!\n";

$|=1; # if not, you can't redirect the output to a file.
while (1) {
    my $trapData;
    my $clientInfo = recv($socket, $trapData, $BUF_SIZE, 0) or die "Failed to receive trap data. $!\n";

    my $clientAddr = (unpack_sockaddr_in($clientInfo))[1];
    my $clientAddrStr = inet_ntoa($clientAddr);
    my $trapDataHexDump = unpack("H*", $trapData);
    
    # Split by space. Ex. "01020304" -> "01 02 03 04"
    my @hexDumpArray = $trapDataHexDump =~ /.{2}/g;
    my $trapDataHexDumpSplit;
    foreach my $hexDump (@hexDumpArray) {
        $trapDataHexDumpSplit .= $hexDump . " ";
    }

    my ($sec, $min, $hour, $day, $mon, $year) = (localtime)[0..5];
    $year += 1900;
    $mon += 1;
    print "$year/$mon/$day $hour:$min:$sec\n";
    print "Trap data: \n$trapDataHexDumpSplit\n";
    print "from $clientAddrStr\n\n";
}

受信したSNMP Trapの情報は以下のように出力される。

2018/4/10 1:12:8
Trap data:
xx xx xx xx ...
from 127.0.0.1

「Trap data:」配下の xx は、受信データを16進ダンプしたもの。

なお、

$|=1;

は、perlが出力をバッファしないようにするために指定している。これがないと、標準出力をリダイレクトしてファイルに出力できない。