static void
netsnmp_ds_set_init (void)
{
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                          NETSNMP_DS_LIB_APPTYPE, DNAME_JNX_EXAMPLED);

    netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
                          NETSNMP_DS_AGENT_X_SOCKET, PATH_MASTER_AGENTX);

    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE,
                           SUB_AGENT);
}
Пример #2
0
static void _parse_server_cert(const char *tok, char *line)
{
    config_pwarn("serverCert is deprecated. Clients should use peerCert, servers should use localCert.");
    if (*line == '"') {
        char buf[SNMP_MAXBUF];
        copy_nword(line, buf, sizeof(buf));
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                              NETSNMP_DS_LIB_X509_CLIENT_PUB, buf);
    } else
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                              NETSNMP_DS_LIB_X509_SERVER_PUB, line);
}
Пример #3
0
void
snmpd_set_agent_address(const char *token, char *cptr)
{
    char            buf[SPRINT_MAX_LEN];
    char           *ptr;

    /*
     * has something been specified before? 
     */
    ptr = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_PORTS);

    if (ptr) {
        /*
         * append to the older specification string 
         */
        sprintf(buf, "%s,%s", ptr, cptr);
    } else {
        strcpy(buf, cptr);
    }

    DEBUGMSGTL(("snmpd_ports", "port spec: %s\n", buf));
    netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
			  NETSNMP_DS_AGENT_PORTS, buf);
}
Пример #4
0
int init_snmp_agent(void)
{
	int result;

	if (user_settings.is_master_agent) {
		netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
	} else {
		netsnmp_enable_subagent();
	}

	if (user_settings.agentx_address != NULL) {
		netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, user_settings.agentx_address);
	}

	if (user_settings.daemonize)
		snmp_enable_syslog();
	else
		snmp_enable_stderrlog();	

	SOCK_STARTUP;

	if ((result = init_agent("collectd-agent")) != 0) {
		return -1;
	}

	if ((result = register_value_handlers()) != 0) {
		return -1;
	}

	if ((result = register_table_handlers()) != 0) {
		return -1;
	}

	if (user_settings.is_master_agent) {
		init_vacm_vars();
		init_usmUser();
	}

	init_snmp("collectd-snmpd");

	if (user_settings.is_master_agent) {
		init_master_agent();
	}

	return 0;
}
Пример #5
0
static void init_snmp_subagent(const char *agentx_host, int agentx_port)
{
    char agentx_socket[128];
    int background = 1; /* change this if you want to run in the background */
    int syslog = 0; /* change this if you want to use syslog */

    snmp_enable_filelog("/var/log/exa_agentx.log", 1);

    snmp_log(LOG_INFO, "exa_agentx configured to connect to %s:%d\n",
	     agentx_host, agentx_port);

    /* we're in an agentx subagent */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
    sprintf(agentx_socket, "tcp:%s:%d", agentx_host, agentx_port);
    netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                          NETSNMP_DS_AGENT_X_SOCKET, agentx_socket);

    /* run in background, if requested */
    if (background && netsnmp_daemonize(1, !syslog))
        exit(1);

    snmp_log(LOG_INFO, "exa_agentx daemonized\n");

    /* initialize tcpip, if necessary */
    SOCK_STARTUP;

    /* initialize the agent library */
    init_agent("exa_agentx");

    /* initialize mib code here */

    /* mib code: init_nstAgentSubagentObject from nstAgentSubagentObject.C */
    /* not necessary to just send TRAPs !! */
/*   init_mib_int_watch(); */

    /* example-demon will be used to read example-demon.conf files. */
    init_snmp("exa_agentx");

    /* In case we recevie a request to stop (kill -TERM or kill -INT) */
    stop = false;
    signal(SIGTERM, stop_server);
    signal(SIGINT, stop_server);

    snmp_log(LOG_INFO, "exa_agentx is up and running.\n");
}
Пример #6
0
int
main(int argc, char **argv)
{
    /*
     * Defs for arg-handling code: handles setting of policy-related variables 
     */
    int             ch;
    int             dont_fork = 0, use_syslog = 0, kdump_only = 0;
    int             ilo_gen = 0;
    char            *transport = "hpilo:";
    int             i;

    int            do_ahs = 1;
    int            do_ide = 1;
    int            do_host = 1;
    int            do_nic = 1;
    int            do_scsi = 1;
    int            do_pmp = 0;
    int            do_se = 1;
    int            do_fca = 1;
    int            do_mibII = 1;
    int scale = 1;
    char *argarg;
    int             prepared_sockets = 0;
    struct stat     st;
    struct timeval the_time[2];

    init_etime(&the_time[0]);

    if (stat("/sys/module/hpilo", &st) != 0 ) {
       printf("hp-ams requires that the hpilo kernel module is loaded");
       exit(1);
    } 
        
#ifndef NETSNMP_NO_SYSTEMD
    /* check if systemd has sockets for us and don't close them */
    prepared_sockets = netsnmp_sd_listen_fds(0);
#endif /* NETSNMP_NO_SYSTEMD */

    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    if (!prepared_sockets) {
        for (i = getdtablesize() - 1; i > 2; --i) {
            (void) close(i);
        }
    }

    snmp_disable_log();

    while ((ch = getopt(argc, argv, "D:fG:kLM::OI:P:t:T::x:V:")) != EOF)
        switch (ch) {
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'f':
            dont_fork = 1;
            break;
        case 'k':
            kdump_only = 1;
            break;
        case 'h':
            usage();
            exit(0);
            break;
        case 'G':
            GenericData = optarg;
            break;
        case 'I':
            log_interval = atoi(optarg);
            if ((log_interval <0) || (log_interval > 3)) {
                usage();
                exit(0);
            }
            break;
        case 'P':
            interval2ping = atoi(optarg);
            if (interval2ping <0)  {
                usage();
                exit(0);
            }
            break;
        case 'L':
            use_syslog = 0;     /* use stderr */
            break;
        case 'M':
            argarg = optarg;
            do_ahs = 0;
            
            do_ide = 0;
            do_nic = 0;
            do_scsi = 0;
            do_host = 0;
            do_pmp = 0;
            do_se = 0;
            do_fca = 0;
            do_mibII = 1;
            while (argarg != 0) {
                char * mibnum;
                int mibitem;

                do_mibII = 0;
                mibnum = argarg;
                argarg = index(mibnum, ',');
                if (argarg != 0) {
                    *argarg = 0;
                    argarg++;
                }
                mibitem = atoi(mibnum);
                switch (mibitem) {
                    case 0:
                        do_ahs = 1;
                        break; 
                    case 1:
                        do_se = 1;
                        break; 
                    case 5:
                        do_scsi = 1;
                        break; 
                    case 11:
                        do_host = 1;
                        break; 
                    case 14:
                        do_ide = 1;
                        break; 
                    case 16:
                        do_fca = 1;
                        break; 
                    case 18:
                        do_nic = 1;
                        break; 
                    case 23:
                        do_pmp = 1;
                        break; 
                    case 99:
                        do_mibII = 1;
                        break; 
                    default:
                        break; 
                }
            }
            break;
        case 'O':
            gen8_only = 0;     /* allow to run on non supported */
            break;
        case 't':
             if (optarg != (char *) 0) 
                trap_fire = atoi(optarg);
            else
                trap_fire = 1;

            break;
        case 'T':
            if (optarg != (char *) 0) {
                switch (optarg[strlen(optarg)-1]) {
                    case 'd':
                    case 'D':
                        optarg[strlen(optarg)-1] = (char )0;
                        scale = 60*60*24;
                        break;
                    case 'h':
                    case 'H':
                        optarg[strlen(optarg)-1] = (char )0;
                        scale = 60*60;
                        break;
                    case 'm':
                    case 'M':
                        optarg[strlen(optarg)-1] = (char )0;
                        scale = 60;
                        break;
                    case 'S':
                    case 's':
                        optarg[strlen(optarg)-1] = (char )0;
                    default:
                        break;
                }
                testtrap_interval = atoi(optarg) * scale;
                if ((testtrap_interval < 10) || (testtrap_interval > (7*24*60*60))) {
                    usage();
                    exit(0);
                }
            }
            break;
        case 'x':
            if (optarg != NULL) {
                transport = optarg;
            } else {
                usage();
            }
            break;
        case 'V':
            if (optarg != NULL) {
                vendor_tag = optarg;
            } else {
                usage();
            }
            break;
        default:
            fprintf(stderr, "unknown option %c\n", ch);
            usage();
            exit(1);
        }

    /* if the -k option was provided, then also set the dont_fork flag. */
    if (kdump_only) {
        dont_fork = 1;
    }

    if (dont_fork) {
        snmp_enable_stderrlog();
    }

    netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, transport);
    /*
     * make us a agentx client. 
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                                    NETSNMP_DS_AGENT_ROLE, 1);

    if (InitSMBIOS() == 0 ) {
        if (gen8_only == 0) {
            fprintf(stderr,"SM BIOS initialization failed,"
                       " some functionality may not exist\n");
        } else {
            fprintf(stderr,"SM BIOS initialization failed,"
                       " unable to determine system type\n");
            exit(1);
        }
    } else {
        ilo_gen = GetiLOGen();
        if ((gen8_only) && (ilo_gen < 4)) {
            fprintf(stderr,"This program requires the host to have a HP Integrated Lights Out 4 (iLO 4)"
                       " BMC\n");
            exit(1);
        }
    }

    /*
     * daemonize 
     */
    snmp_disable_log();

    if (!dont_fork) {
        snmp_enable_calllog();
        int             rc = netsnmp_daemonize(1, use_syslog);
        if (rc)
            exit(-1);
    } else
        snmp_enable_stderrlog();


    /* Clear out Status array */
    memset(cpqHostMibStatusArray,0,sizeof(cpqHostMibStatusArray));
    memset(cpqHoMibHealthStatusArray, 0, sizeof(cpqHoMibHealthStatusArray));

    DEBUGMSG(("amsHelper:timer", "interval for StartUp %dms\n", get_etime(&the_time[0])));

    if (do_ahs) {
        LOG_PROCESS_CRASHES();

        DEBUGMSG(("amsHelper:timer", "interval for Log Crashes %dms\n", get_etime(&the_time[0])));

        if (kdump_only) {
            return 0;
        }

        LOG_OS_BOOT();

        DEBUGMSG(("amsHelper:timer", "interval for Log Boot %dms\n", get_etime(&the_time[0])));

    }
    openlog("hp-ams",  LOG_CONS | LOG_PID, LOG_DAEMON);
    /*
     * initialize the agent library 
     */
    init_agent("amsHelper");

    netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
                       NETSNMP_DS_HPILODOMAIN_IML, 4);

    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, 120 * ONE_SEC);

    /* set ping inetrval to interval2pimn - default is 0 */
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, interval2ping);

    /* sometime iLO4 can be slow so double the default to 2 sec if necessary*/
    netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_TIMEOUT, 3); 

    /* if the ilo starts dropping packets retry a couple of times */
    netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RETRIES, 5);

    init_snmp("amsHelper");

    DEBUGMSG(("amsHelper:timer", "interval for SNMP startup %dms\n", get_etime(&the_time[0])));

    if (do_mibII) {
        init_mib_modules();
        DEBUGMSG(("amsHelper:timer", "interval for init MIB-2 %dms\n", get_etime(&the_time[0])));
    }

    if (do_host) {
        init_cpqHost();
        DEBUGMSG(("amsHelper:timer", "interval for cpqHost %dms\n", get_etime(&the_time[0])));
    }

    if (do_ahs) {
        LOG_OS_INFORMATION();
        DEBUGMSG(("amsHelper:timer", "interval for LOG OS %dms\n", get_etime(&the_time[0])));

        LOG_DRIVERS();
        DEBUGMSG(("amsHelper:timer", "interval for Log drivers %dms\n", get_etime(&the_time[0])));

        LOG_SERVICE();
        DEBUGMSG(("amsHelper:timer", "interval for Log services %dms\n", get_etime(&the_time[0])));

        LOG_PACKAGE();
        DEBUGMSG(("amsHelper:timer", "interval for Log packages %dms\n", get_etime(&the_time[0])));
    }

    if (do_se) {
        init_cpqStdPciTable();
        DEBUGMSG(("amsHelper:timer", "interval for cpqSe %dms\n", get_etime(&the_time[0])));
    }

    if (do_scsi) {
        init_cpqScsi();
        DEBUGMSG(("amsHelper:timer", "interval for cpqScsi %dms\n", get_etime(&the_time[0])));
    }

    if (do_ide) {
        init_cpqIde();
        DEBUGMSG(("amsHelper:timer", "interval for cpqIde %dms\n", get_etime(&the_time[0])));
    }

    if (do_fca) {
        init_cpqFibreArray();
        DEBUGMSG(("amsHelper:timer", "interval for cpqFca %dms\n", get_etime(&the_time[0])));
    }

    if (do_nic) {
        init_cpqNic();
        DEBUGMSG(("amsHelper:timer", "interval for cpqNic %dms\n", get_etime(&the_time[0])));
    }

    if (do_pmp) {
        init_cpqLinOsMgmt();
        DEBUGMSG(("amsHelper:timer", "interval for cpqLinOsMgmt %dms\n", get_etime(&the_time[0])));
    }

    /*
     * Send coldstart trap if possible.
     */
    send_easy_trap(0, 0);
    syslog(LOG_NOTICE, "amsHelper Started . . "); 
    /*
     * Let systemd know we're up.
     */
#ifndef NETSNMP_NO_SYSTEMD
    netsnmp_sd_notify(1, "READY=1\n");
    if (prepared_sockets)
        /*
         * Clear the environment variable, we already processed all the sockets
         * by now.
         */
        netsnmp_sd_listen_fds(1);
