コード例 #1
0
ファイル: event.c プロジェクト: kghost/lldpd
/*
 * Callback function for a SNMP timeout.
 *
 * A SNMP timeout has occurred. Call `snmp_timeout()` to handle it.
 */
static void
levent_snmp_timeout(evutil_socket_t fd, short what, void *arg)
{
	struct lldpd *cfg = arg;
	(void)what; (void)fd;
	snmp_timeout();
	run_alarms();
	levent_snmp_update(cfg);
}
コード例 #2
0
ファイル: snmpmgr.c プロジェクト: tidatida/lagopus
static lagopus_result_t
internal_snmpmgr_poll(lagopus_chrono_t nsec) {
  int numfds = 0;
  fd_set fdset;
  struct timespec timeout = { 0, 0 };
  struct timeval timeout_dummy;
  int count = 0;
  int block = true;
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  NSEC_TO_TS(nsec, timeout);

  FD_ZERO(&fdset);
  if (snmp_select_info(&numfds, &fdset, &timeout_dummy, &block) > 0) {
    if ((count = pselect(numfds, &fdset, NULL, NULL, &timeout, NULL)) > 0) {
      snmp_read(&fdset);
    } else {
      if (count == 0) {
        snmp_timeout();
      } else {
        perror("pselect");
        return LAGOPUS_RESULT_POSIX_API_ERROR;
      }
    }

    /* run callbacks includes that checking connetion to AgetnX master agent */
    run_alarms();

    netsnmp_check_outstanding_agent_requests();

    if (count == 0) {
      ret = LAGOPUS_RESULT_TIMEDOUT;
    } else {
      ret = LAGOPUS_RESULT_OK;
    }
  } else {  /* snmp_select_info */
    ret = LAGOPUS_RESULT_SNMP_API_ERROR;
  }
  return ret;
}
コード例 #3
0
ファイル: snmptrapd.c プロジェクト: michalklempa/net-snmp
static void
snmptrapd_main_loop(void)
{
    int             count, numfds, block;
    fd_set          readfds,writefds,exceptfds;
    struct timeval  timeout, *tvp;

    while (netsnmp_running) {
        if (reconfig) {
                /*
                 * If we are logging to a file, receipt of SIGHUP also
                 * indicates that the log file should be closed and
                 * re-opened.  This is useful for users that want to
                 * rotate logs in a more predictable manner.
                 */
                netsnmp_logging_restart();
                snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
                         netsnmp_get_version());
            trapd_update_config();
            if (trap1_fmt_str_remember) {
                parse_format( NULL, trap1_fmt_str_remember );
            }
            reconfig = 0;
        }
        numfds = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
        block = 0;
        tvp = &timeout;
        timerclear(tvp);
        tvp->tv_sec = 5;
        snmp_select_info(&numfds, &readfds, tvp, &block);
        if (block == 1)
            tvp = NULL;         /* block without timeout */
#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
        netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
        count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
        if (count > 0) {
#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
            netsnmp_dispatch_external_events(&count, &readfds, &writefds,
                                             &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
            /* If there are any more events after external events, then
             * try SNMP events. */
            if (count > 0) {
                snmp_read(&readfds);
            }
        } else {
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR)
                    continue;
                snmp_log_perror("select");
                netsnmp_running = 0;
                break;
            default:
                fprintf(stderr, "select returned %d\n", count);
                netsnmp_running = 0;
            }
	}
	run_alarms();
    }
}
コード例 #4
0
ファイル: snmpd.c プロジェクト: WimObiwan/net-snmp
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *      
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messages for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;
    netsnmp_large_fd_set readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    int             count, block, i;
#ifdef	USING_SMUX_MODULE
    int             sd;
#endif                          /* USING_SMUX_MODULE */

    netsnmp_large_fd_set_init(&readfds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&writefds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE);

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

#if defined(WIN32)
    create_stdin_waiter_thread();
#endif

    /*
     * Loop-forever: execute message handlers for sockets with data
     */
    while (netsnmp_running) {
        if (reconfig) {
#if HAVE_SIGHOLD
            sighold(SIGHUP);
#endif
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
	    /*  Stop and restart logging.  This allows logfiles to be
		rotated etc.  */
	    netsnmp_logging_restart();
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
		     netsnmp_get_version());
            update_config();
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
#if HAVE_SIGHOLD
            sigrelse(SIGHUP);
#endif
        }

        /*
         * default to sleeping for a really long time. INT_MAX
         * should be sufficient (eg we don't care if time_t is
         * a long that's bigger than an int).
         */
        tvp = &timeout;
        tvp->tv_sec = INT_MAX;
        tvp->tv_usec = 0;

        numfds = 0;
        NETSNMP_LARGE_FD_ZERO(&readfds);
        NETSNMP_LARGE_FD_ZERO(&writefds);
        NETSNMP_LARGE_FD_ZERO(&exceptfds);
        block = 0;
        snmp_select_info2(&numfds, &readfds, tvp, &block);
        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            NETSNMP_LARGE_FD_SET(smux_listen_sd, &readfds);
            numfds =
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;

            for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                sd = smux_snmp_select_list_get_SD_from_List(i);
                if (sd != 0)
                {
                   NETSNMP_LARGE_FD_SET(sd, &readfds);
                   numfds = sd >= numfds ? sd + 1 : numfds;
                }
            }
        }
