RETSIGTYPE restart_doit(int a) { char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); snmp_shutdown(name); /* This signal handler may run with SIGALARM blocked. * Since the signal mask is preserved accross execv(), we must * make sure that SIGALARM is unblocked prior of execv'ing. * Otherwise SIGALARM will be ignored in the next incarnation * of snmpd, because the signal is blocked. And thus, the * restart doesn't work anymore. */ #if HAVE_SIGBLOCK sigsetmask(0); #endif /* * do the exec */ #if HAVE_EXECV execv(argvrestartname, argvrestartp); setPerrorstatus(argvrestartname); #endif }
/** * post-request callback * * Note: * New rows have been inserted into the container, and * deleted rows have been removed from the container and * released. * * @param user_context * @param rc : MFD_SUCCESS if all requests succeeded * * @retval MFD_SUCCESS : success. * @retval MFD_ERROR : other error (ignored) */ int dot11ConfigIpGroupTable_post_request(dot11ConfigIpGroupTable_registration * user_context, int rc) { DEBUGMSGTL(("verbose:dot11ConfigIpGroupTable:dot11ConfigIpGroupTable_post_request","called\n")); /* * TODO:511:o: Perform dot11ConfigIpGroupTable post-request actions. */ /* * check to set if any rows were changed. */ if (dot11ConfigIpGroupTable_dirty_get()) { /* * check if request was successful. If so, this would be * a good place to save data to its persistent store. */ if (MFD_SUCCESS == rc) { /* * save changed rows, if you haven't already */ snmp_store(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE)); } dot11ConfigIpGroupTable_dirty_set(0); /* clear table dirty flag */ } return MFD_SUCCESS; } /* dot11ConfigIpGroupTable_post_request */
static int set_default_secmod(int major, int minor, void *serverarg, void *clientarg) { netsnmp_session *sess = (netsnmp_session *) serverarg; char *cptr; int model; if (!sess) return SNMPERR_GENERR; if (sess->securityModel == SNMP_DEFAULT_SECMODEL) { if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECMODEL)) != NULL) { if ((model = se_find_value_in_slist("snmp_secmods", cptr)) != SE_DNE) { sess->securityModel = model; } else { snmp_log(LOG_ERR, "unknown security model name: %s. Forcing USM instead.\n", cptr); sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL; return SNMPERR_GENERR; } } else { sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL; } } return SNMPERR_SUCCESS; }
void init_iquery(void){ char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); netsnmp_ds_register_premib(ASN_OCTET_STR, type, "agentSecName", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECNAME); netsnmp_ds_register_premib(ASN_OCTET_STR, type, "iquerySecName", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECNAME); snmpd_register_config_handler("iqueryVersion", netsnmp_parse_iqueryVersion, NULL, "1 | 2c | 3"); snmpd_register_config_handler("iquerySecLevel", netsnmp_parse_iquerySecLevel, NULL, "noAuthNoPriv | authNoPriv | authPriv"); /* * Set defaults */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_VERSION, SNMP_VERSION_3); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECLEVEL, SNMP_SEC_LEVEL_AUTHNOPRIV); snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_PREMIB_READ_CONFIG, _init_default_iquery_session, NULL); snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG, _tweak_default_iquery_session, NULL); }
void init_perl(void) { const char *appid = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); const char *defaultid = "snmpd"; if (!appid) { appid = defaultid; } /* * register config handlers */ snmpd_register_config_handler("perl", perl_config_handler, NULL, "PERLCODE"); /* * define the perlInitFile token to point to an init file */ netsnmp_ds_register_premib(ASN_OCTET_STR, appid, "perlInitFile", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PERL_INIT_FILE); /* * define the perlInitFile token to point to an init file */ netsnmp_ds_register_premib(ASN_BOOLEAN, appid, "disablePerl", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_DISABLE_PERL); }
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); }
static int _debug_stats_callback(int majorID, int minorID, void *serverarg, void *clientarg) { char sep[] = "##############################################################"; char buf[] = "#\n" "# debug stats\n" "#"; char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); read_config_store((char *) type, sep); read_config_store((char *) type, buf); /* * save all rows */ CONTAINER_FOR_EACH((netsnmp_container *) clientarg, (netsnmp_container_obj_func *) _save_debug_stat, type); read_config_store((char *) type, sep); read_config_store((char *) type, "\n"); /* * never fails */ return SNMPERR_SUCCESS; }
/* * returns non-zero on error */ int subagent_pre_init(void) { DEBUGMSGTL(("agentx/subagent", "initializing....\n")); /* * set up callbacks to initiate master agent pings for this session */ netsnmp_ds_register_config(ASN_INTEGER, netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE), "agentxPingInterval", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL); if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != SUB_AGENT) { return 0; } /* * if a valid ping interval has been defined, call agentx_reopen_session * * to try to connect to master or setup a ping alarm if it couldn't * * succeed */ if (netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL) > 0) agentx_reopen_session(0, NULL); else /* if no ping interval was set up, just try to connect once */ subagent_open_master_session(); if (!main_session) return -1; DEBUGMSGTL(("agentx/subagent", "initializing.... DONE\n")); return 0; }
static void ConnectingEntry(UNUSED tState self) { netsnmp_session init; netsnmp_transport* t; void* sess; if(sessp) { snmp_sess_close(sessp); sessp = NULL; } snmp_sess_init(&init); init.version = AGENTX_VERSION_1; init.retries = 0; /* Retries are handled by the state machine */ init.timeout = SNMP_DEFAULT_TIMEOUT; init.flags |= SNMP_FLAGS_STREAM_SOCKET; init.callback = handle_agentx_response; init.authenticator = NULL; if(!(t = netsnmp_transport_open_client( "agentx", netsnmp_ds_get_string( NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)))) { snmp_log(LOG_ERR, "Failed to connect to AgentX server\n"); change_state(&Exit); } else if(!(sess = snmp_sess_add_ex( &init, t, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet, NULL))) { snmp_log(LOG_ERR, "Failed to create session\n"); change_state(&Exit); } else { sessp = sess; change_state(&Opening); } }
void init_hrh_storage(void) { char *appname; netsnmp_register_scalar( netsnmp_create_handler_registration("host/hrMemorySize", handle_memsize, hrMemorySize_oid, OID_LENGTH(hrMemorySize_oid), HANDLER_CAN_RONLY)); REGISTER_MIB("host/hr_storage", hrstore_variables, variable2, hrStorageTable_oid); appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); netsnmp_ds_register_config(ASN_BOOLEAN, appname, "skipNFSInHostResources", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES); netsnmp_ds_register_config(ASN_BOOLEAN, appname, "realStorageUnits", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_REALSTORAGEUNITS); snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL, "1 | 2\t\t(1 = enable, 2 = disable)"); }
/** stores data in a starsh tree to peristent storage. This function can be called to save all data in a stash tree to Net-SNMP's percent storage. Make sure you register a parsing function with the read_config system to re-incorperate your saved data into future trees. @param root the top of the stash to store. @param tokenname the file token name to save in (passing "snmpd" will save things into snmpd.conf). @param dumpfn A function which can dump the data stored at a particular node into a char buffer. @param curoid must be a pointer to a OID array of length MAX_OID_LEN. @param curoid_len must be 0 for the top level call. */ void netsnmp_oid_stash_store(netsnmp_oid_stash_node *root, const char *tokenname, NetSNMPStashDump *dumpfn, oid *curoid, size_t curoid_len) { char buf[SNMP_MAXBUF]; netsnmp_oid_stash_node *tmpp; char *cp; char *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); int i; if (!tokenname || !root || !curoid || !dumpfn) return; for (i = 0; i < (int)root->children_size; i++) { if (root->children[i]) { for (tmpp = root->children[i]; tmpp; tmpp = tmpp->next_sibling) { curoid[curoid_len] = tmpp->value; if (tmpp->thedata) { snprintf(buf, sizeof(buf), "%s ", tokenname); cp = read_config_save_objid(buf+strlen(buf), curoid, curoid_len+1); *cp++ = ' '; *cp = '\0'; if ((*dumpfn)(cp, sizeof(buf) - strlen(buf), tmpp->thedata, tmpp)) read_config_store(appname, buf); } netsnmp_oid_stash_store(tmpp, tokenname, dumpfn, curoid, curoid_len+1); } } } }
void agentx_config_init(void) { int agent_role = netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE); /* * Common tokens for master/subagent */ netsnmp_register_default_domain("agentx", "unix tcp"); netsnmp_register_default_target("agentx", "unix", NETSNMP_AGENTX_SOCKET); #define val(x) __STRING(x) netsnmp_register_default_target("agentx", "tcp", "localhost:" val(AGENTX_PORT)); #undef val agentx_register_config_handler("agentxsocket", agentx_parse_agentx_socket, NULL, "AgentX bind address"); #ifdef USING_AGENTX_MASTER_MODULE /* * tokens for master agent */ if (MASTER_AGENT == agent_role) { snmpd_register_config_handler("master", agentx_parse_master, NULL, "specify 'agentx' for AgentX support"); agentx_register_config_handler("agentxperms", agentx_parse_agentx_perms, NULL, "AgentX socket permissions: socket_perms [directory_perms [username|userid [groupname|groupid]]]"); agentx_register_config_handler("agentxRetries", agentx_parse_agentx_retries, NULL, "AgentX Retries"); agentx_register_config_handler("agentxTimeout", agentx_parse_agentx_timeout, NULL, "AgentX Timeout (seconds)"); } #endif /* USING_AGENTX_MASTER_MODULE */ #ifdef USING_AGENTX_SUBAGENT_MODULE /* * tokens for master agent */ if (SUB_AGENT == agent_role) { /* * set up callbacks to initiate master agent pings for this session */ netsnmp_ds_register_config(ASN_INTEGER, netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE), "agentxPingInterval", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL); /* ping and/or reconnect by default every 15 seconds */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 15); } #endif /* USING_AGENTX_SUBAGENT_MODULE */ }
int se_store_slist_callback(int majorID, int minorID, void *serverargs, void *clientargs) { char *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); se_store_slist((char *)clientargs, appname); return SNMPERR_SUCCESS; }
static int init_snmpksm_post_config(int majorid, int minorid, void *serverarg, void *clientarg) { if (kcontext == NULL) { /* not reached, i'd imagine */ return SNMPERR_KRB5; } if (service_name == NULL) { /* always reached, i'd imagine */ char *c = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_KSM_SERVICE_NAME); if (c != NULL) { service_name = c; } else { service_name = "host"; } } if (keytab_setup == 0) { /* always reached, i'd imagine */ char *c = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_KSM_KEYTAB); if (c) { krb5_error_code retval; DEBUGMSGTL(("ksm", "Using keytab %s\n", c)); retval = krb5_kt_resolve(kcontext, c, &keytab); if (retval) { DEBUGMSGTL(("ksm", "krb5_kt_resolve(\"%s\") failed. KSM " "config callback failing\n", error_message(retval))); return SNMPERR_KRB5; } } else { DEBUGMSGTL(("ksm", "Using default keytab\n", c)); } keytab_setup = 1; } return SNMPERR_SUCCESS; }
int vacm_warn_if_not_configured(int majorID, int minorID, void *serverarg, void *clientarg) { const char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); const int agent_mode = netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE); if (NULL==name) name = "snmpd"; if (!vacm_is_configured()) { /* * An AgentX subagent relies on the master agent to apply suitable * access control checks, so doesn't need local VACM configuration. * The trap daemon has a separate check (see below). * * Otherwise, an AgentX master or SNMP standalone agent requires some * form of VACM configuration. No config means that no incoming * requests will be accepted, so warn the user accordingly. */ if ((MASTER_AGENT == agent_mode) && (strcmp(name, "snmptrapd") != 0)) { snmp_log(LOG_WARNING, "Warning: no access control information configured.\n" " (Config search path: %s)\n" " It's unlikely this agent can serve any useful purpose in this state.\n" " Run \"snmpconf -g basic_setup\" to help you " "configure the %s.conf file for this agent.\n", get_configuration_directory(), name); } /* * The trap daemon implements VACM-style access control for incoming * notifications, but offers a way of turning this off (for backwards * compatability). Check for this explicitly, and warn if necessary. * * NB: The NETSNMP_DS_APP_NO_AUTHORIZATION definition is a duplicate * of an identical setting in "apps/snmptrapd_ds.h". * These two need to be kept in synch. */ #ifndef NETSNMP_DS_APP_NO_AUTHORIZATION #define NETSNMP_DS_APP_NO_AUTHORIZATION 17 #endif if (!strcmp(name, "snmptrapd") && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_NO_AUTHORIZATION)) { snmp_log(LOG_WARNING, "Warning: no access control information configured.\n" " (Config search path: %s)\n" "This receiver will *NOT* accept any incoming notifications.\n", get_configuration_directory()); } } return SNMP_ERR_NOERROR; }
int create_trap_session(char *sink, u_short sinkport, char *com, int version, int pdutype) { netsnmp_session session, *sesp; char *peername = NULL; int len; len = strlen(sink) + 4 + 32; if ((peername = malloc(len)) == NULL) { return 0; } else if (NULL != strchr(sink,':')) { snprintf(peername, len, "%s", sink); } else { snprintf(peername, len, "udp:%s:%hu", sink, sinkport); } memset(&session, 0, sizeof(netsnmp_session)); session.peername = peername; session.version = version; if (com) { session.community = (u_char *) com; session.community_len = strlen(com); } /* * for informs, set retries to default */ if (SNMP_MSG_INFORM == pdutype) { session.timeout = SNMP_DEFAULT_TIMEOUT; session.retries = SNMP_DEFAULT_RETRIES; } /* * if the sink is localhost, bind to localhost, to reduce open ports. */ if ((NULL == netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_CLIENT_ADDR)) && ((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink)))) session.localname = "localhost"; sesp = snmp_open(&session); free(peername); if (sesp) { return add_trap_session(sesp, pdutype, (pdutype == SNMP_MSG_INFORM), version); } /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpd: create_trap_session", &session); return 0; }
/* * Set up a default session for running internal queries. * This needs to be done before the config files are read, * so that it is available for "monitor" directives... */ int _init_default_iquery_session( int majorID, int minorID, void *serverargs, void *clientarg) { char *secName = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECNAME); if (secName) netsnmp_query_set_default_session( netsnmp_iquery_user_session(secName)); return SNMPERR_SUCCESS; }
SSL_CTX *_sslctx_common_setup (SSL_CTX * the_ctx, _netsnmpTLSBaseData * tlsbase) { char *crlFile; char *cipherList; X509_LOOKUP *lookup; X509_STORE *cert_store = NULL; _load_trusted_certs (the_ctx); /* add in the CRLs if available */ crlFile = netsnmp_ds_get_string (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_X509_CRL_FILE); if (NULL != crlFile) { cert_store = SSL_CTX_get_cert_store (the_ctx); DEBUGMSGTL (("sslctx_client", "loading CRL: %s\n", crlFile)); if (!cert_store) LOGANDDIE ("failed to find certificate store"); if (!(lookup = X509_STORE_add_lookup (cert_store, X509_LOOKUP_file ()))) LOGANDDIE ("failed to create a lookup function for the CRL file"); if (X509_load_crl_file (lookup, crlFile, X509_FILETYPE_PEM) != 1) LOGANDDIE ("failed to load the CRL file"); /* tell openssl to check CRLs */ X509_STORE_set_flags (cert_store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } cipherList = netsnmp_ds_get_string (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_TLS_ALGORITMS); if (NULL != cipherList) { if (SSL_CTX_set_cipher_list (the_ctx, cipherList) != 1) LOGANDDIE ("failed to set the cipher list to the requested value"); else snmp_log (LOG_INFO, "set SSL cipher list to '%s'\n", cipherList); } return the_ctx; }
static val_context_t * netsnmp_validator_context(void) { if (NULL == _val_context) { int rc; char *apptype = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); DEBUGMSGTL(("dns:sec:context", "creating dnssec context for %s\n", apptype)); rc = val_create_context(apptype, &_val_context); } return _val_context; }
int save_persistent(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { if (var_val_type != ASN_INTEGER) { DEBUGMSGTL(("versioninfo", "Wrong type != int\n")); return SNMP_ERR_WRONGTYPE; } if (action == COMMIT) { snmp_store(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE)); } return SNMP_ERR_NOERROR; }
static int create_trap_session2(const char *sink, const char* sinkport, char *com, int version, int pdutype) { netsnmp_transport *t; netsnmp_session session, *sesp; memset(&session, 0, sizeof(netsnmp_session)); session.version = version; if (com) { session.community = (u_char *) com; session.community_len = strlen(com); } /* * for informs, set retries to default */ if (SNMP_MSG_INFORM == pdutype) { session.timeout = SNMP_DEFAULT_TIMEOUT; session.retries = SNMP_DEFAULT_RETRIES; } /* * if the sink is localhost, bind to localhost, to reduce open ports. */ if ((NULL == netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_CLIENT_ADDR)) && ((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink)))) session.localname = "localhost"; t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport); if (t != NULL) { sesp = snmp_add(&session, t, NULL, NULL); if (sesp) { return add_trap_session(sesp, pdutype, (pdutype == SNMP_MSG_INFORM), version); } } /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpd: create_trap_session", &session); return 0; }
/** registers to store a data_list set of data at persistent storage time * * @param datalist the data to be saved * @param type the name of the application to save the data as. If left NULL the default application name that was registered during the init_snmp call will be used (recommended). * @param token the unique token identifier string to use as the first word in the persistent file line. * @param data_list_save_ptr a function pointer which will be called to save the rest of the data to a buffer. * @param data_list_read_ptr a function pointer which can read the remainder of a saved line and return the application specific void * pointer. * @param data_list_free_ptr a function pointer which will be passed to the data node for freeing it in the future when/if the list/node is cleaned up or destroyed. */ void netsnmp_register_save_list(netsnmp_data_list **datalist, const char *type, const char *token, Netsnmp_Save_List_Data *data_list_save_ptr, Netsnmp_Read_List_Data *data_list_read_ptr, Netsnmp_Free_List_Data *data_list_free_ptr) { netsnmp_data_list_saveinfo *info; if (!data_list_save_ptr && !data_list_read_ptr) return; info = SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo); if (!info) { snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef"); return; } info->datalist = datalist; info->token = token; info->type = type; if (!info->type) { info->type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); } /* function which will save the data */ info->data_list_save_ptr = data_list_save_ptr; if (data_list_save_ptr) snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, netsnmp_save_all_data_callback, info); /* function which will read the data back in */ info->data_list_read_ptr = data_list_read_ptr; if (data_list_read_ptr) { /** @todo netsnmp_register_save_list should handle the same token name being saved from different types? */ netsnmp_add_list_data(&saveHead, netsnmp_create_data_list(token, info, NULL)); register_config_handler(type, token, netsnmp_read_data_callback, NULL /* XXX */, NULL); } info->data_list_free_ptr = data_list_free_ptr; }
void maybe_source_perl_startup(void) { const char *embedargs[] = { "", "" }; const char *perl_init_file = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PERL_INIT_FILE); char init_file[SNMP_MAXBUF]; static int have_done_init = 0; if (have_done_init) return; have_done_init = 1; if (!perl_init_file) { snprintf(init_file, sizeof(init_file) - 1, "%s/%s", SNMPSHAREPATH, "snmp_perl.pl"); perl_init_file = init_file; } embedargs[1] = perl_init_file; DEBUGMSGTL(("perl", "initializing perl (%s)\n", embedargs[1])); my_perl = perl_alloc(); if (!my_perl) goto bail_out; perl_construct(my_perl); if (perl_parse(my_perl, xs_init, 2, (char **) embedargs, NULL)) goto bail_out; if (perl_run(my_perl)) goto bail_out; DEBUGMSGTL(("perl", "done initializing perl\n")); return; bail_out: snmp_log(LOG_ERR, "embedded perl support failed to initalize\n"); netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_DISABLE_PERL, 1); return; }
/** Initializes the mteEventsConf module */ void init_mteEventConf(void) { init_event_table_data(); /* * Register config handlers for user-level (fixed) events.... */ snmpd_register_config_handler("notificationEvent", parse_notificationEvent, NULL, "eventname notifyOID [-m] [-i OID|-o OID]*"); snmpd_register_config_handler("setEvent", parse_setEvent, NULL, "eventname [-I] OID = value"); netsnmp_ds_register_config(ASN_BOOLEAN, netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE), "strictDisman", NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_STRICT_DISMAN); /* * ... and for persistent storage of dynamic event table entries. * * (The previous implementation didn't store these entries, * so we don't need to worry about backwards compatability) */ snmpd_register_config_handler("_mteETable", parse_mteETable, NULL, NULL); snmpd_register_config_handler("_mteENotTable", parse_mteENotTable, NULL, NULL); snmpd_register_config_handler("_mteESetTable", parse_mteESetTable, NULL, NULL); /* * Register to save (non-fixed) entries when the agent shuts down */ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, store_mteETable, NULL); snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_PRE_UPDATE_CONFIG, clear_mteETable, NULL); }
RETSIGTYPE restart_doit(int a) { char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); snmp_shutdown(name); /* This signal handler may run with SIGALARM blocked. * Since the signal mask is preserved accross execv(), we must * make sure that SIGALARM is unblocked prior of execv'ing. * Otherwise SIGALARM will be ignored in the next incarnation * of snmpd, because the signal is blocked. And thus, the * restart doesn't work anymore. * * A quote from the sigprocmask() man page: * The use of sigprocmask() is unspecified in a multithreaded process; see * pthread_sigmask(3). */ #if HAVE_SIGPROCMASK { sigset_t empty_set; sigemptyset(&empty_set); sigprocmask(SIG_SETMASK, &empty_set, NULL); } #elif HAVE_SIGBLOCK sigsetmask(0); #endif /* * do the exec */ #if HAVE_EXECV execv(argvrestartname, argvrestartp); setPerrorstatus(argvrestartname); #endif }
int log_handler_syslog( netsnmp_log_handler* logh, int pri, const char *str) { /* * XXX * We've got three items of information to work with: * Is the syslog currently open? * What ident string to use? * What facility to log to? * * We've got two "magic" locations (imagic & magic) plus the token */ if (!(logh->imagic)) { const char *ident = logh->token; int facility = (int)(intptr_t)logh->magic; if (!ident) ident = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); openlog(ident, LOG_CONS | LOG_PID, facility); logh->imagic = 1; } syslog( pri, "%s", str ); return 1; }
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 */
rc = bind(t->sock, (struct sockaddr *) addr, sizeof(struct sockaddr)); if (rc != 0) { netsnmp_socketbase_close(t); netsnmp_transport_free(t); return NULL; } t->data = NULL; t->data_length = 0; } else { /* * This is a client session. If we've been given a * client address to send from, then bind to that. * Otherwise the send will use "something sensible". */ client_socket = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_CLIENT_ADDR); if (client_socket) { struct sockaddr_in client_addr; netsnmp_sockaddr_in2(&client_addr, client_socket, NULL); client_addr.sin_port = 0; DEBUGMSGTL(("netsnmp_udpbase", "binding socket: %d\n", t->sock)); rc = bind(t->sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)); if ( rc != 0 ) { DEBUGMSGTL(("netsnmp_udpbase", "failed to bind for clientaddr: %d %s\n", errno, strerror(errno))); netsnmp_socketbase_close(t); netsnmp_transport_free(t); return NULL; } local_addr_len = sizeof(addr_pair.local_addr);
int main(int argc, char *argv[]) { char *hostname = NULL; struct protoent *p; struct protox *tp = NULL; /* for printing cblocks & stats */ int allprotos = 1; char *community = NULL; char *argp; netsnmp_session session; int timeout = SNMP_DEFAULT_TIMEOUT; int version = SNMP_DEFAULT_VERSION; int arg; #ifndef DISABLE_MIB_LOADING init_mib(); #endif /* DISABLE_MIB_LOADING */ /* * Usage: snmpnetstatwalk -v 1 [-q] hostname community ... or: * Usage: snmpnetstat [-v 2 ] [-q] hostname noAuth ... */ while ((arg = getopt(argc, argv, "VhdqD:t:c:v:aionrsP:I:")) != EOF) { switch (arg) { case 'V': fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version()); exit(0); break; case 'h': usage(); exit(0); case 'd': snmp_set_dump_packet(1); break; case 'q': snmp_set_quick_print(1); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 't': timeout = atoi(optarg); timeout *= 1000000; break; case 'c': community = optarg; break; case 'v': argp = optarg; version = -1; #ifndef DISABLE_SNMPV1 if (!strcasecmp(argp, "1")) version = SNMP_VERSION_1; #endif #ifndef DISABLE_SNMPV2C if (!strcasecmp(argp, "2c")) version = SNMP_VERSION_2c; #endif if (version == -1) { fprintf(stderr, "Invalid version: %s\n", argp); usage(); exit(1); } break; case 'a': aflag++; break; case 'i': iflag++; break; case 'o': oflag++; break; case 'n': nflag++; break; case 'r': rflag++; break; case 's': sflag++; break; case 'P': if ((tp = name2protox(optarg)) == NULLPROTOX) { fprintf(stderr, "%s: unknown or uninstrumented protocol\n", optarg); exit(1); } allprotos = 0; tp->pr_wanted = 1; break; case 'I': iflag++; intrface = optarg; break; default: exit(1); break; } continue; } init_snmp("snmpapp"); snmp_enable_stderrlog(); if (version == SNMP_DEFAULT_VERSION) { version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SNMPVERSION); if (!version) { switch (DEFAULT_SNMP_VERSION) { #ifndef DISABLE_SNMPV1 case 1: version = SNMP_VERSION_1; break; #endif #ifndef DISABLE_SNMPV2C case 2: version = SNMP_VERSION_2c; break; #endif case 3: version = SNMP_VERSION_3; break; } #ifndef DISABLE_SNMPV1 } else if (version == NETSNMP_DS_SNMP_VERSION_1) { /* Bogus value. version1 = 0 */ version = SNMP_VERSION_1; #endif } } if (optind < argc) { hostname = argv[optind++]; } else { fprintf(stderr, "Missing host name.\n"); exit(1); } if (community == NULL) { community = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_COMMUNITY); } if (optind < argc && isdigit(argv[optind][0])) { interval = atoi(argv[optind++]); if (interval <= 0) { usage(); exit(1); } iflag++; } if (optind < argc) { usage(); exit(1); } snmp_sess_init(&session); session.peername = hostname; session.timeout = timeout; #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) if (version != SNMP_VERSION_3) { if (!community) { fprintf(stderr, "Missing community name.\n"); exit(1); } session.version = version; session.community = (u_char *) community; session.community_len = strlen(community); } #endif SOCK_STARTUP; /* * open an SNMP session */ Session = snmp_open(&session); if (Session == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpnetstat", &session); SOCK_CLEANUP; exit(1); } /* * Keep file descriptors open to avoid overhead * of open/close on each call to get* routines. */ sethostent(1); setnetent(1); setprotoent(1); setservent(1); if (iflag) { intpr(interval); } if (oflag) { intpro(interval); } if (rflag) { if (sflag) rt_stats(); else routepr(); } if (!(iflag || rflag || oflag)) { while ((p = getprotoent46())) { for (tp = protox; tp->pr_name; tp++) { if (strcmp(tp->pr_name, p->p_name) == 0) break; } if (tp->pr_name == 0 || (tp->pr_wanted == 0 && allprotos == 0)) continue; if (sflag) { if (tp->pr_stats) (*tp->pr_stats) (); } else if (tp->pr_cblocks) (*tp->pr_cblocks) (tp->pr_name); } } /* ! iflag, rflag, oflag */ endprotoent(); endservent(); endnetent(); endhostent(); snmp_close(Session); SOCK_CLEANUP; return 0; }
static int _save_maps(int majorID, int minorID, void *serverarg, void *clientarg) { char sep[] = "\n##############################################################"; char buf[] = "#\n" "# certificate secName mapping persistent data\n" "#"; char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); netsnmp_container *maps = netsnmp_cert_map_container(); netsnmp_tdata_row *row; netsnmp_iterator *tbl_itr, *map_itr; netsnmp_cert_map *map; certToTSN_entry *entry; if ((NULL == maps) || ((CONTAINER_SIZE(maps) == 0) && (CONTAINER_SIZE(_table->container) == 0))) return SNMPERR_SUCCESS; read_config_store((char *) type, sep); read_config_store((char *) type, buf); /* * save active rows from maps */ if (NULL != maps) { map_itr = CONTAINER_ITERATOR(maps); if (NULL == map_itr) { DEBUGMSGTL(("tlstmCertToTSNTable:save", "cant get map iterator\n")); map = NULL; } else map = ITERATOR_FIRST(map_itr); for( ; map; map = ITERATOR_NEXT(map_itr)) { /** don't store config rows */ if (map->flags & NSCM_FROM_CONFIG) continue; _save_map(map, RS_ACTIVE, type); } } ITERATOR_RELEASE(map_itr); /* * save inactive rows from mib */ tbl_itr = CONTAINER_ITERATOR(_table->container); if (NULL == tbl_itr) DEBUGMSGTL(("tlstmCertToTSNTable:save", "cant get table iterator\n")); else { row = ITERATOR_FIRST(tbl_itr); for( ; row; row = ITERATOR_NEXT(tbl_itr)) { entry = row->data; /* * skip all active rows (should be in maps and thus saved * above) and volatile rows. */ if ((entry->rowStatus == RS_ACTIVE) || (entry->storageType != ST_NONVOLATILE)) continue; _save_entry(entry, type); } ITERATOR_RELEASE(tbl_itr); } read_config_store((char *) type, sep); read_config_store((char *) type, "\n"); /* * never fails */ return SNMPERR_SUCCESS; }