#endif

    if (do_ahs) {
        LOG_OS_USAGE();
        DEBUGMSG(("amsHelper:timer", "interval for LOG OS Usage%dms\n", get_etime(&the_time[0])));

        LOG_PROCESSOR_USAGE();
        DEBUGMSG(("amsHelper:timer", "interval for LOG Processor Usage %dms\n", get_etime(&the_time[0])));

        LOG_MEMORY_USAGE();
        DEBUGMSG(("amsHelper:timer", "interval for LOG Memory Usage %dms\n", get_etime(&the_time[0])));
    }

    /*
     * In case we recevie a request to stop (kill -TERM or kill -INT) 
     */
    ams_running = 1;
    signal(SIGTERM, stop_server);
    signal(SIGINT, stop_server);

    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();

    snmp_shutdown("amsHelper");

    LOG_OS_SHUTDOWN();

    syslog(LOG_NOTICE, "amsHelper Stopped . . "); 
    exit(0);
}
Пример #7
0
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:L:m:M:p:P:qrsS:UvV-:";
    int             arg, i, ret;
    int             dont_fork = 0;
    int             dont_zero_log = 0;
    int             syslog_log = 0;
    int             uid = 0, gid = 0;
    int             agent_mode = -1;
    char            logfile[PATH_MAX + 1] = { 0 };
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
    char            option_compatability[] = "-Le";
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#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 */
    
    /*
     * register signals ASAP to prevent default action (usually core)
     * for signals during startup...
     */
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif
#ifdef SIGXFSZ
    signal(SIGXFSZ, SnmpdCatchRandomSignal);
#endif

#ifdef LOGFILE
    strncpy(logfile, LOGFILE, PATH_MAX);
#endif

#ifdef NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * This is incredibly ugly, but it's probably the simplest way
     *  to handle the old '-L' option as well as the new '-Lx' style
     */
    for (i=0; i<argc; i++) {
        if (!strcmp(argv[i], "-L"))
            argv[i] = option_compatability;            
    }

    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(argv[0]);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            break;

        case 'A':
            dont_zero_log = 1;
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage(argv[0]);
            }
            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(++snmp_dump_packet);
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

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

        case 'f':
            dont_fork = 1;
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, atoi(optarg));
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
            init_agent("snmpd");        /* register our .conf handlers */
            init_mib_modules();
            init_snmp("snmpd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

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

        case 'l':
            printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                strncpy(logfile, optarg, PATH_MAX);
            } else {
                usage(argv[0]);
            }
            break;

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

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

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

        case 'P':
            printf("Warning: -P option is deprecated, use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

        case 's':
            printf("Warning: -s option is deprecated, use -Lsd instead\n");
            syslog_log = 1;
            break;

        case 'S':
            printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
            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(argv[0]);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

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

                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(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = (char*)malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                SNMP_FREE(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
    }

    setup_log(0, dont_zero_log, 0, syslog_log, logfile);

    /*
     * Initialize a argv set to the current for restarting the agent.   
     */
    argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    if (!argvrestartp || !argvrestart || !argvrestartname) {
        fprintf(stderr, "malloc failure processing argvrestart\n");
        exit(1);
    }
    strcpy(argvrestartname, argv[0]);
    if (agent_mode == -1) {
        if (strstr(argvrestartname, "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;

#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
    if(!dont_fork) {
        int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                            NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
        ret = netsnmp_daemonize(quit, snmp_stderrlog_status());
        /*
         * xxx-rks: do we care if fork fails? I think we should...
         */
        if(ret != 0)
            Exit(1);                /*  Exit logs exit val for us  */
    }

    SOCK_STARTUP;
    init_agent("snmpd");        /* do what we need to do first. */
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp("snmpd");

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        Exit(1);                /*  Exit logs exit val for us  */
    }

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store("snmpd");

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

#if HAVE_GETPID
    if (pid_file != NULL) {
        /*
         * unlink the pid_file, if it exists, prior to open.  Without
         * doing this the open will fail if the user specified pid_file
         * already exists.
         */
        unlink(pid_file);
        fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
        if (fd == -1) {
            snmp_log_perror(pid_file);
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        } else {
            if ((PID = fdopen(fd, "w")) == NULL) {
                snmp_log_perror(pid_file);
                exit(1);
            } else {
                fprintf(PID, "%d\n", (int) getpid());
                fclose(PID);
            }
            close(fd);
        }
    }
#endif

#if HAVE_UNISTD_H
#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmpd/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(("snmpd/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

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32SERVICE
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
#include "mib_module_shutdown.h"
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown("snmpd");
#ifdef SHUTDOWN_AGENT_CLEANLY /* broken code */
    /* these attempt to free all known memory, but result in double frees */
    shutdown_master_agent();
    shutdown_agent();
#endif

    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32SERVICE
    agent_status = AGENT_STOPPED;
#endif

    SNMP_FREE(argvrestartname);
    SNMP_FREE(argvrestart);
    SNMP_FREE(argvrestartp);
    SOCK_CLEANUP;
    return 0;
}                               /* End main() -- snmpd */
Пример #8
0
int
main (int argc, char **argv)
{
	
	  	int agentx_subagent = AGENT_TRUE;
	  	int c;
	  	int rc = 0;
        	  
	  	SaErrorT 	rv = SA_OK;
		SaHpiVersionT	hpiVer;
		SaHpiSessionIdT sessionid;
		
		
		
	  	pid_t child;
		
		/* for simulator */
		struct oh_handler_state *state = NULL;
		struct oh_event *event = (struct oh_event *)g_malloc0(sizeof(struct oh_event));
		struct oh_event *event2= (struct oh_event *)g_malloc0(sizeof(struct oh_event));
		struct oh_event *event3= (struct oh_event *)g_malloc0(sizeof(struct oh_event));		
		struct oh_event *event4= (struct oh_event *)g_malloc0(sizeof(struct oh_event));
		struct oh_event *event5= (struct oh_event *)g_malloc0(sizeof(struct oh_event));	
		struct oh_event *event6= (struct oh_event *)g_malloc0(sizeof(struct oh_event));	
		struct oh_event *event7= (struct oh_event *)g_malloc0(sizeof(struct oh_event));	
		struct oh_event *event8= (struct oh_event *)g_malloc0(sizeof(struct oh_event));			
							
		SaErrorT rc1;
	  	char OemString[] = "MY Oem EVENT";
	  	char SWString[] = "MY SW EVENT";			  	
	  	/* change this if you want to be a SNMP master agent */
	  	
	  	debug_register_tokens (AGENT);
                snmp_enable_stderrlog ();
                snmp_set_do_debugging (1);

	  	while ((c = getopt (argc, argv, "fdsCx:h?")) != EOF) {
	    switch (c) {
	   	case 'f':
			do_fork = AGENT_TRUE;
		   	break;
	
	    case 'd':
			debug_register_tokens (AGENT);
			snmp_enable_stderrlog ();
			snmp_set_do_debugging (1);
	      	break;
	
	  	case 's':
			do_syslog = AGENT_FALSE;
	      	break;
	
	   	case 'C':
			netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
				       NETSNMP_DS_LIB_DONT_READ_CONFIGS,
				       1);
	     	break;
	
	  	case 'x':
			netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
				      NETSNMP_DS_AGENT_X_SOCKET,
				      optarg);
	      	break;
	
	 	case 'h':
	    default:
			usage(argv[0]);
			exit(1);
	      	break;
	    }
	  }
	
	  if (do_syslog == AGENT_TRUE) {
	      snmp_enable_calllog ();
	      snmp_enable_syslog_ident (AGENT, LOG_DAEMON);
	  }
	  snmp_log (LOG_INFO, "Starting %s\n", version);
	  /* we're an agentx subagent? */
	  if (agentx_subagent) {
	      /* make us a agentx client. */
	      rc = netsnmp_ds_set_boolean (NETSNMP_DS_APPLICATION_ID,
					   NETSNMP_DS_AGENT_ROLE, 1);
	  }
	
	  /* initialize the agent library */
	  rc = init_agent (AGENT);
	  if (rc != 0) {
	      snmp_log (LOG_ERR, "Could not initialize connection to SNMP daemon. \n"
			"Perhaps you are running %s as non-root?\n", argv[0]);
	      exit (rc);
	  }

	  /* Read configuration information here, before we initialize */
	
	  snmpd_register_config_handler (TRAPS_TOKEN,
					 hpiSubagent_parse_config_traps,
					 NULL,
					 "hpiSubagent on/off switch for sending events upon startup");
	
	  snmpd_register_config_handler (MAX_EVENT_TOKEN,
					 hpiSubagent_parse_config_max_event,
					 NULL,
					 "hpiSubagent MAX number of rows for Events.");
					 
	init_snmp (AGENT); 	
	
	/* 
	 * Initialize HPI library
	 */
	hpiVer = saHpiVersionGet();
	DEBUGMSGTL ((AGENT, "Hpi Version %d Implemented.\n", hpiVer));   	 

	rv = saHpiSessionOpen( SAHPI_UNSPECIFIED_DOMAIN_ID, &sessionid, NULL );
	if (rv != SA_OK) {
		DEBUGMSGTL ((AGENT, "saHpiSessionOpen Error: returns %s\n",
			oh_lookup_error(rv)));
		exit(-1);
	}
   	DEBUGMSGTL ((AGENT, "saHpiSessionOpen returns with SessionId %d\n", 
   		sessionid));  

        /* store session numbers */
   	store_session_info(sessionid, SAHPI_UNSPECIFIED_DOMAIN_ID);	
   				
	/* subscribe all sessions/events */
        subcsribe_all_sessions();

	/* Resource discovery */
	rv = saHpiDiscover(sessionid);
	
	if (rv != SA_OK) {
		DEBUGMSGTL ((AGENT, "saHpiDiscover Error: returns %s\n",oh_lookup_error(rv)));
		exit(-1);
	}
	DEBUGMSGTL ((AGENT, "saHpiDiscover Success!\n"));	

	/* Initialize subagent tables */		
	init_saHpiDomainInfoTable(); 
	init_saHpiDomainAlarmTable();
	init_saHpiDomainReferenceTable();
	
	init_saHpiResourceTable();
	init_saHpiRdrTable();
	init_saHpiCtrlDigitalTable();
	init_saHpiCtrlDiscreteTable();
	init_saHpiCtrlAnalogTable();
	init_saHpiCtrlStreamTable();
	init_saHpiCtrlTextTable();
	init_saHpiCtrlOemTable();
	init_saHpiSensorTable();
	init_saHpiCurrentSensorStateTable();
	init_saHpiSensorReadingMaxTable();
	init_saHpiSensorReadingMinTable();
	init_saHpiSensorReadingNominalTable();
	init_saHpiSensorReadingNormalMaxTable();
	init_saHpiSensorReadingNormalMinTable();
	init_saHpiSensorThdLowCriticalTable();
	init_saHpiSensorThdLowMajorTable();
	init_saHpiSensorThdLowMinorTable();
	init_saHpiSensorThdUpCriticalTable();
	init_saHpiSensorThdUpMajorTable();
	init_saHpiSensorThdUpMinorTable();
	init_saHpiSensorThdPosHysteresisTable();
	init_saHpiSensorThdNegHysteresisTable();
	init_saHpiInventoryTable();
	init_saHpiWatchdogTable();
	init_saHpiAnnunciatorTable();
	init_saHpiAreaTable();
	init_saHpiFieldTable();

	init_saHpiEventTable();
	init_saHpiResourceEventTable();
	init_saHpiDomainEventTable();
	init_saHpiSensorEventTable();
	init_saHpiOemEventTable();
	init_saHpiHotSwapEventTable();
	init_saHpiWatchdogEventTable();		
	init_saHpiSoftwareEventTable();
	init_saHpiSensorEnableChangeEventTable();
	init_saHpiUserEventTable();

	init_saHpiEventLogInfoTable();
	init_saHpiEventLogTable();
	init_saHpiResourceEventLogTable();
	init_saHpiSensorEventLogTable();
	
	init_saHpiHotSwapEventLogTable();
	init_saHpiWatchdogEventLogTable();
	init_saHpiSoftwareEventLogTable();
	init_saHpiOemEventLogTable();
	init_saHpiUserEventLogTable();
	init_saHpiSensorEnableChangeEventLogTable();
	init_saHpiDomainEventLogTable();
	
	init_saHpiHotSwapTable();
	init_saHpiAutoInsertTimeoutTable();
	init_saHpiAnnouncementTable();
/*	init_saHpiAnnouncementEventLogTable();	*/


	if (send_traps_on_startup == AGENT_TRUE)
		send_traps = AGENT_TRUE;
	/* after initialization populate tables */
	populate_saHpiDomainInfoTable(sessionid);

	populate_saHpiDomainAlarmTable(sessionid);

	poplulate_saHpiDomainReferenceTable(sessionid);	

	populate_saHpiResourceTable(sessionid);
	    /* populate_saHpiResourceTable() calls:
	     *     populate_saHpiRdrTable(); calls:
	     *         populate_saHpiCtrlDigitalTable();		
	     *	       populate_saHpiCtrlDiscreteTable();		
	     *	       populate_saHpiCtrlAnalogTable();		
	     *	       populate_saHpiCtrlStreamTable();		
	     *	       populate_saHpiCtrlTextTable();		
	     *	       populate_saHpiCtrlOemTable();		
	     *	       populate_saHpiSensorTable();		
	     *	           populate_saHpiSesnorReadingMaxTable();		
	     *	           populate_saHpiSesnorReadingMinTable();		
	     *	           populate_saHpiSesnorReadingNominalTable();		
	     *	           populate_saHpiSesnorReadingNormalMaxTable();		
	     *	           populate_saHpiSesnorReadingNormalMinTable();		
	     *	           populate_saHpiSensorThdLowCriticalTable();		
	     *	           populate_saHpiSensorThdLowMajorTable();		
	     *	           populate_saHpiSensorThdLowMinorTable();		
	     *	           populate_saHpiSensorThdUpCriticalTable();		
	     *	           populate_saHpiSensorThdUpMajorTable();		
	     *	           populate_saHpiSensorThdUpMinorTable();		
	     *	           populate_saHpiSensorThdPosHysteresisTable();		
	     *	           populate_saHpiSensorThdNegHysteresisTable();		
	     *	       populate_saHpiCurrentSensorStateTable();		
	     *	       populate_saHpiInventoyTable();		
	     *	       populate_saHpiWatchdogTable();		
	     *	       populate_saHpiAnnunciatorTable();		
	     *	       populate_saHpiAreaTable();		
	     *	           populate_saHpiFieldTable();
	     *         populate_saHpiHotSwapTable();
	     */

	populate_saHpiEventTable(sessionid);
            /* populate_saHpiResourceEventTable();
	     * populate_saHpiDomainEventTable();
	     * populate_saHpiSensorEventTable();
	     * populate_saHpiOemEventTable();
	     * populate_saHpiHotSwapEventTable();
	     * populate_saHpiWatchdogEventTable();
	     * populate_saHpiSoftwareEventTable();
	     * populate_saHpiSensorEnableChangeEventTable();
	     * populate_saHpiUserEventTable();
	     */
        populate_saHpiEventLogInfo(sessionid);
        populate_saHpiEventLog (sessionid);
            /*
             * populate_saHpiResourceEventLogTable();
             * populate_saHpiSensorEventLogTable();
	     * populate_saHpiHotSwapEventLogTable();
	     * populate_saHpiWatchdogEventLogTable();
	     * populate_saHpiSoftwareEventLogTable();
	     * populate_saHpiOemEventLogTable();
	     * populate_saHpiUserEventLogTable();
	     * populate_saHpiSensorEnableChangeEventLogTable();
	     * populate_saHpiDomainEventLogTable();	     
             */


        /* Generate Event Here */
		
	DEBUGMSGTL ((AGENT,
        "%%%%%%%% Generating simultor event %%%%%%%%\n"));
	
	state = sim_get_handler_by_name("eventGenerator");
	
	if (!state) {
                DEBUGMSGTL ((AGENT, "%%%%%%%% Couldn't find handler name %%%%%%%%\n"));
	}
	else { // build an event
		
	        event->did = 1; /* domain id for the event */
                event->type = OH_ET_HPI;
                event->u.hpi_event.res = sim_rpt_array[0].rpt;
                event->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event->u.hpi_event.event.EventType = SAHPI_ET_WATCHDOG;
		event->u.hpi_event.event.Timestamp = 0;
		event->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event->u.hpi_event.event.EventDataUnion.WatchdogEvent.WatchdogNum = 1;
		event->u.hpi_event.event.EventDataUnion.WatchdogEvent.WatchdogAction = SAHPI_WAE_RESET;
		event->u.hpi_event.event.EventDataUnion.WatchdogEvent.WatchdogPreTimerAction = SAHPI_WPI_SMI;
		event->u.hpi_event.event.EventDataUnion.WatchdogEvent.WatchdogUse = SAHPI_WTU_BIOS_FRB2;
		
		
		rc1 = sim_inject_event(state, event);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 1: %d %%%%%%%%\n", rc1));
		
	        event2->did = 1; /* domain id for the event */
                event2->type = OH_ET_HPI;
                event2->u.hpi_event.res = sim_rpt_array[0].rpt;
                event2->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event2->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event2->u.hpi_event.event.EventType = SAHPI_ET_HOTSWAP;
		event2->u.hpi_event.event.Timestamp = 0;
		event2->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event2->u.hpi_event.event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_INSERTION_PENDING;
		event2->u.hpi_event.event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = SAHPI_HS_STATE_NOT_PRESENT;				

		rc1 = sim_inject_event(state, event2);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 2: %d %%%%%%%%\n", rc1));
		
	        event3->did = 1; /* domain id for the event */
                event3->type = OH_ET_HPI;
                event3->u.hpi_event.res = sim_rpt_array[0].rpt;
                event3->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event3->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event3->u.hpi_event.event.EventType = SAHPI_ET_SENSOR;
		event3->u.hpi_event.event.Timestamp = 0;
		event3->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.SensorNum = SAHPI_DEFAGSENS_PWR;
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.SensorType = SAHPI_VOLTAGE;	   
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.EventCategory = SAHPI_EC_GENERIC;   
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.Assertion = 1;   
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.EventState = SAHPI_ES_STATE_00;    
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.OptionalDataPresent = SAHPI_SOD_TRIGGER_READING;
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.TriggerReading.IsSupported = 1;
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.TriggerReading.Type = SAHPI_SENSOR_READING_TYPE_UINT64;
		event3->u.hpi_event.event.EventDataUnion.SensorEvent.TriggerReading.Value.SensorUint64 = 0xFEEEEEEEEEEEEEED;
		
		rc1 = sim_inject_event(state, event3);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 3: %d %%%%%%%%\n", rc1));	
		
	        event4->did = 1; /* domain id for the event */
                event4->type = OH_ET_HPI;
                event4->u.hpi_event.res = sim_rpt_array[0].rpt;
                event4->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event4->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event4->u.hpi_event.event.EventType = SAHPI_ET_OEM;
		event4->u.hpi_event.event.Timestamp = 0;
		event4->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event4->u.hpi_event.event.EventDataUnion.OemEvent.MId = SAHPI_MANUFACTURER_ID_UNSPECIFIED;		
		event4->u.hpi_event.event.EventDataUnion.OemEvent.OemEventData.DataType = SAHPI_TL_TYPE_BCDPLUS;
		event4->u.hpi_event.event.EventDataUnion.OemEvent.OemEventData.Language = SAHPI_LANG_ENGLISH;
		event4->u.hpi_event.event.EventDataUnion.OemEvent.OemEventData.DataLength = 12;
		memcpy(event4->u.hpi_event.event.EventDataUnion.OemEvent.OemEventData.Data, &OemString[0],
		       event4->u.hpi_event.event.EventDataUnion.OemEvent.OemEventData.DataLength);
		
		rc1 = sim_inject_event(state, event4);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 4: %d %%%%%%%%\n", rc1));	
		
	        event5->did = 1; /* domain id for the event */
                event5->type = OH_ET_HPI;
                event5->u.hpi_event.res = sim_rpt_array[0].rpt;
                event5->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event5->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event5->u.hpi_event.event.EventType = SAHPI_ET_HPI_SW;
		event5->u.hpi_event.event.Timestamp = 0;
		event5->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.MId = SAHPI_MANUFACTURER_ID_UNSPECIFIED;
		event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.Type = SAHPI_HPIE_STARTUP;
		event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.EventData.DataType = SAHPI_TL_TYPE_TEXT;
		event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.EventData.Language = SAHPI_LANG_ENGLISH;
		event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.EventData.DataLength = 11;  								     
		memcpy(event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.EventData.Data, &SWString[0],
		       event5->u.hpi_event.event.EventDataUnion.HpiSwEvent.EventData.DataLength);

		rc1 = sim_inject_event(state, event5);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 5: %d %%%%%%%%\n", rc1));	
		
	        event6->did = 1; /* domain id for the event */
                event6->type = OH_ET_HPI;
                event6->u.hpi_event.res = sim_rpt_array[0].rpt;
                event6->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event6->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event6->u.hpi_event.event.EventType = SAHPI_ET_SENSOR_ENABLE_CHANGE;
		event6->u.hpi_event.event.Timestamp = 0;
		event6->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.SensorNum = SAHPI_DEFAGSENS_PWR;
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.SensorType = SAHPI_VOLTAGE;	   
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.EventCategory = SAHPI_EC_GENERIC;   
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.SensorEnable = 1;
                event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.SensorEventEnable = 1;
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.AssertEventMask = SAHPI_ES_STATE_ASSERTED;
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.DeassertEventMask = SAHPI_ES_STATE_DEASSERTED;
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.OptionalDataPresent = SAHPI_SEOD_CURRENT_STATE;  
		event6->u.hpi_event.event.EventDataUnion.SensorEnableChangeEvent.CurrentState = SAHPI_ES_LIMIT_EXCEEDED; 
		
		rc1 = sim_inject_event(state, event6);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 6: %d %%%%%%%%\n", rc1));	
		
	        event7->did = 1; /* domain id for the event */
                event7->type = OH_ET_HPI;
                event7->u.hpi_event.res = sim_rpt_array[0].rpt;
                event7->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event7->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event7->u.hpi_event.event.EventType = SAHPI_ET_DOMAIN;
		event7->u.hpi_event.event.Timestamp = 0;
		event7->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event7->u.hpi_event.event.EventDataUnion.DomainEvent.Type = SAHPI_DOMAIN_REF_ADDED;
		event7->u.hpi_event.event.EventDataUnion.DomainEvent.DomainId = SAHPI_UNSPECIFIED_DOMAIN_ID;
		
		rc1 = sim_inject_event(state, event7);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 7: %d %%%%%%%%\n", rc1));	
		
	        event8->did = 1; /* domain id for the event */
                event8->type = OH_ET_HPI;
                event8->u.hpi_event.res = sim_rpt_array[0].rpt;
                event8->u.hpi_event.rdr.RecordId = 0; // Not sure here
		event8->u.hpi_event.event.Source = sim_rpt_array[0].rpt.ResourceId;
		event8->u.hpi_event.event.EventType = SAHPI_ET_RESOURCE;
		event8->u.hpi_event.event.Timestamp = 0;
		event8->u.hpi_event.event.Severity = SAHPI_CRITICAL;
		event8->u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType = SAHPI_RESE_RESOURCE_FAILURE;								  				       	        	     		
		
		rc1 = sim_inject_event(state, event8);
                DEBUGMSGTL ((AGENT, "%%%%%%%% Return code from inject 8: %d %%%%%%%%\n", rc1));	

	}


        /* start event thread */
        set_run_threaded(TRUE);
        if (start_event_thread(sessionid) != AGENT_ERR_NOERROR) {
                snmp_log (LOG_ERR, "Could not start our internal loop . Exiting\n.");
                rc = -1;
                goto stop;
        }

        send_traps = AGENT_TRUE;
        /* If we're going to be a snmp master agent, initial the ports */

        if (!agentx_subagent)
                init_master_agent ();	/* open the port to listen on (defaults to udp:161) */
                
        if (do_fork == AGENT_TRUE) {
                if ((child = fork ()) < 0) {
                        snmp_log (LOG_ERR, "Could not fork!\n");
                        exit (-1);
                }
                if (child != 0)
                        exit (0);
        }

   
        /* In case we recevie a request to stop (kill -TERM or kill -INT) */
        keep_running = 1;
        signal (SIGTERM, stop_server);
        signal (SIGINT, stop_server);



        /* you're main loop here... */
        while (keep_running) {
                /* if you use select(), see snmp_select_info() in snmp_api(3) */
                /*     --- OR ---  */
                rc = agent_check_and_process (1);	/* 0 == don't block */
        }
stop:
        DEBUGMSGTL ((AGENT,
        "WARNING: closeSaHpiSession: hpiSubagent.c: nolong implemented!"));
        //closeSaHpiSession();
        /* at shutdown time */
        snmp_log (LOG_INFO, "Stopping %s\n", version);
        snmp_shutdown (AGENT);
  
  return rc;
}
Пример #9
0
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:";
    int             arg, i, ret;
    int             dont_fork = 0, do_help = 0;
    int             log_set = 0;
    int             agent_mode = -1;
    char           *pid_file = NULL;
    char            option_compatability[] = "-Le";
#ifndef WIN32
    int             prepared_sockets = 0;
#endif
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#endif

#ifndef WIN32
#ifndef NETSNMP_NO_SYSTEMD
    /* check if systemd has sockets for us and don't close them */
    prepared_sockets = netsnmp_sd_listen_fds(0);
#endif /* NETSNMP_NO_SYSTEMD */

    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    if (!prepared_sockets) {
        for (i = getdtablesize() - 1; i > 2; --i) {
            (void) close(i);
        }
    }
#endif /* #WIN32 */
    
    /*
     * register signals ASAP to prevent default action (usually core)
     * for signals during startup...
     */
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif
#ifdef SIGXFSZ
    signal(SIGXFSZ, SnmpdCatchRandomSignal);
#endif

#ifdef NETSNMP_NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5);
    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * This is incredibly ugly, but it's probably the simplest way
     *  to handle the old '-L' option as well as the new '-Lx' style
     */
    for (i=0; i<argc; i++) {
        if (!strcmp(argv[i], "-L"))
            argv[i] = option_compatability;            
    }

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                          NETSNMP_DS_LIB_APPTYPE, app_name);

    /*
     * Now process options normally.  
     */
    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage(argv[0]);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            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(argv[0]);
            }
            break;

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

        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_DUMP_PACKET,
                                   ++snmp_dump_packet);
            break;

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

        case 'f':
            dont_fork = 1;
            break;

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

                gid = strtoul(optarg, &ecp, 10);