#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
        netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

    reselect:
        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        if (tvp)
            DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec,
                        (long) tvp->tv_usec));
        count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
				     tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {

#ifdef USING_SMUX_MODULE
            /*
             * handle the SMUX sd's 
             */
            if (smux_listen_sd >= 0) {
                for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                    sd = smux_snmp_select_list_get_SD_from_List(i);
                    if (NETSNMP_LARGE_FD_ISSET(sd, &readfds)) {
                        if (smux_process(sd) < 0) {
                            smux_snmp_select_list_del(sd);
                        }
                    }
                }
                /*
                 * new connection 
                 */
                if (NETSNMP_LARGE_FD_ISSET(smux_listen_sd, &readfds)) {
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                        smux_snmp_select_list_add(sd);
                    }
                }
            }

#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
            netsnmp_dispatch_external_events2(&count, &readfds,
                                              &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

            /* If there are still events leftover, process them */
            if (count > 0) {
              snmp_read2(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                DEBUGMSGTL(("snmpd/select", "  errno = %d\n", errno));
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (netsnmp_running && !reconfig) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */

        /*
         * see if persistent store needs to be saved
         */
        snmp_store_if_needed();

        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();

    }                           /* endwhile */

    netsnmp_large_fd_set_cleanup(&readfds);
    netsnmp_large_fd_set_cleanup(&writefds);
    netsnmp_large_fd_set_cleanup(&exceptfds);

#if defined(WIN32)
    join_stdin_waiter_thread();
#endif

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}                               /* end receive() */
コード例 #5
0
ファイル: net.c プロジェクト: DomChey/ptpd
/*Check if data has been received*/
int 
netSelect(TimeInternal * timeout, NetPath * netPath, fd_set *readfds)
{
	int ret, nfds;
	struct timeval tv, *tv_ptr;


#if defined PTPD_SNMP
	extern RunTimeOpts rtOpts;
	struct timeval snmp_timer_wait = { 0, 0}; // initialise to avoid unused warnings when SNMP disabled
	int snmpblock = 0;
#endif

	if (timeout) {
		if(isTimeInternalNegative(timeout)) {
			ERROR("Negative timeout attempted for select()\n");
			return -1;
		}
		tv.tv_sec = timeout->seconds;
		tv.tv_usec = timeout->nanoseconds / 1000;
		tv_ptr = &tv;
	} else {
		tv_ptr = NULL;
	}

	FD_ZERO(readfds);
	nfds = 0;
#ifdef PTPD_PCAP
	if (netPath->pcapEventSock >= 0) {
		FD_SET(netPath->pcapEventSock, readfds);
		if (netPath->pcapGeneralSock >= 0)
			FD_SET(netPath->pcapGeneralSock, readfds);

		nfds = netPath->pcapEventSock;
		if (netPath->pcapEventSock < netPath->pcapGeneralSock)
			nfds = netPath->pcapGeneralSock;

	} else if (netPath->eventSock >= 0) {
#endif
		FD_SET(netPath->eventSock, readfds);
		if (netPath->generalSock >= 0)
			FD_SET(netPath->generalSock, readfds);

		nfds = netPath->eventSock;
		if (netPath->eventSock < netPath->generalSock)
			nfds = netPath->generalSock;
#ifdef PTPD_PCAP
	}
#endif
	nfds++;

#if defined PTPD_SNMP
if (rtOpts.snmp_enabled) {
	snmpblock = 1;
	if (tv_ptr) {
		snmpblock = 0;
		memcpy(&snmp_timer_wait, tv_ptr, sizeof(struct timeval));
	}
	snmp_select_info(&nfds, readfds, &snmp_timer_wait, &snmpblock);
	if (snmpblock == 0)
		tv_ptr = &snmp_timer_wait;
}
#endif

	ret = select(nfds, readfds, 0, 0, tv_ptr);

	if (ret < 0) {
		if (errno == EAGAIN || errno == EINTR)
			return 0;
	}
#if defined PTPD_SNMP
if (rtOpts.snmp_enabled) {
	/* Maybe we have received SNMP related data */
	if (ret > 0) {
		snmp_read(readfds);
	} else if (ret == 0) {
		snmp_timeout();
		run_alarms();
	}
	netsnmp_check_outstanding_agent_requests();
}
#endif
	return ret;
}
コード例 #6
0
ファイル: snmptrapd.c プロジェクト: Undrizzle/apps
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::efF:g:hHI:L:m:M:no:O:PqsS:tu:vx:-:";
    netsnmp_session *sess_list = NULL, *ss = NULL;
    netsnmp_transport *transport = NULL;
    int             arg, i = 0, depmsg = 0;
    int             uid = 0, gid = 0;
    int             count, numfds, block;
    fd_set          readfds,writefds,exceptfds;
    struct timeval  timeout, *tvp;
    char           *cp, *listen_ports = NULL;
#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    int             agentx_subagent = 1;
#endif
    netsnmp_trapd_handler *traph;
#ifdef NETSNMP_EMBEDDED_PERL
    extern void init_perl(void);
#endif

#ifndef WIN32
    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    for (i = getdtablesize() - 1; i > 2; --i) {
        (void) close(i);
    }
#endif /* #WIN32 */
    
#ifdef SIGTERM
    signal(SIGTERM, term_handler);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif
#ifdef SIGINT
    signal(SIGINT, term_handler);
#endif
#ifdef SIGPIPE
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif

#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif

    /*
     * register our configuration handlers now so -H properly displays them 
     */
    snmptrapd_register_configs( );
    init_usm_conf( "snmptrapd" );
    register_config_handler("snmptrapd", "snmpTrapdAddr",
                            parse_trapd_address, free_trapd_address, "string");

    register_config_handler("snmptrapd", "doNotLogTraps",
                            parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)");
#if HAVE_GETPID
    register_config_handler("snmptrapd", "pidFile",
                            parse_config_pidFile, NULL, "string");
#endif
#ifdef HAVE_UNISTD_H
    register_config_handler("snmptrapd", "agentuser",
                            parse_config_agentuser, NULL, "userid");
    register_config_handler("snmptrapd", "agentgroup",
                            parse_config_agentgroup, NULL, "groupid");
#endif
    
    register_config_handler("snmptrapd", "logOption",
                            parse_config_logOption, NULL, "string");

    register_config_handler("snmptrapd", "doNotFork",
                            parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "printEventNumbers",
                            parse_config_printEventNumbers, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "ignoreAuthFailure",
                            parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "outputOption",
                            parse_config_outputOption, NULL, "string");

#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:");
#endif

#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif

    /*
     * Now process options normally.  
     */

    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage();
                exit(0);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
                exit(0);
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            dropauth = 1;
            break;

        case 'A':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'e':
            Event++;
            break;

        case 'f':
            dofork = 0;
            break;

        case 'F':
            if (optarg != NULL) {
                trap1_fmt_str_remember = optarg;
            } else {
                usage();
                exit(1);
            }
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, gid = atoi(optarg));
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'h':
            usage();
            exit(0);

        case 'H':
            init_agent("snmptrapd");
