207 lines
7.4 KiB
Diff
207 lines
7.4 KiB
Diff
426355: Cannot set source agent address for SNMP traps
|
|
|
|
Author: Jan Safranek <jsafrane@redhat.com>
|
|
|
|
Introduce "v1trapaddress" snmpd config option, which defines agent address
|
|
set in SNMPv1 traps, i.e. inside the SNMPv1 TRAP-PDU, not UDP packet
|
|
source address. The agent sets arbitrary local address to the TRAP PDU
|
|
when this option is ommited.
|
|
|
|
Index: snmplib/system.c
|
|
===================================================================
|
|
--- snmplib/system.c.orig 2008-06-05 23:11:53.000000000 +0200
|
|
+++ snmplib/system.c 2008-09-06 18:04:38.784302537 +0200
|
|
@@ -77,6 +77,10 @@ SOFTWARE.
|
|
#if HAVE_NET_IF_H
|
|
#include <net/if.h>
|
|
#endif
|
|
+#if HAVE_NETDB_H
|
|
+#include <netdb.h>
|
|
+#endif
|
|
+
|
|
|
|
#if HAVE_SYS_SOCKIO_H
|
|
#include <sys/sockio.h>
|
|
@@ -825,6 +829,84 @@ get_uptime(void)
|
|
#endif /* ! WIN32 */
|
|
/*******************************************************************/
|
|
|
|
+int
|
|
+get_thisaddr(const char* name, in_addr_t *addr_out)
|
|
+{
|
|
+
|
|
+#if HAVE_GETADDRINFO
|
|
+ struct addrinfo *addrs = NULL;
|
|
+ struct addrinfo hint;
|
|
+ int err;
|
|
+
|
|
+ memset(&hint, 0, sizeof hint);
|
|
+ hint.ai_flags = 0;
|
|
+ hint.ai_family = PF_INET;
|
|
+ hint.ai_socktype = SOCK_DGRAM;
|
|
+ hint.ai_protocol = 0;
|
|
+
|
|
+ err = getaddrinfo(name, NULL, &hint, &addrs);
|
|
+ if (err != 0) {
|
|
+#if HAVE_GAI_STRERROR
|
|
+ snmp_log(LOG_ERR, "getaddrinfo: %s %s\n", name,
|
|
+ gai_strerror(err));
|
|
+#else
|
|
+ snmp_log(LOG_ERR, "getaddrinfo: %s (error %d)\n", name,
|
|
+ err);
|
|
+#endif
|
|
+ return -1;
|
|
+ }
|
|
+ if (addrs != NULL) {
|
|
+ memcpy(addr_out,
|
|
+ &((struct sockaddr_in *) addrs->ai_addr)->sin_addr,
|
|
+ sizeof(in_addr_t));
|
|
+ freeaddrinfo(addrs);
|
|
+ } else {
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "Failed to resolve IPv4 hostname\n"));
|
|
+ }
|
|
+ return 0;
|
|
+
|
|
+#elif HAVE_GETHOSTBYNAME
|
|
+ struct hostent *hp = NULL;
|
|
+
|
|
+ hp = gethostbyname(host);
|
|
+ if (hp == NULL) {
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "hostname (couldn't resolve)\n"));
|
|
+ return -1;
|
|
+ } else if (hp->h_addrtype != AF_INET) {
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "hostname (not AF_INET!)\n"));
|
|
+ return -1;
|
|
+ } else {
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "hostname (resolved okay)\n"));
|
|
+ memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
|
|
+ }
|
|
+ return 0;
|
|
+
|
|
+#elif HAVE_GETIPNODEBYNAME
|
|
+ struct hostent *hp = NULL;
|
|
+ int err;
|
|
+
|
|
+ hp = getipnodebyname(peername, AF_INET, 0, &err);
|
|
+ if (hp == NULL) {
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "hostname (couldn't resolve = %d)\n", err));
|
|
+ return -1;
|
|
+ }
|
|
+ DEBUGMSGTL(("get_thisaddr",
|
|
+ "hostname (resolved okay)\n"));
|
|
+ memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
|
|
+ return 0;
|
|
+
|
|
+#else /* HAVE_GETIPNODEBYNAME */
|
|
+ return -1;
|
|
+#endif
|
|
+}
|
|
+
|
|
+/*******************************************************************/
|
|
+
|
|
#ifndef HAVE_STRNCASECMP
|
|
|
|
/*
|
|
Index: man/snmpd.conf.5.def
|
|
===================================================================
|
|
--- man/snmpd.conf.5.def.orig 2008-08-07 11:00:04.000000000 +0200
|
|
+++ man/snmpd.conf.5.def 2008-09-06 18:04:38.788301614 +0200
|
|
@@ -641,6 +641,12 @@ Ordinarily the corresponding MIB
|
|
object (\fCsnmpEnableAuthenTraps.0\fR) is read-write, but specifying
|
|
this directive makes this object read-only, and attempts to set the
|
|
value via SET requests will result in a \fInotWritable\fR error response.
|
|
+.RE
|
|
+.IP "v1trapaddress HOST"
|
|
+defines the agent address, which is inserted into SNMPv1 TRAPs. Arbitrary local
|
|
+IPv4 address is chosen if this option is ommited. This option is useful mainly
|
|
+when the agent is visible from outside world by specific address only (e.g.
|
|
+because of network address translation or firewall).
|
|
.SS "DisMan Event MIB"
|
|
The previous directives can be used to configure where traps should
|
|
be sent, but are not concerned with \fIwhen\fR to send such traps
|
|
Index: include/net-snmp/agent/ds_agent.h
|
|
===================================================================
|
|
--- include/net-snmp/agent/ds_agent.h.orig 2007-05-07 22:23:23.000000000 +0200
|
|
+++ include/net-snmp/agent/ds_agent.h 2008-09-06 18:04:38.823792310 +0200
|
|
@@ -42,6 +42,7 @@
|
|
#define NETSNMP_DS_AGENT_PERL_INIT_FILE 4 /* used by embedded perl */
|
|
#define NETSNMP_DS_SMUX_SOCKET 5 /* ip:port socket addr */
|
|
#define NETSNMP_DS_NOTIF_LOG_CTX 6 /* "" | "snmptrapd" */
|
|
+#define NETSNMP_DS_AGENT_TRAP_ADDR 7 /* used as v1 trap agent addres */
|
|
|
|
/*
|
|
* integers
|
|
Index: include/net-snmp/library/system.h
|
|
===================================================================
|
|
--- include/net-snmp/library/system.h.orig 2007-01-11 23:13:56.000000000 +0100
|
|
+++ include/net-snmp/library/system.h 2008-09-06 18:04:38.855791728 +0200
|
|
@@ -107,6 +107,8 @@ SOFTWARE.
|
|
|
|
#include <net-snmp/types.h> /* For definition of in_addr_t */
|
|
|
|
+ int get_thisaddr(const char* name,
|
|
+ in_addr_t *addr_out);
|
|
in_addr_t get_myaddr(void);
|
|
long get_uptime(void);
|
|
|
|
Index: agent/agent_read_config.c
|
|
===================================================================
|
|
--- agent/agent_read_config.c.orig 2008-07-24 08:53:02.000000000 +0200
|
|
+++ agent/agent_read_config.c 2008-09-06 18:04:38.880308775 +0200
|
|
@@ -243,6 +243,9 @@ init_agent_read_config(const char *app)
|
|
snmpd_free_trapcommunity,
|
|
"community-string");
|
|
#endif /* support for community based SNMP */
|
|
+ netsnmp_ds_register_config(ASN_OCTET_STR, app, "v1trapaddress",
|
|
+ NETSNMP_DS_APPLICATION_ID,
|
|
+ NETSNMP_DS_AGENT_TRAP_ADDR);
|
|
#ifdef HAVE_UNISTD_H
|
|
register_app_config_handler("agentuser",
|
|
snmpd_set_agent_user, NULL, "userid");
|
|
Index: agent/agent_trap.c
|
|
===================================================================
|
|
--- agent/agent_trap.c.orig 2007-05-18 00:16:12.000000000 +0200
|
|
+++ agent/agent_trap.c 2008-09-06 18:06:23.367792400 +0200
|
|
@@ -58,6 +58,7 @@
|
|
#include <net-snmp/utilities.h>
|
|
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
+#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
#include <net-snmp/agent/agent_trap.h>
|
|
#include <net-snmp/agent/snmp_agent.h>
|
|
#include <net-snmp/agent/agent_callbacks.h>
|
|
@@ -639,6 +640,8 @@ netsnmp_send_traps(int trap, int specifi
|
|
in_addr_t *pdu_in_addr_t;
|
|
u_long uptime;
|
|
struct trap_sink *sink;
|
|
+ const char *v1trapaddress;
|
|
+ int res;
|
|
|
|
DEBUGMSGTL(( "trap", "send_trap %d %d ", trap, specific));
|
|
DEBUGMSGOID(("trap", enterprise, enterprise_length));
|
|
@@ -792,7 +795,18 @@ netsnmp_send_traps(int trap, int specifi
|
|
* Ensure that the v1 trap PDU includes the local IP address
|
|
*/
|
|
pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr;
|
|
- *pdu_in_addr_t = get_myaddr();
|
|
+
|
|
+ v1trapaddress = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
|
|
+ NETSNMP_DS_AGENT_TRAP_ADDR);
|
|
+ if (v1trapaddress != NULL) {
|
|
+ /* "v1trapaddress" was specified in config, try to resolve it */
|
|
+ res = get_thisaddr(v1trapaddress, pdu_in_addr_t);
|
|
+ }
|
|
+ if (v1trapaddress == NULL || res < 0) {
|
|
+ /* "v1trapaddress" was not specified in config or the resolution failed,
|
|
+ * try any local address */
|
|
+ *pdu_in_addr_t = get_myaddr();
|
|
+ }
|
|
}
|
|
|
|
|