#if HAVE_GETGRNAM && HAVE_PWD_H
                if (*ecp) {
                    struct group  *info;

                    info = getgrnam(optarg);
                    gid = info ? info->gr_gid : -1;
                    endgrent();
                }
#endif
                if (gid < 0) {
                    fprintf(stderr, "Bad group id: %s\n", optarg);
                    exit(1);
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, gid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            do_help = 1;
            break;

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

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE
        case 'l':
            printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                snmp_enable_filelog(optarg,
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
                log_set = 1;
            } else {
                usage(argv[0]);
            }
            break;
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */

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

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

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

        case 'n':
            if (optarg != NULL) {
                app_name = optarg;
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                      NETSNMP_DS_LIB_APPTYPE, app_name);
            } else {
                usage(argv[0]);
            }
            break;

        case 'P':
            printf("Warning: -P option is deprecated, use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
                                   NETSNMP_DS_LIB_QUICK_PRINT, 1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
        case 's':
            printf("Warning: -s option is deprecated, use -Lsd instead\n");
            snmp_enable_syslog();
            log_set = 1;
            break;

        case 'S':
            printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
            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(argv[0]);
                }
                snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility);
                log_set = 1;
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

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

                uid = strtoul(optarg, &ecp, 10);
#if HAVE_GETPWNAM && HAVE_PWD_H
                if (*ecp) {
                    struct passwd  *info;

                    info = getpwnam(optarg);
                    uid = info ? info->pw_uid : -1;
                    endpwent();
                }
#endif
                if (uid < 0) {
                    fprintf(stderr, "Bad user id: %s\n", optarg);
                    exit(1);
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        case 'Y':
            netsnmp_config_remember(optarg);
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (do_help) {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
                               NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
        init_agent(app_name);        /* register our .conf handlers */
        init_mib_modules();
        init_snmp(app_name);
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);
    }

    if (optind < argc) {
#ifndef NETSNMP_NO_LISTEN_SUPPORT
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = (char*)malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                SNMP_FREE(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
#else /* NETSNMP_NO_LISTEN_SUPPORT */
        fprintf(stderr, "You specified ports to open; this agent was built to only send notifications\n");
        exit(1);
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
    }

#ifdef NETSNMP_LOGFILE
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE
    if (0 == log_set)
        snmp_enable_filelog(NETSNMP_LOGFILE,
                            netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                   NETSNMP_DS_LIB_APPEND_LOGFILES));
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */
#endif