#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
            init_notification_log();
#endif
#ifdef NETSNMP_EMBEDDED_PERL
            init_perl();
#endif
            init_snmp("snmptrapd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

        case 'I':
            if (optarg != NULL) {
                add_to_init_list(optarg);
            } else {
                usage();
            }
            break;

	case 'S':
            fprintf(stderr,
                    "Warning: -S option is deprecated; use -Ls <facility> instead\n");
            depmsg = 1;
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage();
                    exit(1);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage();
                exit(1);
            }
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'n':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_APP_NUMERIC_IP, 1);
            break;

        case 'o':
            fprintf(stderr,
                    "Warning: -o option is deprecated; use -Lf <file> instead\n");
            if (optarg != NULL) {
                logfile = optarg;
                snmp_enable_filelog(optarg, 
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
            } else {
                usage();
                exit(1);
            }
            break;

        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c\n",
			*cp);
                usage();
                exit(1);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage();
                exit(1);
            }
            break;

#if HAVE_GETPID
        case 'p':
            if (optarg != NULL) {
                parse_config_pidFile(NULL, optarg);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'P':
            fprintf(stderr,
                    "Warning: -P option is deprecated; use -f -Le instead\n");
            dofork = 0;
            snmp_enable_stderrlog();
            break;

        case 's':
            fprintf(stderr,
                    "Warning: -s option is deprecated; use -Lsd instead\n");
            depmsg = 1;
#ifdef WIN32
            snmp_enable_syslog_ident(app_name_long, Facility);
#else
            snmp_enable_syslog_ident(app_name, Facility);
#endif
            break;

        case 't':
            SyslogTrap++;
            break;

#if HAVE_UNISTD_H
        case 'u':
            if (optarg != NULL) {
                char           *ecp;

                uid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct passwd  *info;
                    info = getpwnam(optarg);
                    if (info) {
                        uid = info->pw_uid;
                    } else {
#endif
                        fprintf(stderr, "Bad user id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'v':
            version();
            exit(0);
            break;

        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        for (i = optind; i < argc; i++) {
            char *astring;
            if (listen_ports != NULL) {
                astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", listen_ports, argv[i]);
                free(listen_ports);
                listen_ports = astring;
            } else {
                listen_ports = strdup(argv[i]);
                if (listen_ports == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
            }
        }
    }

    SOCK_STARTUP;

    /*
     * I'm being lazy here, and not checking the
     * return value from these registration calls.
     * Don't try this at home, children!
     */
    if (0 == snmp_get_do_logging()) {
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               syslog_handler);
        traph->authtypes = TRAP_AUTH_LOG;
        snmp_enable_syslog();
    } else {
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               print_handler);
        traph->authtypes = TRAP_AUTH_LOG;
    }

    if (Event) {
        traph = netsnmp_add_traphandler(event_handler, risingAlarm,
                                        OID_LENGTH(risingAlarm));
        traph->authtypes = TRAP_AUTH_LOG;

        traph = netsnmp_add_traphandler(event_handler, fallingAlarm,
                                        OID_LENGTH(fallingAlarm));
        traph->authtypes = TRAP_AUTH_LOG;

        traph = netsnmp_add_traphandler(event_handler, unavailableAlarm,
                                        OID_LENGTH(unavailableAlarm));
        traph->authtypes = TRAP_AUTH_LOG;
	/* 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(NETSNMP_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(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    /*
     * initialize local modules 
     */
    if (agentx_subagent) {
#ifdef USING_SNMPV3_SNMPENGINE_MODULE
        extern void register_snmpEngine_scalars_context(const char *);
#endif
        subagent_init();
#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
        /* register the notification log table */
        if (should_init("notificationLogMib")) {
            netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_NOTIF_LOG_CTX,
                              "snmptrapd");
            traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER,
                                                   notification_handler);
            traph->authtypes = TRAP_AUTH_LOG;
            init_notification_log();
        }
#endif
#ifdef USING_SNMPV3_SNMPENGINE_MODULE
        /*
         * register scalars from SNMP-FRAMEWORK-MIB::snmpEngineID group;
         * allows engineID probes via the master agent under the
         * snmptrapd context
         */
        register_snmpEngine_scalars_context("snmptrapd");
#endif
    }
#endif /* USING_AGENTX_SUBAGENT_MODULE && !NETSNMP_SNMPTRAPD_DISABLE_AGENTX */

    /* register our authorization handler */
    init_netsnmp_trapd_auth();

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    if (agentx_subagent) {
#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
        extern void init_register_nsVacm_context(const char *);
#endif
#ifdef USING_SNMPV3_USMUSER_MODULE
        extern void init_register_usmUser_context(const char *);
        /* register ourselves as having a USM user database */
        init_register_usmUser_context("snmptrapd");
#endif
#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
        /* register net-snmp vacm extensions */
        init_register_nsVacm_context("snmptrapd");
#endif
    }
#endif

#ifdef NETSNMP_EMBEDDED_PERL
    init_perl();
    {
        /* set the default path to load */
        char            init_file[SNMP_MAXBUF];
        snprintf(init_file, sizeof(init_file) - 1,
                 "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl");
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_PERL_INIT_FILE,
                              init_file);
    }
