static int32_t snmp_pdu_cipher_init(const struct snmp_pdu *pdu, int32_t len, const EVP_CIPHER **ctype, uint8_t *piv) { int i; uint32_t netint; if (pdu->user.priv_proto == SNMP_PRIV_DES) { if (len % 8 != 0) return (-1); *ctype = EVP_des_cbc(); memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt)); for (i = 0; i < 8; i++) piv[i] = piv[i] ^ pdu->user.priv_key[8 + i]; } else if (pdu->user.priv_proto == SNMP_PRIV_AES) { *ctype = EVP_aes_128_cfb128(); netint = htonl(pdu->engine.engine_boots); memcpy(piv, &netint, sizeof(netint)); piv += sizeof(netint); netint = htonl(pdu->engine.engine_time); memcpy(piv, &netint, sizeof(netint)); piv += sizeof(netint); memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt)); } else if (pdu->user.priv_proto == SNMP_PRIV_NOPRIV) return (0); else { snmp_error("unknown privacy option - %d", pdu->user.priv_proto); return (-1); } return (1); }
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 */
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; }
int init_ilo_snmp_session(struct ilo_snmp_priv * priv_ptr) { int ret = NAGIOS_ILO_SUCCESS_STATUS; netsnmp_session session; init_snmp("Nagios_hpilo_snmp"); snmp_sess_init(&session); session.peername = strdup(priv_ptr->options.host); session.community = strdup(priv_ptr->options.community); session.community_len = strlen((char *) session.community); session.version = priv_ptr->options.version; session.timeout = priv_ptr->options.timeout; session.retries = priv_ptr->options.retries; priv_ptr->session = snmp_open(&session); if (priv_ptr->session == NULL) { snmp_error(&session, &session.s_errno, &session.s_snmp_errno, &priv_ptr->err_str); ret = NAGIOS_ILO_FAIL_STATUS; } return ret; }
static void Snmp_raise_error(struct snmp_session *session) { int liberr, snmperr; char *err; snmp_error(session, &liberr, &snmperr, &err); PyErr_Format(SnmpException, "%s", err); free(err); }
static void MPC_error(struct snmp_session *sptr, const char *fn, const char *msg) { int snmperr = 0; int cliberr = 0; char *errstr; snmp_error(sptr, &cliberr, &snmperr, &errstr); LOG(PIL_CRIT , "%s: %s (cliberr: %i / snmperr: %i / error: %s)." , fn, msg, cliberr, snmperr, errstr); free(errstr); }
enum snmp_code snmp_pdu_calc_digest(const struct snmp_pdu *pdu, uint8_t *digest) { uint8_t md[EVP_MAX_MD_SIZE], extkey[SNMP_EXTENDED_KEY_SIZ]; uint8_t key1[SNMP_EXTENDED_KEY_SIZ], key2[SNMP_EXTENDED_KEY_SIZ]; uint32_t i, keylen, olen; int32_t err; const EVP_MD *dtype; EVP_MD_CTX ctx; err = snmp_digest_init(&pdu->user, &ctx, &dtype, &keylen); if (err < 0) return (SNMP_CODE_BADDIGEST); else if (err == 0) return (SNMP_CODE_OK); memset(pdu->digest_ptr, 0, sizeof(pdu->msg_digest)); memcpy(extkey, pdu->user.auth_key, keylen); memset(extkey + keylen, 0, sizeof(extkey) - keylen); for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++) { key1[i] = extkey[i] ^ ipad; key2[i] = extkey[i] ^ opad; } if (EVP_DigestUpdate(&ctx, key1, SNMP_EXTENDED_KEY_SIZ) != 1 || EVP_DigestUpdate(&ctx, pdu->outer_ptr, pdu->outer_len) != 1 || EVP_DigestFinal(&ctx, md, &olen) != 1) goto failed; if (EVP_DigestInit(&ctx, dtype) != 1 || EVP_DigestUpdate(&ctx, key2, SNMP_EXTENDED_KEY_SIZ) != 1 || EVP_DigestUpdate(&ctx, md, olen) != 1 || EVP_DigestFinal(&ctx, md, &olen) != 1) goto failed; if (olen < SNMP_USM_AUTH_SIZE) { snmp_error("bad digest size - %d", olen); EVP_MD_CTX_cleanup(&ctx); return (SNMP_CODE_BADDIGEST); } memcpy(digest, md, SNMP_USM_AUTH_SIZE); EVP_MD_CTX_cleanup(&ctx); return (SNMP_CODE_OK); failed: EVP_MD_CTX_cleanup(&ctx); return (SNMP_CODE_BADDIGEST); }
void get_netsnmp_error( netsnmp_session *session, CString *errstr ) { int sys_errno, snmp_errno; int winsockerr; winsockerr = WSAGetLastError(); /* Don't bother with error string to snmp_error() since it doesn't * return snmp_detail[]. errno is mostly useless with WinSock but get * it anyway. */ snmp_error( session, &sys_errno, &snmp_errno, NULL ); /* FIXME - snmp_api_errstring() is not threadsafe */ *errstr = snmp_api_errstring( snmp_errno ); }
static int32_t snmp_digest_init(const struct snmp_user *user, EVP_MD_CTX *ctx, const EVP_MD **dtype, uint32_t *keylen) { if (user->auth_proto == SNMP_AUTH_HMAC_MD5) { *dtype = EVP_md5(); *keylen = SNMP_AUTH_HMACMD5_KEY_SIZ; } else if (user->auth_proto == SNMP_AUTH_HMAC_SHA) { *dtype = EVP_sha1(); *keylen = SNMP_AUTH_HMACSHA_KEY_SIZ; } else if (user->auth_proto == SNMP_AUTH_NOAUTH) return (0); else { snmp_error("unknown authentication option - %d", user->auth_proto); return (-1); } if (EVP_DigestInit(ctx, *dtype) != 1) return (-1); return (1); }
// 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(); }
int mp_snmp_query(netsnmp_session *ss, const mp_snmp_query_cmd *querycmd) { netsnmp_pdu *pdu; netsnmp_pdu *response; netsnmp_variable_list *vars; int status; const mp_snmp_query_cmd *p; pdu = snmp_pdu_create(SNMP_MSG_GET); for(p = querycmd; p->oid_len; p++) { snmp_add_null_var(pdu, p->oid, p->oid_len); } /* Send the SNMP Query */ do { status = snmp_synch_response(ss, pdu, &response); if (mp_verbose > 3) printf("snmp_synch_response() rc=%d\n", status); if (!response) return STAT_ERROR; if (status == STAT_SUCCESS && response->errindex == 0) break; if (mp_verbose > 3) printf(" errindex=%ld\n", response->errindex); pdu = snmp_fix_pdu(response, SNMP_MSG_GET); snmp_free_pdu(response); response = NULL; } while (status == STAT_SUCCESS && pdu); if (!response) return status; /* Process the response. */ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { for(vars = response->variables; vars; vars = vars->next_variable) { if (mp_verbose > 1) print_variable(vars->name, vars->name_length, vars); // Skip non existing vars if (vars->type == SNMP_NOSUCHOBJECT || vars->type == SNMP_NOSUCHINSTANCE || vars->type == SNMP_ENDOFMIBVIEW) continue; for(p = querycmd; p->oid_len; p++) { if (snmp_oid_compare(vars->name, vars->name_length, p->oid, p->oid_len) == 0) { copy_value(vars, p->type, p->target_len, p->target); break; } } } } else if (status != STAT_SUCCESS) { char *err; snmp_error(ss, NULL, NULL, &err); if (response) snmp_free_pdu(response); mp_snmp_deinit(); critical("SNMP Error: %s", err); } if (response) snmp_free_pdu(response); return status; }
int handle_master_agentx_packet(int operation, netsnmp_session * session, int reqid, netsnmp_pdu *pdu, void *magic) { netsnmp_agent_session *asp; if (operation == NETSNMP_CALLBACK_OP_DISCONNECT) { DEBUGMSGTL(("agentx/master", "transport disconnect on session %8p\n", session)); /* * Shut this session down gracefully. */ close_agentx_session(session, -1); return 1; } else if (operation == NETSNMP_CALLBACK_OP_CONNECT) { DEBUGMSGTL(("agentx/master", "transport connect on session %8p\n", session)); return 1; } else if (operation != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) { DEBUGMSGTL(("agentx/master", "unexpected callback op %d\n", operation)); return 1; } /* * Okay, it's a NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE op. */ if (magic) { asp = (netsnmp_agent_session *) magic; } else { asp = init_agent_snmp_session(session, pdu); } DEBUGMSGTL(("agentx/master", "handle pdu (req=0x%lx,trans=0x%lx,sess=0x%lx)\n", (unsigned long)pdu->reqid, (unsigned long)pdu->transid, (unsigned long)pdu->sessid)); switch (pdu->command) { case AGENTX_MSG_OPEN: asp->pdu->sessid = open_agentx_session(session, pdu); if (asp->pdu->sessid == -1) asp->status = session->s_snmp_errno; break; case AGENTX_MSG_CLOSE: asp->status = close_agentx_session(session, pdu->sessid); break; case AGENTX_MSG_REGISTER: asp->status = register_agentx_list(session, pdu); break; case AGENTX_MSG_UNREGISTER: asp->status = unregister_agentx_list(session, pdu); break; case AGENTX_MSG_INDEX_ALLOCATE: asp->status = allocate_idx_list(session, asp->pdu); if (asp->status != AGENTX_ERR_NOERROR) { snmp_free_pdu(asp->pdu); asp->pdu = snmp_clone_pdu(pdu); } break; case AGENTX_MSG_INDEX_DEALLOCATE: asp->status = release_idx_list(session, pdu); break; case AGENTX_MSG_ADD_AGENT_CAPS: asp->status = add_agent_caps_list(session, pdu); break; case AGENTX_MSG_REMOVE_AGENT_CAPS: asp->status = remove_agent_caps_list(session, pdu); break; case AGENTX_MSG_NOTIFY: asp->status = agentx_notify(session, pdu); break; case AGENTX_MSG_PING: asp->status = agentx_ping_response(session, pdu); break; /* * TODO: Other admin packets */ case AGENTX_MSG_GET: case AGENTX_MSG_GETNEXT: case AGENTX_MSG_GETBULK: case AGENTX_MSG_TESTSET: case AGENTX_MSG_COMMITSET: case AGENTX_MSG_UNDOSET: case AGENTX_MSG_CLEANUPSET: case AGENTX_MSG_RESPONSE: /* * Shouldn't be handled here */ break; default: asp->status = AGENTX_ERR_PARSE_FAILED; break; } asp->pdu->time = netsnmp_get_agent_uptime(); asp->pdu->command = AGENTX_MSG_RESPONSE; asp->pdu->errstat = asp->status; DEBUGMSGTL(("agentx/master", "send response, stat %d (req=0x%lx,trans=" "0x%lx,sess=0x%lx)\n", asp->status, (unsigned long)pdu->reqid, (unsigned long)pdu->transid, (unsigned long)pdu->sessid)); if (!snmp_send(asp->session, asp->pdu)) { char *eb = NULL; int pe, pse; snmp_error(asp->session, &pe, &pse, &eb); snmp_free_pdu(asp->pdu); DEBUGMSGTL(("agentx/master", "FAILED %d %d %s\n", pe, pse, eb)); free(eb); } asp->pdu = NULL; free_agent_snmp_session(asp); return 1; }
static char *snmp_sess_errstring(struct snmp_session *ss) { char *res; snmp_error(ss, NULL, NULL, &res); return res; }
int main (int argc, char **argv) { /* Local Vars */ int i; int rc = 0; char *output = NULL; long int disk_state; char *disk_name; int status = STATE_OK; mp_snmp_subtree table_state; netsnmp_session *ss; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) critical("Setup SIGALRM trap failed!"); /* Process check arguments */ if (process_arguments(argc, argv) != OK) unknown("Parsing arguments failed!"); /* Start plugin timeout */ alarm(mp_timeout); // PLUGIN CODE ss = mp_snmp_init(); /* OIDs to query */ status = mp_snmp_subtree_query(ss, MP_OID(1,3,6,1,4,1,24681,1,2,11), &table_state); if (status != STAT_SUCCESS) { char *string; snmp_error(ss, NULL, NULL, &string); unknown("QNAP: Error fetching table: %s", string); } mp_snmp_deinit(); status = STATE_OK; disk_name = mp_malloc(64); for (i = 0; i<table_state.size; i++) { rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,24681,1,2,11,1,4), i, ASN_INTEGER, (void *)&disk_state, sizeof(long int)); if (rc == 0) break; if (disk_state == HDD_Ready) continue; mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,24681,1,2,11,1,2), i, ASN_OCTET_STR, (void *)&disk_name, 64); mp_strcat_comma(&output, disk_name); switch (disk_state) { case HDD_NoDisk: mp_strcat_space(&output, "missing"); break; case HDD_Invalid: mp_strcat_space(&output, "invalid"); break; case HDD_RWError: mp_strcat_space(&output, "r/w-error"); break; case HDD_Unknown: default: mp_strcat_space(&output, "unknown"); break; } status = STATE_CRITICAL; } mp_snmp_subtree_free(&table_state); free(disk_name); if (i == 0) unknown("QNAP: No Disks found."); /* Output and return */ if (status == STATE_OK) ok("QNAP: All Disks \"GOOD\""); critical("QNAP: %s", output); }
static int send_snmp_inform_or_trap(const GpErrorData * errorData, const char * subject, const char * severity) { netsnmp_session session, *ss = NULL; netsnmp_pdu *pdu, *response; int status; char csysuptime[20]; static bool snmp_initialized = false; static char myhostname[255]; /* gethostname usually is limited to 65 chars out, but make this big to be safe */ char *rawstring = NULL; List *elemlist = NIL; ListCell *l = NULL; /* * "inform" messages get a positive acknowledgement response from the SNMP manager. * If it doesn't come, the message might be resent. * * "trap" messages are one-way, and we have no idea if the manager received it. * But, it's faster and cheaper, and no need to retry. So some people might prefer it. */ bool inform = strcmp(gp_snmp_use_inform_or_trap,"inform") == 0; if (gp_snmp_monitor_address == NULL || gp_snmp_monitor_address[0] == '\0') { static bool firsttime = 1; ereport(firsttime ? LOG : DEBUG1,(errmsg("SNMP inform/trap alerts are disabled"))); firsttime = false; return -1; } /* * SNMP managers are required to handle messages up to at least 484 bytes long, but I believe most existing * managers support messages up to one packet (ethernet frame) in size, 1472 bytes. * * But, should we take that chance? Or play it safe and limit the message to 484 bytes? */ elog(DEBUG2,"send_snmp_inform_or_trap"); if (!snmp_initialized) { snmp_enable_stderrlog(); if (gp_snmp_debug_log != NULL && gp_snmp_debug_log[0] != '\0') { snmp_enable_filelog(gp_snmp_debug_log, 1); //debug_register_tokens("ALL"); snmp_set_do_debugging(1); } /* * Initialize the SNMP library. This also reads the MIB database. */ /* Add GPDB-MIB to the list to be loaded */ putenv("MIBS=+GPDB-MIB:SNMP-FRAMEWORK-MIB:SNMPv2-CONF:SNMPv2-TC:SNMPv2-TC"); init_snmp("sendalert"); snmp_initialized = true; { char portnum[16]; myhostname[0] = '\0'; if (gethostname(myhostname, sizeof(myhostname)) == 0) { strcat(myhostname,":"); pg_ltoa(PostPortNumber,portnum); strcat(myhostname,portnum); } } } /* * Trap/Inform messages always start with the system up time. (SysUpTime.0) * * This presumably would be the uptime of GPDB, not the machine it is running on, I think. * * Use Postmaster's "MyStartTime" as a way to get that. */ sprintf(csysuptime, "%ld", (long)(time(NULL) - MyStartTime)); /* // ERRCODE_DISK_FULL could be reported vi rbmsMIB rdbmsTraps rdbmsOutOfSpace trap. // But it appears we never generate that error? // ERRCODE_ADMIN_SHUTDOWN means SysAdmin aborted somebody's request. Not interesting? // ERRCODE_CRASH_SHUTDOWN sounds interesting, but I don't see that we ever generate it. // ERRCODE_CANNOT_CONNECT_NOW means we are starting up, shutting down, in recovery, or Too many users are logged on. // abnormal database system shutdown */ /* * The gpdbAlertSeverity is a crude attempt to classify some of these messages based on severity, * where OK means everything is running normal, Down means everything is shut down, degraded would be * for times when some segments are down, but the system is up, The others are maybe useful in the future * * gpdbSevUnknown(0), * gpdbSevOk(1), * gpdbSevWarning(2), * gpdbSevError(3), * gpdbSevFatal(4), * gpdbSevPanic(5), * gpdbSevSystemDegraded(6), * gpdbSevSystemDown(7) */ char detail[MAX_ALERT_STRING+1]; snprintf(detail, MAX_ALERT_STRING, "%s", errorData->error_detail); detail[127] = '\0'; char sqlstmt[MAX_ALERT_STRING+1]; char * sqlstmtp = errorData->debug_query_string; if (sqlstmtp == NULL || sqlstmtp[0] == '\0') sqlstmtp = errorData->internal_query; if (sqlstmtp == NULL) sqlstmtp = ""; snprintf(sqlstmt, MAX_ALERT_STRING, "%s", sqlstmtp); sqlstmt[MAX_ALERT_STRING] = '\0'; /* Need a modifiable copy of To list */ rawstring = pstrdup(gp_snmp_monitor_address); /* Parse string into list of identifiers */ if (!SplitMailString(rawstring, ',', &elemlist)) { /* syntax error in list */ ereport(LOG, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid list syntax for \"gp_snmp_monitor_address\""))); return -1; } /* * This session is just a template, and doesn't need to be connected. * It is used by snmp_add(), which copies this info, opens the new session, and assigns the transport. */ snmp_sess_init( &session ); /* Initialize session to default values */ session.version = SNMP_VERSION_2c; session.timeout = SNMP_DEFAULT_TIMEOUT; session.retries = SNMP_DEFAULT_RETRIES; session.remote_port = 162; // I think this isn't used by net-snmp any more. /*if (strchr(session.peername,':')==NULL) strcat(session.peername,":162");*/ session.community = (u_char *)gp_snmp_community; session.community_len = strlen((const char *)session.community); // SNMP_DEFAULT_COMMUNITY_LEN means "public" session.callback_magic = NULL; foreach(l, elemlist) { char *cur_gp_snmp_monitor_address = (char *) lfirst(l); if (cur_gp_snmp_monitor_address == NULL || cur_gp_snmp_monitor_address[0] == '\0') continue; session.peername = cur_gp_snmp_monitor_address; /* * If we try to "snmp_open( &session )", net-snmp will set up a connection to that * endpoint on port 161, assuming we are the network monitor, and the other side is an agent. * * But we are pretending to be an agent, sending traps to the NM, so we don't need this. */ /*if (!snmp_open( &session )) // Don't open the session here! { const char *str; int xerr; xerr = snmp_errno; str = snmp_api_errstring(xerr); elog(LOG, "snmp_open: %s", str); return -1; }*/ /* * This call copies the info from "session" to "ss", assigns the transport, and opens the session. * We must specify "snmptrap" so the transport will know we want port 162 by default. */ ss = snmp_add(&session, netsnmp_transport_open_client("snmptrap", cur_gp_snmp_monitor_address), NULL, NULL); if (ss == NULL) { /* * diagnose netsnmp_transport_open_client and snmp_add errors with * the input netsnmp_session pointer */ { char *err; snmp_error(&session, NULL, NULL, &err); elog(LOG, "send_alert snmp_add of %s failed: %s", cur_gp_snmp_monitor_address, err); free(err); } return -1; } /* * We need to create the pdu each time, as it gets freed when we send a trap. */ pdu = snmp_pdu_create(inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2); if (!pdu) { const char *str; int xerr; xerr = snmp_errno; str = snmp_api_errstring(xerr); elog(LOG, "Failed to create notification PDU: %s", str); return -1; } /* * Trap/Inform messages always start with the system up time. (SysUpTime.0) * We use Postmaster's "MyStartTime" as a way to get that. */ snmp_add_var(pdu, objid_sysuptime, sizeof(objid_sysuptime) / sizeof(oid), 't', (const char *)csysuptime); #if 0 /* * In the future, we might want to send RDBMS-MIB::rdbmsStateChange when the system becomes unavailable or * partially unavailable. This code, which is not currently used, shows how to build the pdu for * that trap. */ /* {iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) rdbmsMIB(39) rdbmsTraps(2) rdbmsStateChange(1)} */ snmp_add_var(pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid), 'o', "1.3.6.1.2.1.39.2.1"); // rdbmsStateChange snmp_add_var(pdu, objid_rdbmsrelstate, sizeof(objid_rdbmsrelstate) / sizeof(oid), 'i', "5"); // 4 = restricted, 5 = unavailable #endif /* {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprises(1) gpdbMIB(31327) gpdbTraps(5) gpdbTrapsList(0) gpdbAlert(1)} */ /* * We could specify this trap oid by name, rather than numeric oid, but then if the GPDB-MIB wasn't * found, we'd get an error. Using the numeric oid means we can still work without the MIB loaded. */ snmp_add_var(pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid), 'o', "1.3.6.1.4.1.31327.5.0.1"); // gpdbAlert snmp_add_var(pdu, objid_gpdbAlertMsg, sizeof(objid_gpdbAlertMsg) / sizeof(oid), 's', subject); // SnmpAdminString = UTF-8 text snmp_add_var(pdu, objid_gpdbAlertSeverity, sizeof(objid_gpdbAlertSeverity) / sizeof(oid), 'i', (char *)severity); snmp_add_var(pdu, objid_gpdbAlertSqlstate, sizeof(objid_gpdbAlertSqlstate) / sizeof(oid), 's', errorData->sql_state); snmp_add_var(pdu, objid_gpdbAlertDetail, sizeof(objid_gpdbAlertDetail) / sizeof(oid), 's', detail); // SnmpAdminString = UTF-8 text snmp_add_var(pdu, objid_gpdbAlertSqlStmt, sizeof(objid_gpdbAlertSqlStmt) / sizeof(oid), 's', sqlstmt); // SnmpAdminString = UTF-8 text snmp_add_var(pdu, objid_gpdbAlertSystemName, sizeof(objid_gpdbAlertSystemName) / sizeof(oid), 's', myhostname); // SnmpAdminString = UTF-8 text elog(DEBUG2,"ready to send to %s",cur_gp_snmp_monitor_address); if (inform) status = snmp_synch_response(ss, pdu, &response); else status = snmp_send(ss, pdu) == 0; elog(DEBUG2,"send, status %d",status); if (status != STAT_SUCCESS) { /* Something went wrong */ if (ss) { char *err; snmp_error(ss, NULL, NULL, &err); elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", err); free(err); } else { elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", "Something went wrong"); } if (!inform) snmp_free_pdu(pdu); } else if (inform) snmp_free_pdu(response); snmp_close(ss); ss = NULL; }
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 */
int main (int argc, char **argv) { /* Local Vars */ char *output = NULL; char *pdu_name = NULL; int status = STATE_OK; long pdu_psu1 = -1; long pdu_psu2 = -1; long int outlet_state; char *outlet_name; int i; int rc = 0; mp_snmp_subtree table_state; netsnmp_session *ss; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) critical("Setup SIGALRM trap failed!"); /* Process check arguments */ if (process_arguments(argc, argv) != OK) unknown("Parsing arguments failed!"); /* Start plugin timeout */ alarm(mp_timeout); ss = mp_snmp_init(); /* OIDs to query */ mp_snmp_query_cmd snmpcmd[] = { {{1,3,6,1,4,1,318,1,1,12,4,1,1,0}, 14, ASN_INTEGER, (void *)&pdu_psu1, sizeof(long int)}, {{1,3,6,1,4,1,318,1,1,12,4,1,2,0}, 14, ASN_INTEGER, (void *)&pdu_psu2, sizeof(long int)}, {{1,3,6,1,2,1,1,5,0}, 9, ASN_OCTET_STR, (void *)&pdu_name, 0}, {{0}, 0, 0, 0}, }; rc = mp_snmp_query(ss, snmpcmd); if (rc != STAT_SUCCESS) { char *string; snmp_error(ss, NULL, NULL, &string); unknown("APC PDU: Error fetching values: %s", string); } rc = mp_snmp_subtree_query(ss, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1), &table_state); if (rc != STAT_SUCCESS) { char *string; snmp_error(ss, NULL, NULL, &string); unknown("APC PDU: Error fetching table: %s", string); } mp_snmp_deinit(); // Check for PSU Failure if (pdu_psu1 != 1) { status = STATE_CRITICAL; output = strdup("Power Supply 1 Failed!"); } else if (pdu_psu2 != 1) { status = STATE_CRITICAL; output = strdup("Power Supply 2 Failed!"); } outlet_name = mp_malloc(64); if (stateOn == NULL && stateOff == NULL) { // Check all outlets for on. long int outlet_state; for (i = 0; i<table_state.size; i++) { rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,4), i, ASN_INTEGER, (void *)&outlet_state, sizeof(long int)); if (rc != 1) break; if (outlet_state != 1) { mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,2), i, ASN_OCTET_STR, (void *)&outlet_name, 64); mp_strcat_space(&output, outlet_name); mp_strcat_space(&output, " is off!"); status = STATE_CRITICAL; } } } else { if (stateOn != NULL) { char *c, *s, *p; p = s = strdup(stateOn); while((c = strsep(&s, ","))) { i = strtol(c, NULL, 10); if (i == 0) { for (i = 0; i<table_state.size; i++) { rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,2), i, ASN_OCTET_STR, (void *)&outlet_name, 64); if (rc == 0 || strcmp(c, outlet_name) == 0) break; } if (rc == 0) { mp_strcat_space(&output, c); mp_strcat_space(&output, " not found!"); status = status == STATE_OK ? STATE_UNKNOWN : status; continue; } } else { i--; } rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,4), i, ASN_INTEGER, (void *)&outlet_state, sizeof(long int)); if (rc == 0) { mp_strcat_space(&output, c); mp_strcat_space(&output, " not found!"); status = status == STATE_OK ? STATE_UNKNOWN : status; continue; } if (outlet_state != 1) { mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,2), i, ASN_OCTET_STR, (void *)&outlet_name, 64); mp_strcat_space(&output, outlet_name); mp_strcat_space(&output, " is off!"); status = STATE_CRITICAL; } } free( p ); } if (stateOff != NULL) { char *c, *s, *p; p = s = strdup(stateOff); while((c = strsep(&s, ","))) { i = strtol(c, NULL, 10); if (i == 0) { for (i = 0; i<table_state.size; i++) { rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,2), i, ASN_OCTET_STR, (void *)&outlet_name, 64); if (rc == 0 || strcmp(c, outlet_name) == 0) break; } if (rc == 0) { mp_strcat_space(&output, c); mp_strcat_space(&output, " not found!"); status = status == STATE_OK ? STATE_UNKNOWN : status; continue; } } else { i--; } rc = mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,4), i, ASN_INTEGER, (void *)&outlet_state, sizeof(long int)); if (rc == 0) { mp_strcat_space(&output, c); mp_strcat_space(&output, " not found!"); status = status == STATE_OK ? STATE_UNKNOWN : status; continue; } if (outlet_state != 2) { mp_snmp_subtree_get_value(&table_state, MP_OID(1,3,6,1,4,1,318,1,1,12,3,5,1,1,2), i, ASN_OCTET_STR, (void *)&outlet_name, 64); mp_strcat_space(&output, outlet_name); mp_strcat_space(&output, " is on!"); status = STATE_CRITICAL; } } free( p ); } } mp_snmp_subtree_free(&table_state); free(outlet_name); /* Output and return */ if (status == STATE_OK) ok("APC PDU %s", pdu_name); if (status == STATE_WARNING) warning("APC PDU %s [%s]", pdu_name, output); if (status == STATE_UNKNOWN) unknown("APC PDU %s [%s]", pdu_name, output); critical("APC PDU %s [%s]", pdu_name, output); }
fsal_status_t SNMPFSAL_InitClientContext(snmpfsal_op_context_t * p_thr_context) { int rc, i; netsnmp_session session; /* sanity check */ if(!p_thr_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_InitClientContext); /* initialy set the export entry to none */ p_thr_context->export_context = NULL; p_thr_context->user_credential.user = 0; p_thr_context->user_credential.group = 0; /* initialize the SNMP session */ snmp_sess_init(&session); session.version = snmp_glob_config.snmp_version; session.retries = snmp_glob_config.nb_retries; session.timeout = snmp_glob_config.microsec_timeout; session.peername = snmp_glob_config.snmp_server; if(session.version == SNMP_VERSION_3) { if(!strcasecmp(snmp_glob_config.auth_proto, "MD5")) { session.securityAuthProto = usmHMACMD5AuthProtocol; session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; } else if(!strcasecmp(snmp_glob_config.auth_proto, "SHA")) { session.securityAuthProto = usmHMACSHA1AuthProtocol; session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; } if(!strcasecmp(snmp_glob_config.enc_proto, "DES")) { session.securityPrivProto = usmDESPrivProtocol; session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; } else if(!strcasecmp(snmp_glob_config.enc_proto, "AES")) { session.securityPrivProto = usmAES128PrivProtocol; session.securityPrivProtoLen = USM_PRIV_PROTO_AES128_LEN; } session.securityName = snmp_glob_config.username; /* securityName is not allocated */ session.securityNameLen = strlen(snmp_glob_config.username); session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; session.securityAuthKeyLen = USM_AUTH_KU_LEN; if(generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) snmp_glob_config.auth_phrase, strlen(snmp_glob_config.auth_phrase), session.securityAuthKey, &session.securityAuthKeyLen) != SNMPERR_SUCCESS) { LogCrit(COMPONENT_FSAL, "FSAL INIT CONTEXT: ERROR creating SNMP passphrase for authentification"); Return(ERR_FSAL_BAD_INIT, snmp_errno, INDEX_FSAL_InitClientContext); } session.securityPrivKeyLen = USM_PRIV_KU_LEN; if(generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) snmp_glob_config.enc_phrase, strlen(snmp_glob_config.enc_phrase), session.securityPrivKey, &session.securityPrivKeyLen) != SNMPERR_SUCCESS) { LogCrit(COMPONENT_FSAL, "FSAL INIT CONTEXT: ERROR creating SNMP passphrase for encryption"); Return(ERR_FSAL_BAD_INIT, snmp_errno, INDEX_FSAL_InitClientContext); } } else /* v1 or v2c */ { session.community = snmp_glob_config.community; session.community_len = strlen(snmp_glob_config.community); } p_thr_context->snmp_session = snmp_open(&session); if(p_thr_context->snmp_session == NULL) { char *err_msg; snmp_error(&session, &errno, &snmp_errno, &err_msg); LogCrit(COMPONENT_FSAL, "FSAL INIT CONTEXT: ERROR creating SNMP session: %s", err_msg); Return(ERR_FSAL_BAD_INIT, snmp_errno, INDEX_FSAL_InitClientContext); } p_thr_context->snmp_request = NULL; p_thr_context->snmp_response = NULL; p_thr_context->current_response = NULL; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_InitClientContext); }
int get_ilo_oid_list (struct snmp_session *session, oid *target_oid, size_t target_oid_len, char **error_ptr) { int status; int running = TRUE; oid cur_oid[MAX_OID_LEN]; size_t cur_oid_len; struct snmp_pdu *pdu_ptr, *response_ptr; netsnmp_variable_list *var_list,*var_list_prev=NULL; struct ilo_oid_list *oid_list; struct ilo_snmp_priv *priv_ptr = container_of(error_ptr, struct ilo_snmp_priv, err_str); if (priv_ptr == NULL) { ILO_ERR_DEBUG(error_ptr, "priv_ptr is NULL!\n"); return NAGIOS_ILO_FAIL_STATUS; } oid_copy(cur_oid, &cur_oid_len, target_oid, target_oid_len); while (running) { pdu_ptr = snmp_pdu_create(SNMP_MSG_GETBULK); /* Max-repetitions: Tell get-bulk to attemp up to 'errindex' get-next operations to get the remaining objects. */ pdu_ptr->errindex = SNMP_GETBULK_ERRINDEX; /* Non-repeater. */ pdu_ptr->errstat = 0; snmp_add_null_var(pdu_ptr, cur_oid, cur_oid_len); status = snmp_synch_response(session, pdu_ptr, &response_ptr); if (status == STAT_SUCCESS && response_ptr->errstat == SNMP_ERR_NOERROR) { var_list = var_list_prev =response_ptr->variables; /* Add each element of the netsnmp variable list to struct ilo_oid_list. */ while (var_list) { if (netsnmp_oid_is_subtree(target_oid, target_oid_len, var_list->name, var_list->name_length) != 0) { running = FALSE; break; } oid_list = alloc_oid_list(var_list, error_ptr); if (oid_list == NULL) { ILO_ERR_DEBUG(error_ptr, "oid_list is NULL!\n"); return NAGIOS_ILO_FAIL_STATUS; } oid_list_add(&priv_ptr->oid_list, oid_list); var_list_prev = var_list; var_list = var_list->next_variable; } var_list=var_list_prev; if ((var_list->type == SNMP_ENDOFMIBVIEW) || (var_list->type == SNMP_NOSUCHOBJECT) || (var_list->type == SNMP_NOSUCHINSTANCE)) { running = FALSE; } else { oid_copy(cur_oid, &cur_oid_len, var_list->name,var_list->name_length); } } else { /* Cannot get the response */ if (status == STAT_SUCCESS) { ILO_ERR_DEBUG(error_ptr, "Cannot get the response: %s\n", snmp_errstring(response_ptr->errstat)); } else { snmp_error(session, &session->s_errno, &session->s_snmp_errno, error_ptr); } return NAGIOS_ILO_FAIL_STATUS; } if (response_ptr) snmp_free_pdu(response_ptr); } return NAGIOS_ILO_SUCCESS_STATUS; }
// open_error gets the last error in this session, // after snmp_sess_open failes. // // Caller frees returned string. char *open_error(struct snmp_session *session) { int liberr, syserr; char *errstr; snmp_error(session, &liberr, &syserr, &errstr); return errstr; }