#ifdef USING_UTIL_FUNCS_RESTART_MODULE
    {
        /*
         * Initialize a argv set to the current for restarting the agent.
         */
        char *cptr, **argvptr;

        argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
        argvptr = argvrestartp;
        for (i = 0, ret = 1; i < argc; i++) {
            ret += strlen(argv[i]) + 1;
        }
        argvrestart = (char *) malloc(ret);
        argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
        if (!argvrestartp || !argvrestart || !argvrestartname) {
            fprintf(stderr, "malloc failure processing argvrestart\n");
            exit(1);
        }
        strcpy(argvrestartname, argv[0]);

        for (cptr = argvrestart, i = 0; i < argc; i++) {
            strcpy(cptr, argv[i]);
            *(argvptr++) = cptr;
            cptr += strlen(argv[i]) + 1;
        }
    }
#endif /* USING_UTIL_FUNCS_RESTART_MODULE */

    if (agent_mode == -1) {
        if (strstr(argv[0], "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    SOCK_STARTUP;
    if (init_agent(app_name) != 0) {
        snmp_log(LOG_ERR, "Agent initialization failed\n");
        exit(1);
    }
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp(app_name);

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        snmp_log(LOG_ERR, "Server Exiting with code 1\n");
        exit(1);
    }

    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
    if(!dont_fork) {
        int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                            NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
        ret = netsnmp_daemonize(quit,
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO
                                snmp_stderrlog_status()
#else /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
                                0
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
            );
        /*
         * xxx-rks: do we care if fork fails? I think we should...
         */
        if(ret != 0) {
            snmp_log(LOG_ERR, "Server Exiting with code 1\n");
            exit(1);
        }
    }

#if HAVE_GETPID
    if (pid_file != NULL) {
        /*
         * unlink the pid_file, if it exists, prior to open.  Without
         * doing this the open will fail if the user specified pid_file
         * already exists.
         */
        unlink(pid_file);
        fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
        if (fd == -1) {
            snmp_log_perror(pid_file);
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        } else {
            if ((PID = fdopen(fd, "w")) == NULL) {
                snmp_log_perror(pid_file);
                exit(1);
            } else {
                fprintf(PID, "%d\n", (int) getpid());
                fclose(PID);
            }
#ifndef _MSC_VER
            /* The sequence open()/fdopen()/fclose()/close() makes MSVC crash,
               hence skip the close() call when using the MSVC runtime. */
            close(fd);
#endif
        }
    }
#endif

#if defined(HAVE_UNISTD_H) && (defined(HAVE_CHOWN) || defined(HAVE_SETGID) || defined(HAVE_SETUID))
    {
    const char     *persistent_dir;
    int             uid, gid;

    persistent_dir = get_persistent_directory();
    mkdirhier( persistent_dir, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
   
    uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_USERID);
    gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_GROUPID);
    
#ifdef HAVE_CHOWN
    if ( uid != 0 || gid != 0 )
        chown( persistent_dir, uid, gid );
#endif

#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) > 0) {
        DEBUGMSGTL(("snmpd/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) {
#if HAVE_GETPWNAM && HAVE_PWD_H && HAVE_INITGROUPS
        struct passwd *info;

        /*
         * Set supplementary groups before changing UID
         *   (which probably involves giving up privileges)
         */
        info = getpwuid(uid);
        if (info) {
            DEBUGMSGTL(("snmpd/main", "Supplementary groups for %s.\n", info->pw_name));
            if (initgroups(info->pw_name, (gid != 0 ? (gid_t)gid : info->pw_gid)) == -1) {
                snmp_log_perror("initgroups failed");
                if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
                                            NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                    exit(1);
                }
            }
        }
        endpwent();
#endif
        DEBUGMSGTL(("snmpd/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

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store(app_name);

#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32SERVICE
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Let systemd know we're up.
     */
#ifndef NETSNMP_NO_SYSTEMD
    netsnmp_sd_notify(1, "READY=1\n");
    if (prepared_sockets)
        /*
         * Clear the environment variable, we already processed all the sockets
         * by now.
         */
        netsnmp_sd_listen_fds(1);
#endif

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown(app_name);
    shutdown_master_agent();
    shutdown_agent();

    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32SERVICE
    agent_status = AGENT_STOPPED;
#endif

#ifdef USING_UTIL_FUNCS_RESTART_MODULE
    SNMP_FREE(argvrestartname);
    SNMP_FREE(argvrestart);
    SNMP_FREE(argvrestartp);
#endif /* USING_UTIL_FUNCS_RESTART_MODULE */

    SOCK_CLEANUP;
    return 0;
}                               /* End main() -- snmpd */
/* ---------------------------------------------------------------------
 *
 * Common master and sub-agent
 */
void
agentx_parse_agentx_socket(const char *token, char *cptr)
{
    DEBUGMSGTL(("agentx/config", "port spec: %s\n", cptr));
    netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, cptr);
}
Пример #11
0
int
netsnmp_parse_args(int argc,
                   char **argv,
                   netsnmp_session * session, const char *localOpts,
                   void (*proc) (int, char *const *, int),
                   int flags)
{
    static char	   *sensitive[4] = { NULL, NULL, NULL, NULL };
    int             arg, sp = 0, testcase = 0;
    char           *cp;
    char           *Apsz = NULL;
    char           *Xpsz = NULL;
    char           *Cpsz = NULL;
    char            Opts[BUF_SIZE];
    int             zero_sensitive = !( flags & NETSNMP_PARSE_ARGS_NOZERO );
    char           *backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = NULL;

    /*
     * initialize session to default values 
     */
    snmp_sess_init(session);
    strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:s:S:L:");
    if (localOpts) {
        if (strlen(localOpts) + strlen(Opts) >= sizeof(Opts)) {
            snmp_log(LOG_ERR, "Too many localOpts in snmp_parse_args()\n");
            return -1;
        }
        strcat(Opts, localOpts);
    }

    /*
     * get the options 
     */
    DEBUGMSGTL(("snmp_parse_args", "starting: %d/%d\n", optind, argc));
    for (arg = 0; arg < argc; arg++) {
        DEBUGMSGTL(("snmp_parse_args", " arg %d = %s\n", arg, argv[arg]));
    }

    optind = 1;
    while ((arg = getopt(argc, argv, Opts)) != EOF) {
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %c\n", optind, arg));
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            if (strcasecmp(optarg, "version") == 0) {
                fprintf(stderr,"NET-SNMP version: %s\n",netsnmp_get_version());
                return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);
            }

            handle_long_opt(optarg);
            break;

        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
            return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);

        case 'h':
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        case 'H':
            init_snmp("snmpapp");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);

        case 'Y':
            netsnmp_config_remember(optarg);
            break;

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'm':
            setenv("MIBS", optarg, 1);
            break;

        case 'M':
            netsnmp_get_mib_directory(); /* prepare the default directories */
            netsnmp_set_mib_directory(optarg);
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

        case 'O':
            cp = snmp_out_options(optarg, argc, argv);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c.\n", 
			*cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'I':
            cp = snmp_in_options(optarg, argc, argv);
            if (cp != NULL) {
                fprintf(stderr, "Unknown input option passed to -I: %c.\n",
			*cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr,
                        "Unknown parsing option passed to -P: %c.\n", *cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

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

        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;

        case 'v':
            session->version = -1;
#ifndef NETSNMP_DISABLE_SNMPV1
            if (!strcmp(optarg, "1")) {
                session->version = SNMP_VERSION_1;
            }
#endif
#ifndef NETSNMP_DISABLE_SNMPV2C
            if (!strcasecmp(optarg, "2c")) {
                session->version = SNMP_VERSION_2c;
            }
#endif
            if (!strcasecmp(optarg, "3")) {
                session->version = SNMP_VERSION_3;
            }
            if (session->version == -1) {
                fprintf(stderr,
                        "Invalid version specified after -v flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'p':
            fprintf(stderr, "Warning: -p option is no longer used - ");
            fprintf(stderr, "specify the remote host as HOST:PORT\n");
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        case 'T':
        {
            char leftside[SNMP_MAXBUF_MEDIUM], rightside[SNMP_MAXBUF_MEDIUM];
            char *tmpcp, *tmpopt;
            
            /* ensure we have a proper argument */
            tmpopt = strdup(optarg);
            tmpcp = strchr(tmpopt, '=');
            if (!tmpcp) {
                fprintf(stderr, "-T expects a NAME=VALUE pair.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            *tmpcp++ = '\0';

            /* create the transport config container if this is the first */
            if (!session->transport_configuration) {
                netsnmp_container_init_list();
                session->transport_configuration =
                    netsnmp_container_find("transport_configuration:fifo");
                if (!session->transport_configuration) {
                    fprintf(stderr, "failed to initialize the transport configuration container\n");
                    free(tmpopt);
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }

                session->transport_configuration->compare =
                    (netsnmp_container_compare*)
                    netsnmp_transport_config_compare;
            }

            /* set the config */
            strlcpy(leftside, tmpopt, sizeof(leftside));
            strlcpy(rightside, tmpcp, sizeof(rightside));

            CONTAINER_INSERT(session->transport_configuration,
                             netsnmp_transport_create_config(leftside,
                                                             rightside));
            free(tmpopt);
        }
        break;
            
        case 't':
            session->timeout = (long)(atof(optarg) * 1000000L);
            if (session->timeout <= 0) {
                fprintf(stderr, "Invalid timeout in seconds after -t flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'r':
            session->retries = atoi(optarg);
            if (session->retries < 0 || !isdigit((unsigned char)(optarg[0]))) {
                fprintf(stderr, "Invalid number of retries after -r flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'c':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Cpsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -c flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Cpsz = optarg;
	    }
            break;

        case '3':
	    /*  TODO: This needs to zero things too.  */
            if (snmpv3_options(optarg, session, &Apsz, &Xpsz, argc, argv) < 0){
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0) {
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

#define SNMPV3_CMD_OPTIONS
#ifdef  SNMPV3_CMD_OPTIONS
        case 'Z':
            errno = 0;
            session->engineBoots = strtoul(optarg, &cp, 10);
            if (errno || cp == optarg) {
                fprintf(stderr, "Need engine boots value after -Z flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            if (*cp == ',') {
                char *endptr;
                cp++;
                session->engineTime = strtoul(cp, &endptr, 10);
                if (errno || cp == endptr) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot,\".\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
            }
            /*
             * Handle previous '-Z boot time' syntax 
             */
            else if (optind < argc) {
                session->engineTime = strtoul(argv[optind], &cp, 10);
                if (errno || cp == argv[optind]) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
            } else {
                fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'e':{
                size_t ebuf_len = 32, eout_len = 0;
                u_char *ebuf = (u_char *)malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr, "malloc failure processing -e flag.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }
                if (!snmp_hex_to_binary
                    (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
                    fprintf(stderr, "Bad engine ID value after -e flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                if ((eout_len < 5) || (eout_len > 32)) {
                    fprintf(stderr, "Invalid engine ID value after -e flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                session->securityEngineID = ebuf;
                session->securityEngineIDLen = eout_len;
                break;
            }

        case 'E':{
                size_t ebuf_len = 32, eout_len = 0;
                u_char *ebuf = (u_char *)malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr, "malloc failure processing -E flag.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }
                if (!snmp_hex_to_binary(&ebuf, &ebuf_len,
					&eout_len, 1, optarg)) {
                    fprintf(stderr, "Bad engine ID value after -E flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                if ((eout_len < 5) || (eout_len > 32)) {
                    fprintf(stderr, "Invalid engine ID value after -E flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                session->contextEngineID = ebuf;
                session->contextEngineIDLen = eout_len;
                break;
            }

        case 'n':
            session->contextName = optarg;
            session->contextNameLen = strlen(optarg);
            break;

        case 'u':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    session->securityName = sensitive[sp];
		    session->securityNameLen = strlen(sensitive[sp]);
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -u flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		session->securityName = optarg;
		session->securityNameLen = strlen(optarg);
	    }
            break;

        case 'l':
            if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1")
                || !strcasecmp(optarg, "noauth")
                || !strcasecmp(optarg, "nanp")) {
                session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
            } else if (!strcasecmp(optarg, "authNoPriv")
                       || !strcmp(optarg, "2")
                       || !strcasecmp(optarg, "auth")
                       || !strcasecmp(optarg, "anp")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
            } else if (!strcasecmp(optarg, "authPriv")
                       || !strcmp(optarg, "3")
                       || !strcasecmp(optarg, "priv")
                       || !strcasecmp(optarg, "ap")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
            } else {
                fprintf(stderr,
                        "Invalid security level specified after -l flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }

            break;

#ifdef NETSNMP_SECMOD_USM
        case 'a':
#ifndef NETSNMP_DISABLE_MD5
            if (!strcasecmp(optarg, "MD5")) {
                session->securityAuthProto = usmHMACMD5AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
            } else
#endif
                if (!strcasecmp(optarg, "SHA")) {
                session->securityAuthProto = usmHMACSHA1AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
            } else {
                fprintf(stderr,
                        "Invalid authentication protocol specified after -a flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'x':
            testcase = 0;
#ifndef NETSNMP_DISABLE_DES
            if (!strcasecmp(optarg, "DES")) {
                testcase = 1;
                session->securityPrivProto = usmDESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
            }
#endif
#ifdef HAVE_AES
            if (!strcasecmp(optarg, "AES128") ||
                !strcasecmp(optarg, "AES")) {
                testcase = 1;
                session->securityPrivProto = usmAESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
            }
#endif
            if (testcase == 0) {
                fprintf(stderr,
                      "Invalid privacy protocol specified after -x flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'A':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Apsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -A flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Apsz = optarg;
	    }
            break;

        case 'X':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Xpsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -X flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Xpsz = optarg;
	    }
            break;
#endif                          /* SNMPV3_CMD_OPTIONS */
#endif /* NETSNMP_SECMOD_USM */

        case '?':
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        default:
            proc(argc, argv, arg);
            break;
        }
    }
    DEBUGMSGTL(("snmp_parse_args", "finished: %d/%d\n", optind, argc));
    
    /*
     * save command line parameters which should have precedence above config file settings
     *    (There ought to be a more scalable approach than this....)
     */
    if (netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION)) {
        backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = 
            strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION));
    }

    /*
     * read in MIB database and initialize the snmp library, read the config file
     */
    init_snmp("snmpapp");

    /*
     * restore command line parameters which should have precedence above config file settings
     */
    if(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION) {
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION, backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
        free(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
    }

    /*
     * session default version 
     */
    if (session->version == SNMP_DEFAULT_VERSION) {
        /*
         * run time default version 
         */
        session->version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
					      NETSNMP_DS_LIB_SNMPVERSION);

        /*
         * compile time default version 
         */
        if (!session->version) {
            switch (NETSNMP_DEFAULT_SNMP_VERSION) {
#ifndef NETSNMP_DISABLE_SNMPV1
            case 1:
                session->version = SNMP_VERSION_1;
                break;
#endif

#ifndef NETSNMP_DISABLE_SNMPV2C
            case 2:
                session->version = SNMP_VERSION_2c;
                break;
#endif

            case 3:
                session->version = SNMP_VERSION_3;
                break;

            default:
                snmp_log(LOG_ERR, "Can't determine a valid SNMP version for the session\n");
                return(NETSNMP_PARSE_ARGS_ERROR);
            }
        } else {
#ifndef NETSNMP_DISABLE_SNMPV1
            if (session->version == NETSNMP_DS_SNMP_VERSION_1)  /* bogus value.  version 1 actually = 0 */
                session->version = SNMP_VERSION_1;
#endif
        }
    }

#ifdef NETSNMP_SECMOD_USM
    /* XXX: this should ideally be moved to snmpusm.c somehow */

    /*
     * make master key from pass phrases 
     */
    if (Apsz) {
        session->securityAuthKeyLen = USM_AUTH_KU_LEN;
        if (session->securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session->securityAuthProtoLen);
            session->securityAuthProto =
                snmp_duplicate_objid(def, session->securityAuthProtoLen);
        }
        if (session->securityAuthProto == NULL) {
#ifndef NETSNMP_DISABLE_MD5
            /*
             * assume MD5
             */
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     USM_AUTH_PROTO_MD5_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
#else
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
                                     USM_AUTH_PROTO_SHA_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
#endif
        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Apsz, strlen(Apsz),
                        session->securityAuthKey,
                        &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied authentication pass phrase. \n");
            return (NETSNMP_PARSE_ARGS_ERROR);
        }
    }
    if (Xpsz) {
        session->securityPrivKeyLen = USM_PRIV_KU_LEN;
        if (session->securityPrivProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_privtype(&session->securityPrivProtoLen);
            session->securityPrivProto =
                snmp_duplicate_objid(def, session->securityPrivProtoLen);
        }
        if (session->securityPrivProto == NULL) {
            /*
             * assume DES 
             */
#ifndef NETSNMP_DISABLE_DES
            session->securityPrivProto =
                snmp_duplicate_objid(usmDESPrivProtocol,
                                     USM_PRIV_PROTO_DES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
#else
            session->securityPrivProto =
                snmp_duplicate_objid(usmAESPrivProtocol,
                                     USM_PRIV_PROTO_AES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
#endif

        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Xpsz, strlen(Xpsz),
                        session->securityPrivKey,
                        &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied privacy pass phrase. \n");
            return (NETSNMP_PARSE_ARGS_ERROR);
        }
    }
#endif /* NETSNMP_SECMOD_USM */

    /*
     * get the hostname 
     */
    if (optind == argc) {
        fprintf(stderr, "No hostname specified.\n");
        return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
    }
    session->peername = argv[optind++]; /* hostname */

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    /*
     * If v1 or v2c, check community has been set, either by a -c option above,
     * or via a default token somewhere.  
     * If neither, it will be taken from the incoming request PDU.
     */

#if defined(NETSNMP_DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c)
#else 
#if defined(NETSNMP_DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1)
#else
    if (session->version == SNMP_VERSION_1 ||
	session->version == SNMP_VERSION_2c)
#endif
#endif
    {
        if (Cpsz == NULL) {
            Cpsz = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					 NETSNMP_DS_LIB_COMMUNITY);
	    if (Cpsz == NULL) {
                if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                           NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY)){
                    DEBUGMSGTL(("snmp_parse_args",
                                "ignoring that the community string is not present\n"));
                    session->community = NULL;
                    session->community_len = 0;
                } else {
                    fprintf(stderr, "No community name specified.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
	    }
	} else {
            session->community = (unsigned char *)Cpsz;
            session->community_len = strlen(Cpsz);
        }
    }
#endif /* support for community based SNMP */

    return optind;
}
Пример #12
0
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:LP:qrsS:UvV-:";
    int             arg, i, ret;
    int             dont_fork = 0;
    int             dont_zero_log = 0;
    int             stderr_log = 0, syslog_log = 0;
    int             uid = 0, gid = 0;
    int             agent_mode = -1;
    char            logfile[PATH_MAX + 1] = { 0 };
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#endif

#ifdef LOGFILE
    strncpy(logfile, LOGFILE, PATH_MAX);
#endif

#ifdef NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * Now process options normally.  
     */

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

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            break;

        case 'A':
            dont_zero_log = 1;
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage(argv[0]);
            }
            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(++snmp_dump_packet);
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

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

        case 'f':
            dont_fork = 1;
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, atoi(optarg));
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
            init_agent("snmpd");        /* register our .conf handlers */
            init_mib_modules();
            init_snmp("snmpd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

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

        case 'l':
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                strncpy(logfile, optarg, PATH_MAX);
            } else {
                usage(argv[0]);
            }
            break;

        case 'L':
            stderr_log = 1;
            break;

        case 'P':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

        case 's':
            syslog_log = 1;
            break;

        case 'S':
            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(argv[0]);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

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

                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(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                free(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
    }

    setup_log(0, dont_zero_log, stderr_log, syslog_log, logfile);

    /*
     * Initialize a argv set to the current for restarting the agent.   
     */
    argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    if (!argvrestartp || !argvrestart || !argvrestartname) {
        fprintf(stderr, "malloc failure processing argvrestart\n");
        exit(1);
    }
    strcpy(argvrestartname, argv[0]);
    if (agent_mode == -1) {
        if (strstr(argvrestartname, "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;

#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
#if HAVE_FORK
    if (!dont_fork) {
        /*
         * Fork to return control to the invoking process and to
         * guarantee that we aren't a process group leader.
         */
        if (fork() != 0) {
            /* Parent. */
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                        NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
                exit(0);
            }
        } else {
            /* Child. */
#ifdef HAVE_SETSID
            /* Become a process/session group leader. */
            setsid();
#endif
            /*
             * Fork to let the process/session group leader exit.
             */
            if (fork() != 0) {
                /* Parent. */
                exit(0);
            }
#ifndef WIN32
            else {
                /* Child. */

                /* Avoid keeping any directory in use. */
                chdir("/");

                if (!stderr_log) {
                    /*
                     * Close inherited file descriptors to avoid
                     * keeping unnecessary references.
                     */
                    close(0);
                    close(1);
                    close(2);

                    /*
                     * Redirect std{in,out,err} to /dev/null, just in
                     * case.
                     */
                    open("/dev/null", O_RDWR);
                    dup(0);
                    dup(0);
                }
            }
#endif /* !WIN32 */
        }
    }
#endif /* HAVE_FORK */

    SOCK_STARTUP;
    init_agent("snmpd");        /* do what we need to do first. */
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp("snmpd");

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        Exit(1);                /*  Exit logs exit val for us  */
    }
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store("snmpd");

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

#if HAVE_GETPID
    if (pid_file != NULL) {
	    /*
	     * unlink the pid_file, if it exists, prior to open.  Without
	     * doing this the open will fail if the user specified pid_file
	     * already exists.
	     */
	    unlink(pid_file);
	    fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
	    if (fd == -1) {
		    snmp_log_perror(pid_file);
		    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
			    exit(1);
		    }
	    } else {
		    if ((PID = fdopen(fd, "w")) == NULL) {
			    snmp_log_perror(pid_file);
			    exit(1);
		    } else {
			    fprintf(PID, "%d\n", (int) getpid());
			    fclose(PID);
		    }
		    close(fd);
	    }
    }
#endif

#if HAVE_UNISTD_H
#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmpd/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(("snmpd/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

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
#include "mib_module_shutdown.h"
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown("snmpd");
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32
    agent_status = AGENT_STOPPED;
#endif
    return 0;
}                               /* End main() -- snmpd */
Пример #13
0
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;
}
Пример #14
0
int
main(int argc, char *argv[])
{
    int             arg;
    char           *prognam;
    char           *cp = NULL;
    const char*     sysUpTime = NULL;

    /* initialize tcpip, if necessary */
    SOCK_STARTUP;

    prognam = strrchr(argv[0], '/');
    if (prognam)
        ++prognam;
    else
        prognam = argv[0];

    putenv(strdup("POSIXLY_CORRECT=1"));

    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, 1);
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_DISABLE_PERSISTENT_SAVE, 1);

    while ((arg = getopt(argc, argv, ":Vhm:M:D:dP:L:U:c:x:")) != -1) {
        switch (arg) {
        case 'h':
            usage(prognam);
            result = 0;
            goto out;
        case 'm':
            setenv("MIBS", optarg, 1);
            break;
        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;
        case 'c':
            context = optarg;
            contextLen = strlen(context);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;
        case 'U':
            sysUpTime = optarg;
            break;
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
            result = 0;
            goto out;
#ifndef DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
                usage(prognam);
                goto out;
            }
            break;
#endif /* DISABLE_MIB_LOADING */
        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0)
                goto out;
            break;
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else
                usage(argv[0]);
            break;

        case ':':
            fprintf(stderr, "Option -%c requires an operand\n", optopt);
            usage(prognam);
            goto out;
        case '?':
            fprintf(stderr, "Unrecognized option: -%c\n", optopt);
            usage(prognam);
            goto out;
        }
    }

    arg = optind;

    init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE);
    agentx_config_init();

    /* NOTIFY varlist */
    pdu = pdu_create_opt_context(AGENTX_MSG_NOTIFY, context, contextLen);

    if (sysUpTime)
        snmp_add_var(pdu, sysuptime_oid, sysuptime_oid_len, 't', sysUpTime);

    if (arg == argc) {
        fprintf(stderr, "Missing trap-oid parameter\n");
        usage(prognam);
        goto out;
    }

    if (snmp_add_var(pdu, snmptrap_oid, snmptrap_oid_len, 'o', argv[arg])) {
        snmp_perror(argv[arg]);
        goto out;
    }
    ++arg;

    while (arg < argc) {
        oid    name[MAX_OID_LEN];
        size_t name_length = MAX_OID_LEN;
        arg += 3;
        if (arg > argc) {
            fprintf(stderr, "%s: Missing type/value for variable\n",
                    argv[arg - 3]);
            goto out;
        }
        if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) {
            snmp_perror(argv[arg - 3]);
            goto out;
        }
        if (snmp_add_var(pdu, name, name_length, argv[arg - 2][0],
                         argv[arg - 1]) != 0) {
            snmp_perror(argv[arg - 3]);
            goto out;
        }
    }

    packetid = 0;

    state = &Connecting;
    next_state = NULL;
    if(state->entry) state->entry(state);

    /* main loop here... */
    for(;;) {
        int block = 1;
        int numfds = 0;
        int count;
        fd_set fdset;
        struct timeval timeout;

        while(next_state) {
            if(state->exit) state->exit(state);
            DEBUGMSGTL(("process", "State transition: %s -> %s\n",
                        state->name, next_state->name));
            state = next_state;
            next_state = NULL;
            if(state->entry) state->entry(state);
        }

        if(state == &Exit)
            break;

        FD_ZERO(&fdset);
        snmp_sess_select_info(sessp, &numfds, &fdset, &timeout, &block);
        count = select(numfds, &fdset, NULL, NULL, !block ? &timeout : NULL);
        if (count > 0)
            snmp_sess_read(sessp, &fdset);
        else if (count == 0)
            snmp_sess_timeout(sessp);
        else if (errno != EINTR) {
            snmp_log(LOG_ERR, "select error [%s]\n", strerror(errno));
            change_state(&Exit);
        }
    }

    /* at shutdown time */
    snmp_free_pdu(pdu);
    pdu = NULL;

    snmp_shutdown(NETSNMP_APPLICATION_CONFIG_TYPE);

out:
    SOCK_CLEANUP;
    return result;
}
Пример #15
0
int
main (int argc, char **argv) {
  int agentx_subagent=1; /* change this if you want to be a SNMP master agent */
  /* Defs for arg-handling code: handles setting of policy-related variables */
  int          ch;
  extern char *optarg;
  int dont_fork = 0, use_stderr = 0;
  char *agentx_socket = NULL;

  while ((ch = getopt(argc, argv, "D:fHLMx:")) != EOF)
    switch(ch) {
    case 'D':
      debug_register_tokens(optarg);
      snmp_set_do_debugging(1);
      break;
    case 'f':
      dont_fork = 1;
      break;
    case 'H':
      netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
	                     NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
      init_agent("libvirtGuestTable");        /* register our .conf handlers */
      init_libvirtGuestTable();
      init_snmp("libvirtGuestTable");
      fprintf(stderr, "Configuration directives understood:\n");
      read_config_print_usage("  ");
      snmp_shutdown("libvirtGuestTable");
      shutdown_libvirtGuestTable();
      exit(0);
    case 'M':
      agentx_subagent = 0;
      break;
    case 'L':
      use_stderr = 1;
      break;
    case 'x':
      agentx_socket = optarg;
      break;
    default:
      fprintf(stderr,"unknown option %c\n", ch);
      usage();
  }

  if (optind < argc) {
      int i;
      /*
       * There are optional transport addresses on the command line.
       */
      DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
      for (i = optind; i < argc; i++) {
          char *c, *astring;
          if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                         NETSNMP_DS_AGENT_PORTS))) {
              astring = malloc(strlen(c) + 2 + strlen(argv[i]));
              if (astring == NULL) {
                  fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                  exit(1);
              }
              sprintf(astring, "%s,%s", c, argv[i]);
              netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                    NETSNMP_DS_AGENT_PORTS, astring);
              SNMP_FREE(astring);
          } else {
              netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                    NETSNMP_DS_AGENT_PORTS, argv[i]);
          }
      }
      DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                  netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                        NETSNMP_DS_AGENT_PORTS)));
  }

  /* we're an agentx subagent? */
  if (agentx_subagent) {
    /* make us a agentx client. */
    netsnmp_enable_subagent();
    if (NULL != agentx_socket)
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_X_SOCKET, agentx_socket);
  }

  snmp_disable_log();
  if (use_stderr)
      snmp_enable_stderrlog();
  else
      snmp_enable_calllog();

  /* daemonize */
  if(!dont_fork) {
    int rc = netsnmp_daemonize(1, use_stderr);
    if(rc)
       exit(-1);
  }

  /* initialize tcp/ip if necessary */
  SOCK_STARTUP;

  /* initialize the agent library */
  init_agent("libvirtGuestTable");

  /* init libvirtGuestTable mib code */
  init_libvirtGuestTable();

  /* read libvirtGuestTable.conf files. */
  init_snmp("libvirtGuestTable");

  /* If we're going to be a snmp master agent, initial the ports */
  if (!agentx_subagent)
    init_master_agent();  /* open the port to listen on (defaults to udp:161) */

  /* In case we recevie a request to stop (kill -TERM or kill -INT) */
  keep_running = 1;
  signal(SIGTERM, stop_server);
  signal(SIGINT, stop_server);

  /* you're main loop here... */
  while(keep_running) {
    /* if you use select(), see snmp_select_info() in snmp_api(3) */
    /*     --- OR ---  */
    agent_check_and_process(1); /* 0 == don't block */
  }

  /* at shutdown time */
  snmp_shutdown("libvirtGuestTable");
  shutdown_libvirtGuestTable();
  SOCK_CLEANUP;
  exit(0);
}
Пример #16
0
int main(int argc, char** argv) {
    int agentx_subagent =
        1; /* change this if you want to be a SNMP master agent */
    /* Defs for arg-handling code: handles setting of policy-related variables
     */
    int ch;
    extern char* optarg;
    int dont_fork = 0, use_syslog = 0;
    char const* agentx_socket = NULL;
    char const* app_name = "moninor-agent";
    char const* directory = "/home/";

    while ((ch = getopt(argc, argv, "a:p:hdD:fHLMx:")) != EOF) {
        switch (ch) {
        case 'a':
            app_name = optarg;
            break;
        case 'p':
            directory = optarg;
            break;
        case 'h':
            print_usage();
            exit(0);
        case 'd':
            print_tokens();
            exit(0);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'f':
            dont_fork = 1;
            break;
        case 'M':
            agentx_subagent = 0;
            break;
        case 'L':
            use_syslog = 0; /* use stderr */
            break;
        case 'x':
            agentx_socket = optarg;
            break;
        default:
            fprintf(stderr, "unknown option %c\n", ch);
            print_usage();
        }
    }

    if (optind < argc) {
        int i;
        /*
            * There are optional transport addresses on the command line.
            */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char* c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                           NETSNMP_DS_AGENT_PORTS))) {
                astring = malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_PORTS, astring);
                SNMP_FREE(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                          NETSNMP_DS_AGENT_PORTS)));
    }

    /* check directory existence */
    DIR* dir = opendir(directory);
    if (dir) {
        closedir(dir);
    } else if (ENOENT == errno) {
        puts("Directory doesn't not exist.");
        exit(-1);
    } else {
        puts("Cannot open direcory.");
        exit(-1);
    }

    /* we're an agentx subagent? */
    if (agentx_subagent) {
        /* make us a agentx client. */
        netsnmp_enable_subagent();
        if (NULL != agentx_socket) {
            netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                  NETSNMP_DS_AGENT_X_SOCKET, agentx_socket);
        }
    }

    snmp_disable_log();
    if (use_syslog)
        snmp_enable_calllog();
    else
        snmp_enable_stderrlog();

    /* daemonize */
    if (!dont_fork) {
        int rc = netsnmp_daemonize(1, !use_syslog);
        if (rc) exit(-1);
    }

    /* initialize tcp/ip if necessary */
    SOCK_STARTUP;

    /* initialize the agent library */
    init_agent(app_name);

    /* init mib code */
    global_settings_t* settings = get_mutable_global_settings();
    strcpy(settings->path, directory);

    void* data[4] = {NULL, NULL, NULL, NULL};
    init_Directory(data + 0);
    init_DirectoryStateNotification(data + 1);
    init_NumDirectories(data + 2);
    init_NumFiles(data + 3);
    init_DirectoryContentTable();

    /* read app_name.conf files. */
    init_snmp(app_name);

    /* If we're going to be a snmp master agent, initial the ports */
    if (!agentx_subagent)
        init_master_agent(); /* open the port to listen on (defaults to udp:161)
                                */

    /* In case we recevie a request to stop (kill -TERM or kill -INT) */
    g_keep_running = 1;
    signal(SIGTERM, stop_server);
    signal(SIGINT, stop_server);

    /* you're main loop here... */
    while (g_keep_running) {
        agent_check_and_process(1); /* 0 == don't block */
    }

    shutdown_DirectoryContentTable();
    shutdown_NumFiles(data[3]);
    shutdown_NumDirectories(data[2]);
    shutdown_DirectoryStateNotification(data[1]);
    shutdown_Directory(data[0]);

    /* at shutdown time */
    snmp_shutdown(app_name);
    SOCK_CLEANUP;
    exit(0);
}
Пример #17
0
/*
 * Locate the appropriate transport domain and call the create function for
 * it.
 */