#endif

    /*
     * Initialize the world.
     */
    init_snmp("snmptrapd");

#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif

    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. 
         */
        netsnmp_running = 0;
    }

    /*
     * if no logging options on command line or in conf files, use syslog
     */
    if (0 == snmp_get_do_logging()) {
#ifdef WIN32
        snmp_enable_syslog_ident(app_name_long, Facility);
#else
        snmp_enable_syslog_ident(app_name, Facility);
#endif        
    }

#ifndef WIN32
    /*
     * fork the process to the background if we are not printing to stderr 
     */
    if (dofork && netsnmp_running) {
        int             fd;

        switch (fork()) {
        case -1:
            fprintf(stderr, "bad fork - %s\n", strerror(errno));
            _exit(1);

        case 0:
            /*
             * become process group leader 
             */
            if (setsid() == -1) {
                fprintf(stderr, "bad setsid - %s\n", strerror(errno));
                _exit(1);
            }

            /*
             * if we are forked, we don't want to print out to stdout or stderr 
             */
            fd = open("/dev/null", O_RDWR);
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            close(fd);
            break;

        default:
            _exit(0);
        }
    }
#endif                          /* WIN32 */
#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            exit(1);
        }
        fprintf(PID, "%d\n", (int) getpid());
        fclose(PID);
        free_config_pidFile();
    }
