1#!/usr/bin/env perl
2
3#
4# Zabbix
5# Copyright (C) 2001-2021 Zabbix SIA
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20#
21
22#########################################
23#### ABOUT ZABBIX SNMP TRAP RECEIVER ####
24#########################################
25
26# This is an embedded perl SNMP trapper receiver designed for sending data to the server.
27# The receiver will pass the received SNMP traps to Zabbix server or proxy running on the
28# same machine. Please configure the server/proxy accordingly.
29#
30# Read more about using embedded perl with Net-SNMP:
31#	http://net-snmp.sourceforge.net/wiki/index.php/Tut:Extending_snmpd_using_perl
32
33#################################################
34#### ZABBIX SNMP TRAP RECEIVER CONFIGURATION ####
35#################################################
36
37### Option: SNMPTrapperFile
38#	Temporary file used for passing data to the server (or proxy). Must be the same
39#	as in the server (or proxy) configuration file.
40#
41# Mandatory: yes
42# Default:
43$SNMPTrapperFile = '/tmp/zabbix_traps.tmp';
44
45### Option: DateTimeFormat
46#	The date time format in strftime() format. Please make sure to have a corresponding
47#	log time format for the SNMP trap items.
48#
49# Mandatory: yes
50# Default:
51$DateTimeFormat = '%H:%M:%S %Y/%m/%d';
52
53###################################
54#### ZABBIX SNMP TRAP RECEIVER ####
55###################################
56
57use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
58use POSIX qw(strftime);
59
60sub zabbix_receiver
61{
62	my (%pdu_info) = %{$_[0]};
63	my (@varbinds) = @{$_[1]};
64
65	# open the output file
66	unless (sysopen(OUTPUT_FILE, $SNMPTrapperFile, O_WRONLY|O_APPEND|O_CREAT, 0666))
67	{
68		print STDERR "Cannot open [$SNMPTrapperFile]: $!\n";
69		return NETSNMPTRAPD_HANDLER_FAIL;
70	}
71
72	# get the host name
73	my $hostname = $pdu_info{'receivedfrom'} || 'unknown';
74	if ($hostname ne 'unknown')
75	{
76		$hostname =~ /\[(.*?)\].*/;                    # format: "UDP: [127.0.0.1]:41070->[127.0.0.1]"
77		$hostname = $1 || 'unknown';
78	}
79
80	# print trap header
81	#       timestamp must be placed at the beginning of the first line (can be omitted)
82	#       the first line must include the header "ZBXTRAP [IP/DNS address] "
83	#              * IP/DNS address is the used to find the corresponding SNMP trap items
84	#              * this header will be cut during processing (will not appear in the item value)
85	printf OUTPUT_FILE "%s ZBXTRAP %s\n", strftime($DateTimeFormat, localtime), $hostname;
86
87	# print the PDU info
88	print OUTPUT_FILE "PDU INFO:\n";
89	foreach my $key(keys(%pdu_info))
90	{
91		if ($pdu_info{$key} !~ /^[[:print:]]*$/)
92		{
93			my $OctetAsHex = unpack('H*', $pdu_info{$key});	# convert octet string to hex
94			$pdu_info{$key} = "0x$OctetAsHex";		# apply 0x prefix for consistency
95		}
96
97		printf OUTPUT_FILE "  %-30s %s\n", $key, $pdu_info{$key};
98	}
99
100	# print the variable bindings:
101	print OUTPUT_FILE "VARBINDS:\n";
102	foreach my $x (@varbinds)
103	{
104		printf OUTPUT_FILE "  %-30s type=%-2d value=%s\n", $x->[0], $x->[2], $x->[1];
105	}
106
107	close (OUTPUT_FILE);
108
109	return NETSNMPTRAPD_HANDLER_OK;
110}
111
112NetSNMP::TrapReceiver::register("all", \&zabbix_receiver) or
113	die "failed to register Zabbix SNMP trap receiver\n";
114
115print STDOUT "Loaded Zabbix SNMP trap receiver\n";
116