netsnmp_transport *
netsnmp_tdomain_transport_full(const char *application,
                               const char *str, int local,
                               const char *default_domain,
                               const char *default_target)
{
    netsnmp_tdomain    *match = NULL;
    const char         *addr = NULL;
    const char * const *spec = NULL;
    int                 any_found = 0;
    char buf[SNMP_MAXPATH];
    char **lspec = 0;

    DEBUGMSGTL(("tdomain",
                "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n",
                application, str ? str : "[NIL]", local,
                default_domain ? default_domain : "[NIL]",
                default_target ? default_target : "[NIL]"));

    /* see if we can load a host-name specific set of conf files */
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES) &&
            netsnmp_is_fqdn(str)) {
        static int have_added_handler = 0;
        char *newhost;
        struct config_line *config_handlers;
        struct config_files file_names;
        char *prev_hostname;

        /* register a "transport" specifier */
        if (!have_added_handler) {
            have_added_handler = 1;
            netsnmp_ds_register_config(ASN_OCTET_STR,
                                       "snmp", "transport",
                                       NETSNMP_DS_LIBRARY_ID,
                                       NETSNMP_DS_LIB_HOSTNAME);
        }

        /* we save on specific setting that we don't allow to change
           from one transport creation to the next; ie, we don't want
           the "transport" specifier to be a default.  It should be a
           single invocation use only */
        prev_hostname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                              NETSNMP_DS_LIB_HOSTNAME);
        if (prev_hostname)
            prev_hostname = strdup(prev_hostname);

        /* read in the hosts/STRING.conf files */
        config_handlers = read_config_get_handlers("snmp");
        snprintf(buf, sizeof(buf)-1, "hosts/%s", str);
        file_names.fileHeader = buf;
        file_names.start = config_handlers;
        file_names.next = NULL;
        DEBUGMSGTL(("tdomain", "checking for host specific config %s\n",
                    buf));
        read_config_files_of_type(EITHER_CONFIG, &file_names);

        if (NULL !=
                (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_HOSTNAME))) {
            strlcpy(buf, newhost, sizeof(buf));
            str = buf;
        }

        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                              NETSNMP_DS_LIB_HOSTNAME,
                              prev_hostname);
        SNMP_FREE(prev_hostname);
    }

    /* First try - assume that there is a domain in str (domain:target) */

    if (str != NULL) {
        const char *cp;
        if ((cp = strchr(str, ':')) != NULL) {
            char* mystring = (char*)malloc(cp + 1 - str);
            memcpy(mystring, str, cp - str);
            mystring[cp - str] = '\0';
            addr = cp + 1;

            match = find_tdomain(mystring);
            free(mystring);
        }
    }

    /*
     * Second try, if there is no domain in str (target), then try the
     * default domain
     */

    if (match == NULL) {
        addr = str;
        if (addr && *addr == '/') {
            DEBUGMSGTL(("tdomain",
                        "Address starts with '/', so assume \"unix\" "
                        "domain\n"));
            match = find_tdomain("unix");
        } else if (default_domain) {
            DEBUGMSGTL(("tdomain",
                        "Use user specified default domain \"%s\"\n",
                        default_domain));
            if (!strchr(default_domain, ','))
                match = find_tdomain(default_domain);
            else {
                int commas = 0;
                const char *cp = default_domain;
                char *dup = strdup(default_domain);

                while (*++cp) if (*cp == ',') commas++;
                lspec = (char **) calloc(commas+2, sizeof(char *));
                commas = 1;
                lspec[0] = strtok(dup, ",");
                while ((lspec[commas++] = strtok(NULL, ",")))
                    ;
                spec = (const char * const *)lspec;
            }
        } else {
            spec = netsnmp_lookup_default_domains(application);
            if (spec == NULL) {
                DEBUGMSGTL(("tdomain",
                            "No default domain found, assume \"udp\"\n"));
                match = find_tdomain("udp");
            } else {
                const char * const * r = spec;
                DEBUGMSGTL(("tdomain",
                            "Use application default domains"));
                while(*r) {
                    DEBUGMSG(("tdomain", " \"%s\"", *r));
                    ++r;
                }
                DEBUGMSG(("tdomain", "\n"));
            }
        }
    }

    for(;;) {
        if (match) {
            netsnmp_transport *t = NULL;
            const char* addr2;

            any_found = 1;
            /*
             * Ok, we know what domain to try, lets see what default data
             * should be used with it
             */
            if (default_target != NULL)
                addr2 = default_target;
            else
                addr2 = netsnmp_lookup_default_target(application,
                                                      match->prefix[0]);
            DEBUGMSGTL(("tdomain",
                        "trying domain \"%s\" address \"%s\" "
                        "default address \"%s\"\n",
                        match->prefix[0], addr ? addr : "[NIL]",
                        addr2 ? addr2 : "[NIL]"));
            if (match->f_create_from_tstring) {
                NETSNMP_LOGONCE((LOG_WARNING,
                                 "transport domain %s uses deprecated f_create_from_tstring\n",
                                 match->prefix[0]));
                t = match->f_create_from_tstring(addr, local);
            }
            else
                t = match->f_create_from_tstring_new(addr, local, addr2);
            if (t) {
                if (lspec) {
                    free(lspec[0]);
                    free(lspec);
                }
                return t;
            }
        }
        addr = str;
        if (spec && *spec)
            match = find_tdomain(*spec++);
        else
            break;
    }
    if (!any_found)
        snmp_log(LOG_ERR, "No support for any checked transport domain\n");
    if (lspec) {
        free(lspec[0]);
        free(lspec);
    }
    return NULL;
}
Пример #18
0
void
init_agent_read_config(const char *app)
{
    if (app != NULL) {
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
			      NETSNMP_DS_LIB_APPTYPE, app);
    } else {
        app = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
				    NETSNMP_DS_LIB_APPTYPE);
    }

    register_app_config_handler("authtrapenable",
                                snmpd_parse_config_authtrap, NULL,
                                "1 | 2\t\t(1 = enable, 2 = disable)");
    register_app_config_handler("pauthtrapenable",
                                snmpd_parse_config_authtrap, NULL, NULL);


    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE) == MASTER_AGENT) {
#ifndef DISABLE_SNMPV1
        register_app_config_handler("trapsink",
                                    snmpd_parse_config_trapsink,
                                    snmpd_free_trapsinks,
                                    "host [community] [port]");
#endif
#ifndef DISABLE_SNMPV2C
        register_app_config_handler("trap2sink",
                                    snmpd_parse_config_trap2sink, NULL,
                                    "host [community] [port]");
        register_app_config_handler("informsink",
                                    snmpd_parse_config_informsink, NULL,
                                    "host [community] [port]");
#endif
        register_app_config_handler("trapsess",
                                    snmpd_parse_config_trapsess, NULL,
                                    "[snmpcmdargs] host");
    }
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
    register_app_config_handler("trapcommunity",
                                snmpd_parse_config_trapcommunity,
                                snmpd_free_trapcommunity,
                                "community-string");
