I have been asked to install an HP OpenView agent onto a remote Unix platform to capture SNMP traps forwarded by a client application.
I have since discovered that the client application can only forward SNMPv3 traps, and the agents we use can only accept SNMPv2 traps.
I have discovered that I may be able to resolve this issue through the use of the Perl module NetSNMP::TrapReceiver
but I am unclear how this is setup or how/if you can convert a v3 trap to a v2 trap.
My goal is to capture the v3 trap and, hopefully via a script or tool, convert this to a v2 trap and send it back out on an alternative port.
By chance I have same task for now. So my decision with NetSNMP::TrapReceiver is here:
#!/usr/bin/perl use strict; use warnings; use diagnostics; use Net::SNMP; use SNMP; use Switch; my $snmpTrapDestHost = "127.0.0.1"; my $snmpTrapRemotePort = 16162; #other than default trap port or we got infinite trap loop my $snmpTrapCommunity = "public"; my $snmpTrapVersion = "2c"; my $sess = new SNMP::TrapSession(DestHost => $snmpTrapDestHost, Community => $snmpTrapCommunity, Version => $snmpTrapVersion, RemotePort => $snmpTrapRemotePort); sub my_receiver { print "********** PERL RECEIVED A NOTIFICATION:\n"; my @bunchOfVarbinds; foreach my $x (@{$_[1]}) { printf "'%s' type='%d' value='%s'\n", $x->[0], $x->[2], $x->[1]; my $lsOid = $x->[0]; my $liOid = &SNMP::translateObj($lsOid); my $lsVal = $x->[1]; my $lType = $x->[2]; my $lVal; # You need some convertion here, cause we got data in "human readable" format switch($lType) { case Net::SNMP::OBJECT_IDENTIFIER { $lType = "OBJECTID"; if ($lsVal =~ /OID\:\s+(.*)$/) { $lVal = $1 } else { $lVal = $lsVal; } $lVal = &SNMP::translateObj($lVal); } case Net::SNMP::TIMETICKS { $lType = "TICKS"; if($lsVal =~ /Timeticks\:\s+\((\d+)\)\s+.*$/) { $lVal = $1; } else { my ($d, $h, $m, $s) = split(/\:/, $lsVal); $lVal = $d * 24; $lVal = ($lVal + $h)*60; $lVal = ($lVal + $m)*60; $lVal = ($lVal + $s)*100; } } case Net::SNMP::OCTET_STRING { $lType = "OCTETSTR"; my $isHex; ($isHex, $lVal) = split(/STRING\:\s*/, $lsVal); if (!defined($lVal)) { $lVal = $lsVal; } $lVal =~ s/"//g; if (defined($isHex)) { if($isHex eq "Hex-") { $lVal =~ s/\n//g; $lVal =~ s/ //g; } } } case Net::SNMP::INTEGER { $lType = "INTEGER"; $lVal = $lsVal; } case Net::SNMP::IPADDRESS { # IPADDR # NETADDR $lType = "IPADDR"; $lVal = $lsVal; } case Net::SNMP::COUNTER { # COUNTER $lType = "COUNTER"; $lVal = $lsVal; } case Net::SNMP::COUNTER64 { # COUNTER64 $lType = "COUNTER64"; $lVal = $lsVal; } case Net::SNMP::GAUGE { # GAUGE $lType = "GAUGE"; $lVal = $lsVal; } case Net::SNMP::NULL { # NULL $lType = "NULL"; $lVal = $lsVal; } else { # UINTEGER # OPAQUE $lVal = $lsVal; } } push @bunchOfVarbinds, new SNMP::Varbind([$liOid, undef, $lVal, $lType]); } my $vl = new SNMP::VarList(@bunchOfVarbinds); $sess->trap( oid => $initiTrapProxyServiceOid, uptime => $trapUptimeValue, $vl ); return NETSNMPTRAPD_HANDLER_OK; } $SNMP::use_numeric = 1; NetSNMP::TrapReceiver::register("all", \&my_receiver) || warn "failed to register perl trap handler\n"; print STDERR "Loaded perl snmptrapd handler\n";
I am newbie in perl so any fixes are appreciated.