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); }
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); }
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); }
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; }
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"); }
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); }
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 */
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; }
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); }
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; }
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 */
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; }
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; }
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); }
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); }
/* * 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; }
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 }
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; }
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; }
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 }
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"); }
int ds_set_string (int storeid, int which, const char *value) { return netsnmp_ds_set_string (storeid, which, value); }
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(); }
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); }