#endif

    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
    if (depmsg) {
        snmp_log(LOG_WARNING, "-s and -S options are deprecated; use -Ls <facility> instead\n");
    }
    
    if (listen_ports)
        cp = listen_ports;
    else
        cp = default_port;

    while (cp != NULL) {
        char *sep = strchr(cp, ',');

        if (sep != NULL) {
            *sep = 0;
        }

        transport = netsnmp_transport_open_server("snmptrap", cp);
        if (transport == NULL) {
            snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
                     cp, 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);
                snmp_log(LOG_ERR, "couldn't open snmp - %s", strerror(errno));
                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;

#if HAVE_UNISTD_H
#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmptrapd/main", "Changing gid to %d.\n", gid));
        if (setgid(gid) == -1
#ifdef HAVE_SETGROUPS
            || setgroups(1, (gid_t *)&gid) == -1
#endif
            ) {
            snmp_log_perror("setgid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#ifdef HAVE_SETUID
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_USERID)) != 0) {
        DEBUGMSGTL(("snmptrapd/main", "Changing uid to %d.\n", uid));
        if (setuid(uid) == -1) {
            snmp_log_perror("setuid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#endif

#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_RUNNING;
#endif
    while (netsnmp_running) {
        if (reconfig) {
                /*
                 * 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.
                 */
                netsnmp_logging_restart();
                snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
                         netsnmp_get_version());
            trapd_update_config();
            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);
            }
            reconfig = 0;
        }
        numfds = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
        block = 0;
        tvp = &timeout;
        timerclear(tvp);
        tvp->tv_sec = 5;
        snmp_select_info(&numfds, &readfds, tvp, &block);
        if (block == 1)
            tvp = NULL;         /* block without timeout */
        netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
        count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
        gettimeofday(&Now, 0);
        if (count > 0) {
            netsnmp_dispatch_external_events(&count, &readfds, &writefds,
                                             &exceptfds);
            /* If there are any more events after external events, then
             * try SNMP events. */
            if (count > 0) {
                snmp_read(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR)
                    continue;
                snmp_log_perror("select");
                netsnmp_running = 0;
                break;
            default:
                fprintf(stderr, "select returned %d\n", count);
                netsnmp_running = 0;
            }
	run_alarms();
    }

    if (snmp_get_do_logging()) {
        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());
    }
    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;
}
コード例 #7
0
ファイル: amsHelper.c プロジェクト: marker55/hp-ams
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *
 * Returns:
 *  0   On success.
 *  -1  System error.
 *
 * Infinite while-loop which monitors incoming messages for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;

    netsnmp_large_fd_set readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    int             count, block, i;

    netsnmp_large_fd_set_init(&readfds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&writefds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE);

    /*
     * you're main loop here... 
     */
    while (ams_running) {
	/* following code from snmpd */
        /*
         * if you use select(), see snmp_select_info() in snmp_api(3) 
         */
        /*
         * default to sleeping for a really long time. INT_MAX
         * should be sufficient (eg we don't care if time_t is
         * a long that's bigger than an int).
         */
        tvp = &timeout;
        tvp->tv_sec = INT_MAX;
        tvp->tv_usec = 0;

        numfds = 0;
        NETSNMP_LARGE_FD_ZERO(&readfds);
        NETSNMP_LARGE_FD_ZERO(&writefds);
        NETSNMP_LARGE_FD_ZERO(&exceptfds);
        block = 0;
        snmp_sess_select_info2_flags(0, &numfds, &readfds, tvp, &block, 
                                     NETSNMP_SELECT_NOFLAGS);

        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

        netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds);

    reselect:
        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        if (tvp)
            DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec,
                        (long) tvp->tv_usec));
        count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
				     tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {
            netsnmp_dispatch_external_events2(&count, &readfds,
                                              &writefds, &exceptfds);

            /* If there are still events leftover, process them */
            if (count > 0) {
              snmp_read2(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                DEBUGMSGTL(("snmpd/select", "  errno = %d\n", errno));
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (ams_running) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */

        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();
    }
    /* lets give a seconb or 2 to log the shutdown */
    sleep(0);
    netsnmp_large_fd_set_cleanup(&readfds);
    netsnmp_large_fd_set_cleanup(&writefds);
    netsnmp_large_fd_set_cleanup(&exceptfds);

    /*
     * at shutdown time 
     */


    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;
}                               /* end receive() */
コード例 #8
0
ファイル: snmp_alarm.c プロジェクト: EPiCS/reconos_v2
RETSIGTYPE
alarm_handler(int a) {
  run_alarms();
  set_an_alarm();
}
コード例 #9
0
ファイル: snmpd.c プロジェクト: sjz6578/net-snmp-5.1.4.2
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *      
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messges for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;
    fd_set          readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    struct timeval  sched, *svp = &sched, now, *nvp = &now;
    int             count, block, i;
#ifdef	USING_SMUX_MODULE
    int             sd;
#endif                          /* USING_SMUX_MODULE */


    /*
     * Set the 'sched'uled timeout to the current time + one TIMETICK.
     */
    gettimeofday(nvp, (struct timezone *) NULL);
    svp->tv_usec = nvp->tv_usec + TIMETICK;
    svp->tv_sec = nvp->tv_sec;

    while (svp->tv_usec >= ONE_SEC) {
        svp->tv_usec -= ONE_SEC;
        svp->tv_sec++;
    }

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

    /*
     * Loop-forever: execute message handlers for sockets with data,
     * reset the 'sched'uler.
     */
    while (netsnmp_running) {
        if (reconfig) {
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
	    /*  Stop and restart logging.  This allows logfiles to be
		rotated etc.  */
	    snmp_disable_log();
	    setup_log(1, 0, 0, 0, NULL);
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
		     netsnmp_get_version());
            update_config();
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
        }

        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        tvp = &timeout;
        tvp->tv_sec = 0;
        tvp->tv_usec = TIMETICK;

        numfds = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
        block = 0;
        snmp_select_info(&numfds, &readfds, tvp, &block);
        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            FD_SET(smux_listen_sd, &readfds);
            numfds =
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
            for (i = 0; i < sdlen; i++) {
                FD_SET(sdlist[i], &readfds);
                numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
            }
        }
