The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 012
META.json 11
META.yml 11
bin/snmptrapd-sendtest.pl 11
bin/snmptrapd-simple.pl 1123
lib/Net/SNMPTrapd.pm 2418
test.pl 11
7 files changed (This is a version diff) 3957
@@ -1,5 +1,17 @@
 Revision history for Perl extension Net::SNMPTrapd.
 
+0.16  Thu Mar 19 20:30:00 2015
+      - Updated bin/snmptrapd-simple.pl server.
+
+0.15  Wed Mar 18 16:30:00 2015
+      - Fixed informRequest response coming from UDP 162 with original 
+        server socket.
+      - Fixed v6Only tag when selecting IPv6 to account for Windows issues.
+
+0.14  Mon Mar  2 09:30:00 2015
+      - Missing semicolon in bin/snmptrapd-sendtest.pl.
+      - Updated v6Only tag when selecting IPv6 to account for Linux issues.
+
 0.13  Mon Aug  4 09:30:00 2014
       - Top down order for Changes.
       - Added LICENSE to Makefile.PL.
@@ -39,5 +39,5 @@
       }
    },
    "release_status" : "stable",
-   "version" : "0.13"
+   "version" : "0.16"
 }
@@ -21,4 +21,4 @@ requires:
   Convert::ASN1: 0.22
   Socket: 0
   Test::Simple: 0
-version: 0.13
+version: 0.16
@@ -1,7 +1,7 @@
 #! /usr/bin/perl
 
 use strict;
-use warnings
+use warnings;
 use Getopt::Long qw(:config no_ignore_case); #bundling
 use Pod::Usage;
 