#endif /* support for community based SNMP */
#ifdef HAVE_UNISTD_H
    register_app_config_handler("agentuser",
                                snmpd_set_agent_user, NULL, "userid");
    register_app_config_handler("agentgroup",
                                snmpd_set_agent_group, NULL, "groupid");
#endif
    register_app_config_handler("agentaddress",
                                snmpd_set_agent_address, NULL,
                                "SNMP bind address");
    netsnmp_ds_register_config(ASN_BOOLEAN, app, "quit", 
			       NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
    netsnmp_ds_register_config(ASN_BOOLEAN, app, "leave_pidfile", 
			       NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_LEAVE_PIDFILE);
    netsnmp_init_handler_conf();

#include "agent_module_dot_conf.h"
#include "mib_module_dot_conf.h"
#ifdef TESTING
    print_config_handlers();
#endif
}
Пример #19
0
int
main (int argc, char **argv)
{
	
	  	int agentx_subagent = AGENT_TRUE;
	  	int c;
	  	int rc = 0;
	  
	  	SaErrorT 	rv = SA_OK;
		SaHpiVersionT	hpiVer;
		SaHpiSessionIdT sessionid;
                SaHpiDomainInfoT        domain_info;  		
		SaHpiBoolT      run_threaded = TRUE;
		
	  	pid_t child;
		
		char * env;
	  		  	
	  	/* change this if you want to be a SNMP master agent */
	  	
	  	debug_register_tokens (AGENT);
                snmp_enable_stderrlog ();
                snmp_set_do_debugging (1);

	  	while ((c = getopt (argc, argv, "fdsCx:h?")) != EOF) {
	    switch (c) {
	   	case 'f':
			do_fork = AGENT_TRUE;
		   	break;
	
	    case 'd':
			debug_register_tokens (AGENT);
			snmp_enable_stderrlog ();
			snmp_set_do_debugging (1);
	      	break;
	
	  	case 's':
			do_syslog = AGENT_FALSE;
	      	break;
	
	   	case 'C':
			netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
				       NETSNMP_DS_LIB_DONT_READ_CONFIGS,
				       1);
	     	break;
	
	  	case 'x':
			netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
				      NETSNMP_DS_AGENT_X_SOCKET,
				      optarg);
	      	break;
	
	 	case 'h':
	    default:
			usage(argv[0]);
			exit(1);
	      	break;
	    }
	  }
	
	  if (do_syslog == AGENT_TRUE) {
	      snmp_enable_calllog ();
	      snmp_enable_syslog_ident (AGENT, LOG_DAEMON);
	  }
	  snmp_log (LOG_INFO, "Starting %s\n", version);
	  /* we're an agentx subagent? */
	  if (agentx_subagent) {
	      /* make us a agentx client. */
	      rc = netsnmp_ds_set_boolean (NETSNMP_DS_APPLICATION_ID,
					   NETSNMP_DS_AGENT_ROLE, 1);
	  }
	
	  /* initialize the agent library */
	  rc = init_agent (AGENT);
	  if (rc != 0) {
	      snmp_log (LOG_ERR, "Could not initialize connection to SNMP daemon. \n"
			"Perhaps you are running %s as non-root?\n", argv[0]);
	      exit (rc);
	  }

	  /* Read configuration information here, before we initialize */
	
	  snmpd_register_config_handler (TRAPS_TOKEN,
					 hpiSubagent_parse_config_traps,
					 NULL,
					 "hpiSubagent on/off switch for sending events upon startup");
	
	  snmpd_register_config_handler (MAX_EVENT_TOKEN,
					 hpiSubagent_parse_config_max_event,
					 NULL,
					 "hpiSubagent MAX number of rows for Events.");
					 
	init_snmp (AGENT); 	
	
	/* 
	 * Initialize HPI library
	 */
	hpiVer = saHpiVersionGet();
	DEBUGMSGTL ((AGENT, "Hpi Version %d Implemented.\n", hpiVer));   	 

	rv = saHpiSessionOpen( SAHPI_UNSPECIFIED_DOMAIN_ID, &sessionid, NULL );
	if (rv != SA_OK) {
		DEBUGMSGTL ((AGENT, "saHpiSessionOpen Error: returns %s\n",
			oh_lookup_error(rv)));
		exit(-1);
	}
   	DEBUGMSGTL ((AGENT, "saHpiSessionOpen returns with SessionId %d\n", 
   		sessionid)); 

        /* Get the DomainInfo structur,  This is how we get theDomainId for this Session */
	rv = saHpiDomainInfoGet(sessionid, &domain_info);
	if (rv != SA_OK) {
                DEBUGMSGTL ((AGENT, "saHpiSessionOpen Error: returns %s\n",
                        oh_lookup_error(rv)));
                exit(-1);
	}

        /* store session numbers */
   	store_session_info(sessionid, domain_info.DomainId);	
   				
	/* subscribe all sessions/events */
        subcsribe_all_sessions();

	/* Resource discovery */
	rv = saHpiDiscover(sessionid);
	
	if (rv != SA_OK) {
		DEBUGMSGTL ((AGENT, "saHpiDiscover Error: returns %s\n",oh_lookup_error(rv)));
		exit(-1);
	}
	DEBUGMSGTL ((AGENT, "saHpiDiscover Success!\n"));	

	/* Initialize subagent tables */		
	init_saHpiDomainInfoTable(); 
	init_saHpiDomainAlarmTable();
	init_saHpiDomainReferenceTable();
	
	init_saHpiResourceTable();
	init_saHpiRdrTable();
	init_saHpiCtrlDigitalTable();
	init_saHpiCtrlDiscreteTable();
	init_saHpiCtrlAnalogTable();
	init_saHpiCtrlStreamTable();
	init_saHpiCtrlTextTable();
	init_saHpiCtrlOemTable();
	init_saHpiSensorTable();
	init_saHpiCurrentSensorStateTable();
	init_saHpiSensorReadingMaxTable();
	init_saHpiSensorReadingMinTable();
	init_saHpiSensorReadingNominalTable();
	init_saHpiSensorReadingNormalMaxTable();
	init_saHpiSensorReadingNormalMinTable();
	init_saHpiSensorThdLowCriticalTable();
	init_saHpiSensorThdLowMajorTable();
	init_saHpiSensorThdLowMinorTable();
	init_saHpiSensorThdUpCriticalTable();
	init_saHpiSensorThdUpMajorTable();
	init_saHpiSensorThdUpMinorTable();
	init_saHpiSensorThdPosHysteresisTable();
	init_saHpiSensorThdNegHysteresisTable();
	init_saHpiInventoryTable();
	init_saHpiWatchdogTable();
	init_saHpiAnnunciatorTable();
	init_saHpiAreaTable();
	init_saHpiFieldTable();

	init_saHpiEventTable();
	init_saHpiResourceEventTable();
	init_saHpiDomainEventTable();
	init_saHpiSensorEventTable();
	init_saHpiOEMEventTable();
	init_saHpiHotSwapEventTable();
	init_saHpiWatchdogEventTable();		
	init_saHpiSoftwareEventTable();
	init_saHpiSensorEnableChangeEventTable();
	init_saHpiUserEventTable();

	init_saHpiEventLogInfoTable();
	init_saHpiEventLogTable();
	init_saHpiResourceEventLogTable();
	init_saHpiSensorEventLogTable();
	
	init_saHpiHotSwapEventLogTable();
	init_saHpiWatchdogEventLogTable();
	init_saHpiSoftwareEventLogTable();
	init_saHpiOEMEventLogTable();
	init_saHpiUserEventLogTable();
	init_saHpiSensorEnableChangeEventLogTable();
	init_saHpiDomainEventLogTable();
	
	init_saHpiHotSwapTable();
        init_saHpiAutoInsertTimeoutTable();
	init_saHpiAutoInsertTimeoutTable();
	init_saHpiAnnouncementTable();
	init_saHpiAnnouncementEventLogTable();


	if (send_traps_on_startup == AGENT_TRUE)
		send_traps = AGENT_TRUE;
	/* after initialization populate tables */
	populate_saHpiDomainInfoTable(sessionid);

	populate_saHpiDomainAlarmTable(sessionid);

	poplulate_saHpiDomainReferenceTable(sessionid);	

	populate_saHpiResourceTable(sessionid);
	    /* populate_saHpiResourceTable() calls:
	     *     populate_saHpiRdrTable(); calls:
	     *         populate_saHpiCtrlDigitalTable();		
	     *	       populate_saHpiCtrlDiscreteTable();		
	     *	       populate_saHpiCtrlAnalogTable();		
	     *	       populate_saHpiCtrlStreamTable();		
	     *	       populate_saHpiCtrlTextTable();		
	     *	       populate_saHpiCtrlOemTable();		
	     *	       populate_saHpiSensorTable();		
	     *	           populate_saHpiSesnorReadingMaxTable();		
	     *	           populate_saHpiSesnorReadingMinTable();		
	     *	           populate_saHpiSesnorReadingNominalTable();		
	     *	           populate_saHpiSesnorReadingNormalMaxTable();		
	     *	           populate_saHpiSesnorReadingNormalMinTable();		
	     *	           populate_saHpiSensorThdLowCriticalTable();		
	     *	           populate_saHpiSensorThdLowMajorTable();		
	     *	           populate_saHpiSensorThdLowMinorTable();		
	     *	           populate_saHpiSensorThdUpCriticalTable();		
	     *	           populate_saHpiSensorThdUpMajorTable();		
	     *	           populate_saHpiSensorThdUpMinorTable();		
	     *	           populate_saHpiSensorThdPosHysteresisTable();		
	     *	           populate_saHpiSensorThdNegHysteresisTable();		
	     *	       populate_saHpiCurrentSensorStateTable();		
	     *	       populate_saHpiInventoyTable();		
	     *	       populate_saHpiWatchdogTable();		
	     *	       populate_saHpiAnnunciatorTable();		
	     *	       populate_saHpiAreaTable();		
	     *	           populate_saHpiFieldTable(); 
             *         populate_saHpiHotSwapTable();
             *             populate_saHpiAutoInsertTimeoutTable();             
  	     *         populate_saHpiAnnouncementTable();
	     */
            
	populate_saHpiEventTable(sessionid);
            /* populate_saHpiResourceEventTable();
	     * populate_saHpiDomainEventTable();
	     * populate_saHpiSensorEventTable();
	     * populate_saHpiOemEventTable();
	     * populate_saHpiHotSwapEventTable();
	     * populate_saHpiWatchdogEventTable();
	     * populate_saHpiSoftwareEventTable();
	     * populate_saHpiSensorEnableChangeEventTable();
	     * populate_saHpiUserEventTable();
	     */
        populate_saHpiEventLogInfo(sessionid);
        populate_saHpiEventLog (sessionid);
            /*
             * populate_saHpiResourceEventLogTable();
             * populate_saHpiSensorEventLogTable();
	     * populate_saHpiHotSwapEventLogTable();
	     * populate_saHpiWatchdogEventLogTable();
	     * populate_saHpiSoftwareEventLogTable();
	     * populate_saHpiOemEventLogTable();
	     * populate_saHpiUserEventLogTable();
	     * populate_saHpiSensorEnableChangeEventLogTable();
	     * populate_saHpiDomainEventLogTable();	     
             */

        /* Determine whether or not we're in threaded mode */
	env = getenv("OPENHPI_THREADED");
	if ((env == (char *)NULL) || (strcmp(env, "NO") == 0)) {
                DEBUGMSGTL ((AGENT, "Running in nonthreaded mode.  Configuring polling mechanism\n"));  
                run_threaded = SAHPI_FALSE;
		if (init_alarm() != AGENT_ERR_NOERROR) {
                    snmp_log (LOG_ERR, "Could not initialize polling mechanism. Exiting\n.");
                    rc = -1;
                    goto stop;
                }
	}	
	else {
                DEBUGMSGTL ((AGENT, "Running in threaded mode.  Spawing thread\n"));
		/* start event thread */
                set_run_threaded(TRUE);
                if (start_event_thread(&sessionid) != AGENT_ERR_NOERROR) {
                        snmp_log (LOG_ERR, "Could not start our internal loop . Exiting\n.");
                        rc = -1;
                        goto stop;
                }
	}	

        send_traps = AGENT_TRUE;
        /* If we're going to be a snmp master agent, initial the ports */

        if (!agentx_subagent)
                init_master_agent ();	/* open the port to listen on (defaults to udp:161) */
                
        if (do_fork == AGENT_TRUE) {
                if ((child = fork ()) < 0) {
                        snmp_log (LOG_ERR, "Could not fork!\n");
                        exit (-1);
                }
                if (child != 0)
                        exit (0);
        }

        /* In case we recevie a request to stop (kill -TERM or kill -INT) */
        keep_running = 1;
        signal (SIGTERM, stop_server);
        signal (SIGINT, stop_server);

                /* you're main loop here... */
        while (keep_running) {
                /* if you use select(), see snmp_select_info() in snmp_api(3) */
                /*     --- OR ---  */		
                rc = agent_check_and_process (1);
		
        }