#endif                          /* USING_SMUX_MODULE */

        for (i = 0; i < external_readfdlen; i++) {
            FD_SET(external_readfd[i], &readfds);
            if (external_readfd[i] >= numfds)
                numfds = external_readfd[i] + 1;
        }
        for (i = 0; i < external_writefdlen; i++) {
            FD_SET(external_writefd[i], &writefds);
            if (external_writefd[i] >= numfds)
                numfds = external_writefd[i] + 1;
        }
        for (i = 0; i < external_exceptfdlen; i++) {
            FD_SET(external_exceptfd[i], &exceptfds);
            if (external_exceptfd[i] >= numfds)
                numfds = external_exceptfd[i] + 1;
        }

    reselect:
        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {

#ifdef USING_SMUX_MODULE
            /*
             * handle the SMUX sd's 
             */
            if (smux_listen_sd >= 0) {
                for (i = 0; i < sdlen; i++) {
                    if (FD_ISSET(sdlist[i], &readfds)) {
                        if (smux_process(sdlist[i]) < 0) {
                            for (; i < (sdlen - 1); i++) {
                                sdlist[i] = sdlist[i + 1];
                            }
                            sdlen--;
                        }
                    }
                }
                /*
                 * new connection 
                 */
                if (FD_ISSET(smux_listen_sd, &readfds)) {
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                        sdlist[sdlen++] = sd;
                    }
                }
            }
#endif                          /* USING_SMUX_MODULE */

            snmp_read(&readfds);

            for (i = 0; count && (i < external_readfdlen); i++) {
                if (FD_ISSET(external_readfd[i], &readfds)) {
                    DEBUGMSGTL(("snmpd/select", "readfd[%d] = %d\n",
                                i, external_readfd[i]));
                    external_readfdfunc[i] (external_readfd[i],
                                            external_readfd_data[i]);
                    FD_CLR(external_readfd[i], &readfds);
                    count--;
                }
            }
            for (i = 0; count && (i < external_writefdlen); i++) {
                if (FD_ISSET(external_writefd[i], &writefds)) {
                    DEBUGMSGTL(("snmpd/select", "writefd[%d] = %d\n",
                                i, external_writefd[i]));
                    external_writefdfunc[i] (external_writefd[i],
                                             external_writefd_data[i]);
                    FD_CLR(external_writefd[i], &writefds);
                    count--;
                }
            }
            for (i = 0; count && (i < external_exceptfdlen); i++) {
                if (FD_ISSET(external_exceptfd[i], &exceptfds)) {
                    DEBUGMSGTL(("snmpd/select", "exceptfd[%d] = %d\n",
                                i, external_exceptfd[i]));
                    external_exceptfdfunc[i] (external_exceptfd[i],
                                              external_exceptfd_data[i]);
                    FD_CLR(external_exceptfd[i], &exceptfds);
                    count--;
                }
            }

        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (netsnmp_running && !reconfig) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */




        /*
         * If the time 'now' is greater than the 'sched'uled time, then:
         *
         *    Check alarm and event timers.
         *    Reset the 'sched'uled time to current time + one TIMETICK.
         *    Age the cache network addresses (from whom messges have
         *        been received).
         */
        gettimeofday(nvp, (struct timezone *)NULL);

        if (nvp->tv_sec > svp->tv_sec || (nvp->tv_sec == svp->tv_sec &&
					  nvp->tv_usec > svp->tv_usec)) {
            svp->tv_usec = nvp->tv_usec + TIMETICK;
            svp->tv_sec = nvp->tv_sec;

            while (svp->tv_usec >= ONE_SEC) {
                svp->tv_usec -= ONE_SEC;
                svp->tv_sec++;
            }
        }

        /*
         * endif -- now>sched 
         */
        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();

    }                           /* endwhile */

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}                               /* end receive() */
コード例 #10
0
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messges for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int numfds;
    fd_set fdset;
    struct timeval	timeout, *tvp = &timeout;
    struct timeval	sched,   *svp = &sched,
                                  now,     *nvp = &now;
    int count, block;
