// Send a report message. int v3MP::send_report(unsigned char* scopedPDU, int scopedPDULength, struct snmp_pdu *pdu, int errorCode, int sLevel, int sModel, OctetStr &sName, UdpAddress &destination, Snmp *snmp_session) { debugprintf(2, "v3MP::send_report: Sending report message."); unsigned char *data; int dataLength; int pdu_type = 0; unsigned char cEngineID[MAXLENGTH_ENGINEID+1]; unsigned char cName[MAXLENGTH_CONTEXT_NAME+1]; int cEngineIDLength = MAXLENGTH_ENGINEID+1; int cNameLength = MAXLENGTH_CONTEXT_NAME+1; debugprintf(2, "v3MP::send_report: securityLevel %d",sLevel); if (scopedPDULength != MAX_SNMP_PACKET) { // try to get scopedPDU and PDU data = asn1_parse_scoped_pdu(scopedPDU, &scopedPDULength, cEngineID, &cEngineIDLength, cName, &cNameLength); if (data == NULL) { debugprintf(1, "mp: Error while trying to parse scopedPDU!"); cEngineID[0] = '\0'; cEngineIDLength = 0; cName[0] = '\0'; cNameLength = 0; // Dont send encrypted report if decryption failed: //if (sLevel == SNMP_SECURITY_LEVEL_AUTH_PRIV) // sLevel = SNMP_SECURITY_LEVEL_AUTH_NOPRIV; } else { // data != NULL dataLength = scopedPDULength; // parse data of scopedPDU snmp_parse_data_pdu(pdu, data, dataLength); pdu_type = pdu->command; if (!data) { debugprintf(0, "mp: Error while trying to parse PDU!"); } } // end of: if (data == NULL) } // end if (scopedPDULength != MAX_SNMP_PACKET) else { // scopedPDULength == MAX_SNMP_PACKET cEngineID[0] = '\0'; cEngineIDLength = 0; cName[0] = '\0'; cNameLength = 0; pdu->reqid = 0; } clear_pdu(pdu); // Clear pdu and free all content debugprintf(4, "pdu->reqid = %ld",pdu->reqid); pdu->errstat = 0; pdu->errindex = 0; pdu->command = REPORT_MSG; Vb counterVb; Oid counterOid; SmiLPOID smioid; SmiVALUE smival; switch (errorCode) { case SNMPv3_MP_INVALID_MESSAGE: case SNMPv3_USM_PARSE_ERROR: { counterVb.set_oid(oidSnmpInvalidMsgs); counterVb.set_value(Counter32(get_stats_invalid_msgs())); break; } case SNMPv3_USM_NOT_IN_TIME_WINDOW: case SNMPv3_MP_NOT_IN_TIME_WINDOW: { counterVb.set_oid(oidUsmStatsNotInTimeWindows); counterVb.set_value(Counter32(usm->get_stats_not_in_time_windows())); break; } case SNMPv3_USM_DECRYPTION_ERROR: { counterVb.set_oid(oidUsmStatsDecryptionErrors); counterVb.set_value(Counter32(usm->get_stats_decryption_errors())); //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_AUTHENTICATION_ERROR: case SNMPv3_USM_AUTHENTICATION_FAILURE: { counterVb.set_oid(oidUsmStatsWrongDigests); counterVb.set_value(Counter32(usm->get_stats_wrong_digests())); //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_UNKNOWN_ENGINEID: case SNMPv3_MP_INVALID_ENGINEID: { //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; counterVb.set_oid(oidUsmStatsUnknownEngineIDs); counterVb.set_value(Counter32(usm->get_stats_unknown_engine_ids())); break; } case SNMPv3_MP_UNSUPPORTED_SECURITY_MODEL: { counterVb.set_oid(oidSnmpUnknownSecurityModels); counterVb.set_value(Counter32(get_stats_unknown_security_models())); sModel = SNMP_SECURITY_MODEL_USM; sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_UNKNOWN_SECURITY_NAME: { counterVb.set_oid(oidUsmStatsUnknownUserNames); counterVb.set_value(Counter32(usm->get_stats_unknown_user_names())); sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; debugprintf(2, "Report: SecurityName: %s",sName.get_printable()); break; } case SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL: { counterVb.set_oid(oidUsmStatsUnsupportedSecLevels); counterVb.set_value(Counter32(usm->get_stats_unsupported_sec_levels())); sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } default: { counterVb.set_oid(oidSnmpInvalidMsgs); counterVb.set_value(Counter32(get_stats_invalid_msgs())); sModel = SNMP_SECURITY_MODEL_USM; sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; sName.set_data(0, 0); debugprintf(2, "ErrorCode was %i in snmp_parse", errorCode); } } // end switch counterVb.get_oid(counterOid); smioid = counterOid.oidval(); int status = convertVbToSmival(counterVb, &smival); if (status != SNMP_CLASS_SUCCESS) { return SNMPv3_MP_ERROR; } snmp_add_var(pdu, smioid->ptr, (int) smioid->len, &smival); freeSmivalDescriptor(&smival); Buffer<unsigned char> sendbuffer(MAX_SNMP_PACKET); int sendbufferlen= MAX_SNMP_PACKET; status = snmp_build( pdu, sendbuffer.get_ptr(), &sendbufferlen, own_engine_id_oct, sName, sModel, sLevel, OctetStr(cEngineID, cEngineIDLength), OctetStr(cName, cNameLength)); if (status != SNMPv3_MP_OK) { debugprintf(2, "v3MP::send_report: error serializing message (mpSnmpBuild returns: %i).", status); return SNMPv3_MP_ERROR; } SnmpSocket send_fd = INVALID_SOCKET; if (pdu_type == sNMP_PDU_INFORM) { debugprintf(4, "Received a snmpInform pdu."); if (snmp_session->get_eventListHolder()->notifyEventList()) send_fd = snmp_session->get_eventListHolder()->notifyEventList()->get_notify_fd(); } status = snmp_session->send_raw_data(sendbuffer.get_ptr(), (size_t)sendbufferlen,// pdu to send destination, // target address send_fd); // the fd to use if ( status != 0) { debugprintf(1, "v3MP::send_report: error sending message (%i)", status); return SNMPv3_MP_ERROR; } debugprintf(3, "v3MP::send_report: Report sent."); return SNMPv3_MP_OK; }
bool DataSourceExternalCommand::updateMibObj() { ExternalCommand *cmd; MibObjectConfig const mibCfg = mMibObj->getConfig(); LOG_BEGIN( loggerModuleName, DEBUG_LOG | 1 ); LOG("DataSourceExternalCommand::updateMibObj(): (commandline)"); LOG( mCommandLine.c_str() ); LOG_END; ThreadSynchronize guard(*this); if( !mibCfg.ExternalCommand.User.empty() ) cmd = new ExternalCommandAsUser(mibCfg.ExternalCommand); else cmd = new ExternalCommand(mibCfg.ExternalCommand); MibObject::ContentManagerType &cntMgr = mMibObj->beginContentUpdate(); cntMgr.clear(); ExtCmdMib smExtCmdMib( cntMgr ); smExtCmdMib.setLastStartedTimestamp( time(NULL) ); smExtCmdMib.setCommandConfig( mibCfg.ExternalCommand.Executable, mCommandLine, mibCfg.ExternalCommand.User ); int comp_rc; if( ( comp_rc = cmd->start() ) != 0 ) { #if 0 mMibObj->set_value( mLastExitCodeOid, SnmpInt32(-1) ); mMibObj->set_value( mLastSignalCodeOid, SnmpInt32(-1) ); mMibObj->set_value( mLastErrorCodeOid, SnmpInt32(comp_rc) ); #else smExtCmdMib.setLastExecutionErrorCode( comp_rc ); #endif LOG_BEGIN( loggerModuleName, ERROR_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) failed to start with (error)" ); LOG( mCommandLine.c_str() ); LOG( comp_rc ); LOG_END; delete cmd; // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); return false; } LOG_BEGIN( loggerModuleName, DEBUG_LOG | 5 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) started with (pid)" ); LOG( mCommandLine.c_str() ); LOG( cmd->getChildPid() ); LOG_END; while( cmd->poll(5) ) (void)0; /* nop() */ cmd->finish(); #if 0 rc = mMibObj->set_value( mLastFinishedTimestampOid, Counter64( time(NULL) ) ); status &= rc; rc = mMibObj->set_value( mLastExitCodeOid, SnmpInt32( cmd->getExitCode() ) ); status &= rc; rc = mMibObj->set_value( mLastSignalCodeOid, SnmpInt32( cmd->getExitSignal() ) ); status &= rc; rc = mMibObj->set_value( mLastErrorMessageOid, OctetStr( cmd->getErrBuf().c_str() ) ); status &= rc; #else smExtCmdMib.setLastExecutionState( cmd->getExitCode(), cmd->getExitSignal(), cmd->getErrBuf(), time(NULL) ); #endif LOG_BEGIN( loggerModuleName, DEBUG_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) finished with (exit code) (exit signal)" ); LOG( mCommandLine.c_str() ); LOG( cmd->getExitCode() ); LOG( cmd->getExitSignal() ); LOG_END; if( cmd->getExitCode() != 0 ) { delete cmd; // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); return false; } ParseExternalJson pej; pej.reserve(mExpectedEntryCount); if( 0 == ( comp_rc = pej.parse( cmd->getOutBuf() ) ) ) { LOG_BEGIN(loggerModuleName, DEBUG_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): json output successful parsed" ); LOG_END; smExtCmdMib.setLastErrorCode( 0 ); } else { LOG_BEGIN(loggerModuleName, ERROR_LOG | 3 ); LOG( "DataSourceExternalCommand::updateMibObj(): error parsing json output" ); LOG_END; smExtCmdMib.setLastErrorCode( comp_rc ); // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); delete cmd; return false; } delete cmd; vector<ExternalDataTuple> const &data = pej.getData(); mExpectedEntryCount = data.size(); #if 0 MibStaticTable *extContent = new MibStaticTable( mExternalDataOid ); for( vector<ExternalDataTuple>::const_iterator iter = data.begin(); iter != data.end(); ++iter ) { const ExternalDataTuple &edt = *iter; extContent->add( MibStaticEntry( Vbx( edt.Oid, *edt.Datum ) ) ); } rc = mMibObj->set_value( extContent ); status &= rc; rc = mMibObj->set_value( mLastUpdateTimestampOid, Counter64( time(NULL) ) ); status &= rc; #else smExtCmdMib.setCommandResult( data ); smExtCmdMib.setUpdateTimestamp( time(NULL) ); mMibObj->commitContentUpdate(); #endif return true; }