stop:
        DEBUGMSGTL ((AGENT,
        "WARNING: closeSaHpiSession: hpiSubagent.c: nolong implemented!"));
        //closeSaHpiSession();
        /* at shutdown time */
        snmp_log (LOG_INFO, "Stopping %s\n", version);
        snmp_shutdown (AGENT);
  
  return rc;
}
Пример #20
0
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;
}
Пример #21
0
void
init_agent_read_config(const char *app)
{
    if (app != NULL) {
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
			      NETSNMP_DS_LIB_APPTYPE, app);
    } else {
        app = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
				    NETSNMP_DS_LIB_APPTYPE);
    }

    register_app_config_handler("authtrapenable",
                                snmpd_parse_config_authtrap, NULL,
                                "1 | 2\t\t(1 = enable, 2 = disable)");
    register_app_config_handler("pauthtrapenable",snmpd_parse_config_authtrap, NULL, NULL);


    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE) == MASTER_AGENT) {
#ifndef NETSNMP_DISABLE_SNMPV1
        register_app_config_handler("trapsink",
                                    snmpd_parse_config_trapsink,
                                    snmpd_free_trapsinks,
                                    "host [community] [port]");
#endif
#ifndef NETSNMP_DISABLE_SNMPV2C
        register_app_config_handler("trap2sink",
                                    snmpd_parse_config_trap2sink, 
                                    snmpd_free_trapsinks,
                                    "host [community] [port]");
        register_app_config_handler("informsink",
                                    snmpd_parse_config_informsink,
                                    snmpd_free_trapsinks,
                                    "host [community] [port]");
#endif
        register_app_config_handler("trapsess",
                                    snmpd_parse_config_trapsess,
                                    snmpd_free_trapsinks,
                                    "[snmpcmdargs] host");
    }
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    register_app_config_handler("trapcommunity",
                                snmpd_parse_config_trapcommunity,
                                snmpd_free_trapcommunity,
                                "community-string");
#endif /* support for community based SNMP */
    netsnmp_ds_register_config(ASN_OCTET_STR, app, "v1trapaddress", 
                               NETSNMP_DS_APPLICATION_ID, 
                               NETSNMP_DS_AGENT_TRAP_ADDR);
#ifdef HAVE_UNISTD_H
    register_app_config_handler("agentuser",
                                snmpd_set_agent_user, NULL, "userid");
    register_app_config_handler("agentgroup",
                                snmpd_set_agent_group, NULL, "groupid");
