#!/usr/bin/perl
#
# Simple snmptrap logger.
# version 1
# By Pegasus Epsilon <pegasus@pimpninjas.org>
use strict;
use IO::Socket::INET;
# mmm...OOP udp...
my $sock = IO::Socket::INET->new(
LocalPort => '162',
Proto => 'udp'
) or die "Socket error: $!\n";
$sock->autoflush(1);
# Crashing with a full buffer is bad, mmk?
select(((select STDOUT), $| = 1)[0]);
my @months = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
);
while (defined($sock->recv(my $packet, 9999))) {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
# Calculate offset from GMT for RFC822/RFC2822 compliant date format,
# minus day-of-week, which is useless most of the time anyway.
#
# I know of no better/simpler way to sort this out without Date::Manip,
# which is a buttload to require for this. This ought to be right, and
# it's less overhead than Date::Manip.
#
# I'm doing this in-loop, because the daemon may be left running over
# the DST changeover, and i don't want to fiddle with $isdst. Besides,
# the DST changeover may well not be *universally* one hour.
#
# I'd love to see a more efficent way of pulling this off, though...
#
my ($gsec,$gmin,$ghour) = gmtime();
my $gsec = $ghour*3600+$gmin*60+$gsec;
my $lsec = $hour*3600+$min*60+$sec;
my $off = abs($gsec-$lsec)/3600*100;
my $offsign = $lsec > $gsec ? "+" : "-";
printf (
"%02d %s %02d:%02d:%02d %d %s%04d: %s",
$mday, $months[$mon], $hour, $min, $sec, ($year+1900),
$offsign, $off, substr($packet, 74)
);
}