#ifdef	USING_SMUX_MODULE
    int i, sd;
#endif	/* USING_SMUX_MODULE */


    /*
     * Set the 'sched'uled timeout to the current time + one TIMETICK.
     */
    gettimeofday(nvp, (struct timezone *) NULL);
    svp->tv_usec = nvp->tv_usec + TIMETICK;
    svp->tv_sec = nvp->tv_sec;

    while (svp->tv_usec >= ONE_SEC) {
        svp->tv_usec -= ONE_SEC;
        svp->tv_sec++;
    }

    /*
     * Loop-forever: execute message handlers for sockets with data,
     * reset the 'sched'uler.
     */
    while (running) {
        if (reconfig) {
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
            update_config();
        }
        tvp =  &timeout;
        tvp->tv_sec = 0;
        tvp->tv_usec = TIMETICK;

        numfds = 0;
        FD_ZERO(&fdset);
        block = 0;
        snmp_select_info(&numfds, &fdset, tvp, &block);
        if (block == 1)
            tvp = NULL; /* block without timeout */

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            FD_SET(smux_listen_sd, &fdset);
            numfds = smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
            for (i = 0; i < sdlen; i++) {
                FD_SET(sdlist[i], &fdset);
                numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
            }
        }
#endif	/* USING_SMUX_MODULE */

        count = select(numfds, &fdset, 0, 0, tvp);

        if (count > 0) {
            snmp_read(&fdset);
        } else switch(count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR) {
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }  /* endif -- count>0 */

#ifdef	USING_SMUX_MODULE
        /* handle the SMUX sd's */
        if (smux_listen_sd >= 0) {
            for (i = 0; i < sdlen; i++) {
                if (FD_ISSET(sdlist[i], &fdset)) {
                    if (smux_process(sdlist[i]) < 0) {
                        for (; i < (sdlen - 1); i++) {
                            sdlist[i] = sdlist[i+1];
                        }
                        sdlen--;
                    }
                }
            }
            /* new connection */
            if (FD_ISSET(smux_listen_sd, &fdset)) {
                if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                    sdlist[sdlen++] = sd;
                }
            }
        }