#endif
#ifndef NETSNMP_NO_LISTEN_SUPPORT
    register_app_config_handler("agentaddress",
                                snmpd_set_agent_address, NULL,
                                "SNMP bind address");
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
    netsnmp_ds_register_config(ASN_BOOLEAN, app, "quit", 
			       NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
    netsnmp_ds_register_config(ASN_BOOLEAN, app, "leave_pidfile", 
			       NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_LEAVE_PIDFILE);
    netsnmp_ds_register_config(ASN_BOOLEAN, app, "dontLogTCPWrappersConnects",
                               NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_DONT_LOG_TCPWRAPPERS_CONNECTS);
    netsnmp_ds_register_config(ASN_INTEGER, app, "maxGetbulkRepeats",
                               NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_MAX_GETBULKREPEATS);
    netsnmp_ds_register_config(ASN_INTEGER, app, "maxGetbulkResponses",
                               NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_MAX_GETBULKRESPONSES);
    netsnmp_init_handler_conf();

#include "agent_module_dot_conf.h"
#include "mib_module_dot_conf.h"
#ifdef TESTING
    print_config_handlers();
#endif
}
Пример #22
0
static void
initialize_internal(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  void *logger_client_arg = NULL;
  char *master_agentx_socket = NULL;
  char *ping_interval_string = NULL;
  uint16_t ping_interval = 0;

  state = SNMPMGR_NONE;

  /* `is_thread` is able to be changed only once here */
  is_thread = is_thread_dummy;
  if (is_thread == false && thdptr_dummy != NULL) {
    *thdptr_dummy = NULL;
  } else if (thdptr_dummy != NULL) {
    *thdptr_dummy = &snmpmgr;
  } else {
    /* never reached! */
    return;
  }

  if (lagopus_mutex_create(&snmp_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  if (lagopus_mutex_create(&snmp_state_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  snmp_set_do_debugging(false);

  /* setup Net-SNMP logger to use the lagopus logging function */
  if (snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                             SNMP_CALLBACK_LOGGING,
                             snmp_log_callback_wrapper,
                             logger_client_arg) != SNMPERR_SUCCESS) {
    return;
  }
  snmp_enable_calllog();

  /* setup the SNMP module to be Agentx subagent */
  netsnmp_enable_subagent();

#ifdef THE_CONFSYS_ERA
  master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  if (master_agentx_socket == NULL) {
    config_set_default("snmp master-agentx-socket WORD",
                       (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET);
    master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  master_agentx_socket = (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET;
#endif /* THE_CONFSYS_ERA */
  lagopus_msg_debug(25, "master agentx socket is %s\n", master_agentx_socket);

  if (netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                            NETSNMP_DS_AGENT_X_SOCKET,
                            master_agentx_socket)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* don't read/write configuration files */
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DONT_PERSIST_STATE,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* the interval [sec] to send ping to AgentX master agent */
#ifdef THE_CONFSYS_ERA
  ping_interval_string = config_get("snmp ping-interval-second 1-255");
  if (ping_interval_string != NULL &&
      (ret = check_ping_interval(ping_interval_string, &ping_interval))
      != LAGOPUS_RESULT_OK) {
    config_set_default("snmp ping-interval-second 1-255",
                       (char *) __STR__(DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC));
    ping_interval_string = config_get("snmp ping-interval-second 1-255");
    ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC; /* default value */
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC;
#endif /* THE_CONFSYS_ERA */

  if (netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                         NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL,
                         (int)ping_interval)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if (init_agent(SNMP_TYPE) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if ((ret = lagopus_hashmap_create(&iftable_entry_hash,
                                    LAGOPUS_HASHMAP_TYPE_STRING,
                                    delete_entry)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
    exit(1);
  }

  init_ifTable();
  init_ifNumber();
  init_dot1dBaseBridgeAddress();
  init_dot1dBaseNumPorts();
  init_dot1dBasePortTable();
  init_dot1dBaseType();

  if (is_thread == false) {
    initialize_ret = LAGOPUS_RESULT_OK;
  } else {
    keep_running = true;
    initialize_ret = lagopus_thread_create(&snmpmgr,
                                           snmpmgr_thread_loop,
                                           snmpmgr_thread_finally_called,
                                           NULL,
                                           "snmpmgr",
                                           NULL);
  }

  lagopus_msg_info("SNMP manager initialized.\n");
}
Пример #23
0
int ds_set_string (int storeid, int which, const char *value)
{
    return netsnmp_ds_set_string (storeid, which, value);
}
Пример #24
0
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::efF:g:hHI:L:m:M:no:O:Ptu:vx:X-:";
    netsnmp_session *sess_list = NULL, *ss = NULL;
    netsnmp_transport *transport = NULL;
    int             arg, i = 0;
    int             uid = 0, gid = 0;
    int             exit_code = 1;
    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;
#ifndef WIN32
    int             prepared_sockets = 0;
#endif


#ifndef NETSNMP_NO_SYSTEMD
    /* check if systemd has sockets for us and don't close them */
    prepared_sockets = netsnmp_sd_listen_fds(0);
#endif
#ifndef WIN32
    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    if (!prepared_sockets)
        netsnmp_close_fds(2);
#endif
    
#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

    /*
     * register our configuration handlers now so -H properly displays them 
     */
    snmptrapd_register_configs( );
#ifdef NETSNMP_USE_MYSQL
    snmptrapd_register_sql_configs( );
#endif
#ifdef NETSNMP_SECMOD_USM
    init_usm_conf( "snmptrapd" );
#endif /* NETSNMP_SECMOD_USM */
    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", "doNotFork",
                            parse_config_doNotFork, 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");

    /*
     * Add some options if they are available.  
     */
#if HAVE_GETPID
    strcat(options, "p:");
#endif

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */

    /*
     * Now process options normally.  
     */

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

            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();
                goto out;
            }
            break;

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

        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
                                   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;

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

        case 'f':
            dofork = 0;
            break;

        case 'F':
            if (optarg != NULL) {
                if (( strncmp( optarg, "print",   5 ) == 0 ) ||
                    ( strncmp( optarg, "syslog",  6 ) == 0 ) ||
                    ( strncmp( optarg, "execute", 7 ) == 0 )) {
                    /* New style: "type=format" */
                    trap1_fmt_str_remember = strdup(optarg);
                    cp = strchr( trap1_fmt_str_remember, '=' );
                    if (cp)
                        *cp = ' ';
                } else {
                    /* Old style: implicitly "print=format" */
                    trap1_fmt_str_remember = malloc(strlen(optarg) + 7);
                    sprintf( trap1_fmt_str_remember, "print %s", optarg );
                }
            } else {
                usage();
                goto out;
            }
            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();
                goto out;
            }
            break;
#endif

        case 'h':
            usage();
            exit_code = 0;
            goto out;

        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_code = 0;
            goto out;

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

	case 'S':
            fprintf(stderr,
                    "Warning: -S option has been withdrawn; use -Ls <facility> instead\n");
            goto out;

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

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage();
                goto out;
            }
            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 has been withdrawn; use -Lf <file> instead\n");
            goto out;

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

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

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

        case 'P':
            fprintf(stderr,
                    "Warning: -P option has been withdrawn; use -f -Le instead\n");
            goto out;

        case 's':
            fprintf(stderr,
                    "Warning: -s option has been withdrawn; use -Lsd instead\n");
            goto out;

        case 't':
            SyslogTrap++;
            break;

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

                uid = strtoul(optarg, &ecp, 10);
#if HAVE_GETPWNAM && HAVE_PWD_H
                if (*ecp) {
                    struct passwd  *info;

                    info = getpwnam(optarg);
                    uid = info ? info->pw_uid : -1;
                    endpwent();
                }
#endif
                if (uid < 0) {
                    fprintf(stderr, "Bad user id: %s\n", optarg);
                    goto out;
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage();
                goto out;
            }
            break;
#endif

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

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage();
                goto out;
            }
            break;

         case 'X':
            agentx_subagent = 0;
            break;
#endif

        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            goto out;
            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);
                    goto out;
                }
                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);
                    goto out;
                }
            }
        }
    }

    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()) {
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               syslog_handler);
        traph->authtypes = TRAP_AUTH_LOG;
        snmp_enable_syslog();
#else /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               print_handler);
        traph->authtypes = TRAP_AUTH_LOG;
        snmp_enable_stderr();
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
    } else {
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               print_handler);
        traph->authtypes = TRAP_AUTH_LOG;
    }

#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)
#ifdef NETSNMP_FEATURE_CHECKING
    netsnmp_feature_require(register_snmpEngine_scalars_context)
#endif /* NETSNMP_FEATURE_CHECKING */
    /*
     * 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
#ifdef NETSNMP_FEATURE_CHECKING
        netsnmp_feature_require(init_register_usmUser_context)
#endif /* NETSNMP_FEATURE_CHECKING */
        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
#ifdef USING_TLSTM_MIB_SNMPTLSTMCERTTOTSNTABLE_MODULE
        init_snmpTlstmCertToTSNTable_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) {
        parse_format( NULL, 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()) {
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
#ifdef WIN32
        snmp_enable_syslog_ident(app_name_long, Facility);
#else
        snmp_enable_syslog_ident(app_name, Facility);
#endif        
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
    }

    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);
            goto sock_cleanup;
        } 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);
                snmp_log(LOG_ERR, "couldn't open snmp - %s", strerror(errno));
                goto sock_cleanup;
            } 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;
        }
    }
    SNMP_FREE(listen_ports); /* done with them */

#ifdef NETSNMP_USE_MYSQL
    if( netsnmp_mysql_init() ) {
        fprintf(stderr, "MySQL initialization failed\n");
        goto sock_cleanup;
    }
#endif

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

#if HAVE_FORKALL
        switch (forkall()) {
#else
        switch (fork()) {
#endif
        case -1:
            fprintf(stderr, "bad fork - %s\n", strerror(errno));
            goto sock_cleanup;

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

            /*
             * if we are forked, we don't want to print out to stdout or stderr 
             */
            fd = open("/dev/null", O_RDWR);
            if (fd >= 0) {
                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");
            goto sock_cleanup;
        }
        fprintf(PID, "%d\n", (int) getpid());
        fclose(PID);
        free_config_pidFile();
    }
#endif

    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());

    /*
     * 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)) {
                goto sock_cleanup;
            }
        }
    }
#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)) {
                goto sock_cleanup;
            }
        }
    }
#endif
#endif

    /*
     * Let systemd know we're up.
     */
#ifndef NETSNMP_NO_SYSTEMD
    netsnmp_sd_notify(1, "READY=1\n");
    if (prepared_sockets)
        /*
         * Clear the environment variable, we already processed all the sockets
         * by now.
         */
        netsnmp_sd_listen_fds(1);
#endif

#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_RUNNING;
#endif

    snmptrapd_main_loop();

    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\n");
    
#ifdef NETSNMP_EMBEDDED_PERL
    shutdown_perl();
#endif
    snmptrapd_close_sessions(sess_list);
    snmp_shutdown("snmptrapd");
#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_STOPPED;
#endif
    snmp_disable_log();

    exit_code = 0;

sock_cleanup:
    SOCK_CLEANUP;

out:
    return exit_code;
}

/*
 * Read the configuration files. Implemented as a signal handler so that
 * receipt of SIGHUP will cause configuration to be re-read when the
 * trap daemon is running detatched from the console.
 *
 */
void
trapd_update_config(void)
{
    free_config();
#ifdef USING_MIBII_VACM_CONF_MODULE
    vacm_standard_views(0,0,NULL,NULL);
#endif
    read_configs();
}
Пример #25
0
int
main (int argc, char **argv)
{
  int arg;
  char* cp = NULL;
  int dont_fork = 0, do_help = 0;

  while ((arg = getopt(argc, argv, "dD:fhHL:Xp"
#ifndef DISABLE_MIB_LOADING
                       "m:M:"
#endif /* DISABLE_MIB_LOADING */
                       "n:"
#ifndef DISABLE_MIB_LOADING
                       "P:"
#endif /* DISABLE_MIB_LOADING */
                       "vx:")) != EOF) {
    switch (arg) {
    case 'd':
      netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DUMP_PACKET, 1);
      break;

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

    case 'f':
      dont_fork = 1;
      break;

    case 'h':
      usage(argv[0]);
      break;

    case 'H':
      do_help = 1;
      break;

    case 'L':
      if (snmp_log_options(optarg, argc, argv) < 0) {
        exit(1);
      }
      break;
#ifndef DISABLE_MIB_LOADING
    case 'm':
      if (optarg != NULL) {
        setenv("MIBS", optarg, 1);
      } else {
        usage(argv[0]);
      }
      break;

    case 'M':
      if (optarg != NULL) {
        setenv("MIBDIRS", optarg, 1);
      } else {
        usage(argv[0]);
      }
      break;
#endif /* DISABLE_MIB_LOADING */

    case 'n':
      if (optarg != NULL) {
        app_name = optarg;
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                              NETSNMP_DS_LIB_APPTYPE, app_name);
      } else {
        usage(argv[0]);
      }
      break;

#ifndef DISABLE_MIB_LOADING
    case 'P':
      cp = snmp_mib_toggle_options(optarg);
      if (cp != NULL) {
        fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
        usage(argv[0]);
      }
      break;
#endif /* DISABLE_MIB_LOADING */

    case 'v':
      version();
      break;

    case 'x':
      if (optarg != NULL) {
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_X_SOCKET, optarg);
      } else {
        usage(argv[0]);
      }
      break;

    default:
      fprintf(stderr, "invalid option: -%c\n", arg);
      usage(argv[0]);
      break;
    }
  }

  if (do_help) {
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
  } else {
    /* we are a subagent */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_ROLE, 1);

    if (!dont_fork) {
      if (netsnmp_daemonize(1, snmp_stderrlog_status()) != 0)
        exit(1);
    }

    /* initialize tcpip, if necessary */
    SOCK_STARTUP;
  }

  /* Parse file */
  m_parse(argv[argc-1]);

  /* initialize the agent library */
  init_agent(app_name);

  /* Initialize SNMP */
  init_snmp(app_name);

  if (do_help) {
    fprintf(stderr, "Configuration directives understood:\n");
    read_config_print_usage("  ");
    exit(0);
  }

  /* In case we received a request to stop (kill -TERM or kill -INT) */
  netsnmp_running = 1;
#ifdef SIGTERM
  signal(SIGTERM, stop_server);
#endif
#ifdef SIGINT
  signal(SIGINT, stop_server);
#endif

  /* main loop here... */
  while(netsnmp_running) {
    agent_check_and_process(1);
  }

  /* at shutdown time */
  snmp_shutdown(app_name);
  SOCK_CLEANUP;
  exit(0);
}