@@ -17,6 +17,7 @@ GetOptions(
   'Dump!'       => \$opt{dump},
   'Hexdump!'    => \$opt{hex},
   'interface:i' => \$opt{interface},
+  'time!'       => \$opt{time},
   'write+'      => \$opt{write},
   'help!'       => \$opt_help,
   'man!'        => \$opt_man
@@ -31,10 +32,11 @@ if ($opt{6}) {
     $family = 6
 }
 
-$opt{hex} = $opt{hex} || 0;
+$opt{hex}  = $opt{hex}  || 0;
+$opt{time} = $opt{time} || 0;
 
 # -d is a directory, if it exists, assign it
-if (defined($opt{dir})) {
+if (defined $opt{dir}) {
 
     # replace \ with / for compatibility with UNIX/Windows
     $opt{dir} =~ s/\\/\//g;
@@ -49,7 +51,7 @@ if (defined($opt{dir})) {
     $opt{write} = 1 if (!$opt{write})
 }
 
-if (defined($opt{interface})) {
+if (defined $opt{interface}) {
     if (!(($opt{interface} > 0) && ($opt{interface} < 65536))) {
         print "$0: port not valid - $opt{interface}"
     }
@@ -72,14 +74,14 @@ printf "Listening on %s:%i\n", $snmptrapd->server->sockhost, $snmptrapd->server-
 while (1) {
     my $trap = $snmptrapd->get_trap();
 
-    if (!defined($trap)) {
+    if (!defined $trap) {
         printf "$0: %s\n", Net::SNMPTrapd->error;
         exit 1
     } elsif ($trap == 0) {
         next
     }
 
-    if (!defined($trap->process_trap())) {
+    if (!defined $trap->process_trap()) {
         printf "$0: %s\n", Net::SNMPTrapd->error
     } else {
         my $p;
@@ -88,7 +90,8 @@ while (1) {
         } elsif ($opt{dump}) {
             $trap->dump
         } else {
-            $p = sprintf "%s\t%i\t%i\t%s\t%s\t", 
+            $p = sprintf "%s\t%s\t%i\t%i\t%s\t%s\t", 
+                ($opt{time} ? yyyymmddhhmmss() : time),
                 $trap->remoteaddr, 
                 $trap->remoteport, 
                 $trap->version, 
@@ -121,17 +124,18 @@ while (1) {
                 }
             }
         }
-        print "$p\n";
+        $p .= "\n";
+        print $p;
 
         if ($opt{write}) {
             my $outfile;
-            if (defined($opt{dir})) { $outfile = $opt{dir} . "/" }
+            if (defined $opt{dir}) { $outfile = $opt{dir} . "/" }
 
             $outfile .= "snmptrapd.log";
             
-            if (open(OUT, ">>$outfile")) {
-                print OUT $p;
-                close(OUT)
+            if (open(my $OUT, '>>', $outfile)) {
+                print $OUT $p;
+                close $OUT
             } else {
                 print STDERR "$0: cannot open outfile - $outfile\n"
             }
@@ -139,6 +143,11 @@ while (1) {
     }
 }
 
+sub yyyymmddhhmmss {
+    my @time = localtime();
+    return (($time[5] + 1900) . ((($time[4] + 1) < 10)?("0" . ($time[4] + 1)):($time[4] + 1)) . (($time[3] < 10)?("0" . $time[3]):$time[3]) . (($time[2] < 10)?("0" . $time[2]):$time[2]) . (($time[1] < 10)?("0" . $time[1]):$time[1]) . (($time[0] < 10)?("0" . $time[0]):$time[0]))
+}
+
 __END__
 
 =head1 NAME
@@ -185,6 +194,9 @@ file.  Can decode SNMP v1 and v2c traps and v2c InformRequest
  -i #             UDP Port to listen on.
  --interface      DEFAULT:  (or not specified) 162.
 
+ -t               Print time in human-readable yyyymmddhhmmss format.
+ --time           DEFAULT:  (or not specified) Unix epoch.
+
  -w               Log to "snmptrapd.log".
 
 =head1 LICENSE
@@ -13,7 +13,7 @@ use Socket qw(inet_ntoa AF_INET IPPROTO_TCP);
 my $AF_INET6 = eval { Socket::AF_INET6() };
 my $NI_NUMERICHOST = eval { Socket::NI_NUMERICHOST() };
 
-our $VERSION = '0.13';
+our $VERSION = '0.16';
 our @ISA;
 
 my $HAVE_IO_Socket_IP = 0;
@@ -94,7 +94,6 @@ $asn->prepare("
     }
 ");
 my $snmpasn = $asn->find('PDU');
-
 ########################################################
 # End Variables
 ########################################################
@@ -134,7 +133,10 @@ sub new {
                             $LASTERROR = "IO::Socket::IP required for IPv6";
                             return undef
                         }
-                        $params{Family} = $AF_INET6
+                        $params{Family} = $AF_INET6;
+                        if ($^O ne 'MSWin32') {
+                            $params{V6Only} = 1
+                        }
                     }
                 } else {
                     $LASTERROR = "Invalid family - $cfg{$_}";
@@ -147,6 +149,9 @@ sub new {
                     $LASTERROR = "Invalid timeout - $cfg{$_}";
                     return undef
                 }
+            # pass through
+            } else {
+                $params{$_} = $cfg{$_}
             }
         }
     }
@@ -226,6 +231,7 @@ sub get_trap {
     # read the message
     if ($udpserver->recv($datagram, $datagramsize)) {
 
+        $trap->{_UDPSERVER_} = $udpserver;
         $trap->{_TRAP_}{PeerPort} = $udpserver->SUPER::peerport;
         $trap->{_TRAP_}{PeerAddr} = $udpserver->SUPER::peerhost;
         $trap->{_TRAP_}{datagram} = $datagram;
@@ -450,7 +456,7 @@ sub varbinds {
 }
 
 sub error {
-    return($LASTERROR)
+    return $LASTERROR
 }
 
 sub dump {
@@ -496,37 +502,25 @@ sub _InformRequest_Response {
     my ($self, $trap, $pdutype) = @_;
     my $class = ref($$self) || $$self;
 
+    #DEBUG print "BUFFER = $buffer\n";
+    if (!defined $$self->{_UDPSERVER_}) {
+        return "Server not defined"
+    }
+
     # Change from request to response
     $trap->{pdu_type}{response} = delete $trap->{pdu_type}{inform_request};
-
     my $buffer = $snmpasn->encode($trap);
     if (!defined($buffer)) {
         return $snmpasn->error
     }
-    #DEBUG print "BUFFER = $buffer\n";
-    if (!defined($$self->{_TRAP_}->{PeerAddr}) || ($$self->{_TRAP_}->{PeerAddr} eq "")) {
-        return "Peer Addr undefined"
-    }
-    if (!defined($$self->{_TRAP_}->{PeerPort}) || ($$self->{_TRAP_}->{PeerPort} == 0)) {
-        return "Peer Port undefined"
-    }
 
-    my $socket = $class->SUPER::new(
-        Proto     => "udp",
-        PeerAddr  => $$self->{_TRAP_}->{PeerAddr},
-        PeerPort  => $$self->{_TRAP_}->{PeerPort},
-        # LocalPort should be set, but creates error.
-        # Tried setting ReusePort on initial server,
-        # but not implemented on Windows.  What to do?
-        #LocalPort => SNMPTRAPD_DEFAULT_PORT,
-        Family    => $$self->{Family}
-    ) || return "Can't create Response socket";
+    # send Inform response
+    my $socket = $$self->{_UDPSERVER_};
     $socket->send($buffer);
-    close $socket;
 
     # Change back to request from response
     $trap->{pdu_type}{inform_request} = delete $trap->{pdu_type}{response};
-    return ("OK")
+    return "OK"
 }
 
 sub _inetNtoa {
@@ -334,7 +334,7 @@ sub test5 {
         $snmptrapd->recv($buffer, 1500);
         my $trap;
         if (!defined($trap = Net::SNMPTrapd->process_trap($buffer))) {
-            if ((my $error = sprintf "%s", Net::SNMPTrapd->error) eq "Error sending InformRequest Response - Peer Addr undefined") {
+            if ((my $error = sprintf "%s", Net::SNMPTrapd->error) eq "Error sending InformRequest Response - Server not defined") {
 if ($VERBOSE) {
                 printf "  -- Datagram with no address --\n  %s\n", Net::SNMPTrapd->error
 }