#endif	/* USING_SMUX_MODULE */



        /*
         * If the time 'now' is greater than the 'sched'uled time, then:
         *
         *    Check alarm and event timers.
         *    Reset the 'sched'uled time to current time + one TIMETICK.
         *    Age the cache network addresses (from whom messges have
         *        been received).
         */
        gettimeofday(nvp, (struct timezone *) NULL);

        if (nvp->tv_sec > svp->tv_sec
                || (nvp->tv_sec == svp->tv_sec && nvp->tv_usec > svp->tv_usec)) {
            svp->tv_usec = nvp->tv_usec + TIMETICK;
            svp->tv_sec = nvp->tv_sec;

            while (svp->tv_usec >= ONE_SEC) {
                svp->tv_usec -= ONE_SEC;
                svp->tv_sec++;
            }
            if (log_addresses && lastAddrAge++ > 600) {

                lastAddrAge = 0;
                for(count = 0; count < ADDRCACHE; count++) {
                    if (addrCache[count].status == OLD)
                        addrCache[count].status = UNUSED;
                    if (addrCache[count].status == USED)
                        addrCache[count].status = OLD;
                }
            }
        }  /* endif -- now>sched */

        /* run requested alarms */
        run_alarms();

    }  /* endwhile */

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}  /* end receive() */
コード例 #11
0
ファイル: snmptrapd.c プロジェクト: DYFeng/infinidb
main(int argc, char *argv[])
#endif
{
    char            options[128] = "ac:CdD::efF:hHl:L:m:M:no:PqsS:tvO:-:";
    netsnmp_session *sess_list = NULL, *ss = NULL;
    netsnmp_transport *transport = NULL;
    int             arg, i = 0;
    int             count, numfds, block;
    fd_set          fdset;
    struct timeval  timeout, *tvp;
    char           *cp, *listen_ports = NULL;
    int             agentx_subagent = 1, depmsg = 0;

    /*
     * register our configuration handlers now so -H properly displays them 
     */
    snmptrapd_register_configs( );
    init_usm_conf( "snmptrapd" );
    register_config_handler("snmptrapd", "snmptrapdaddr",
                            parse_trapd_address, free_trapd_address, "string");

    register_config_handler("snmptrapd", "doNotLogTraps",
                            parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)");
#if HAVE_GETPID
    register_config_handler("snmptrapd", "pidFile",
                            parse_config_pidFile, NULL, "string");
#endif
    
    register_config_handler("snmptrapd", "logOption",
                            parse_config_logOption, NULL, "string");

    register_config_handler("snmptrapd", "doNotFork",
                            parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "printEventNumbers",
                            parse_config_printEventNumbers, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "ignoreAuthFailure",
                            parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "outputOption",
                            parse_config_outputOption, NULL, "string");
    
#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);

    /*
     * Now process options normally.  
     */

    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage();
                exit(0);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
                exit(0);
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            dropauth = 1;
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'e':
            Event++;
            break;

        case 'f':
            dofork = 0;
            break;

        case 'F':
            if (optarg != NULL) {
                trap1_fmt_str_remember = optarg;
            } else {
                usage();
                exit(1);
            }
            break;

        case 'h':
            usage();
            exit(0);

        case 'H':
            init_notification_log();
            init_snmp("snmptrapd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

	case 'S':
            fprintf(stderr,
                    "Warning: -S option is deprecated; use -Ls <facility> instead\n");
            depmsg = 1;
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage();
                    exit(1);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage();
                exit(1);
            }
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'n':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_APP_NUMERIC_IP, 1);
            break;

        case 'o':
            fprintf(stderr,
                    "Warning: -o option is deprecated; use -Lf <file> instead\n");
            Print++;
            if (optarg != NULL) {
                logfile = optarg;
                snmp_enable_filelog(optarg, 0);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c\n",
			*cp);
                usage();
                exit(1);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage();
                exit(1);
            }
            Log++;
            break;

        case 'P':
            fprintf(stderr,
                    "Warning: -P option is deprecated; use -f -Le instead\n");
            dofork = 0;
            snmp_enable_stderrlog();
            Print++;
            break;

        case 's':
            fprintf(stderr,
                    "Warning: -s option is deprecated; use -Lsd instead\n");
            depmsg = 1;
            Syslog++;
            break;

        case 't':
            SyslogTrap++;
            break;


#if HAVE_GETPID
        case 'u':
            fprintf(stderr,
                    "Warning: -u option is deprecated; use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                parse_config_pidFile(NULL, optarg);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'v':
            version();
            exit(0);
            break;

        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        for (i = optind; i < argc; i++) {
            char *astring;
            if (listen_ports != NULL) {
                astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", listen_ports, argv[i]);
                free(listen_ports);
                listen_ports = astring;
            } else {
                listen_ports = strdup(argv[i]);
                if (listen_ports == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
            }
        }
    }

    /*
     * 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);
    }
    netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER, notification_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.
	 */
    }

#ifdef USING_AGENTX_SUBAGENT_MODULE
    /*
     * 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");

    /*
     * initialize local modules 
     */
    if (agentx_subagent) {
        extern void init_register_usmUser_context(const char *);
#ifdef USING_AGENTX_SUBAGENT_MODULE
	void  init_subagent(void);
        init_subagent();
#endif
        /* register the notification log table */
        init_notification_log();

        /* register ourselves as having a USM user database */
        init_register_usmUser_context("snmptrapd");
    }

#ifdef NETSNMP_EMBEDDED_PERL
    init_perl();
    {
        /* set the default path to load */
        char            init_file[SNMP_MAXBUF];
        snprintf(init_file, sizeof(init_file) - 1,
                 "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl");
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_PERL_INIT_FILE,
                              init_file);
    }
#endif

    /*
     * Initialize the world.
     */
    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;
    }
#ifndef WIN32
    /*
     * fork the process to the background if we are not printing to stderr 
     */
    if (dofork && running) {
        int             fd;

        switch (fork()) {
        case -1:
            fprintf(stderr, "bad fork - %s\n", strerror(errno));
            _exit(1);

        case 0:
            /*
             * become process group leader 
             */
            if (setsid() == -1) {
                fprintf(stderr, "bad setsid - %s\n", strerror(errno));
                _exit(1);
            }

            /*
             * if we are forked, we don't want to print out to stdout or stderr 
             */
            fd = open("/dev/null", O_RDWR);
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            close(fd);
            break;

        default:
            _exit(0);
        }
    }
#endif                          /* WIN32 */
#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            exit(1);
        }
        fprintf(PID, "%d\n", (int) getpid());
        fclose(PID);
        free_config_pidFile();
    }
#endif

    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;
        }
    }

    signal(SIGTERM, term_handler);
#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif
    signal(SIGINT, term_handler);

#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 = 0;
        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;
}