Skip to content

Instantly share code, notes, and snippets.

@akirad
Last active August 12, 2018 15:56
Show Gist options
  • Save akirad/7e51ca9dafcacad7c71d0916db7f102a to your computer and use it in GitHub Desktop.
Save akirad/7e51ca9dafcacad7c71d0916db7f102a to your computer and use it in GitHub Desktop.
Send trap perl script
use strict;
use warnings;
use Socket;
use Getopt::Long 'GetOptions';
#---------------
# Constant value
#---------------
my $V1_TRAP = 'a4';
my $V2c_TRAP = 'a7';
my $SNMP_V1 = 0;
my $SNMP_V2C = 1;
my $INTEGER = '02';
my $OCTET_STRING = '04';
my $OBJECT_ID = '06';
my $SEQUENCE = '30';
my $IP_ADDRESS = '40';
my $TIME_TICKS = '43';
#-------------------
# Set default value
#-------------------
my $destAddr = 'localhost';
my $destPort = 162;
my $snmpVersion = '2';
my $enterpriseOid = '1.2.3.200.5';
my $agentAddr = '192.168.0.1';
GetOptions(
'dest=s' => \$destAddr,
'version=s' => \$snmpVersion,
'agentaddr=s' => \$agentAddr
);
#-------------------
# Check user's input
#-------------------
if ($destAddr =~ /^\d/) { # This is an ip address. Because hostname doesn't start from a digit.
if (!isIpAddress($agentAddr)) {
die("$destAddr is not an ip address.");
}
}
if (($snmpVersion ne '1') and ($snmpVersion ne '2') and ($snmpVersion ne '2c')) {
die("$snmpVersion must be 1 or 2(2c)");
}
if (!isIpAddress($agentAddr)) {
die("$agentAddr is not an ip address.");
}
#---------------
# MAIN
#---------------
my $socket;
socket($socket, PF_INET, SOCK_DGRAM, 0) or die "Failed to create socket. $!";
my $addrBin = inet_aton($destAddr);
my $sockAddr = pack_sockaddr_in($destPort, $addrBin);
my $trapData;
if ($snmpVersion eq '1') {
$trapData = constractV1TrapData();
}
elsif (($snmpVersion eq '2') or ($snmpVersion eq '2c')) {
$trapData = constractV2cTrapData();
}
else {
die("Need to specify 1 or 2(2c) for version.");
}
my $trapDataBin = pack("H*", $trapData);
send($socket, $trapDataBin, 0, $sockAddr) or die "Failed to send. $!";
#---------------
# Sub functions
#---------------
sub constractV1TrapData {
my $snmpVersion = $SNMP_V1;
my $commName = 'public';
my $pduType = $V1_TRAP;
my $requestID = 10;
my $errorStatus = 0;
my $errorIndex = 0;
my $genericTrap = 0;
my $specificTrap = 0;
my $timeStamp = 0;
my $snmpVersionBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($snmpVersion));
my $commNameBerUnit = constractBerData($OCTET_STRING, unpack("H*", $commName));
my $enterpriseOidBerUnit = constractBerData($OBJECT_ID, convertOidStrToHexStr($enterpriseOid));
my $agentAddrBerUnit = constractBerData($IP_ADDRESS, convertIpAddrStrToHexStr($agentAddr));
my $genericTrapBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($genericTrap));
my $specificTrapBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($specificTrap));
my $timeStampBerUnit = constractBerData($TIME_TICKS, convertDecNumToHexStr($timeStamp));
my $emptyVarbindBerUnit = constractBerData($SEQUENCE, "");
my $trapPduLength = getBinLengthFromHexStr(
$enterpriseOidBerUnit,
$agentAddrBerUnit,
$genericTrapBerUnit,
$specificTrapBerUnit,
$timeStampBerUnit,
$emptyVarbindBerUnit);
my $totalength = getBinLengthFromHexStr(
$snmpVersionBerUnit,
$commNameBerUnit,
$pduType,
convertDecNumToHexStr($trapPduLength))
+ $trapPduLength;
my $trapData = $SEQUENCE .
convertDecNumToHexStr($totalength) .
$snmpVersionBerUnit .
$commNameBerUnit .
$pduType .
convertDecNumToHexStr($trapPduLength) .
$enterpriseOidBerUnit .
$agentAddrBerUnit .
$genericTrapBerUnit .
$specificTrapBerUnit .
$timeStampBerUnit .
$emptyVarbindBerUnit;
return $trapData;
}
sub constractV2cTrapData {
my $snmpVersion = $SNMP_V2C;
my $commName = 'public';
my $pduType = $V2c_TRAP;
my $requestID = 10;
my $errorStatus = 0;
my $errorIndex = 0;
my $snmpVersionBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($snmpVersion));
my $commNameBerUnit = constractBerData($OCTET_STRING, unpack("H*", $commName));
my $requestIDBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($requestID));
my $errorStatusBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($errorStatus));
my $errorIndexBerUnit = constractBerData($INTEGER, convertDecNumToHexStr($errorIndex));
my $varbindData = constractVarbindData();
my $trapPduLength = getBinLengthFromHexStr(
$requestIDBerUnit,
$errorStatusBerUnit,
$errorIndexBerUnit,
$SEQUENCE,
convertDecNumToHexStr(getBinLengthFromHexStr($varbindData)),
$varbindData);
my $totalength = getBinLengthFromHexStr(
$snmpVersionBerUnit,
$commNameBerUnit,
$pduType,
convertDecNumToHexStr($trapPduLength))
+ $trapPduLength;
my $trapData = $SEQUENCE .
convertDecNumToHexStr($totalength) .
$snmpVersionBerUnit .
$commNameBerUnit .
$pduType .
convertDecNumToHexStr($trapPduLength) .
$requestIDBerUnit .
$errorStatusBerUnit .
$errorIndexBerUnit .
$SEQUENCE .
convertDecNumToHexStr(getBinLengthFromHexStr($varbindData)) .
$varbindData;
return $trapData;
}
sub constractVarbindData {
# ------------------------
# sysUpTime
# ------------------------
my $sysUpTimeOid = '1.3.6.1.2.1.1.3.0';
my $sysUpTimeOidBerData = constractBerData($OBJECT_ID, convertOidStrToHexStr($sysUpTimeOid));
my $sysUpTime = 10;
my $sysUpTimeBerData = constractBerData($TIME_TICKS, convertDecNumToHexStr($sysUpTime));
my $sysUpTimeVarbindLength = getBinLengthFromHexStr($sysUpTimeOidBerData, $sysUpTimeBerData);
my $sysUpTimeVarbind = $SEQUENCE .
convertDecNumToHexStr($sysUpTimeVarbindLength) .
$sysUpTimeOidBerData .
$sysUpTimeBerData;
# ------------------------
# sysTrapOID
# ------------------------
my $sysTrapOid = '1.3.6.1.6.3.1.1.4.1.0';
my $sysTrapOidBerData = constractBerData($OBJECT_ID, convertOidStrToHexStr($sysTrapOid));
my $sysTrapOidData = '1.3.6.1.6.3.1.1.5.1';
my $sysTrapBerData = constractBerData($OBJECT_ID, convertOidStrToHexStr($sysTrapOidData));
my $sysTrapVarbindLength = getBinLengthFromHexStr($sysTrapOidBerData, $sysTrapBerData);
my $sysTrapVarbind = $SEQUENCE .
convertDecNumToHexStr($sysTrapVarbindLength) .
$sysTrapOidBerData .
$sysTrapBerData;
return $sysUpTimeVarbind . $sysTrapVarbind;
}
sub isIpAddress {
my $ipAddr = shift;
my @octets = split(/\./, $ipAddr);
return 0 if (@octets != 4);
foreach my $octet (@octets) {
if (!($octet =~ /^\d+$/) or !(0 <= $octet and $octet <= 255)) {
return 0;
}
}
return 1;
}
sub convertIpAddrStrToHexStr {
my $ipAddrStr = shift;
my @octets = split(/\./, $ipAddrStr);
my $ipAddrHexStr;
foreach my $octet (@octets) {
$ipAddrHexStr .= convertDecNumToHexStr($octet);
}
return $ipAddrHexStr;
}
sub convertOidStrToHexStr {
my $oidStr = shift;
my @oids = split(/\./, $oidStr);
my $hexStr = convertDecNumToHexStr(40*$oids[0] + $oids[1]);
for (my $i = 2; $i <= $#oids; $i++) {
if ($oids[$i] < 128) {
$hexStr .= convertDecNumToHexStr($oids[$i]);
}
else {
convertOidNumToHexStrForMultiBytes($oids[$i]);
}
}
return $hexStr;
}
sub convertOidNumToHexStrForMultiBytes {
my $oidNum = shift;
my $hexStr;
my $counter = 0;
my $workVal = $oidNum;
while (1) {
my $quotient = $workVal / 128;
my $remainder = $workVal % 128;
if ($counter != 0) {
$remainder += 128;
}
$hexStr = convertDecNumToHexStr($remainder) . $hexStr;
if ($quotient == 0) {
last;
}
$workVal = $quotient;
$counter++;
}
return $hexStr;
}
sub getBinLengthFromHexStr {
my @hexStrs = @_;
my $binLength = 0;
foreach my $hexStr (@hexStrs) {
$binLength += length($hexStr)/2;
}
return $binLength;
}
sub constractBerData {
my ($tag, $data) = @_;
$data =~ s/\s//g;
my $binLength = (length($data))/2;
my $berData = $tag . convertDecNumToHexStr($binLength) . $data;
return $berData;
}
sub convertDecNumToHexStr {
my $decNum = shift;
my $hexStr = sprintf("%02x", $decNum);
if (length($hexStr)%2 != 0) {
$hexStr = '0' . $hexStr;
}
return $hexStr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment