HSNMP SnmpOpen(const char* ipAddress) { HSNMP m_sessp; struct snmp_session session; snmp_sess_init(&session); // structure defaults session.version = SNMP_VERSION_2c; session.peername = strdup(ipAddress); session.community = (u_char*)strdup(readCommunity); session.community_len = strlen((char*)session.community); session.timeout = 100000; // timeout (us) session.retries = 3; // retries if(!(m_sessp = snmp_sess_open(&session))) { int liberr, syserr; char *errstr; snmp_error(&session, &liberr, &syserr, &errstr); syslog(LOG_ERR,"Open SNMP session for host \"%s\": %s",ipAddress,errstr); free(errstr); return 0; } // m_session = snmp_sess_session(m_sessp); // get the session pointer syslog(LOG_INFO,"SNMP session for host \"%s\" opened",ipAddress); return m_sessp; }
static void csnmp_host_open_session (host_definition_t *host) { struct snmp_session sess; if (host->sess_handle != NULL) csnmp_host_close_session (host); snmp_sess_init (&sess); sess.peername = host->address; sess.community = (u_char *) host->community; sess.community_len = strlen (host->community); sess.version = (host->version == 1) ? SNMP_VERSION_1 : SNMP_VERSION_2c; /* snmp_sess_open will copy the `struct snmp_session *'. */ host->sess_handle = snmp_sess_open (&sess); if (host->sess_handle == NULL) { char *errstr = NULL; snmp_error (&sess, NULL, NULL, &errstr); ERROR ("snmp plugin: host %s: snmp_sess_open failed: %s", host->name, (errstr == NULL) ? "Unknown problem" : errstr); sfree (errstr); } } /* void csnmp_host_open_session */
/** * snmp_bc_manage_snmp_open: * @hnd: Pointer to handler structure. * * . * * Returns: * SA_OK - able to open a snmp session **/ SaErrorT snmp_bc_manage_snmp_open(struct snmp_bc_hnd *custom_handle, SaHpiBoolT recovery_requested) { SaErrorT rv; rv = SA_OK; /* Windows32 specific net-snmp initialization (noop on unix) */ SOCK_STARTUP; custom_handle->sessp = snmp_sess_open(&(custom_handle->session)); if (custom_handle->sessp == NULL) { // snmp_perror("ack"); // snmp_log(LOG_ERR, "Something horrible happened!!!\n"); if (recovery_requested) { rv = snmp_bc_recover_snmp_session(custom_handle); } else { rv = SA_ERR_HPI_NO_RESPONSE; } } if (rv == SA_OK) custom_handle->ss = snmp_sess_session(custom_handle->sessp); return(rv); }
v8::Handle<v8::Value> Session::Open(const v8::Arguments& args) { UNWRAP(Session, wrap, args.This()); SwapScope scope(wrap, args); if(0 != wrap->session_) { return ThrowError("Session already opened."); } wrap->session_ = snmp_sess_open(&wrap->arguments_); if(0 == wrap->session_) { return ThrowError(snmp_api_errstring(wrap->arguments_.s_snmp_errno)); } if(scope.hasException()) { return scope.getException(); } return v8::Undefined(); }
// Creates a SNMP session void snmpDeliverTrap_netsnmp::_createSession( const String& targetHost, Uint16 targetHostFormat, Uint32 portNumber, const String& securityName, void*& sessionHandle, snmp_session*& sessionPtr) { PEG_METHOD_ENTER(TRC_IND_HANDLER, "snmpDeliverTrap_netsnmp::_createSession"); Sint32 libErr, sysErr; char* errStr; String exceptionStr; struct snmp_session snmpSession; { AutoMutex autoMut(_sessionInitMutex); snmp_sess_init(&snmpSession); CString targetHostCStr = targetHost.getCString(); // peername has format: targetHost:portNumber snmpSession.peername = (char*)malloc((size_t)(strlen(targetHostCStr) + 1 + 32)); if (targetHostFormat == _IPV6_ADDRESS) { sprintf(snmpSession.peername, "udp6:[%s]:%u", (const char*)targetHostCStr, portNumber); } else { sprintf(snmpSession.peername, "%s:%u", (const char*)targetHostCStr, portNumber); } sessionHandle = snmp_sess_open(&snmpSession); } if (sessionHandle == NULL) { exceptionStr = _MSG_SESSION_OPEN_FAILED; // Get library, system errno snmp_error(&snmpSession, &libErr, &sysErr, &errStr); exceptionStr.append(errStr); free(errStr); free(snmpSession.peername); PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(_MSG_SESSION_OPEN_FAILED_KEY, exceptionStr)); } try { // get the snmp_session pointer sessionPtr = snmp_sess_session(sessionHandle); if (sessionPtr == NULL) { exceptionStr = _MSG_GET_SESSION_POINT_FAILED; // Get library, system errno snmp_sess_error(&snmpSession, &libErr, &sysErr, &errStr); exceptionStr.append(errStr); free(errStr); free(snmpSession.peername); throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( _MSG_GET_SESSION_POINTER_FAILED_KEY, exceptionStr)); } // Community Name, default is public String communityName; if (securityName.size() == 0) { communityName.assign("public"); } else { communityName = securityName; } free(snmpSession.peername); free(sessionPtr->community); CString communityNameCStr = communityName.getCString(); size_t communityNameLen = strlen(communityNameCStr); sessionPtr->community = (u_char*)malloc(communityNameLen); memcpy(sessionPtr->community, (const char*)communityNameCStr, communityNameLen); sessionPtr->community_len = communityNameLen; } catch (...) { _destroySession(sessionHandle); PEG_METHOD_EXIT(); throw; } PEG_METHOD_EXIT(); }
static void *snmp_client_open(GHashTable *handler_config) { struct oh_handler_state *handle; struct snmp_client_hnd *custom_handle; char *root_tuple; /* snmpv3 sercurity */ char *version = NULL; char *security_name = NULL; char *security_level = NULL; char *authpassphrase = NULL; char *privpassphrase = NULL; root_tuple = (char *)g_hash_table_lookup(handler_config, "entity_root"); if(!root_tuple) { dbg("ERROR: Cannot open snmp_client plugin. No entity root found in configuration."); return NULL; } handle = (struct oh_handler_state *)g_malloc0(sizeof(*handle)); custom_handle = (struct snmp_client_hnd *)g_malloc0(sizeof(*custom_handle)); if(!handle || !custom_handle) { dbg("Could not allocate memory for handle or custom_handle."); return NULL; } handle->data = custom_handle; handle->config = handler_config; /* Initialize RPT cache */ handle->rptcache = (RPTable *)g_malloc0(sizeof(RPTable)); /* Initialize snmp library */ init_snmp("oh_snmp_client"); snmp_sess_init(&(custom_handle->session)); /* Setting up all defaults for now. */ custom_handle->session.peername = (char *)g_hash_table_lookup(handle->config, "host"); /* snmp version */ version = (char *)g_hash_table_lookup(handle->config, "version"); /* Use SNMPv3 to talk to the server */ if (!strncmp(version, "3", 1)) { if(!(security_name = (char *)g_hash_table_lookup(handle->config, "security_name"))){ dbg("MISSING security_name"); return NULL; } if (!(security_level = (char *)g_hash_table_lookup(handle->config, "security_level"))){ dbg("MISSING security_level"); return NULL; } if (!(authpassphrase = (char *)g_hash_table_lookup(handle->config, "authpassphrase"))){ dbg("MISSING authpassphrase"); return NULL; } if (!(privpassphrase = (char *)g_hash_table_lookup(handle->config, "privpassphrase"))){ dbg("MISSING privpassphrase"); return NULL; } /* set the SNMPv3 user name */ custom_handle->session.securityName = strdup(security_name); custom_handle->session.securityNameLen = strlen(custom_handle->session.securityName); /* set the SNMP version number */ custom_handle->session.version = SNMP_VERSION_3; /* set the security level to authenticated, AND not encrypted */ if(!strncmp(security_level, "noAuthnoPriv", sizeof("noAuthnoPriv"))) custom_handle->session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; else if(!strncmp(security_level, "authNoPriv", sizeof("authNoPriv"))) custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; else if(!strncmp(security_level, "authPriv", sizeof("suthPriv"))) custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; else { dbg("ERROR: unsupport securtiy_level"); return NULL; } /* set the authentication method to MD5 */ if (authpassphrase) { custom_handle->session.securityAuthProto = usmHMACMD5AuthProtocol; custom_handle->session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid); custom_handle->session.securityAuthKeyLen = USM_AUTH_KU_LEN; /* set the authentication key to a MD5 hashed version of our passphrase "The UCD Demo Password" (which must be at least 8 characters long) */ if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) authpassphrase, strlen(authpassphrase), custom_handle->session.securityAuthKey, &custom_handle->session.securityAuthKeyLen) != SNMPERR_SUCCESS) { snmp_perror("ack"); snmp_log(LOG_ERR, "Error generating Ku from AUTHENTICATION pass phrase. "); dbg("Error generating Ku from AUTHENTICATION pass phrase."); } } /* set the encryption method to DES */ if (privpassphrase) { custom_handle->session.securityPrivProto = usmDESPrivProtocol; custom_handle->session.securityPrivProtoLen = sizeof(usmDESPrivProtocol)/sizeof(oid); custom_handle->session.securityPrivKeyLen = USM_PRIV_KU_LEN; /* generate Key */ if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) privpassphrase, strlen(privpassphrase), custom_handle->session.securityPrivKey, &custom_handle->session.securityPrivKeyLen) != SNMPERR_SUCCESS) { snmp_perror("ack"); snmp_log(LOG_ERR, "Error generating Ku from PRIVACY pass phrase. "); dbg("Error generating Ku from PRIVACY pass phrase."); } } } /* Use SNMPv2c to talk to the server */ if (!strncmp(version, "2c", 2)) { /* set the SNMP version number */ custom_handle->session.version = SNMP_VERSION_2c; /* set the SNMPv1 community name used for authentication */ custom_handle->session.community = (char *)g_hash_table_lookup(handle->config, "community"); custom_handle->session.community_len = strlen(custom_handle->session.community); } /* windows32 specific net-snmp initialization (is a noop on unix) */ SOCK_STARTUP; custom_handle->sessp = snmp_sess_open(&(custom_handle->session)); if(!custom_handle->sessp) { snmp_perror("ack"); snmp_log(LOG_ERR, "something horrible happened!!!"); dbg("Unable to open snmp session."); return NULL; } return handle; }
void *sync_poller(void *thread_args) { // phoenix async poller; worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker -> crew; // target_t *entry = NULL; target_t *_current_local = NULL; PT_MUTEX_LOCK(&crew -> mutex); PT_COND_WAIT(&crew->go, &crew->mutex); PT_MUTEX_UNLOCK(&crew -> mutex); for( ; ; ) { PT_MUTEX_LOCK(&crew -> mutex); current = _current_local = getNext(); crew -> _sent_work_count--; if (_current_local == NULL && crew->_sent_work_count <= 0) { crew -> _send_worker_count--; PT_COND_BROAD(&crew -> _sending_done); PT_COND_WAIT(&crew -> go, &crew -> mutex); // } else if (_current_local == NULL) { // PT_COND_WAIT(&crew->go, &crew->mutex); // // PT_MUTEX_UNLOCK(&crew -> mutex); // continue; // // return 0; // } else if (crew->_sent_work_count <= 0) { // PT_COND_BROAD(&crew->_sending_done); // // PT_MUTEX_UNLOCK(&crew -> mutex); // continue; // // return 0; PT_MUTEX_UNLOCK(&crew -> mutex); continue; } PT_MUTEX_UNLOCK(&crew -> mutex); // PT_MUTEX_LOCK(&crew->mutex); // current = getNext(); // if (status == STAT_SUCCESS) entry->last_value = result; // if (init == NEW) entry->init = LIVE; // signal for our control thread; // but should also check for number of threads completed; // PT_MUTEX_UNLOCK(&crew->mutex); // while (current == NULL) { // PT_COND_WAIT(&crew -> go, &crew -> mutex); // _current_local = NULL; // } // // if (current != NULL) { // _current_local = current; // // printf("[ info] thread [%d] work_count index: %d\n", worker->index, crew -> _send_work_count); // } // make a copy of current and then unlock; // preparing snmp session; // we got what we need from current entry // moving to next entry for other wating threads; printf( "[ info] thread [%d] processing -> host: %s, oid: %s\n", worker -> index, _current_local -> host, _current_local -> objoid ); // making a snmp session ... // struct session *_host_ss = stuepd you are, this is a ptr! sohuld be initialized 1st :- ; struct session *_host_ss = calloc(1, sizeof(struct session)); // stuepd you are, this is a ptr! sohuld be initialized 1st :- ; // struct host *hp; /* startup all hosts */ // for (hs = sessions, hp = hosts; hp->name; hs++, hp++) { struct snmp_session _sess; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; snmp_sess_init(&_sess); /* initialize session */ _sess.version = SNMP_VERSION_2c; _sess.peername = strdup(_current_local-> host); _sess.community = strdup(_current_local -> community); _sess.community_len = strlen(_sess.community); // /* default callback */ // _sess.callback = asynch_response; // _sess.callback_magic = _host_ss; // if (!(_host_ss -> _sess = snmp_sess_open(&_sess))) { //, snmp_api_errstring(snmp_errno) printf("[error] %s!\n", snmp_api_errstring(snmp_errno)); // exit(-1); // snmp_perror(snmp_errno); continue; } // printf("[ info] thread [%d] &sess: %llu, _host_ss -> _sess: %llu\n", worker->index, // &sess, _host_ss -> _sess); // struct snmp_session *_ss_ptr = snmp_sess_session(_host_ss -> _sess); _host_ss -> _oid_name = strdup(_current_local -> objoid); // also translate this in to snmp format; _host_ss -> _oid_len = sizeof(_host_ss -> _oid) / sizeof(_host_ss -> _oid[0]); if (!read_objid(_host_ss -> _oid_name, _host_ss -> _oid, &_host_ss -> _oid_len)) { snmp_perror("read_objid"); exit(1); } pdu = snmp_pdu_create(SNMP_MSG_GET); /* send the first GET */ snmp_add_null_var(pdu, _host_ss -> _oid, _host_ss -> _oid_len); int _status = snmp_sess_synch_response(_host_ss -> _sess, pdu, &response); // int print_result (int status, struct snmp_session *sp, struct snmp_pdu *pdu) print_result(_status, &_sess, response); // analyzing the result; // and making it look like correct one (limits and correctness check); // if out of range for example we have the following stats update; // PT_MUTEX_LOCK(&stats.mutex); // stats.out_of_range++; // PT_MUTEX_UNLOCK(&stats.mutex); snmp_sess_close(_host_ss -> _sess); /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); // when we have a snmp result, updating a starts counters; PT_MUTEX_UNLOCK(&stats.mutex); // decreasing work counter; } // for (;;) }
void *poller(void *thread_args) { worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker->crew; target_t *entry = NULL; void *sessp = NULL; struct snmp_session session; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars = NULL; unsigned long long result = 0; unsigned long long last_value = 0; unsigned long long insert_val = 0; int status = 0, bits = 0, init = 0; char query[BUFSIZE]; char storedoid[BUFSIZE]; char result_string[BUFSIZE]; if (set.verbose >= HIGH) printf("Thread [%d] starting.\n", worker->index); if (MYSQL_VERSION_ID > 40000) mysql_thread_init(); else my_thread_init(); while (1) { if (set.verbose >= DEVELOP) printf("Thread [%d] locking (wait on work)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); while (current == NULL) { PT_COND_WAIT(&crew->go, &crew->mutex); } if (set.verbose >= DEVELOP) printf("Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count); if (current != NULL) { if (set.verbose >= HIGH) printf("Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host, current->objoid, crew->work_count); snmp_sess_init(&session); if (set.snmp_ver == 2) session.version = SNMP_VERSION_2c; else session.version = SNMP_VERSION_1; session.peername = current->host; session.remote_port = set.snmp_port; session.community = current->community; session.community_len = strlen(session.community); sessp = snmp_sess_open(&session); anOID_len = MAX_OID_LEN; pdu = snmp_pdu_create(SNMP_MSG_GET); read_objid(current->objoid, anOID, &anOID_len); entry = current; last_value = current->last_value; init = current->init; insert_val = 0; bits = current->bits; strncpy(storedoid, current->objoid, sizeof(storedoid)); current = getNext(); } if (set.verbose >= DEVELOP) printf("Thread [%d] unlocking (done grabbing current)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); snmp_add_null_var(pdu, anOID, anOID_len); if (sessp != NULL) status = snmp_sess_synch_response(sessp, pdu, &response); else status = STAT_DESCRIP_ERROR; /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); if (status == STAT_DESCRIP_ERROR) { stats.errors++; printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername); } else if (status == STAT_TIMEOUT) { stats.no_resp++; printf("*** SNMP No response: (%s@%s).\n", session.peername, storedoid); } else if (status != STAT_SUCCESS) { stats.errors++; printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername, storedoid, status); } else if (status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) { stats.errors++; printf("*** SNMP Error: (%s@%s) %s\n", session.peername, storedoid, snmp_errstring(response->errstat)); } else if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { stats.polls++; } PT_MUTEX_UNLOCK(&stats.mutex); /* Liftoff, successful poll, process it */ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { vars = response->variables; #ifdef OLD_UCD_SNMP sprint_value(result_string, anOID, anOID_len, vars); #else snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars); #endif switch (vars->type) { /* * Switch over vars->type and modify/assign result accordingly. */ case ASN_COUNTER64: if (set.verbose >= DEBUG) printf("64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = vars->val.counter64->high; result = result << 32; result = result + vars->val.counter64->low; break; case ASN_COUNTER: if (set.verbose >= DEBUG) printf("32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_INTEGER: if (set.verbose >= DEBUG) printf("Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_GAUGE: if (set.verbose >= DEBUG) printf("32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_TIMETICKS: if (set.verbose >= DEBUG) printf("Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OPAQUE: if (set.verbose >= DEBUG) printf("Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; default: if (set.verbose >= DEBUG) printf("Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string); } /* Gauge Type */ if (bits == 0) { if (result != last_value) { insert_val = result; if (set.verbose >= HIGH) printf("Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val); } else { if (set.withzeros) insert_val = result; if (set.verbose >= HIGH) printf("Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val); } /* Counter Wrap Condition */ } else if (result < last_value) { PT_MUTEX_LOCK(&stats.mutex); stats.wraps++; PT_MUTEX_UNLOCK(&stats.mutex); if (bits == 32) insert_val = (THIRTYTWO - last_value) + result; else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result; if (set.verbose >= LOW) { printf("*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n", session.peername, storedoid, result, last_value, insert_val); } /* Not a counter wrap and this is not the first poll */ } else if ((last_value >= 0) && (init != NEW)) { insert_val = result - last_value; /* Print out SNMP result if verbose */ if (set.verbose == DEBUG) printf("Thread [%d]: (%lld-%lld) = %llu\n", worker->index, result, last_value, insert_val); if (set.verbose == HIGH) printf("Thread [%d]: %llu\n", worker->index, insert_val); /* last_value < 0, so this must be the first poll */ } else { if (set.verbose >= HIGH) printf("Thread [%d]: First Poll, Normalizing\n", worker->index); } /* Check for bogus data, either negative or unrealistic */ if (insert_val > entry->maxspeed || result < 0) { if (set.verbose >= LOW) printf("*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n", session.peername, storedoid, insert_val, entry->maxspeed); insert_val = 0; PT_MUTEX_LOCK(&stats.mutex); stats.out_of_range++; PT_MUTEX_UNLOCK(&stats.mutex); } if (!(set.dboff)) { if ( (insert_val > 0) || (set.withzeros) ) { PT_MUTEX_LOCK(&crew->mutex); snprintf(query, sizeof(query), "INSERT INTO %s VALUES (%d, NOW(), %llu)", entry->table, entry->iid, insert_val); if (set.verbose >= DEBUG) printf("SQL: %s\n", query); status = mysql_query(&mysql, query); if (status) printf("*** MySQL Error: %s\n", mysql_error(&mysql)); PT_MUTEX_UNLOCK(&crew->mutex); if (!status) { PT_MUTEX_LOCK(&stats.mutex); stats.db_inserts++; PT_MUTEX_UNLOCK(&stats.mutex); } } /* insert_val > 0 or withzeros */ } /* !dboff */ } /* STAT_SUCCESS */ if (sessp != NULL) { snmp_sess_close(sessp); if (response != NULL) snmp_free_pdu(response); } if (set.verbose >= DEVELOP) printf("Thread [%d] locking (update work_count)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); crew->work_count--; /* Only if we received a positive result back do we update the last_value object */ if (status == STAT_SUCCESS) entry->last_value = result; if (init == NEW) entry->init = LIVE; if (crew->work_count <= 0) { if (set.verbose >= HIGH) printf("Queue processed. Broadcasting thread done condition.\n"); PT_COND_BROAD(&crew->done); } if (set.verbose >= DEVELOP) printf("Thread [%d] unlocking (update work_count)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); } /* while(1) */ }
/** * snmp_bc_open: * @handler_config: Pointer to hash table (passed by infrastructure) * * Open an SNMP BladeCenter/RSA plugin handler instance. * * Returns: * Plugin handle - normal operation. * NULL - on error. **/ void *snmp_bc_open(GHashTable *handler_config) { struct oh_handler_state *handle; struct snmp_bc_hnd *custom_handle; char *hostname, *version, *sec_level, *authtype, *user, *pass, *community; char *root_tuple; root_tuple = (char *)g_hash_table_lookup(handler_config, "entity_root"); if (!root_tuple) { dbg("Cannot find \"entity_root\" configuration parameter."); return NULL; } hostname = (char *)g_hash_table_lookup(handler_config, "host"); if (!hostname) { dbg("Cannot find \"host\" configuration parameter."); return NULL; } handle = (struct oh_handler_state *)g_malloc0(sizeof(struct oh_handler_state)); custom_handle = (struct snmp_bc_hnd *)g_malloc0(sizeof(struct snmp_bc_hnd)); if (!handle || !custom_handle) { dbg("Out of memory."); return NULL; } handle->data = custom_handle; handle->config = handler_config; /* Initialize the lock */ /* g_static_rec_mutex_init(&handle->handler_lock); */ g_static_rec_mutex_init(&custom_handle->snmp_bc_hlock.lock); custom_handle->snmp_bc_hlock.count = 0; /* Initialize RPT cache */ handle->rptcache = (RPTable *)g_malloc0(sizeof(RPTable)); oh_init_rpt(handle->rptcache); /* Initialize event log cache */ handle->elcache = oh_el_create(BC_EL_MAX_SIZE); handle->elcache->gentimestamp = FALSE; /* Initialize simulator tables */ if (is_simulator()) { custom_handle->ss = NULL; sim_init(); } else { /* Initialize SNMP library */ init_snmp("oh_snmp_bc"); snmp_sess_init(&(custom_handle->session)); custom_handle->session.peername = hostname; /* Set retries/timeouts - based on testing with BC/BCT MM SNMP V3 agent */ custom_handle->session.retries = 3; custom_handle->session.timeout = 5000000; /* in microseconds */ version = (char *)g_hash_table_lookup(handle->config, "version"); if (!version) { dbg("Cannot find \"version\" configuration parameter."); return NULL; } sec_level = (char *)g_hash_table_lookup(handle->config, "security_level"); authtype = (char *)g_hash_table_lookup(handle->config, "auth_type"); user = (char *)g_hash_table_lookup(handle->config, "security_name"); pass = (char *)g_hash_table_lookup(handle->config, "passphrase"); community = (char *)g_hash_table_lookup(handle->config, "community"); /* Configure SNMP V3 session */ if (!strcmp(version, "3")) { if (!user) { dbg("Cannot find \"security_name\" configuration parameter."); return NULL; } custom_handle->session.version = SNMP_VERSION_3; custom_handle->session.securityName = user; custom_handle->session.securityNameLen = strlen(user); custom_handle->session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; if (!strncmp(sec_level, "auth", 4)) { /* If using password */ if (!pass) { dbg("Cannot find \"passphrase\" configuration parameter."); return NULL; } custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; if (!authtype || !strcmp(authtype,"MD5")) { custom_handle->session.securityAuthProto = usmHMACMD5AuthProtocol; custom_handle->session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; } else if (!strcmp(authtype,"SHA")) { custom_handle->session.securityAuthProto = usmHMACSHA1AuthProtocol; custom_handle->session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; } else { dbg("Unrecognized authenication type=%s.", authtype); return NULL; } custom_handle->session.securityAuthKeyLen = USM_AUTH_KU_LEN; if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) pass, strlen(pass), custom_handle->session.securityAuthKey, &(custom_handle->session.securityAuthKeyLen)) != SNMPERR_SUCCESS) { snmp_perror("snmp_bc"); snmp_log(LOG_ERR, "Error generating Ku from authentication passphrase.\n"); dbg("Unable to establish SNMP authnopriv session."); return NULL; } if (!strcmp(sec_level, "authPriv")) { /* if using encryption */ custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; custom_handle->session.securityPrivProto = usmDESPrivProtocol; custom_handle->session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; custom_handle->session.securityPrivKeyLen = USM_PRIV_KU_LEN; if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) pass, strlen(pass), custom_handle->session.securityPrivKey, &(custom_handle->session.securityPrivKeyLen)) != SNMPERR_SUCCESS) { snmp_perror("snmp_bc"); snmp_log(LOG_ERR, "Error generating Ku from private passphrase.\n"); dbg("Unable to establish SNMP authpriv session."); return NULL; } } } /* Configure SNMP V1 session */ } else if (!strcmp(version, "1")) { if (!community) { dbg("Cannot find \"community\" configuration parameter."); return NULL; } custom_handle->session.version = SNMP_VERSION_1; custom_handle->session.community = (u_char *)community; custom_handle->session.community_len = strlen(community); } else { dbg("Unrecognized SNMP version=%s.", version); return NULL; } /* Windows32 specific net-snmp initialization (noop on unix) */ SOCK_STARTUP; custom_handle->sessp = snmp_sess_open(&(custom_handle->session)); if (!custom_handle->sessp) { snmp_perror("ack"); snmp_log(LOG_ERR, "Something horrible happened!!!\n"); dbg("Unable to open SNMP session."); return NULL; } custom_handle->ss = snmp_sess_session(custom_handle->sessp); } /* Determine platform type and daylight savings time */ { const char *oid; struct snmp_value get_value; SaErrorT err; err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_RSA, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found RSA"); custom_handle->platform = SNMP_BC_PLATFORM_RSA; } else { err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_BCT, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found BCT"); custom_handle->platform = SNMP_BC_PLATFORM_BCT; } else { err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_BC, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found BC"); custom_handle->platform = SNMP_BC_PLATFORM_BC; } else { dbg("Cannot read model type=%s; Error=%d.", SNMP_BC_PLATFORM_OID_BCT, err); return NULL; } } } /* DST */ if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) { oid = SNMP_BC_DST_RSA; } else { oid = SNMP_BC_DST; } err = snmp_bc_snmp_get(custom_handle, oid, &get_value, SAHPI_TRUE); if (err == SA_OK) { strcpy(custom_handle->handler_timezone, get_value.string); } else { dbg("Cannot read DST=%s; Error=%d.", oid, get_value.type); return NULL; } } /* Initialize "String to Event" mapping hash table */ if (errlog2event_hash_use_count == 0) { if (errlog2event_hash_init(custom_handle)) { dbg("Out of memory."); return NULL; } } errlog2event_hash_use_count++; /* Initialize "Event Number to HPI Event" mapping hash table */ if (event2hpi_hash_init(handle)) { dbg("Out of memory."); return NULL; } if (is_simulator()) { sim_banner(custom_handle); } return handle; }
/** * snmp_bc_open: * @handler_config: Pointer to hash table (passed by infrastructure) * * Open an SNMP BladeCenter/RSA plugin handler instance. * * Returns: * Plugin handle - normal operation. * NULL - on error. **/ void *snmp_bc_open(GHashTable *handler_config) { struct oh_handler_state *handle; struct snmp_bc_hnd *custom_handle; char *hostname, *version, *sec_level, *authtype, *user, *pass, *community, *context_name, *count_per_getbulk, *privacy_passwd, *privacy_protocol; char *root_tuple; if (!handler_config) { dbg("INVALID PARM - NULL handler_config pointer."); return NULL; } root_tuple = (char *)g_hash_table_lookup(handler_config, "entity_root"); if (!root_tuple) { dbg("Cannot find \"entity_root\" configuration parameter."); return NULL; } hostname = (char *)g_hash_table_lookup(handler_config, "host"); if (!hostname) { dbg("Cannot find \"host\" configuration parameter."); return NULL; } handle = (struct oh_handler_state *)g_malloc0(sizeof(struct oh_handler_state)); custom_handle = (struct snmp_bc_hnd *)g_malloc0(sizeof(struct snmp_bc_hnd)); if (!handle || !custom_handle) { dbg("Out of memory."); return NULL; } handle->data = custom_handle; handle->config = handler_config; /* Initialize the lock */ /* g_static_rec_mutex_init(&handle->handler_lock); */ g_static_rec_mutex_init(&custom_handle->snmp_bc_hlock.lock); custom_handle->snmp_bc_hlock.count = 0; /* Initialize resource masks */ /* Set all masks and counts to zero's */ custom_handle->max_pb_supported = 0; /* pb - processor blade */ custom_handle->max_blower_supported = 0; /* blower - fan/blower */ custom_handle->max_pm_supported = 0; /* pm - power module */ custom_handle->max_sm_supported = 0; /* sm - switch module */ custom_handle->max_mm_supported = 0; /* mm - management module */ custom_handle->max_mt_supported = 0; /* mt - media tray */ memset(&custom_handle->installed_pb_mask, '\0', SNMP_BC_MAX_RESOURCES_MASK); memset(&custom_handle->installed_blower_mask, '\0', SNMP_BC_MAX_RESOURCES_MASK); memset(&custom_handle->installed_pm_mask, '\0', SNMP_BC_MAX_RESOURCES_MASK); memset(&custom_handle->installed_sm_mask, '\0', SNMP_BC_MAX_RESOURCES_MASK); memset(&custom_handle->installed_mm_mask, '\0', SNMP_BC_MAX_RESOURCES_MASK); custom_handle->installed_mt_mask = 0; /* Indicate this is the 1st discovery (T0 discovery) */ /* Use to see if we need to create events for log entries. */ /* Do not report any event from event log entries, for */ /* entries that are created before this instance of OpenHPI */ custom_handle->isFirstDiscovery = SAHPI_TRUE; /* Initialize RPT cache */ handle->rptcache = (RPTable *)g_malloc0(sizeof(RPTable)); oh_init_rpt(handle->rptcache); /* Initialize event log cache */ handle->elcache = oh_el_create(BC_EL_MAX_SIZE); handle->elcache->gentimestamp = FALSE; /* Initialize simulator tables */ if (is_simulator()) { custom_handle->ss = NULL; sim_init(); } else { /* Initialize SNMP library */ init_snmp("oh_snmp_bc"); snmp_sess_init(&(custom_handle->session)); custom_handle->session.peername = hostname; /* Set retries/timeouts - based on testing with BC/BCT MM SNMP V3 agent */ custom_handle->session.retries = 3; custom_handle->session.timeout = 5000000; /* in microseconds */ version = (char *)g_hash_table_lookup(handle->config, "version"); if (!version) { dbg("Cannot find \"version\" configuration parameter."); return NULL; } sec_level = (char *)g_hash_table_lookup(handle->config, "security_level"); authtype = (char *)g_hash_table_lookup(handle->config, "auth_type"); user = (char *)g_hash_table_lookup(handle->config, "security_name"); pass = (char *)g_hash_table_lookup(handle->config, "passphrase"); community = (char *)g_hash_table_lookup(handle->config, "community"); context_name = (char *)g_hash_table_lookup(handle->config, "context_name"); count_per_getbulk = (char *)g_hash_table_lookup(handle->config, "count_per_getbulk"); privacy_passwd = (char *)g_hash_table_lookup(handle->config, "privacy_passwd"); privacy_protocol = (char *)g_hash_table_lookup(handle->config, "privacy_protocol"); /* Configure SNMP V3 session */ if (!strcmp(version, "3")) { if (!user) { dbg("Cannot find \"security_name\" configuration parameter."); return NULL; } custom_handle->session.version = SNMP_VERSION_3; custom_handle->session.securityName = user; custom_handle->session.securityNameLen = strlen(user); custom_handle->session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; if (!strncmp(sec_level, "auth", 4)) { /* If using password */ if (!pass) { dbg("Cannot find \"passphrase\" configuration parameter."); return NULL; } custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; if (!authtype || !strcmp(authtype,"MD5")) { custom_handle->session.securityAuthProto = usmHMACMD5AuthProtocol; custom_handle->session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; } else if (!strcmp(authtype,"SHA")) { custom_handle->session.securityAuthProto = usmHMACSHA1AuthProtocol; custom_handle->session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; } else { dbg("Unrecognized authenication type=%s.", authtype); return NULL; } custom_handle->session.securityAuthKeyLen = USM_AUTH_KU_LEN; if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) pass, strlen(pass), custom_handle->session.securityAuthKey, &(custom_handle->session.securityAuthKeyLen)) != SNMPERR_SUCCESS) { snmp_perror("snmp_bc"); snmp_log(LOG_ERR, "Error generating Ku from authentication passphrase.\n"); dbg("Unable to establish SNMP authnopriv session."); return NULL; } if (!strcmp(sec_level, "authPriv")) { /* if using encryption */ if (!privacy_passwd) { dbg("Cannot find \"privacy_passwd\" configuration parameter."); return NULL; } custom_handle->session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; custom_handle->session.securityPrivProto = usmDESPrivProtocol; custom_handle->session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; custom_handle->session.securityPrivKeyLen = USM_PRIV_KU_LEN; if (generate_Ku(custom_handle->session.securityAuthProto, custom_handle->session.securityAuthProtoLen, (u_char *) privacy_passwd, strlen(privacy_passwd), custom_handle->session.securityPrivKey, &(custom_handle->session.securityPrivKeyLen)) != SNMPERR_SUCCESS) { snmp_perror("snmp_bc"); snmp_log(LOG_ERR, "Error generating Ku from private passphrase.\n"); dbg("Unable to establish SNMP authpriv session."); return NULL; } } if (count_per_getbulk != NULL) { custom_handle->count_per_getbulk = atoi((char *)count_per_getbulk); if (custom_handle->count_per_getbulk <= 10) { custom_handle->count_per_getbulk = 10; } } else { custom_handle->count_per_getbulk = SNMP_BC_BULK_DEFAULT; } if (context_name != NULL) { custom_handle->session.contextName = (char *)context_name; custom_handle->session.contextNameLen = strlen(context_name); } } /* Configure SNMP V1 session */ } else if (!strcmp(version, "1")) { if (!community) { dbg("Cannot find \"community\" configuration parameter."); return NULL; } custom_handle->session.version = SNMP_VERSION_1; custom_handle->session.community = (u_char *)community; custom_handle->session.community_len = strlen(community); } else { dbg("Unrecognized SNMP version=%s.", version); return NULL; } /* Windows32 specific net-snmp initialization (noop on unix) */ SOCK_STARTUP; custom_handle->sessp = snmp_sess_open(&(custom_handle->session)); if (!custom_handle->sessp) { snmp_perror("ack"); snmp_log(LOG_ERR, "Something horrible happened!!!\n"); dbg("Unable to open SNMP session."); return NULL; } custom_handle->ss = snmp_sess_session(custom_handle->sessp); } /* Determine BladeCenter chassis type */ { const char *oid; struct snmp_value get_value; SaErrorT err; do { err = snmp_bc_snmp_get(custom_handle, SNMP_BC_CHASSIS_TYPE_OID, &get_value, SAHPI_FALSE); if (err == SA_OK) { int chassis_type, chassis_subtype; chassis_type = get_value.integer; err = snmp_bc_snmp_get(custom_handle, SNMP_BC_CHASSIS_SUBTYPE_OID, &get_value, SAHPI_FALSE); if (err) { dbg("Cannot read model subtype"); return NULL; } chassis_subtype = get_value.integer; if (chassis_type == SNMP_BC_CHASSIS_TYPE_BC && chassis_subtype == SNMP_BC_CHASSIS_SUBTYPE_ORIG) { trace("Found BC"); custom_handle->platform = SNMP_BC_PLATFORM_BC; break; } if (chassis_type == SNMP_BC_CHASSIS_TYPE_BC && chassis_subtype == SNMP_BC_CHASSIS_SUBTYPE_H) { trace("Found BCH"); custom_handle->platform = SNMP_BC_PLATFORM_BCH; break; } if (chassis_type == SNMP_BC_CHASSIS_TYPE_BCT && chassis_subtype == SNMP_BC_CHASSIS_SUBTYPE_ORIG) { trace("Found BCT"); custom_handle->platform = SNMP_BC_PLATFORM_BCT; break; } dbg("Unknown BladeCenter model"); return NULL; } else { /* Older MM software doesn't support chassis type and subtype OIDs */ err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_BCT, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found BCT"); custom_handle->platform = SNMP_BC_PLATFORM_BCT; break; } err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_BC, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found BC"); custom_handle->platform = SNMP_BC_PLATFORM_BC; break; } err = snmp_bc_snmp_get(custom_handle, SNMP_BC_PLATFORM_OID_RSA, &get_value, SAHPI_FALSE); if (err == SA_OK) { trace("Found RSA"); custom_handle->platform = SNMP_BC_PLATFORM_RSA; break; } dbg("Unknown BladeCenter model"); return NULL; } } while(0); /* Determine if daylight savings time (DST) is enabled */ if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) { oid = SNMP_BC_DST_RSA; } else { oid = SNMP_BC_DST; } err = snmp_bc_snmp_get(custom_handle, oid, &get_value, SAHPI_TRUE); if (err == SA_OK) { strcpy(custom_handle->handler_timezone, get_value.string); } else { dbg("Cannot read DST=%s; Error=%d.", oid, get_value.type); return NULL; } } /* Initialize "String to Event" mapping hash table */ if (errlog2event_hash_use_count == 0) { if (errlog2event_hash_init(custom_handle)) { dbg("Out of memory."); return NULL; } } errlog2event_hash_use_count++; /* Initialize "Event Number to HPI Event" mapping hash table */ if (event2hpi_hash_init(handle)) { dbg("Out of memory."); return NULL; } if (is_simulator()) { sim_banner(custom_handle); } return handle; }
/*! \fn void *snmp_host_init(int host_id, char *hostname, int snmp_version, * char *snmp_community, char *snmp_username, char *snmp_password, * char *snmp_auth_protocol, char *snmp_priv_passphrase, char *snmp_priv_protocol, * char *snmp_context, int snmp_port, int snmp_timeout) * \brief initializes an snmp_session object for a Spine host * * This function will initialize NET-SNMP or UCD-SNMP for the Spine host * in question. * */ void *snmp_host_init(int host_id, char *hostname, int snmp_version, char *snmp_community, char *snmp_username, char *snmp_password, char *snmp_auth_protocol, char *snmp_priv_passphrase, char *snmp_priv_protocol, char *snmp_context, int snmp_port, int snmp_timeout) { void *sessp = NULL; struct snmp_session session; char hostnameport[BUFSIZE]; /* initialize SNMP */ snmp_sess_init(&session); #ifdef USE_NET_SNMP /* Prevent update of the snmpapp.conf file */ #ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1); #endif /* Prevent update of the snmpapp.conf file */ #ifdef NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, 1); #endif #ifdef NETSNMP_DS_LIB_DONT_PRINT_UNITS netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS, 1); #endif netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1); netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT, 1); netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE, 1); netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS, 1); #else ds_set_boolean(DS_LIBRARY_ID, DS_LIB_QUICK_PRINT, 1); ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_BARE_VALUE, 1); ds_set_boolean(DS_LIBRARY_ID, DS_LIB_NUMERIC_TIMETICKS, 1); #endif /* verify snmp version is accurate */ if (snmp_version == 2) { session.version = SNMP_VERSION_2c; session.securityModel = SNMP_SEC_MODEL_SNMPv2c; }else if (snmp_version == 1) { session.version = SNMP_VERSION_1; session.securityModel = SNMP_SEC_MODEL_SNMPv1; }else if (snmp_version == 3) { session.version = SNMP_VERSION_3; session.securityModel = USM_SEC_MODEL_NUMBER; }else { SPINE_LOG(("Host[%i] ERROR: SNMP Version Error for Host '%s'\n", host_id, hostname)); return 0; } snprintf(hostnameport, BUFSIZE, "%s:%i", hostname, snmp_port); session.peername = hostnameport; session.retries = 3; session.remote_port = snmp_port; session.timeout = (snmp_timeout * 1000); /* net-snmp likes microseconds */ if ((snmp_version == 2) || (snmp_version == 1)) { session.community = snmp_community; session.community_len = strlen(snmp_community); }else { /* set the SNMPv3 user name */ session.securityName = snmp_username; session.securityNameLen = strlen(session.securityName); session.contextName = snmp_context; session.contextNameLen = strlen(session.contextName); session.securityAuthKeyLen = USM_AUTH_KU_LEN; /* set the authentication protocol */ if (strcmp(snmp_auth_protocol, "MD5") == 0) { /* set the authentication method to MD5 */ session.securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol, OIDSIZE(usmHMACMD5AuthProtocol)); session.securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol); }else{ /* set the authentication method to SHA1 */ session.securityAuthProto = snmp_duplicate_objid(usmHMACSHA1AuthProtocol, OIDSIZE(usmHMACSHA1AuthProtocol)); session.securityAuthProtoLen = OIDSIZE(usmHMACSHA1AuthProtocol); } /* set the authentication key to the hashed version. The password must me at least 8 char */ if (generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) snmp_password, strlen(snmp_password), session.securityAuthKey, &(session.securityAuthKeyLen)) != SNMPERR_SUCCESS) { SPINE_LOG(("SNMP: Error generating SNMPv3 Ku from authentication pass phrase.")); } /* set the privacy protocol to none */ if (strcmp(snmp_priv_protocol, "[None]") == 0) { session.securityPrivProto = snmp_duplicate_objid(usmNoPrivProtocol, OIDSIZE(usmNoPrivProtocol)); session.securityPrivProtoLen = OIDSIZE(usmNoPrivProtocol); session.securityPrivKeyLen = USM_PRIV_KU_LEN; /* set the security level to authenticate, but not encrypted */ session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; }else{ if (strcmp(snmp_priv_protocol, "DES") == 0) { session.securityPrivProto = snmp_duplicate_objid(usmDESPrivProtocol, OIDSIZE(usmDESPrivProtocol)); session.securityPrivProtoLen = OIDSIZE(usmDESPrivProtocol); session.securityPrivKeyLen = USM_PRIV_KU_LEN; /* set the security level to authenticate, and encrypted */ session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; }else{ session.securityPrivProto = snmp_duplicate_objid(usmAES128PrivProtocol, OIDSIZE(usmAES128PrivProtocol)); session.securityPrivProtoLen = OIDSIZE(usmAES128PrivProtocol); session.securityPrivKeyLen = USM_PRIV_KU_LEN; /* set the security level to authenticate, and encrypted */ session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; } /* set the privacy key to the hashed version. */ if (generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) snmp_priv_passphrase, strlen(snmp_priv_passphrase), session.securityPrivKey, &(session.securityPrivKeyLen)) != SNMPERR_SUCCESS) { SPINE_LOG(("SNMP: Error generating SNMPv3 Ku from privacy pass phrase.")); } } } /* open SNMP Session */ thread_mutex_lock(LOCK_SNMP); sessp = snmp_sess_open(&session); thread_mutex_unlock(LOCK_SNMP); if (!sessp) { SPINE_LOG(("ERROR: Problem initializing SNMP session '%s'\n", hostname)); } return sessp; }
static void csnmp_host_open_session (host_definition_t *host) { struct snmp_session sess; int error; if (host->sess_handle != NULL) csnmp_host_close_session (host); snmp_sess_init (&sess); sess.peername = host->address; switch (host->version) { case 1: sess.version = SNMP_VERSION_1; break; case 3: sess.version = SNMP_VERSION_3; break; default: sess.version = SNMP_VERSION_2c; break; } if (host->version == 3) { sess.securityName = host->username; sess.securityNameLen = strlen (host->username); sess.securityLevel = host->security_level; if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { sess.securityAuthProto = host->auth_protocol; sess.securityAuthProtoLen = host->auth_protocol_len; sess.securityAuthKeyLen = USM_AUTH_KU_LEN; error = generate_Ku (sess.securityAuthProto, sess.securityAuthProtoLen, (u_char *) host->auth_passphrase, strlen(host->auth_passphrase), sess.securityAuthKey, &sess.securityAuthKeyLen); if (error != SNMPERR_SUCCESS) { ERROR ("snmp plugin: host %s: Error generating Ku from auth_passphrase. (Error %d)", host->name, error); } } if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { sess.securityPrivProto = host->priv_protocol; sess.securityPrivProtoLen = host->priv_protocol_len; sess.securityPrivKeyLen = USM_PRIV_KU_LEN; error = generate_Ku (sess.securityAuthProto, sess.securityAuthProtoLen, (u_char *) host->priv_passphrase, strlen(host->priv_passphrase), sess.securityPrivKey, &sess.securityPrivKeyLen); if (error != SNMPERR_SUCCESS) { ERROR ("snmp plugin: host %s: Error generating Ku from priv_passphrase. (Error %d)", host->name, error); } } if (host->context != NULL) { sess.contextName = host->context; sess.contextNameLen = strlen (host->context); } } else /* SNMPv1/2 "authenticates" with community string */ { sess.community = (u_char *) host->community; sess.community_len = strlen (host->community); } /* snmp_sess_open will copy the `struct snmp_session *'. */ host->sess_handle = snmp_sess_open (&sess); if (host->sess_handle == NULL) { char *errstr = NULL; snmp_error (&sess, NULL, NULL, &errstr); ERROR ("snmp plugin: host %s: snmp_sess_open failed: %s", host->name, (errstr == NULL) ? "Unknown problem" : errstr); sfree (errstr); } } /* void csnmp_host_open_session */
/////////////////////////////////////////////////////////////// /// Given a host loads all the oid mappings for that host /// Uses snmp bulk get to minimize the time required for each /// mapping. int Host_Info::load_oid_table(){ unsigned int thread_id; struct snmp_session session; map<string,OID_Value_Table>::iterator iter; int fvalue=0; //// //netsnmp_session session, *ss; int numprinted = 0; int reps = 15, non_reps = 0; netsnmp_pdu *pdu, *response=NULL; netsnmp_variable_list *vars; int arg; oid name[MAX_OID_LEN]; size_t name_length; oid root[MAX_OID_LEN]; size_t rootlen; int count; int running; int status; int check; int exitval = 0; struct snmp_pdu *req, *resp; void *sp; char snmp_err_str[SNMP_ERR_STR_SIZE]; char buf[512]; char *placeholder; char buf2[512]; /// string temp_string1,temp_string2; int i; //////////// thread_id=(unsigned int)((uint64_t) pthread_self()); simple_snmp_sess_init(&session); session.retries=4; session.version = SNMP_VERSION_2c; //ARE THE NEXT TWO LINES VALID???! session.peername = (char *) ip_address.c_str(); session.community = (u_char *) community.c_str(); session.community_len = strlen(community.c_str()); for (iter = oid_table.begin(); iter != oid_table.end(); iter++){ /// assert(0==iter->first.compare(iter->second.oid)); print_log(LOG_INFO,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str()); rootlen = MAX_OID_LEN; //rootlen = strlen(iter->first.c_str()); if (!read_objid(iter->first.c_str(), root, &rootlen)) { //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) { //snmp_perror(argv[arg]); //exit(1); print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d host=%s\n",iter->first.c_str(),rootlen,ip_address.c_str()); snmp_perror("read_objid"); return -1; } if(!(sp = snmp_sess_open(&session))){ snmp_perror("snmp_open"); print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str()); return -1; } running=1; //why memmove and not memcpy? ask the netsmpbulk writers memmove(name, root, rootlen * sizeof(oid)); name_length = rootlen; //should be a while while(running==1){ /* * create PDU for GETBULK request and add object name to request */ pdu = snmp_pdu_create(SNMP_MSG_GETBULK); pdu->non_repeaters = non_reps; pdu->max_repetitions = reps; /* fill the packet */ snmp_add_null_var(pdu, name, name_length); /* * do the request */ //status = snmp_synch_response(sp, pdu, &response); status = snmp_sess_synch_response(sp,pdu,&response); switch (status){ case STAT_SUCCESS: if (response->errstat == SNMP_ERR_NOERROR) { //Yay success! ////////////// for (vars = response->variables; vars; vars = vars->next_variable) { if ((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0)) { /* * not part of this subtree */ running = 0; continue; } numprinted++; //print_log(LOG_DEBUG,"num_printed=%d\n",numprinted); //print_variable(vars->name, vars->name_length, vars); if ((vars->type != SNMP_ENDOFMIBVIEW) && (vars->type != SNMP_NOSUCHOBJECT) && (vars->type != SNMP_NOSUCHINSTANCE)) { /* * not an exception value */ /* if (check && snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) { fprintf(stderr, "Error: OID not increasing: "); fprint_objid(stderr, name, name_length); fprintf(stderr, " >= "); fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); running = 0; exitval = 1; } */ snmp_err_str[0]=0; snprint_objid(snmp_err_str,SNMP_ERR_STR_SIZE-1,vars->name,vars->name_length); snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars); //print_log(LOG_DEBUG,"[Thread %u] '%s'='%s'\n",thread_id,snmp_err_str,buf); temp_string1=snmp_err_str; size_t found; found=temp_string1.find_last_of("."); temp_string2=temp_string1.substr(found+1); string search_string; found=iter->first.find_last_not_of(".0123456789"); if(found==iter->first.npos){ //not found the search string is the whole thing! search_string=iter->first; } else{ search_string=iter->first.substr(found); } search_string=iter->first.substr((iter->first.length()*2)/3); string suffix_str; //iterate over the data. found=temp_string1.find(iter->first); found=temp_string1.find(search_string); print_log(LOG_DEBUG,"[Thread %u] [host %s] found=%u first=%s temp_string1=%s search_str=%s\n" , thread_id,ip_address.c_str(), found,iter->first.c_str(),temp_string1.c_str(),search_string.c_str()); if(temp_string1.npos!=found){ //print_log(LOG_INFO,"[Thread %u] [host %s] found!\n",thread_id,ip_address.c_str()); //suffix_str=temp_string1.substr(found+iter->first.length()+1); suffix_str=temp_string1.substr(found+search_string.length()+1); //print_log(LOG_INFO,"[Thread %u] found=%u first=%s temp_string1=%s\n" , thread_id,found,iter->first.c_str(),temp_string1.c_str()); print_log(LOG_DEBUG,"[Thread %u] [host %s] found =%s!\n",thread_id,ip_address.c_str(),suffix_str.c_str()); } else{ print_log(LOG_DEBUG,"[Thread %u] [host %s] NOT found!\n",thread_id,ip_address.c_str()); found=temp_string1.find_last_of("."); suffix_str=temp_string1.substr(found+1); } //print_log(LOG_DEBUG,"[Thread %u] index='%s'\n",thread_id,temp_string2.c_str()); uint64_t local_index; local_index=atoll(temp_string2.c_str()); //printf("Raw Value = %s\n",buf); temp_string2=extract_value_from_raw(buf); //print_log(LOG_DEBUG,"[Thread %u] index=%lu value='%s' \n",thread_id,local_index,buf2); //iter->second.indexof[temp_string2]=local_index; //iter->second.valueof[local_index]=temp_string2; iter->second.suffix_of[temp_string2]=suffix_str; iter->second.value_of[suffix_str]=temp_string2; print_log(LOG_DEBUG,"[Thread %u] [host %s] suffix_of[%s]='%s' \n",thread_id,ip_address.c_str(),temp_string2.c_str(),suffix_str.c_str()); /* * Check if last variable, and if so, save for next request. */ if (vars->next_variable == NULL) { memmove(name, vars->name, vars->name_length * sizeof(oid)); name_length = vars->name_length; } } else { /* * an exception value, so stop */ running = 0; } } //////////////// } else{ ///Error in response, report and exit loop running=0; snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, ip_address.c_str()); snmp_perror(snmp_err_str); } break; case STAT_TIMEOUT: print_log(LOG_NOTICE,"[Thread %u] SNMP timeout(building table), host=%15s \n",thread_id, ip_address.c_str() ); running=0; break; default: //other error! print_log(LOG_ERR,"SNMP MISC error\n"); running=0; break; } if (response){ snmp_free_pdu(response); response=NULL; } if(0==iter->second.suffix_of.size()){ print_log(LOG_WARNING,"[Thread %u][host %s] no data inserted for %s\n",thread_id,ip_address.c_str(),iter->first.c_str()); //fvalue=-1; } //print_log(LOG_DEBUG,"[Thread %u] inserted %d values\n" ,thread_id,iter->second.indexof.size()); }//end while if (response){ snmp_free_pdu(response); response=NULL; } //is this the best place to clse it? snmp_sess_close(sp); }//end for return fvalue; }
int Host_Info::load_oid_table_get(){ unsigned int thread_id; struct snmp_session session; map<string,OID_Value_Table>::iterator iter; int fvalue=0; struct snmp_pdu *req, *resp; void *sp; // struct snmp_session *sptr; oid name[MAX_OID_LEN]; size_t name_length=MAX_OID_LEN; oid root[MAX_OID_LEN]; size_t rootlen=MAX_OID_LEN; struct variable_list *vars; char snmp_err_str[SNMP_ERR_STR_SIZE]; char buf[512]; char *placeholder; char buf2[512]; /// string temp_string1,temp_string2; int running; int status; int i; thread_id=(unsigned int) ((uint64_t)pthread_self()); snmp_sess_init(&session); session.version = SNMP_VERSION_2c; session.peername = (char *) ip_address.c_str(); session.community = (u_char *) community.c_str(); session.community_len = strlen(community.c_str()); for (iter = oid_table.begin(); iter != oid_table.end(); iter++){ assert(0==iter->first.compare(iter->second.oid)); print_log(LOG_DEBUG,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str()); rootlen = MAX_OID_LEN; //rootlen = strlen(iter->first.c_str()); if (!read_objid(iter->first.c_str(), root, &rootlen)) { //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) { //snmp_perror(argv[arg]); //exit(1); print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d oid table get?\n",iter->first.c_str(),rootlen); snmp_perror("read_objid"); return -1; } if(!(sp = snmp_sess_open(&session))){ snmp_perror("snmp_open"); print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str()); return -1; } //////////// req = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(req, root, rootlen); status = snmp_sess_synch_response(sp,req,&resp); if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){ char buf1[512]; char *placeholder; int j; oid tmp[MAX_OID_LEN]; char temp[MAX_OID_LEN]; char ifIndexstr[MAX_OID_LEN]; string value; uint64_t local_index; vars = resp->variables; //first = malloc(sizeof(struct Value_index_mapping)); //assert(first!=NULL); //memset(buf1,'\0',sizeof(buf1)); //memset(first->value,'\0',sizeof(first->value)); //int toosmall = snprint_value(buf1, sizeof(buf1), vars->name, vars->name_length, vars); placeholder = strstr(buf1,":"); if(placeholder != NULL) placeholder = placeholder +2; if(strstr(placeholder,"\"")){ placeholder = placeholder +1; //strncpy(first->value,placeholder,strlen(placeholder)-1); value=placeholder; value.resize(value.size()-1); }else{ //strcpy(first->value,placeholder); value=placeholder; } memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); for(j=0;j<vars->name_length-rootlen;j++){ if(j>0){ i = sprintf(temp, ".%d", (int) tmp[rootlen+j]); strcat(ifIndexstr,temp); }else{ i = sprintf(ifIndexstr, "%d", (int) tmp[rootlen+j]); } } //strcpy(first->index,ifIndexstr); temp_string2=ifIndexstr; local_index=atoll(temp_string2.c_str()); assert(0==1); //this should never get here! under rev 3.1.0 initial //iter->second.indexof[value]=local_index; //iter->second.valueof[local_index]=value; //first->next = NULL; //current = first; }else{ snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"Failure buidling snmp_table Hostname: %s snmp_sync_response",ip_address.c_str()); snmp_perror(snmp_err_str); if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); return -1; } //////////////// running=1; while(running==1) { ///////// oid tmp[MAX_OID_LEN]; req = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(req,vars->name,vars->name_length); if(resp) snmp_free_pdu(resp); status = snmp_sess_synch_response(sp,req,&resp); if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){ struct Value_index_mapping *tempIndex = NULL; char buf[512]; char *placeholder; char ifIndexstr[MAX_OID_LEN]; int j; char temp[MAX_OID_LEN]; oid tmp[MAX_OID_LEN]; string value_string; string index_string; int64_t local_index; vars = resp->variables; //tempIndex = malloc(sizeof(struct Value_index_mapping)); //why allocate a != struct? //assert(tempIndex!=NULL); //memset(buf,'\0',sizeof(buf)); //memset(tempIndex->value,'\0',sizeof(tempIndex->value)); //will add a few extra bytes later, ensure we are covered snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars); //printf("Raw Value = %s\n",buf); placeholder = strstr(buf,":"); if(placeholder != NULL) placeholder = placeholder +2; if(strstr(placeholder,"\"")){ placeholder = placeholder +1; //you assert on the size of the dest, not the origin assert(strlen(placeholder)+1<STD_STRING_SIZE); //strncpy(tempIndex->value,placeholder,strlen(placeholder)); value_string=placeholder; }else{ //strncpy(tempIndex->value,placeholder,STD_STRING_SIZE-1); value_string=placeholder; value_string.resize(value_string.size()-1); } memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); for(j=0;j<vars->name_length-rootlen;j++){ if(j>0){ i = sprintf(temp, ".%d",(int) tmp[rootlen+j]); strcat(ifIndexstr,temp); }else{ i = sprintf(ifIndexstr, "%d",(int) tmp[rootlen+j]); } } //strcpy(tempIndex->index,ifIndexstr); index_string=ifIndexstr; local_index=atoll(index_string.c_str()); assert(1==0); //this should never reach this under 3.1.0 //iter->second.indexof[value_string]=local_index; //iter->second.valueof[local_index]=value_string; //print_log(LOG_DEBUG,"[Thread %u] Index = %u , Value = %s\n",thread_id,local_index,value_string.c_str()); //current->next = tempIndex; //current = tempIndex; //current->next = NULL; }else{ //snmp_perror("snmp_synch_response"); //snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, hostInfo.name); snmp_perror(snmp_err_str); if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); return -1; } //oid tmp[MAX_OID_LEN]; memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); if(tmp[rootlen-1] != root[rootlen-1]){ if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); running=0; //done? } ////////// } //end while }//end for each host }
void *poller(void *thread_args) { worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker->crew; target_t *entry = NULL; void *sessp = NULL; struct snmp_session session; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars = NULL; unsigned long long result = 0; unsigned long long last_value = 0; unsigned long long insert_val = 0; int poll_status = 0, db_status = 0, bits = 0, init = 0; char query[BUFSIZE]; char storedoid[BUFSIZE]; char result_string[BUFSIZE]; int cur_work = 0; int prev_work = 99999999; int loop_count = 0; #ifdef FEATURES /* Per thread SQL connection testing */ #if HAVE_MYSQL MYSQL mysql; #elif HAVE_PGSQL PGconn *pgsql; #endif double rate = 0; struct timezone tzp; struct timeval current_time; struct timeval last_time; /* for thread settings */ int oldstate, oldtype; #endif debug(HIGH, "Thread [%d] starting.\n", worker->index); pthread_cleanup_push(cleanup_db, NULL); /* Attempt to connect to the MySQL Database */ #ifdef FEATURES /* Per thread MySQL connection testing */ if (!(set->dboff)) { /* load the database driver */ if (!(db_init(set))) { fatal("** Database error - check configuration.\n"); } /* connect to the database */ if (!(db_connect(set))) { fatal("server not responding.\n"); } /* set up cancel function for exit */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); } #endif /* FEATURES */ while (1) { /* if(loop_count >= POLLS_PER_TRANSACTION) { debug(HIGH, "Thread [%d] doing commit on %d\n", worker->index, POLLS_PER_TRANSACTION); db_status = db_commit(); loop_count = 0; } */ #ifdef FEATURES /* see if we've been cancelled before we start another loop */ pthread_testcancel(); #endif debug(DEVELOP, "Thread [%d] locking (wait on work)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); #ifdef FEATURES /* add an unlock to the cancel stack */ pthread_cleanup_push(cancel_lock, &crew->mutex); #endif while (current == NULL) { PT_COND_WAIT(&crew->go, &crew->mutex); } debug(DEVELOP, "Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count); cur_work = crew->work_count; /* if(cur_work > prev_work) { debug(HIGH, "Thread [%d] doing commit at %d\n", worker->index,time(NULL)); db_status = db_commit(); loop_count = 0; } */ prev_work = cur_work; if (current != NULL) { debug(DEVELOP, "Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host->host, current->objoid, crew->work_count); snmp_enable_stderrlog(); snmp_sess_init(&session); if (current->host->snmp_ver == 2) session.version = SNMP_VERSION_2c; else session.version = SNMP_VERSION_1; session.peername = current->host->host; session.community = current->host->community; session.remote_port = set->snmp_port; session.community_len = strlen(session.community); sessp = snmp_sess_open(&session); anOID_len = MAX_OID_LEN; pdu = snmp_pdu_create(SNMP_MSG_GET); read_objid(current->objoid, anOID, &anOID_len); entry = current; last_value = current->last_value; #ifdef FEATURES /* save the time so we can calculate rate */ last_time = current->last_time; #endif init = current->init; insert_val = 0; bits = current->bits; strncpy(storedoid, current->objoid, sizeof(storedoid)); current = getNext(); } debug(DEVELOP, "Thread [%d] unlocking (done grabbing current)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); #ifdef FEATURES /* take the unlock off the cancel stack */ pthread_cleanup_pop(FALSE); #endif snmp_add_null_var(pdu, anOID, anOID_len); if (sessp != NULL) poll_status = snmp_sess_synch_response(sessp, pdu, &response); else poll_status = STAT_DESCRIP_ERROR; /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); if (poll_status == STAT_DESCRIP_ERROR) { stats.errors++; printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername); } else if (poll_status == STAT_TIMEOUT) { stats.no_resp++; printf("*** SNMP No response: (%s@%s).\n", session.peername, storedoid); } else if (poll_status != STAT_SUCCESS) { stats.errors++; printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername, storedoid, poll_status); } else if (poll_status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) { stats.errors++; printf("*** SNMP Error: (%s@%s) %s\n", session.peername, storedoid, snmp_errstring(response->errstat)); } else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type == SNMP_NOSUCHINSTANCE) { stats.errors++; printf("*** SNMP Error: No Such Instance Exists (%s@%s)\n", session.peername, storedoid); } else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { stats.polls++; } PT_MUTEX_UNLOCK(&stats.mutex); /* Liftoff, successful poll, process it */ #ifdef FEATURES /* Get the current time */ gettimeofday(¤t_time, &tzp); #endif if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type != SNMP_NOSUCHINSTANCE) { vars = response->variables; #ifdef OLD_UCD_SNMP sprint_value(result_string, anOID, anOID_len, vars); #else snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars); #endif switch (vars->type) { /* * Switch over vars->type and modify/assign result accordingly. */ case ASN_COUNTER64: debug(DEBUG, "64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = vars->val.counter64->high; result = result << 32; result = result + vars->val.counter64->low; break; case ASN_COUNTER: debug(DEBUG, "32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_INTEGER: debug(DEBUG, "Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_GAUGE: debug(DEBUG, "32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_TIMETICKS: debug(DEBUG, "Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OPAQUE: debug(DEBUG, "Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OCTET_STR: debug(DEBUG, "String Result: (%s@%s) %s\n", session.peername, storedoid, result_string); #ifdef HAVE_STRTOLL result = strtoll(vars->val.string, NULL, 0); #else result = strtol(vars->val.string, NULL, 0); #endif break; default: debug(LOW, "Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string); } /* Gauge Type */ if (bits == 0) { if (result != last_value) { insert_val = result; debug(DEVELOP, "Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val); } else { if (set->withzeros) insert_val = result; debug(DEVELOP, "Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val); } /* Counter Wrap Condition */ } else if (result < last_value) { PT_MUTEX_LOCK(&stats.mutex); stats.wraps++; PT_MUTEX_UNLOCK(&stats.mutex); if (bits == 32) insert_val = (THIRTYTWO - last_value) + result; else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result; #ifdef FEATURES rate = insert_val / timediff(current_time, last_time); #endif debug(LOW, "*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n", session.peername, storedoid, result, last_value, insert_val); /* Not a counter wrap and this is not the first poll */ } else if ((last_value >= 0) && (init != NEW)) { insert_val = result - last_value; #ifdef FEATURES rate = insert_val / timediff(current_time, last_time); #endif /* Print out SNMP result if verbose */ if (set->verbose == DEBUG) printf("Thread [%d]: (%lld-%lld -- %llu) = %llu\n", worker->index, result, last_value, insert_val,rate); if (set->verbose == HIGH) printf("Thread [%d]: %llu\n", worker->index, insert_val); /* last_value < 0, so this must be the first poll */ } else { #ifdef FEATURES /* set up this result for the next poll */ entry->last_value = result; #endif debug(HIGH, "Thread [%d]: First Poll, Normalizing\n", worker->index); } /* Check for bogus data, either negative or unrealistic */ if (insert_val > entry->maxspeed || result < 0) { debug(LOW, "*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n", session.peername, storedoid, insert_val, entry->maxspeed); insert_val = 0; #ifdef FEATURES rate = 0; #endif PT_MUTEX_LOCK(&stats.mutex); stats.out_of_range++; PT_MUTEX_UNLOCK(&stats.mutex); } if (!(set->dboff)) { if ( (insert_val > 0) || (set->withzeros) ) { #ifndef FEATURES /* MP - since we have our own database connection we don't need to lock it anymore */ PT_MUTEX_LOCK(&crew->mutex); #endif debug(DEVELOP, "db_insert sent: %s %d %d %e\n",entry->table,entry->iid,insert_val,rate); /* insert into the database */ db_status = db_insert(entry->table, entry->iid, insert_val, rate); #ifndef FEATURES /* MP - since we have our own database connection we don't need to lock it anymore */ PT_MUTEX_UNLOCK(&crew->mutex); #endif if (db_status) { PT_MUTEX_LOCK(&stats.mutex); stats.db_inserts++; PT_MUTEX_UNLOCK(&stats.mutex); } else { fatal("Fatal database error.\n"); } } /* insert_val > 0 or withzeros */ } /* !dboff */ } /* STAT_SUCCESS */ /* debug(HIGH, "Thread [%d] doing commit\n", worker->index); db_status = db_commit(); */ if (sessp != NULL) { snmp_sess_close(sessp); if (response != NULL) snmp_free_pdu(response); } debug(DEVELOP, "Thread [%d] locking (update work_count)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); crew->work_count--; /* Only if we received a positive result back do we update the last_value object */ if (poll_status == STAT_SUCCESS) { entry->last_value = result; if (init == NEW) entry->init = LIVE; } #ifdef FEATURES /* always update the time */ entry->last_time = current_time; #endif if (crew->work_count <= 0) { debug(HIGH, "Queue processed. Broadcasting thread done condition.\n"); PT_COND_BROAD(&crew->done); } debug(DEVELOP, "Thread [%d] unlocking (update work_count)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); loop_count++; } /* while(1) */ pthread_cleanup_pop(FALSE); /* Not reached */ }
// bulkwalk executes the SNMP GETBULK operation. // Caller frees returned response. struct bulkwalk_response *bulkwalk(char *peername, char *community) { struct bulkwalk_response *response = calloc(1, sizeof(struct bulkwalk_response)); void *sessp; struct snmp_session session, *sptr; snmp_sess_init(&session); session.version = SNMP_VERSION_2c; session.community = (unsigned char *) community; session.community_len = strlen(community); session.peername = peername; if ((sessp = snmp_sess_open(&session)) == NULL) { char *errstr = open_error(&session); char *err = NULL; int failure = asprintf(&err, "Open SNMP session error: %s", errstr); if (failure == -1) { err = errstr; } else { free(errstr); } add_error(response, err); return response; } oid name[MAX_OID_LEN]; size_t name_length = PRINTER_OID_LEN; memmove(name, PRINTER_OID, name_length * sizeof(oid)); long max_repetitions = MAX_REPETITIONS; struct oid_value **next_ov = &response->ov_root; while (1) { struct snmp_pdu *subtree; char *err = request(sessp, max_repetitions, name, name_length, &subtree); if (err != NULL) { add_error(response, err); snmp_free_pdu(subtree); break; } if (subtree->errstat == SNMP_ERR_NOERROR) { add_responses(subtree->variables, &next_ov, name, &name_length); snmp_free_pdu(subtree); if (name_length == 0) { break; } continue; } if (subtree->errstat == SNMP_ERR_TOOBIG) { // We tried to request too many OIDs at once; request fewer. if (max_repetitions <= 1) { snmp_free_pdu(subtree); break; } max_repetitions /= 2; snmp_free_pdu(subtree); continue; } char *errstr = session_error(sessp); err = NULL; int failure = asprintf(&err, "SNMP response error (%ld): %s", subtree->errstat, errstr); if (failure == -1) { err = errstr; } else { free(errstr); } add_error(response, err); snmp_free_pdu(subtree); break; } snmp_sess_close(sessp); return response; }