snmptrapd makes got mad -_-
麻 雪蛟 <[email protected]>
| Newsgroups | gmane.network.net-snmp.user |
|---|---|
| Message-ID | <[email protected]> |
hi
I've converted snmptrapd to a c++ class, and my function start_trapd
likes standard snmptrapd's main function...
But a problem lets me got mad, when I use my trapd c++ class for about 5
minutes,it couldn't receive trap message, I debuged it looks like snmp_read
blocked..I don't konw why.
about libsnmptrapd, I only delete WIN32SERVICE marco and main function..
who can tell me why my trapd c++ class sometimes lose trap packet???
(I havn't delete original snmptrapd critical code)
------------------following code---------------------------
#include <net-snmp/net-snmp-config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
//#if HAVE_UNISTD_H
//#include <unistd.h>
//#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <sys/types.h>
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if HAVE_WINSOCK_H
#include <winsock.h>
#else
#include <sys/socket.h>
#endif
//#if HAVE_SYS_SOCKIO_H
//#include <sys/sockio.h>
//#endif
//#if HAVE_NETINET_IN_H
//#include <netinet/in.h>
// #endif
#include <stdio.h>
//#if HAVE_SYS_TIME_H
//# include <sys/time.h>
//# if TIME_WITH_SYS_TIME
//# include <time.h>
//# endif
// #else
#include <time.h>
// #endif
//#if HAVE_SYS_SELECT_H
//#include <sys/select.h>
//#endif
//#if HAVE_SYS_PARAM_H
//#include <sys/param.h>
//#endif
//#if HAVE_SYSLOG_H
//#include <syslog.h>
//#endif
//#if HAVE_SYS_IOCTL_H
//#include <sys/ioctl.h>
//#endif
//#if HAVE_NET_IF_H
//#include <net/if.h>
//#endif
//#if HAVE_NETDB_H
//#include <netdb.h>
//#endif
//#if HAVE_ARPA_INET_H
//#include <arpa/inet.h>
//#endif
//#if HAVE_FCNTL_H
//#include <fcntl.h>
//#endif
//#if HAVE_PROCESS_H /* Win32-getpid */
//#include <process.h>
//#endif
//#include <signal.h>
#include <errno.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "snmptrapd_handlers.h"
/*
* Include an extra Facility variable to allow command line adjustment of
* syslog destination
*/
//int Facility = LOG_DAEMON;
//
//
//const char *app_name = "snmptrapd";
//
//struct timeval Now;
// void trapd_update_config(void);
//static oid risingAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 1 };
//static oid fallingAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 2 };
//static oid unavailableAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 3 };
//#ifdef WIN32SERVICE
//void StopSnmpTrapd(void);
//int SnmpTrapdMain(int argc, TCHAR * argv[]);
//int __cdecl _tmain(int argc, TCHAR * argv[]);
//#else
//int main(int, char **);
// #endif
/*+------------- anders add part--------------------------+*/
//int trap_message_handler(netsnmp_pdu *pdu,
// netsnmp_transport *transport,
// netsnmp_trapd_handler *handler);
extern "C"{
extern struct timeval Now;
extern char *logfile;
extern int Log;
extern int Print;
extern int Syslog;
extern int SyslogTrap;
extern int Event;
extern int dropauth;
extern int running;
extern int reconfig;
extern u_long num_received;
extern char ddefault_port[]; /* Default default port */
extern char *default_port;
//void snmptrapd_close_sessions(netsnmp_session * sess_list);
//netsnmp_session* snmptrapd_add_session(netsnmp_transport *t);
//---------------------2005-12-01 add part---------------------------
extern int Facility;
extern LPTSTR app_name;
void init_subagent(void);
void parse_trapd_address(const char *token, char *cptr);
void free_trapd_address(void);
void trapd_update_config(void);
void init_notification_log(void);
Netsnmp_Node_Handler nlmLogTable_handler;
Netsnmp_Node_Handler nlmLogVariableTable_handler;
Netsnmp_Trap_Handler notification_handler;
Netsnmp_Trap_Handler syslog_handler;
Netsnmp_Trap_Handler print_handler;
Netsnmp_Trap_Handler command_handler;
Netsnmp_Trap_Handler event_handler;
Netsnmp_Trap_Handler forward_handler;
}
static oid risingAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 1 };
static oid fallingAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 2 };
static oid unavailableAlarm[] = { 1, 3, 6, 1, 6, 3, 2, 1, 1, 3, 3 };
static int
pre_parse(netsnmp_session * session, netsnmp_transport *transport,
void *transport_data, int transport_data_length)
{
#if USE_LIBWRAP
char *addr_string = NULL;
if (transport != NULL && transport->f_fmtaddr != NULL) {
/*
* Okay I do know how to format this address for logging.
*/
addr_string = transport->f_fmtaddr(transport, transport_data,
transport_data_length);
/*
* Don't forget to free() it.
*/
}
if (addr_string != NULL) {
if( addr_string[0] == '[' ) { /* fix up ipv6 addr */
int i;
for( i = 1; addr_string[i] != ']'; i++ ) {
addr_string[i-1] = addr_string[i];
}
addr_string[i-1] = '\0';
}
if (hosts_ctl("snmptrapd", STRING_UNKNOWN,
addr_string, STRING_UNKNOWN) == 0) {
free(addr_string);
return 0;
}
free(addr_string);
} else {
if (hosts_ctl("snmptrapd", STRING_UNKNOWN,
STRING_UNKNOWN, STRING_UNKNOWN) == 0) {
return 0;
}
}
#endif /* USE_LIBWRAP */
return 1;
}
static netsnmp_session *
snmptrapd_add_session(netsnmp_transport *t)
{
netsnmp_session sess, *session = &sess, *rc = NULL;
snmp_sess_init(session);
session->peername = SNMP_DEFAULT_PEERNAME; /* Original code had NULL
here */
session->version = SNMP_DEFAULT_VERSION;
session->community_len = SNMP_DEFAULT_COMMUNITY_LEN;
session->retries = SNMP_DEFAULT_RETRIES;
session->timeout = SNMP_DEFAULT_TIMEOUT;
session->callback = snmp_input;
session->callback_magic = (void *) t;
session->authenticator = NULL;
sess.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;
rc = snmp_add(session, t, pre_parse, NULL);
if (rc == NULL) {
snmp_sess_perror("snmptrapd", session);
}
return rc;
}
static void
snmptrapd_close_sessions(netsnmp_session * sess_list)
{
netsnmp_session *s = NULL, *next = NULL;
for (s = sess_list; s != NULL; s = next) {
next = s->next;
snmp_close(s);
}
}
class CSnmpTrapd
{
public:
CSnmpTrapd();
~CSnmpTrapd();
public:
int start_trapd();
static int trap_message_handler(netsnmp_pdu *pdu,
netsnmp_transport *transport,
netsnmp_trapd_handler *handler);
};
int CSnmpTrapd::start_trapd()
{
char options[128] =
"ac:CdD::efF:hHI:l:L:m:M:no:PqsS:tvO:-:";
netsnmp_session *sess_list = NULL, *ss = NULL;
netsnmp_transport *transport = NULL;
int i = 0, depmsg = 0;
int count, numfds, block;
fd_set fdset;
struct timeval timeout, *tvp;
int dofork = 1;
char *cp, *listen_ports = NULL;
char *trap1_fmt_str_remember = NULL;
#if defined(USING_AGENTX_SUBAGENT_MODULE) &&
!defined(SNMPTRAPD_DISABLE_AGENTX)
int agentx_subagent = 1;
#endif
#if HAVE_GETPID
FILE *PID;
char *pid_file = NULL;
#endif
#ifdef SIGTERM
signal(SIGTERM, term_handler);
#endif
#ifdef SIGHUP
signal(SIGHUP, hup_handler);
#endif
#ifdef SIGINT
signal(SIGINT, term_handler);
#endif
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN); /* 'Inline' failure of wayward readers */
#endif
/*
* register our configuration handlers now so -H properly displays them
*/
snmptrapd_register_configs( );
register_config_handler("snmptrapd", "createUser",
usm_parse_create_usmUser, NULL,
"username (MD5|SHA) passphrase [DES
[passphrase]]");
register_config_handler("snmptrapd", "usmUser",
usm_parse_config_usmUser, NULL, NULL);
register_config_handler("snmptrapd", "snmptrapdaddr",
parse_trapd_address, free_trapd_address, NULL);
/*
* we need to be called back later
*/
snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
usm_store_users, NULL);
#ifdef WIN32
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
#else
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
/*
* Add some options if they are available.
*/
#if HAVE_GETPID
strcat(options, "p:u:");
#endif
snmp_log_syslogname(app_name);
/*
add trap message handler
--anders
*/
// netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
trap_message_handler);
/*
* I'm being lazy here, and not checking the
* return value from these registration calls.
* Don't try this at home, children!
*/
if (!Log && !Print) {
Syslog = 1;
netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
syslog_handler);
} else {
netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
print_handler);
}
if (Event) {
netsnmp_add_traphandler(event_handler, risingAlarm,
OID_LENGTH(risingAlarm));
netsnmp_add_traphandler(event_handler, fallingAlarm,
OID_LENGTH(fallingAlarm));
netsnmp_add_traphandler(event_handler, unavailableAlarm,
OID_LENGTH(unavailableAlarm));
/* XXX - might be worth setting some "magic data"
* in the traphandler structure that 'event_handler'
* can use to avoid checking the trap OID values.
*/
}
#if defined(USING_AGENTX_SUBAGENT_MODULE) &&
!defined(SNMPTRAPD_DISABLE_AGENTX)
/*
* we're an agentx subagent?
*/
if (agentx_subagent) {
/*
* make us a agentx client.
*/
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_ROLE, 1);
}
#endif
/*
* don't fail if we can't do agentx (ie, socket not there, or not root)
*/
netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
/*
* ignore any warning messages.
*/
netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS);
/*
* initialize the agent library
*/
init_agent("snmptrapd");
#if defined(USING_AGENTX_SUBAGENT_MODULE) &&
!defined(SNMPTRAPD_DISABLE_AGENTX)
/*
* initialize local modules
*/
if (agentx_subagent) {
init_subagent();
if (should_init("notificationLogMib")) {
netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER,
notification_handler);
init_notification_log();
}
}
#endif
/*
* Initialize the world. Create initial user
*/
init_snmp("snmptrapd");
if (trap1_fmt_str_remember) {
free_trap1_fmt();
free_trap2_fmt();
print_format1 = strdup(trap1_fmt_str_remember);
print_format2 = strdup(trap1_fmt_str_remember);
}
if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
/*
* just starting up to process specific configuration and then
* shutting down immediately.
*/
running = 0;
}
if (Syslog) {
snmp_enable_syslog_ident(app_name, Facility);
snmp_log(LOG_INFO, "Starting snmptrapd %s\n",
netsnmp_get_version());
if (depmsg) {
snmp_log(LOG_WARNING, "-s and -S options are deprecated; use -Ls
<facility> instead\n");
}
}
if (Print || Log) {
struct tm *tm;
time_t timer;
time(&timer);
tm = localtime(&timer);
snmp_log(LOG_INFO,
"%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s
Started.\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
netsnmp_get_version());
}
SOCK_STARTUP;
if (listen_ports)
cp = listen_ports;
else
cp = default_port;
while (cp != NULL) {
char *sep = strchr(cp, ',');
char listen_name[128];
char *cp2 = strchr(cp, ':');
if (sep != NULL) {
*sep = 0;
}
/*
* Make sure this defaults to listening on port 162
*/
if (!cp2) {
snprintf(listen_name, sizeof(listen_name), "%s:162", cp);
cp2 = listen_name;
} else {
cp2 = cp;
}
transport = netsnmp_tdomain_transport(cp2, 1, "udp");
if (transport == NULL) {
snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
cp2, errno, strerror(errno));
snmptrapd_close_sessions(sess_list);
SOCK_CLEANUP;
exit(1);
} else {
ss = snmptrapd_add_session(transport);
if (ss == NULL) {
/*
* Shouldn't happen? We have already opened the transport
* successfully so what could have gone wrong?
*/
snmptrapd_close_sessions(sess_list);
netsnmp_transport_free(transport);
if (Syslog) {
snmp_log(LOG_ERR, "couldn't open snmp - %m");
}
SOCK_CLEANUP;
exit(1);
} else {
ss->next = sess_list;
sess_list = ss;
}
}
/*
* Process next listen address, if there is one.
*/
if (sep != NULL) {
*sep = ',';
cp = sep + 1;
} else {
cp = NULL;
}
}
/*
* ignore early sighup during startup
*/
reconfig = 0;
#ifdef WIN32SERVICE
trapd_status = SNMPTRAPD_RUNNING;
#endif
while (running) {
if (reconfig) {
if (Print || Log) {
struct tm *tm;
time_t timer;
time(&timer);
tm = localtime(&timer);
/*
* If we are logging to a file, receipt of SIGHUP also
* indicates the the log file should be closed and
* re-opened. This is useful for users that want to
* rotate logs in a more predictable manner.
*/
if (logfile)
snmp_enable_filelog(logfile, 1);
snmp_log(LOG_INFO,
"%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s
Reconfigured.\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
netsnmp_get_version());
}
if (Syslog)
snmp_log(LOG_INFO, "Snmptrapd reconfiguring");
trapd_update_config();
if (trap1_fmt_str_remember) {
free_trap1_fmt();
print_format1 = strdup(trap1_fmt_str_remember);
}
reconfig = 0;
}
numfds = 0;
FD_ZERO(&fdset);
block = 1;
tvp = &timeout;
timerclear(tvp);
tvp->tv_sec = 5;
snmp_select_info(&numfds, &fdset, tvp, &block);
if (block == 1)
tvp = NULL; /* block without timeout */
count = select(numfds, &fdset, 0, 0, tvp);
gettimeofday(&Now, 0);
if (count > 0) {
snmp_read(&fdset);
} else
switch (count) {
case 0:
snmp_timeout();
break;
case -1:
if (errno == EINTR)
continue;
snmp_log_perror("select");
running = 0;
break;
default:
fprintf(stderr, "select returned %d\n", count);
running = 0;
}
run_alarms();
}
if (Print || Log) {
struct tm *tm;
time_t timer;
time(&timer);
tm = localtime(&timer);
snmp_log(LOG_INFO,
"%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s
Stopped.\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour,
tm->tm_min, tm->tm_sec, netsnmp_get_version());
}
if (Syslog) {
snmp_log(LOG_INFO, "Stopping snmptrapd");
}
snmptrapd_close_sessions(sess_list);
snmp_shutdown("snmptrapd");
#ifdef WIN32SERVICE
trapd_status = SNMPTRAPD_STOPPED;
#endif
snmp_disable_log();
SOCK_CLEANUP;
return 0;
}
CSnmpTrapd::CSnmpTrapd()
{
}
CSnmpTrapd::~CSnmpTrapd()
{
}
Best Regards
Anders
_________________________________________________________________
璐逛杞 MSN Explorer: http://explorer.msn.com/lccn/
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users