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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.