|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-features.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if HAVE_STDLIB_H
|
|
Packit |
fcad23 |
#include <stdlib.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_UNISTD_H
|
|
Packit |
fcad23 |
#include <unistd.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#include <stdio.h>
|
|
Packit |
fcad23 |
#if HAVE_STRING_H
|
|
Packit |
fcad23 |
#include <string.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
#include <strings.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#include <ctype.h>
|
|
Packit |
fcad23 |
#include <sys/types.h>
|
|
Packit |
fcad23 |
#if HAVE_NETINET_IN_H
|
|
Packit |
fcad23 |
#include <netinet/in.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_NETDB_H
|
|
Packit |
fcad23 |
#include <netdb.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_WAIT_H
|
|
Packit |
fcad23 |
#include <sys/wait.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/config_api.h>
|
|
Packit |
fcad23 |
#include <net-snmp/output_api.h>
|
|
Packit |
fcad23 |
#include <net-snmp/mib_api.h>
|
|
Packit |
fcad23 |
#include <net-snmp/utilities.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit |
fcad23 |
#include "utilities/execute.h"
|
|
Packit |
fcad23 |
#include "snmptrapd_handlers.h"
|
|
Packit |
fcad23 |
#include "snmptrapd_auth.h"
|
|
Packit |
fcad23 |
#include "snmptrapd_log.h"
|
|
Packit |
fcad23 |
#include "notification-log-mib/notification_log.h"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(add_default_traphandler, snmptrapd)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
char *syslog_format1 = NULL;
|
|
Packit |
fcad23 |
char *syslog_format2 = NULL;
|
|
Packit |
fcad23 |
char *print_format1 = NULL;
|
|
Packit |
fcad23 |
char *print_format2 = NULL;
|
|
Packit |
fcad23 |
char *exec_format1 = NULL;
|
|
Packit |
fcad23 |
char *exec_format2 = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int SyslogTrap = 0;
|
|
Packit |
fcad23 |
int dropauth = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
const char *trap1_std_str = "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b] (via %A [%a]): %N\n\t%W Trap (%q) Uptime: %#T\n%v\n";
|
|
Packit |
fcad23 |
const char *trap2_std_str = "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b]:\n%v\n";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void snmptrapd_free_traphandle(void);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
const char *
|
|
Packit |
fcad23 |
trap_description(int trap)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
switch (trap) {
|
|
Packit |
fcad23 |
case SNMP_TRAP_COLDSTART:
|
|
Packit |
fcad23 |
return "Cold Start";
|
|
Packit |
fcad23 |
case SNMP_TRAP_WARMSTART:
|
|
Packit |
fcad23 |
return "Warm Start";
|
|
Packit |
fcad23 |
case SNMP_TRAP_LINKDOWN:
|
|
Packit |
fcad23 |
return "Link Down";
|
|
Packit |
fcad23 |
case SNMP_TRAP_LINKUP:
|
|
Packit |
fcad23 |
return "Link Up";
|
|
Packit |
fcad23 |
case SNMP_TRAP_AUTHFAIL:
|
|
Packit |
fcad23 |
return "Authentication Failure";
|
|
Packit |
fcad23 |
case SNMP_TRAP_EGPNEIGHBORLOSS:
|
|
Packit |
fcad23 |
return "EGP Neighbor Loss";
|
|
Packit |
fcad23 |
case SNMP_TRAP_ENTERPRISESPECIFIC:
|
|
Packit |
fcad23 |
return "Enterprise Specific";
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
return "Unknown Type";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
snmptrapd_parse_traphandle(const char *token, char *line)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char buf[STRINGMAX];
|
|
Packit |
fcad23 |
oid obuf[MAX_OID_LEN];
|
|
Packit |
fcad23 |
size_t olen = MAX_OID_LEN;
|
|
Packit |
fcad23 |
char *cptr, *cp;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph;
|
|
Packit |
fcad23 |
int flags = 0;
|
|
Packit |
fcad23 |
char *format = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
memset( buf, 0, sizeof(buf));
|
|
Packit |
fcad23 |
memset(obuf, 0, sizeof(obuf));
|
|
Packit |
fcad23 |
cptr = copy_nword(line, buf, sizeof(buf));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( buf[0] == '-' && buf[1] == 'F' ) {
|
|
Packit |
fcad23 |
cptr = copy_nword(cptr, buf, sizeof(buf));
|
|
Packit |
fcad23 |
format = strdup( buf );
|
|
Packit |
fcad23 |
cptr = copy_nword(cptr, buf, sizeof(buf));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( !cptr ) {
|
|
Packit |
fcad23 |
netsnmp_config_error("Missing traphandle command (%s)", buf);
|
|
Packit |
fcad23 |
free(format);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("read_config:traphandle", "registering handler for: "));
|
|
Packit |
fcad23 |
if (!strcmp(buf, "default")) {
|
|
Packit |
fcad23 |
DEBUGMSG(("read_config:traphandle", "default"));
|
|
Packit |
fcad23 |
traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
|
|
Packit |
fcad23 |
command_handler );
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
cp = buf+strlen(buf)-1;
|
|
Packit |
fcad23 |
if ( *cp == '*' ) {
|
|
Packit |
fcad23 |
flags |= NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE;
|
|
Packit |
fcad23 |
*(cp--) = '\0';
|
|
Packit |
fcad23 |
if ( *cp == '.' ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Distinguish between 'oid.*' & 'oid*'
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
flags |= NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE;
|
|
Packit |
fcad23 |
*(cp--) = '\0';
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (!read_objid(buf, obuf, &olen)) {
|
|
Packit |
fcad23 |
netsnmp_config_error("Bad trap OID in traphandle directive: %s",
|
|
Packit |
fcad23 |
buf);
|
|
Packit |
fcad23 |
free(format);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGOID(("read_config:traphandle", obuf, olen));
|
|
Packit |
fcad23 |
traph = netsnmp_add_traphandler( command_handler, obuf, olen );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSG(("read_config:traphandle", "\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (traph) {
|
|
Packit |
fcad23 |
traph->flags = flags;
|
|
Packit |
fcad23 |
traph->authtypes = TRAP_AUTH_EXE;
|
|
Packit |
fcad23 |
traph->token = strdup(cptr);
|
|
Packit |
fcad23 |
if (format) {
|
|
Packit |
fcad23 |
traph->format = format;
|
|
Packit |
fcad23 |
format = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
free(format);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
parse_forward(const char *token, char *line)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char buf[STRINGMAX];
|
|
Packit |
fcad23 |
oid obuf[MAX_OID_LEN];
|
|
Packit |
fcad23 |
size_t olen = MAX_OID_LEN;
|
|
Packit |
fcad23 |
char *cptr, *cp;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph;
|
|
Packit |
fcad23 |
int flags = 0;
|
|
Packit |
fcad23 |
char *format = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
memset( buf, 0, sizeof(buf));
|
|
Packit |
fcad23 |
memset(obuf, 0, sizeof(obuf));
|
|
Packit |
fcad23 |
cptr = copy_nword(line, buf, sizeof(buf));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( buf[0] == '-' && buf[1] == 'F' ) {
|
|
Packit |
fcad23 |
cptr = copy_nword(cptr, buf, sizeof(buf));
|
|
Packit |
fcad23 |
format = strdup( buf );
|
|
Packit |
fcad23 |
cptr = copy_nword(cptr, buf, sizeof(buf));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("read_config:forward", "registering forward for: "));
|
|
Packit |
fcad23 |
if (!strcmp(buf, "default")) {
|
|
Packit |
fcad23 |
DEBUGMSG(("read_config:forward", "default"));
|
|
Packit |
fcad23 |
if ( !strcmp( cptr, "agentx" ))
|
|
Packit |
fcad23 |
traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
|
|
Packit |
fcad23 |
axforward_handler );
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
|
|
Packit |
fcad23 |
forward_handler );
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
cp = buf+strlen(buf)-1;
|
|
Packit |
fcad23 |
if ( *cp == '*' ) {
|
|
Packit |
fcad23 |
flags |= NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE;
|
|
Packit |
fcad23 |
*(cp--) = '\0';
|
|
Packit |
fcad23 |
if ( *cp == '.' ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Distinguish between 'oid.*' & 'oid*'
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
flags |= NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE;
|
|
Packit |
fcad23 |
*(cp--) = '\0';
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!read_objid(buf, obuf, &olen)) {
|
|
Packit |
fcad23 |
netsnmp_config_error("Bad trap OID in forward directive: %s", buf);
|
|
Packit |
fcad23 |
free(format);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGOID(("read_config:forward", obuf, olen));
|
|
Packit |
fcad23 |
if ( !strcmp( cptr, "agentx" ))
|
|
Packit |
fcad23 |
traph = netsnmp_add_traphandler( axforward_handler, obuf, olen );
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
traph = netsnmp_add_traphandler( forward_handler, obuf, olen );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSG(("read_config:forward", "\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (traph) {
|
|
Packit |
fcad23 |
traph->flags = flags;
|
|
Packit |
fcad23 |
traph->authtypes = TRAP_AUTH_NET;
|
|
Packit |
fcad23 |
traph->token = strdup(cptr);
|
|
Packit |
fcad23 |
if (format)
|
|
Packit |
fcad23 |
traph->format = format;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
free(format);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
parse_format(const char *token, char *line)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char *cp, *sep;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Extract the first token from the value
|
|
Packit |
fcad23 |
* which tells us which style of format this is
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
cp = line;
|
|
Packit |
fcad23 |
while (*cp && !isspace((unsigned char)(*cp)))
|
|
Packit |
fcad23 |
cp++;
|
|
Packit |
fcad23 |
if (!(*cp)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If we haven't got anything left,
|
|
Packit |
fcad23 |
* then this entry is malformed.
|
|
Packit |
fcad23 |
* So report this, and give up
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sep = cp;
|
|
Packit |
fcad23 |
*(cp++) = '\0';
|
|
Packit |
fcad23 |
while (*cp && isspace((unsigned char)(*cp)))
|
|
Packit |
fcad23 |
cp++;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* OK - now "line" contains the format type,
|
|
Packit |
fcad23 |
* and cp points to the actual format string.
|
|
Packit |
fcad23 |
* So update the appropriate pointer(s).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!strcmp( line, "print1")) {
|
|
Packit |
fcad23 |
SNMP_FREE( print_format1 );
|
|
Packit |
fcad23 |
print_format1 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "print2")) {
|
|
Packit |
fcad23 |
SNMP_FREE( print_format2 );
|
|
Packit |
fcad23 |
print_format2 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "print")) {
|
|
Packit |
fcad23 |
SNMP_FREE( print_format1 );
|
|
Packit |
fcad23 |
SNMP_FREE( print_format2 );
|
|
Packit |
fcad23 |
print_format1 = strdup(cp);
|
|
Packit |
fcad23 |
print_format2 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "syslog1")) {
|
|
Packit |
fcad23 |
SNMP_FREE( syslog_format1 );
|
|
Packit |
fcad23 |
syslog_format1 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "syslog2")) {
|
|
Packit |
fcad23 |
SNMP_FREE( syslog_format2 );
|
|
Packit |
fcad23 |
syslog_format2 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "syslog")) {
|
|
Packit |
fcad23 |
SNMP_FREE( syslog_format1 );
|
|
Packit |
fcad23 |
SNMP_FREE( syslog_format2 );
|
|
Packit |
fcad23 |
syslog_format1 = strdup(cp);
|
|
Packit |
fcad23 |
syslog_format2 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "execute1")) {
|
|
Packit |
fcad23 |
SNMP_FREE( exec_format1 );
|
|
Packit |
fcad23 |
exec_format1 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "execute2")) {
|
|
Packit |
fcad23 |
SNMP_FREE( exec_format2 );
|
|
Packit |
fcad23 |
exec_format2 = strdup(cp);
|
|
Packit |
fcad23 |
} else if (!strcmp( line, "execute")) {
|
|
Packit |
fcad23 |
SNMP_FREE( exec_format1 );
|
|
Packit |
fcad23 |
SNMP_FREE( exec_format2 );
|
|
Packit |
fcad23 |
exec_format1 = strdup(cp);
|
|
Packit |
fcad23 |
exec_format2 = strdup(cp);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
*sep = ' ';
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
parse_trap1_fmt(const char *token, char *line)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
print_format1 = strdup(line);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
free_trap1_fmt(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (print_format1 && print_format1 != trap1_std_str)
|
|
Packit |
fcad23 |
free((char *) print_format1);
|
|
Packit |
fcad23 |
print_format1 = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
parse_trap2_fmt(const char *token, char *line)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
print_format2 = strdup(line);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
free_trap2_fmt(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (print_format2 && print_format2 != trap2_std_str)
|
|
Packit |
fcad23 |
free((char *) print_format2);
|
|
Packit |
fcad23 |
print_format2 = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
snmptrapd_register_configs( void )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
register_config_handler("snmptrapd", "traphandle",
|
|
Packit |
fcad23 |
snmptrapd_parse_traphandle,
|
|
Packit |
fcad23 |
snmptrapd_free_traphandle,
|
|
Packit |
fcad23 |
"oid|\"default\" program [args ...] ");
|
|
Packit |
fcad23 |
register_config_handler("snmptrapd", "format1",
|
|
Packit |
fcad23 |
parse_trap1_fmt, free_trap1_fmt, "format");
|
|
Packit |
fcad23 |
register_config_handler("snmptrapd", "format2",
|
|
Packit |
fcad23 |
parse_trap2_fmt, free_trap2_fmt, "format");
|
|
Packit |
fcad23 |
register_config_handler("snmptrapd", "format",
|
|
Packit |
fcad23 |
parse_format, NULL,
|
|
Packit |
fcad23 |
"[print{,1,2}|syslog{,1,2}|execute{,1,2}] format");
|
|
Packit |
fcad23 |
register_config_handler("snmptrapd", "forward",
|
|
Packit |
fcad23 |
parse_forward, NULL, "OID|\"default\" destination");
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*-----------------------------
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Routines to implement a "registry" of trap handlers
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*-----------------------------*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *netsnmp_auth_global_traphandlers = NULL;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *netsnmp_pre_global_traphandlers = NULL;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *netsnmp_post_global_traphandlers = NULL;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *netsnmp_default_traphandlers = NULL;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *netsnmp_specific_traphandlers = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
typedef struct netsnmp_handler_map_t {
|
|
Packit |
fcad23 |
netsnmp_trapd_handler **handler;
|
|
Packit |
fcad23 |
const char *descr;
|
|
Packit |
fcad23 |
} netsnmp_handler_map;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static netsnmp_handler_map handlers[] = {
|
|
Packit |
fcad23 |
{ &netsnmp_auth_global_traphandlers, "auth trap" },
|
|
Packit |
fcad23 |
{ &netsnmp_pre_global_traphandlers, "pre-global trap" },
|
|
Packit |
fcad23 |
{ NULL, "trap specific" },
|
|
Packit |
fcad23 |
{ &netsnmp_post_global_traphandlers, "global" },
|
|
Packit |
fcad23 |
{ NULL, NULL }
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Register a new "global" traphandler,
|
|
Packit |
fcad23 |
* to be applied to *all* incoming traps
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *
|
|
Packit |
fcad23 |
netsnmp_add_global_traphandler(int list, Netsnmp_Trap_Handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( !handler )
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
traph = SNMP_MALLOC_TYPEDEF(netsnmp_trapd_handler);
|
|
Packit |
fcad23 |
if ( !traph )
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Add this new handler to the front of the appropriate list
|
|
Packit |
fcad23 |
* (or should it go on the end?)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
traph->handler = handler;
|
|
Packit |
fcad23 |
traph->authtypes = TRAP_AUTH_ALL; /* callers will likely change this */
|
|
Packit |
fcad23 |
switch (list) {
|
|
Packit |
fcad23 |
case NETSNMPTRAPD_AUTH_HANDLER:
|
|
Packit |
fcad23 |
traph->nexth = netsnmp_auth_global_traphandlers;
|
|
Packit |
fcad23 |
netsnmp_auth_global_traphandlers = traph;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case NETSNMPTRAPD_PRE_HANDLER:
|
|
Packit |
fcad23 |
traph->nexth = netsnmp_pre_global_traphandlers;
|
|
Packit |
fcad23 |
netsnmp_pre_global_traphandlers = traph;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case NETSNMPTRAPD_POST_HANDLER:
|
|
Packit |
fcad23 |
traph->nexth = netsnmp_post_global_traphandlers;
|
|
Packit |
fcad23 |
netsnmp_post_global_traphandlers = traph;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case NETSNMPTRAPD_DEFAULT_HANDLER:
|
|
Packit |
fcad23 |
traph->nexth = netsnmp_default_traphandlers;
|
|
Packit |
fcad23 |
netsnmp_default_traphandlers = traph;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
free( traph );
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_ADD_DEFAULT_TRAPHANDLER
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Register a new "default" traphandler, to be applied to all
|
|
Packit |
fcad23 |
* traps with no specific trap handlers of their own.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *
|
|
Packit |
fcad23 |
netsnmp_add_default_traphandler(Netsnmp_Trap_Handler *handler) {
|
|
Packit |
fcad23 |
return netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
|
|
Packit |
fcad23 |
handler);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_ADD_DEFAULT_TRAPHANDLER */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Register a new trap-specific traphandler
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *
|
|
Packit |
fcad23 |
netsnmp_add_traphandler(Netsnmp_Trap_Handler* handler,
|
|
Packit |
fcad23 |
oid *trapOid, int trapOidLen ) {
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph, *traph2;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( !handler )
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
traph = SNMP_MALLOC_TYPEDEF(netsnmp_trapd_handler);
|
|
Packit |
fcad23 |
if ( !traph )
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Populate this new handler with the trap information
|
|
Packit |
fcad23 |
* (NB: the OID fields were not used in the default/global lists)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
traph->authtypes = TRAP_AUTH_ALL; /* callers will likely change this */
|
|
Packit |
fcad23 |
traph->handler = handler;
|
|
Packit |
fcad23 |
traph->trapoid_len = trapOidLen;
|
|
Packit |
fcad23 |
traph->trapoid = snmp_duplicate_objid(trapOid, trapOidLen);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Now try to find the appropriate place in the trap-specific
|
|
Packit |
fcad23 |
* list for this particular trap OID. If there's a matching OID
|
|
Packit |
fcad23 |
* already, then find it. Otherwise find the one that follows.
|
|
Packit |
fcad23 |
* If we run out of entried, the new one should be tacked onto the end.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
for (traph2 = netsnmp_specific_traphandlers;
|
|
Packit |
fcad23 |
traph2; traph2 = traph2->nextt) {
|
|
Packit |
fcad23 |
/* XXX - check this! */
|
|
Packit |
fcad23 |
if (snmp_oid_compare(traph2->trapoid, traph2->trapoid_len,
|
|
Packit |
fcad23 |
trapOid, trapOidLen) <= 0)
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (traph2) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* OK - We've either got an exact match, or we've found the
|
|
Packit |
fcad23 |
* entry *after* where the new one should go.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!snmp_oid_compare(traph->trapoid, traph->trapoid_len,
|
|
Packit |
fcad23 |
traph2->trapoid, traph2->trapoid_len)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Exact match, so find the end of the *handler* list
|
|
Packit |
fcad23 |
* and tack on this new entry...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
while (traph2->nexth)
|
|
Packit |
fcad23 |
traph2 = traph2->nexth;
|
|
Packit |
fcad23 |
traph2->nexth = traph;
|
|
Packit |
fcad23 |
traph->nextt = traph2->nextt; /* Might as well... */
|
|
Packit |
fcad23 |
traph->prevt = traph2->prevt;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* .. or the following entry, so insert the new one before it.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
traph->prevt = traph2->prevt;
|
|
Packit |
fcad23 |
if (traph2->prevt)
|
|
Packit |
fcad23 |
traph2->prevt->nextt = traph;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
netsnmp_specific_traphandlers = traph;
|
|
Packit |
fcad23 |
traph2->prevt = traph;
|
|
Packit |
fcad23 |
traph->nextt = traph2;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If we've run out of entries without finding a suitable spot,
|
|
Packit |
fcad23 |
* the new one should be tacked onto the end.....
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (netsnmp_specific_traphandlers) {
|
|
Packit |
fcad23 |
traph2 = netsnmp_specific_traphandlers;
|
|
Packit |
fcad23 |
while (traph2->nextt)
|
|
Packit |
fcad23 |
traph2 = traph2->nextt;
|
|
Packit |
fcad23 |
traph2->nextt = traph;
|
|
Packit |
fcad23 |
traph->prevt = traph2;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* .... unless this is the very first entry, of course!
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_specific_traphandlers = traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
snmptrapd_free_traphandle(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph = NULL, *nextt = NULL, *nexth = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("snmptrapd", "Freeing trap handler lists\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Free default trap handlers
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
traph = netsnmp_default_traphandlers;
|
|
Packit |
fcad23 |
/* loop over handlers */
|
|
Packit |
fcad23 |
while (traph) {
|
|
Packit |
fcad23 |
DEBUGMSG(("snmptrapd", "Freeing default trap handler\n"));
|
|
Packit |
fcad23 |
nexth = traph->nexth;
|
|
Packit |
fcad23 |
SNMP_FREE(traph->token);
|
|
Packit |
fcad23 |
SNMP_FREE(traph);
|
|
Packit |
fcad23 |
traph = nexth;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
netsnmp_default_traphandlers = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Free specific trap handlers
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
traph = netsnmp_specific_traphandlers;
|
|
Packit |
fcad23 |
/* loop over traps */
|
|
Packit |
fcad23 |
while (traph) {
|
|
Packit |
fcad23 |
nextt = traph->nextt;
|
|
Packit |
fcad23 |
/* loop over handlers for this trap */
|
|
Packit |
fcad23 |
while (traph) {
|
|
Packit |
fcad23 |
DEBUGMSG(("snmptrapd", "Freeing specific trap handler\n"));
|
|
Packit |
fcad23 |
nexth = traph->nexth;
|
|
Packit |
fcad23 |
SNMP_FREE(traph->token);
|
|
Packit |
fcad23 |
SNMP_FREE(traph->trapoid);
|
|
Packit |
fcad23 |
SNMP_FREE(traph);
|
|
Packit |
fcad23 |
traph = nexth;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
traph = nextt;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
netsnmp_specific_traphandlers = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Locate the list of handlers for this particular Trap OID
|
|
Packit |
fcad23 |
* Returns NULL if there are no relevant traps
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *
|
|
Packit |
fcad23 |
netsnmp_get_traphandler( oid *trapOid, int trapOidLen ) {
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!trapOid || !trapOidLen) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler no OID!\n"));
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup", "Looking up Trap OID: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("snmptrapd:lookup", trapOid, trapOidLen));
|
|
Packit |
fcad23 |
DEBUGMSG(( "snmptrapd:lookup", "\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Look for a matching OID, and return that list...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
for (traph = netsnmp_specific_traphandlers;
|
|
Packit |
fcad23 |
traph; traph=traph->nextt ) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If the trap handler wasn't wildcarded, then the trapOID
|
|
Packit |
fcad23 |
* should match the registered OID exactly.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!(traph->flags & NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE)) {
|
|
Packit |
fcad23 |
if (snmp_oid_compare(traph->trapoid, traph->trapoid_len,
|
|
Packit |
fcad23 |
trapOid, trapOidLen) == 0) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup",
|
|
Packit |
fcad23 |
"get_traphandler exact match (%p)\n", traph));
|
|
Packit |
fcad23 |
return traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If the trap handler *was* wildcarded, then the trapOID
|
|
Packit |
fcad23 |
* should have the registered OID as a prefix...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (snmp_oidsubtree_compare(traph->trapoid,
|
|
Packit |
fcad23 |
traph->trapoid_len,
|
|
Packit |
fcad23 |
trapOid, trapOidLen) == 0) {
|
|
Packit |
fcad23 |
if (traph->flags & NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and (optionally) *strictly* as a prefix
|
|
Packit |
fcad23 |
* i.e. not including an exact match.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (snmp_oid_compare(traph->trapoid, traph->trapoid_len,
|
|
Packit |
fcad23 |
trapOid, trapOidLen) != 0) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler strict subtree match (%p)\n", traph));
|
|
Packit |
fcad23 |
return traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler subtree match (%p)\n", traph));
|
|
Packit |
fcad23 |
return traph;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* .... or failing that, return the "default" list (which may be NULL)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler default (%p)\n",
|
|
Packit |
fcad23 |
netsnmp_default_traphandlers));
|
|
Packit |
fcad23 |
return netsnmp_default_traphandlers;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*-----------------------------
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Standard traphandlers for the common requirements
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*-----------------------------*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define SYSLOG_V1_STANDARD_FORMAT "%a: %W Trap (%q) Uptime: %#T%#v\n"
|
|
Packit |
fcad23 |
#define SYSLOG_V1_ENTERPRISE_FORMAT "%a: %W Trap (%q) Uptime: %#T%#v\n" /* XXX - (%q) become (.N) ??? */
|
|
Packit |
fcad23 |
#define SYSLOG_V23_NOTIFICATION_FORMAT "%B [%b]: Trap %#v\n" /* XXX - introduces a leading " ," */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Trap handler for logging via syslog
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int syslog_handler( netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
u_char *rbuf = NULL;
|
|
Packit |
fcad23 |
size_t r_len = 64, o_len = 0;
|
|
Packit |
fcad23 |
int trunc = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "syslog_handler\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (SyslogTrap)
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If there's a format string registered for this trap, then use it.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (handler && handler->format) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
|
|
Packit |
fcad23 |
if (*handler->format) {
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
handler->format, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
free(rbuf);
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK; /* A 0-length format string means don't log */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Otherwise (i.e. a NULL handler format string),
|
|
Packit |
fcad23 |
* use a standard output format setting
|
|
Packit |
fcad23 |
* either configurable, or hardwired
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* XXX - v1 traps use a different hardwired formats for
|
|
Packit |
fcad23 |
* standard and enterprise specific traps
|
|
Packit |
fcad23 |
* Do we actually need this?
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if ( pdu->command == SNMP_MSG_TRAP ) {
|
|
Packit |
fcad23 |
if (syslog_format1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "syslog_format v1 = '%s'\n", syslog_format1));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
syslog_format1, pdu, transport);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} else if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "v1 enterprise format\n"));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
SYSLOG_V1_ENTERPRISE_FORMAT,
|
|
Packit |
fcad23 |
pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "v1 standard trap format\n"));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
SYSLOG_V1_STANDARD_FORMAT,
|
|
Packit |
fcad23 |
pdu, transport);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else { /* SNMPv2/3 notifications */
|
|
Packit |
fcad23 |
if (syslog_format2) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "syslog_format v1 = '%s'\n", syslog_format2));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
syslog_format2, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "v2/3 format\n"));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
SYSLOG_V23_NOTIFICATION_FORMAT,
|
|
Packit |
fcad23 |
pdu, transport);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_log(LOG_WARNING, "%s%s", rbuf, (trunc?" [TRUNCATED]\n":""));
|
|
Packit |
fcad23 |
free(rbuf);
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define PRINT_V23_NOTIFICATION_FORMAT "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b]:\n%v\n"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Trap handler for logging to a file
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int print_handler( netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
u_char *rbuf = NULL;
|
|
Packit |
fcad23 |
size_t r_len = 64, o_len = 0;
|
|
Packit |
fcad23 |
int trunc = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "print_handler\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Don't bother logging authentication failures
|
|
Packit |
fcad23 |
* XXX - can we handle this via suitable handler entries instead?
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (pdu->trap_type == SNMP_TRAP_AUTHFAIL && dropauth)
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If there's a format string registered for this trap, then use it.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (handler && handler->format) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
|
|
Packit |
fcad23 |
if (*handler->format) {
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
handler->format, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
free(rbuf);
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK; /* A 0-length format string means don't log */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Otherwise (i.e. a NULL handler format string),
|
|
Packit |
fcad23 |
* use a standard output format setting
|
|
Packit |
fcad23 |
* either configurable, or hardwired
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* XXX - v1 traps use a different routine for hardwired output
|
|
Packit |
fcad23 |
* Do we actually need this separate v1 routine?
|
|
Packit |
fcad23 |
* Or would a suitable format string be sufficient?
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if ( pdu->command == SNMP_MSG_TRAP ) {
|
|
Packit |
fcad23 |
if (print_format1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "print_format v1 = '%s'\n", print_format1));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
print_format1, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "v1 format\n"));
|
|
Packit |
fcad23 |
trunc = !realloc_format_plain_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
pdu, transport);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if (print_format2) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "print_format v2 = '%s'\n", print_format2));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
print_format2, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "v2/3 format\n"));
|
|
Packit |
fcad23 |
trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
PRINT_V23_NOTIFICATION_FORMAT,
|
|
Packit |
fcad23 |
pdu, transport);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_log(LOG_INFO, "%s%s", rbuf, (trunc?" [TRUNCATED]\n":""));
|
|
Packit |
fcad23 |
free(rbuf);
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define EXECUTE_FORMAT "%B\n%b\n%V\n%v\n"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Trap handler for invoking a suitable script
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int command_handler( netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifndef USING_UTILITIES_EXECUTE_MODULE
|
|
Packit |
fcad23 |
NETSNMP_LOGONCE((LOG_WARNING,
|
|
Packit |
fcad23 |
"support for run_shell_command not available\n"));
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_FAIL;
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
u_char *rbuf = NULL;
|
|
Packit |
fcad23 |
size_t r_len = 64, o_len = 0;
|
|
Packit |
fcad23 |
int oldquick;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "command_handler\n"));
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "token = '%s'\n", handler->token));
|
|
Packit |
fcad23 |
if (handler && handler->token && *handler->token) {
|
|
Packit |
fcad23 |
netsnmp_pdu *v2_pdu = NULL;
|
|
Packit |
fcad23 |
if (pdu->command == SNMP_MSG_TRAP)
|
|
Packit |
fcad23 |
v2_pdu = convert_v1pdu_to_v2(pdu);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
v2_pdu = pdu;
|
|
Packit |
fcad23 |
oldquick = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_QUICK_PRINT);
|
|
Packit |
fcad23 |
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_QUICK_PRINT, 1);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Format the trap and pass this string to the external command
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If there's a format string registered for this trap, then use it.
|
|
Packit |
fcad23 |
* Otherwise use the standard execution format setting.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (handler && handler->format && *handler->format) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
|
|
Packit |
fcad23 |
realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
handler->format,
|
|
Packit |
fcad23 |
v2_pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if ( pdu->command == SNMP_MSG_TRAP && exec_format1 ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "exec v1 = '%s'\n", exec_format1));
|
|
Packit |
fcad23 |
realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
exec_format1, pdu, transport);
|
|
Packit |
fcad23 |
} else if ( pdu->command != SNMP_MSG_TRAP && exec_format2 ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "exec v2/3 = '%s'\n", exec_format2));
|
|
Packit |
fcad23 |
realloc_format_trap(&rbuf, &r_len, &o_len, 1,
|
|
Packit |
fcad23 |
exec_format2, pdu, transport);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "execute format\n"));
|
|
Packit |
fcad23 |
realloc_format_trap(&rbuf, &r_len, &o_len, 1, EXECUTE_FORMAT,
|
|
Packit |
fcad23 |
v2_pdu, transport);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* and pass this formatted string to the command specified
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
run_shell_command(handler->token, (char*)rbuf, NULL, NULL); /* Not interested in output */
|
|
Packit |
fcad23 |
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_QUICK_PRINT, oldquick);
|
|
Packit |
fcad23 |
if (pdu->command == SNMP_MSG_TRAP)
|
|
Packit |
fcad23 |
snmp_free_pdu(v2_pdu);
|
|
Packit |
fcad23 |
free(rbuf);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
#endif /* !def USING_UTILITIES_EXECUTE_MODULE */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Trap handler for forwarding to the AgentX master agent
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int axforward_handler( netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
send_v2trap( pdu->variables );
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Trap handler for forwarding to another destination
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int forward_handler( netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_session session, *ss;
|
|
Packit |
fcad23 |
netsnmp_pdu *pdu2;
|
|
Packit |
fcad23 |
char buf[BUFSIZ], *cp;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "forward_handler (%s)\n", handler->token));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
snmp_sess_init( &session );
|
|
Packit |
fcad23 |
if (strchr( handler->token, ':') == NULL) {
|
|
Packit |
fcad23 |
snprintf( buf, BUFSIZ, "%s:%d", handler->token, SNMP_TRAP_PORT);
|
|
Packit |
fcad23 |
cp = buf;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
cp = handler->token;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
session.peername = cp;
|
|
Packit |
fcad23 |
session.version = pdu->version;
|
|
Packit |
fcad23 |
ss = snmp_open( &session );
|
|
Packit |
fcad23 |
if (!ss)
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_FAIL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* XXX: wjh we should be caching sessions here and not always
|
|
Packit |
fcad23 |
reopening a session. It's very ineffecient, especially with v3
|
|
Packit |
fcad23 |
INFORMS which may require engineID probing */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
pdu2 = snmp_clone_pdu(pdu);
|
|
Packit |
fcad23 |
if (pdu2->transport_data) {
|
|
Packit |
fcad23 |
free(pdu2->transport_data);
|
|
Packit |
fcad23 |
pdu2->transport_data = NULL;
|
|
Packit |
fcad23 |
pdu2->transport_data_length = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
ss->s_snmp_errno = SNMPERR_SUCCESS;
|
|
Packit |
fcad23 |
if (!snmp_send( ss, pdu2 ) &&
|
|
Packit |
fcad23 |
ss->s_snmp_errno != SNMPERR_SUCCESS) {
|
|
Packit |
fcad23 |
snmp_sess_perror("Forward failed", ss);
|
|
Packit |
fcad23 |
snmp_free_pdu(pdu2);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_close( ss );
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if defined(USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE) && defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* "Notification" handler for implementing NOTIFICATION-MIB
|
|
Packit |
fcad23 |
* (presumably)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int notification_handler(netsnmp_pdu *pdu,
|
|
Packit |
fcad23 |
netsnmp_transport *transport,
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *handler)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "notification_handler\n"));
|
|
Packit |
fcad23 |
log_notification(pdu, transport);
|
|
Packit |
fcad23 |
return NETSNMPTRAPD_HANDLER_OK;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*-----------------------------
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Main driving code, to process an incoming trap
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*-----------------------------*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
snmp_input(int op, netsnmp_session *session,
|
|
Packit |
fcad23 |
int reqid, netsnmp_pdu *pdu, void *magic)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
oid stdTrapOidRoot[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5 };
|
|
Packit |
fcad23 |
oid snmpTrapOid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
|
|
Packit |
fcad23 |
oid trapOid[MAX_OID_LEN+2] = {0};
|
|
Packit |
fcad23 |
int trapOidLen;
|
|
Packit |
fcad23 |
netsnmp_variable_list *vars;
|
|
Packit |
fcad23 |
netsnmp_trapd_handler *traph;
|
|
Packit |
fcad23 |
netsnmp_transport *transport = (netsnmp_transport *) magic;
|
|
Packit |
fcad23 |
int ret, idx;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
switch (op) {
|
|
Packit |
fcad23 |
case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Drops packets with reception problems
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (session->s_snmp_errno) {
|
|
Packit |
fcad23 |
/* drop problem packets */
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Determine the OID that identifies the trap being handled
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(("snmptrapd", "input: %x\n", pdu->command));
|
|
Packit |
fcad23 |
switch (pdu->command) {
|
|
Packit |
fcad23 |
case SNMP_MSG_TRAP:
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Convert v1 traps into a v2-style trap OID
|
|
Packit |
fcad23 |
* (following RFC 2576)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
|
|
Packit |
fcad23 |
trapOidLen = pdu->enterprise_length;
|
|
Packit |
fcad23 |
memcpy(trapOid, pdu->enterprise, sizeof(oid) * trapOidLen);
|
|
Packit |
fcad23 |
if (trapOid[trapOidLen - 1] != 0) {
|
|
Packit |
fcad23 |
trapOid[trapOidLen++] = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
trapOid[trapOidLen++] = pdu->specific_type;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
memcpy(trapOid, stdTrapOidRoot, sizeof(stdTrapOidRoot));
|
|
Packit |
fcad23 |
trapOidLen = OID_LENGTH(stdTrapOidRoot); /* 9 */
|
|
Packit |
fcad23 |
trapOid[trapOidLen++] = pdu->trap_type+1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
case SNMP_MSG_TRAP2:
|
|
Packit |
fcad23 |
case SNMP_MSG_INFORM:
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* v2c/v3 notifications *should* have snmpTrapOID as the
|
|
Packit |
fcad23 |
* second varbind, so we can go straight there.
|
|
Packit |
fcad23 |
* But check, just to make sure
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vars = pdu->variables;
|
|
Packit |
fcad23 |
if (vars)
|
|
Packit |
fcad23 |
vars = vars->next_variable;
|
|
Packit |
fcad23 |
if (!vars || snmp_oid_compare(vars->name, vars->name_length,
|
|
Packit |
fcad23 |
snmpTrapOid, OID_LENGTH(snmpTrapOid))) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Didn't find it!
|
|
Packit |
fcad23 |
* Let's look through the full list....
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
for ( vars = pdu->variables; vars; vars=vars->next_variable) {
|
|
Packit |
fcad23 |
if (!snmp_oid_compare(vars->name, vars->name_length,
|
|
Packit |
fcad23 |
snmpTrapOid, OID_LENGTH(snmpTrapOid)))
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (!vars) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Still can't find it! Give up.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "Cannot find TrapOID in TRAP2 PDU\n");
|
|
Packit |
fcad23 |
return 1; /* ??? */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
memcpy(trapOid, vars->val.objid, vars->val_len);
|
|
Packit |
fcad23 |
trapOidLen = vars->val_len /sizeof(oid);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
/* SHOULDN'T HAPPEN! */
|
|
Packit |
fcad23 |
return 1; /* ??? */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "snmptrapd", "Trap OID: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("snmptrapd", trapOid, trapOidLen));
|
|
Packit |
fcad23 |
DEBUGMSG(( "snmptrapd", "\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* OK - We've found the Trap OID used to identify this trap.
|
|
Packit |
fcad23 |
* Call each of the various lists of handlers:
|
|
Packit |
fcad23 |
* a) authentication-related handlers,
|
|
Packit |
fcad23 |
* b) other handlers to be applied to all traps
|
|
Packit |
fcad23 |
* (*before* trap-specific handlers)
|
|
Packit |
fcad23 |
* c) the handler(s) specific to this trap
|
|
Packit |
fcad23 |
t * d) any other global handlers
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* In each case, a particular trap handler can abort further
|
|
Packit |
fcad23 |
* processing - either just for that particular list,
|
|
Packit |
fcad23 |
* or for the trap completely.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* This is particularly designed for authentication-related
|
|
Packit |
fcad23 |
* handlers, but can also be used elsewhere.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* OK - Enough waffling, let's get to work.....
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for( idx = 0; handlers[idx].descr; ++idx ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("snmptrapd", "Running %s handlers\n",
|
|
Packit |
fcad23 |
handlers[idx].descr));
|
|
Packit |
fcad23 |
if (NULL == handlers[idx].handler) /* specific */
|
|
Packit |
fcad23 |
traph = netsnmp_get_traphandler(trapOid, trapOidLen);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
traph = *handlers[idx].handler;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for( ; traph; traph = traph->nexth) {
|
|
Packit |
fcad23 |
if (!netsnmp_trapd_check_auth(traph->authtypes))
|
|
Packit |
fcad23 |
continue; /* we continue on and skip this one */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
ret = (*(traph->handler))(pdu, transport, traph);
|
|
Packit |
fcad23 |
if(NETSNMPTRAPD_HANDLER_FINISH == ret)
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
if (ret == NETSNMPTRAPD_HANDLER_BREAK)
|
|
Packit |
fcad23 |
break; /* move on to next type */
|
|
Packit |
fcad23 |
} /* traph */
|
|
Packit |
fcad23 |
} /* handlers */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (pdu->command == SNMP_MSG_INFORM) {
|
|
Packit |
fcad23 |
netsnmp_pdu *reply = snmp_clone_pdu(pdu);
|
|
Packit |
fcad23 |
if (!reply) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't clone PDU for INFORM response\n");
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
reply->command = SNMP_MSG_RESPONSE;
|
|
Packit |
fcad23 |
reply->errstat = 0;
|
|
Packit |
fcad23 |
reply->errindex = 0;
|
|
Packit |
fcad23 |
if (!snmp_send(session, reply)) {
|
|
Packit |
fcad23 |
snmp_sess_perror("snmptrapd: Couldn't respond to inform pdu",
|
|
Packit |
fcad23 |
session);
|
|
Packit |
fcad23 |
snmp_free_pdu(reply);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
case NETSNMP_CALLBACK_OP_TIMED_OUT:
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "Timeout: This shouldn't happen!\n");
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
case NETSNMP_CALLBACK_OP_SEND_FAILED:
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "Send Failed: This shouldn't happen either!\n");
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
case NETSNMP_CALLBACK_OP_CONNECT:
|
|
Packit |
fcad23 |
case NETSNMP_CALLBACK_OP_DISCONNECT:
|
|
Packit |
fcad23 |
/* Ignore silently */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "Unknown operation (%d): This shouldn't happen!\n", op);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|