int trapapp::run() { if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { cout << "\nASNMP:ERROR:Create session failed: "<< snmp_.error_string()<< "\n"; return 1; } if (address_.get_port() == 0) address_.set_port(DEF_TRAP_PORT); target_.set_address( address_); // make a target using the address //-------[ issue the request, blocked mode ]----------------------------- cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ " TRAP GENERATOR SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; target_.get_address(address_); // target updates port used int rc; const char *name = address_.resolve_hostname(rc); cout << "Device: " << address_ << " "; cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; cout << "[ Community=" << community_.to_string() << " ]"<< endl; if (snmp_.trap( pdu_, target_) == SNMP_CLASS_SUCCESS) { cout << "Trap was written to network...\n"; } else { const char *ptr = snmp_.error_string(); cout << "ASNMP:ERROR: trap command failed reason: " << ptr << endl; } cout << "ASNMP:INFO:command completed normally.\n"<< endl; return 0; }
int wpdu::load_vbs(snmp_pdu *raw_pdu, const Pdu& pdu) { int status = 0; // load up the payload // for all Vbs in list, add them to the pdu int vb_count; Vb tempvb; Oid tempoid; SmiLPOID smioid; SmiVALUE smival; vb_count = pdu.get_vb_count(); for (int z = 0; z < vb_count; z++) { pdu.get_vb( tempvb, z); tempvb.get_oid( tempoid); smioid = tempoid.oidval(); // what are we trying to convert here (vb oid part or value part) status = convert_vb_to_smival( tempvb, &smival ); if ( status != SNMP_CLASS_SUCCESS) return status; // add the var to the raw pdu cmu_snmp::add_var(raw_pdu, smioid->ptr, (int) smioid->len, &smival); free_smival_descriptor( &smival); } return status; }
Oid agentxcpp::generate_v1_snmpTrapOID(generic_trap_t generic_trap, quint32 specific_trap) { // We need the OID of the SNMPv1 traps. These are defined here. // // First we define a "helper" OID: static const Oid snmpTraps_oid(snmpMIBObjects_oid, "5"); // // Some traps according to RFC 1907: static const Oid snmpTraps_coldStart_oid(snmpTraps_oid, "1"); static const Oid snmpTraps_warmStart_oid(snmpTraps_oid, "2"); static const Oid snmpTraps_authenticationFailure_oid(snmpTraps_oid, "5"); // // Some traps according to RFC 1573: static const Oid snmpTraps_linkDown_oid(snmpTraps_oid, "3"); static const Oid snmpTraps_linkUp_oid(snmpTraps_oid, "4"); // Finally, egpNeighborLoss. According to RC 1907 it is defined in RFC // 1213, however, the latter doesn't define it. On the other hand, // RFC 2089 defines egpNeighborLoss as 1.3.6.1.6.3.1.1.5.6, which is // snmpTraps.6 and corresponds to the comment in RFC 1907, so we use this // one: static const Oid snmpTraps_egpNeighborLoss_oid(snmpTraps_oid, "6"); // calculate the value of snmpTrapOID.0 according to RFC 1908: Oid value; switch(generic_trap) { case coldStart: value = snmpTraps_coldStart_oid; break; case warmStart: value = snmpTraps_warmStart_oid; break; case linkDown: value = snmpTraps_linkDown_oid; break; case linkUp: value = snmpTraps_linkUp_oid; break; case authenticationFailure: value = snmpTraps_authenticationFailure_oid; break; case egpNeighborLoss: value = snmpTraps_egpNeighborLoss_oid; break; case enterpriseSpecific: value = enterprises_oid; value.push_back(0); value.push_back(specific_trap); break; default: // invalid generic_trap value! throw(inval_param()); } // Create and return varbind return value; }
/** * \brief Convert the value to an OID. * * The conversion is done according to RFC 2578, * 7.7. "Mapping of the INDEX clause". The created OID * has exactly 4 subids which corresponds to the 4 * integers of the IP address. */ virtual Oid toOid() const { Oid oid; oid.push_back(v[0]); oid.push_back(v[1]); oid.push_back(v[2]); oid.push_back(v[3]); return oid; }
//==============[ operator<(Oid &x,Oid &y) ]============================= // less than < overloaded int operator<(const Oid &lhs, const Oid &rhs) { int result; // call nCompare with the current // Oidx, Oidy and len of Oidx if((result = lhs.nCompare(rhs.len(), rhs))<0) return 1; if (result > 0) return 0; // if here, equivalent substrings, call the shorter one < return (lhs.len() < rhs.len()); }
MibIter::MibIter(Snmp* snmp, Pdu& pdu, UdpTarget *target): snmp_(snmp), target_(target), pdu_(pdu), first_(0), valid_(0) { // verify we have a valid oid to begin iterating with Oid oid; Vb vb; pdu.get_vb(vb, 0); vb.get_oid(oid); if (oid.valid()) valid_ = 1; }
int insertOid(Oid oid) { sqlite3_stmt * stmt; std::string time = currentDateTime(); int rc = sqlite3_prepare_v2(db, sql_insert.c_str(), -1, &stmt, NULL); if (rc != SQLITE_OK) { sqlite3_finalize(stmt); return rc; } // (\'device_id\', \'oid\', \'translate\', \'active\', \'created_at\', \'updated_at\') rc |= sqlite3_bind_int(stmt, 1, oid.getDeviceId()); rc |= sqlite3_bind_text(stmt, 2, oid.getOid().c_str(), oid.getOid().length(), SQLITE_STATIC); rc |= sqlite3_bind_text(stmt, 3, oid.getTranslate().c_str(), oid.getTranslate().length(), SQLITE_STATIC); rc |= sqlite3_bind_int(stmt, 4, oid.getPingRequest()); rc |= sqlite3_bind_text(stmt, 5, oid.getActive() ? "t" : "f", 1, SQLITE_STATIC); rc |= sqlite3_bind_text(stmt, 6, time.c_str(), time.length(), SQLITE_STATIC); rc |= sqlite3_bind_text(stmt, 7, time.c_str(), time.length(), SQLITE_STATIC); if (rc != SQLITE_OK) { sqlite3_finalize(stmt); // formatting problems and SQL return rc; } rc = sqlite3_step(stmt); sqlite3_finalize(stmt); return rc; }
int getapp::run() { //----------[ create a ASNMP session ]----------------------------------- if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { cout << "\nASNMP:ERROR:Create session failed: "<< snmp_.error_string()<< "\n"; return 1; } //--------[ build up ASNMP object needed ]------------------------------- if (address_.get_port() == 0) address_.set_port(DEF_AGENT_PORT); target_.set_address( address_); // make a target using the address //-------[ issue the request, blocked mode ]----------------------------- cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ " GET SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; target_.get_address(address_); // target updates port used int rc; const char *name = address_.resolve_hostname(rc); cout << "Device: " << address_ << " "; //FUZZ: disable check_for_lack_ACE_OS cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; //FUZZ: enable check_for_lack_ACE_OS cout << "[ Retries=" << target_.get_retry() << " \ Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ community_.to_string() << " ]"<< endl; if (snmp_.get( pdu_, target_) == SNMP_CLASS_SUCCESS) { Vb vb; // check to see if there are any errors if (pdu_.get_error_status()) { cout << "ERROR: agent replied as follows\n"; cout << pdu_.agent_error_reason() << endl; } else { VbIter iter(pdu_); while (iter.next(vb)) { cout << "\tOid = " << vb.to_string_oid() << "\n"; cout << "\tValue = " << vb.to_string_value() << "\n"; } } } else { const char *ptr = snmp_.error_string(); cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; } cout << "\nASNMP:INFO: command completed normally.\n"<< endl; return 0; }
Oid OctetStringVariable::toOid() const { // There are fixed length string, but don't support them currently. bool fixedLength = false; Oid oid; // Store string length if needed if(!fixedLength) { oid.push_back(v.size()); } // Store string for(binary::const_iterator i = v.begin(); i != v.end(); ++i) { oid.push_back(*i); } return oid; }
int walkapp::run() { //----------[ create a ASNMP session ]----------------------------------- if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { cout << "\nASNMP:ERROR:Create session failed: "<< snmp_.error_string()<< "\n"; return 1; } //--------[ build up ASNMP object needed ]------------------------------- if (address_.get_port() == 0) address_.set_port(DEF_AGENT_PORT); target_.set_address( address_); // make a target using the address //-------[ issue the request, blocked mode ]----------------------------- cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ " WALK SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; target_.get_address(address_); // target updates port used int rc; const char *name = address_.resolve_hostname(rc); cout << "Device: " << address_ << " "; //FUZZ: disable check_for_lack_ACE_OS cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; //FUZZ: enable check_for_lack_ACE_OS cout << "[ Retries=" << target_.get_retry() << " \ Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ community_.to_string() << " ]"<< endl; MibIter iter(&snmp_, pdu_, &target_); char *err_str = 0; Vb vb; unsigned ctr = 0; while (iter.next(vb, err_str)) { cout << "\tOid = " << vb.to_string_oid() << "\n"; cout << "\tValue = " << vb.to_string_value() << "\n"; ctr++; } if (!err_str) { cout << "ERROR: walk: " << err_str << endl; return 0; } cout << "ASNMP:INFO:command completed normally. ACE Rocks...\n"<< endl; return 0; }
int getapp::run() { //----------[ create a ASNMP session ]----------------------------------- if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { cout << "\nASNMP:ERROR:Create session failed: "<< snmp_.error_string()<< "\n"; return 1; } //--------[ build up ASNMP object needed ]------------------------------- if (address_.get_port() == 0) address_.set_port(DEF_AGENT_PORT); target_.set_address( address_); // make a target using the address //-------[ issue the request, blocked mode ]----------------------------- cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ " GET SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; target_.get_address(address_); // target updates port used int rc; const char *name = address_.resolve_hostname(rc); cout << "Device: " << address_ << " "; //FUZZ: disable check_for_lack_ACE_OS cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; //FUZZ: enable check_for_lack_ACE_OS cout << "[ Retries=" << target_.get_retry() << " \ Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ community_.to_string() << " ]"<< endl; if (snmp_.get( pdu_, target_, this) != SNMP_CLASS_SUCCESS) { const char *ptr = snmp_.error_string(); cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; } else { ACE_Reactor::instance()->run_reactor_event_loop(); } return 0; }
void MainWindow::async_callback(int reason, Snmp * /*snmp*/, Pdu &pdu, SnmpTarget &target) { Vb nextVb; int pdu_error; QString prefix_text; QString notify_text; push_button_get_next->setEnabled(true); // What is the reason for this callback? if (reason == SNMP_CLASS_NOTIFICATION) { prefix_text = "Trap: "; // get the notify id for traps Oid id; pdu.get_notify_id(id); notify_text = QString(" ID: %1 Type %2 -- ").arg(id.get_printable()) .arg(pdu.get_type()); } else if (reason == SNMP_CLASS_ASYNC_RESPONSE) { prefix_text = "Response "; } else if (reason == SNMP_CLASS_TIMEOUT) { prefix_text = "Timeout "; } else { QString err = QString("\nDid not receive async response/trap: (%1) %2\n") .arg(reason).arg(Snmp::error_msg(reason)); text_edit_output->append(err); } // Look at the error status of the Pdu pdu_error = pdu.get_error_status(); if (pdu_error) { QString err = "\nResponse contains error:\n"; err += Snmp::error_msg(pdu_error); text_edit_output->append(err); return; } // The Pdu must contain at least one Vb if (pdu.get_vb_count() == 0) { QString err = "\nPdu is empty\n"; text_edit_output->append(err); return; } for (int i=0; i<pdu.get_vb_count(); i++) { // Get the Vb of the Pdu pdu.get_vb(nextVb, i); // Get Oid and value from the Vb and display it line_edit_obj_id->setText(nextVb.get_printable_oid()); line_edit_value->setText(nextVb.get_printable_value()); text_edit_output->append(prefix_text + target.get_address().get_printable() + " -- " + notify_text + line_edit_obj_id->text() + " = " + line_edit_value->text() + "\n"); } // If we received a inform pdu, we have to send a response if (pdu.get_type() == sNMP_PDU_INFORM) { text_edit_output->append("Sending response to inform.\n"); // just change the value of the first vb pdu.get_vb(nextVb, 0); nextVb.set_value("This is the response."); pdu.set_vb(nextVb, 0); snmp->response(pdu, target); } }
bool SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName, const uint8_t* buf, size_t size, const std::string& passwordStr) { using namespace CryptoPP; Oid pbes2Id; Oid pbkdf2Id; SecByteBlock saltBlock; uint32_t iterationCount; Oid pbes2encsId; SecByteBlock ivBlock; SecByteBlock encryptedDataBlock; try { // decode some decoding processes are not necessary for now, // because we assume only one encryption scheme. StringSource source(buf, size, true); // EncryptedPrivateKeyInfo ::= SEQUENCE { // encryptionAlgorithm EncryptionAlgorithmIdentifier, // encryptedData OCTET STRING } BERSequenceDecoder encryptedPrivateKeyInfo(source); { // EncryptionAlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER {{PBES2-id}}, // parameters SEQUENCE {{PBES2-params}} } BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo); { pbes2Id.decode(encryptionAlgorithm); // PBES2-params ::= SEQUENCE { // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} } BERSequenceDecoder pbes2Params(encryptionAlgorithm); { // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER {{PBKDF2-id}}, // parameters SEQUENCE {{PBKDF2-params}} } BERSequenceDecoder pbes2KDFs(pbes2Params); { pbkdf2Id.decode(pbes2KDFs); // AlgorithmIdentifier ::= SEQUENCE { // salt OCTET STRING, // iterationCount INTEGER (1..MAX), // keyLength INTEGER (1..MAX) OPTIONAL, // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 } BERSequenceDecoder pbkdf2Params(pbes2KDFs); { BERDecodeOctetString(pbkdf2Params, saltBlock); BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER); } pbkdf2Params.MessageEnd(); } pbes2KDFs.MessageEnd(); // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}}, // parameters OCTET STRING} {{iv}} } BERSequenceDecoder pbes2Encs(pbes2Params); { pbes2encsId.decode(pbes2Encs); BERDecodeOctetString(pbes2Encs, ivBlock); } pbes2Encs.MessageEnd(); } pbes2Params.MessageEnd(); } encryptionAlgorithm.MessageEnd(); BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock); } encryptedPrivateKeyInfo.MessageEnd(); } catch (const CryptoPP::Exception& e) { return false; } PKCS5_PBKDF2_HMAC<SHA1> keyGenerator; size_t derivedLen = 24; //For DES-EDE3-CBC-PAD byte derived[24] = {0}; byte purpose = 0; try { keyGenerator.DeriveKey(derived, derivedLen, purpose, reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(), saltBlock.BytePtr(), saltBlock.size(), iterationCount); } catch (const CryptoPP::Exception& e) { return false; } //decrypt CBC_Mode< DES_EDE3 >::Decryption d; d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr()); OBufferStream privateKeyOs; try { StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true, new StreamTransformationFilter(d, new FileSink(privateKeyOs))); } catch (const CryptoPP::Exception& e) { return false; } if (!importPrivateKeyPkcs8IntoTpm(keyName, privateKeyOs.buf()->buf(), privateKeyOs.buf()->size())) return false; // determine key type StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true); KeyType publicKeyType = KeyType::NONE; SecByteBlock rawKeyBits; // PrivateKeyInfo ::= SEQUENCE { // INTEGER, // SEQUENCE, // OCTECT STRING} BERSequenceDecoder privateKeyInfo(privateKeySource); { uint32_t versionNum; BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER); BERSequenceDecoder sequenceDecoder(privateKeyInfo); { Oid keyTypeOid; keyTypeOid.decode(sequenceDecoder); if (keyTypeOid == oid::RSA) publicKeyType = KeyType::RSA; else if (keyTypeOid == oid::ECDSA) publicKeyType = KeyType::EC; else return false; // Unsupported key type; } } // derive public key OBufferStream publicKeyOs; try { switch (publicKeyType) { case KeyType::RSA: { RSA::PrivateKey privateKey; privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref()); RSAFunction publicKey(privateKey); FileSink publicKeySink(publicKeyOs); publicKey.DEREncode(publicKeySink); publicKeySink.MessageEnd(); break; } case KeyType::EC: { ECDSA<ECP, SHA256>::PrivateKey privateKey; privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref()); ECDSA<ECP, SHA256>::PublicKey publicKey; privateKey.MakePublicKey(publicKey); publicKey.AccessGroupParameters().SetEncodeAsOID(true); FileSink publicKeySink(publicKeyOs); publicKey.DEREncode(publicKeySink); publicKeySink.MessageEnd(); break; } default: return false; } } catch (const CryptoPP::Exception& e) { return false; } if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size())) return false; return true; }
int wpdu::restore_vbs(Pdu& pdu, const snmp_pdu *raw_pdu) const { Vb tempvb; Oid tempoid; struct variable_list *vp; for(vp = raw_pdu->variables; vp; vp = vp->next_variable) { // extract the oid portion tempoid.set_data( (unsigned long *)vp->name, ( unsigned int) vp->name_length); tempvb.set_oid( tempoid); // extract the value portion switch(vp->type) { // octet string case sNMP_SYNTAX_OCTETS: case sNMP_SYNTAX_OPAQUE: { OctetStr octets( (char *) vp->val.string, (long) vp->val_len); tempvb.set_value( octets); } break; // object id case sNMP_SYNTAX_OID: { Oid oid( (unsigned long*) vp->val.objid, (int) vp->val_len); tempvb.set_value( oid); } break; // timeticks case sNMP_SYNTAX_TIMETICKS: { TimeTicks timeticks( (unsigned long) *(vp->val.integer)); tempvb.set_value( timeticks); } break; // Gauge32 case sNMP_SYNTAX_GAUGE32: { Gauge32 gauge32( (unsigned long) *(vp->val.integer)); tempvb.set_value( gauge32); } break; // 32 bit counter case sNMP_SYNTAX_CNTR32: { Counter32 counter32( (unsigned long) *(vp->val.integer)); tempvb.set_value( counter32); } break; // ip address case sNMP_SYNTAX_IPADDR: { char buffer[20]; ACE_OS::sprintf( buffer,"%d.%d.%d.%d", vp->val.string[0], vp->val.string[1], vp->val.string[2], vp->val.string[3]); IpAddress ipaddress( buffer); tempvb.set_value( ipaddress); } break; // 32 bit integer case sNMP_SYNTAX_INT: { SnmpInt32 int32( (long) *(vp->val.integer)); tempvb.set_value( int32); } break; // 32 bit unsigned integer case sNMP_SYNTAX_UINT32: { SnmpUInt32 uint32( (unsigned long) *(vp->val.integer)); tempvb.set_value( uint32); } break; // v2 counter 64's case sNMP_SYNTAX_CNTR64: break; case sNMP_SYNTAX_NULL: tempvb.set_null(); break; // v2 vb exceptions case sNMP_SYNTAX_NOSUCHOBJECT: case sNMP_SYNTAX_NOSUCHINSTANCE: case sNMP_SYNTAX_ENDOFMIBVIEW: set_exception_status( &tempvb, vp->type); break; default: tempvb.set_null(); } // end switch // append the vb to the pdu pdu += tempvb; } return 0; }
int wpdu::convert_vb_to_smival( Vb &tempvb, SmiVALUE *smival ) { smival->syntax = tempvb.get_syntax(); switch ( smival->syntax ) { case sNMP_SYNTAX_NULL: break; // case sNMP_SYNTAX_INT32: case sNMP_SYNTAX_INT: { SnmpInt32 tmp; tempvb.get_value(tmp); smival->value.sNumber = tmp; } break; // case sNMP_SYNTAX_UINT32: case sNMP_SYNTAX_GAUGE32: case sNMP_SYNTAX_CNTR32: case sNMP_SYNTAX_TIMETICKS: { SnmpUInt32 tmp; tempvb.get_value(tmp); smival->value.uNumber = tmp; } break; // case Counter64 case sNMP_SYNTAX_CNTR64: { Counter64 c64; tempvb.get_value(c64); smival->value.hNumber.hipart = c64.high(); smival->value.hNumber.lopart = c64.low(); } break; // OID syntax case sNMP_SYNTAX_OID: { Oid tmpoid; tmpoid.oidval(); tempvb.get_value(tmpoid); SmiLPOID smi = tmpoid.oidval(); smival->value.oid.len = tmpoid.length(); ACE_NEW_RETURN(smival->value.oid.ptr, SmiUINT32 [smival->value.oid.len], 1); ACE_OS::memcpy(smival->value.oid.ptr, smi->ptr, smival->value.oid.len *sizeof(SmiUINT32)); } break; case sNMP_SYNTAX_BITS: case sNMP_SYNTAX_OCTETS: case sNMP_SYNTAX_IPADDR: { OctetStr os; tempvb.get_value(os); smival->value.string.ptr = 0; smival->value.string.len = os.length(); if ( smival->value.string.len > 0 ) { ACE_NEW_RETURN(smival->value.string.ptr, SmiBYTE [smival->value.string.len], 1); if ( smival->value.string.ptr ) { for (int i=0; i<(int) smival->value.string.len ; i++) smival->value.string.ptr[i] = os[i]; } else { smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival return SNMP_CLASS_RESOURCE_UNAVAIL; } } } break; default: ACE_DEBUG((LM_DEBUG, "wpdu::convert_vb_to_smival did not convert vb\n")); // ACE_ASSERT(0); } // switch return 0; }
int SnmpMessage::load(const Pdu &cpdu, const OctetStr &community, const snmp_version version, const OctetStr* engine_id, const OctetStr* security_name, const int security_model) { int status; const Pdu *pdu = &cpdu; Pdu temppdu; // make sure pdu is valid if ( !pdu->valid()) return SNMP_CLASS_INVALID_PDU; // create a raw pdu snmp_pdu *raw_pdu; raw_pdu = snmp_pdu_create( (int) pdu->get_type()); Oid enterprise; // load it up raw_pdu->reqid = pdu->get_request_id(); #ifdef _SNMPv3 raw_pdu->msgid = pdu->get_message_id(); #endif raw_pdu->errstat= (unsigned long) pdu->get_error_status(); raw_pdu->errindex= (unsigned long) pdu->get_error_index(); // if its a V1 trap then load up other values // for v2, use normal pdu format if (raw_pdu->command == sNMP_PDU_V1TRAP) { // DON'T forget about the v1 trap agent address (changed by Frank Fock) GenAddress gen_addr; IpAddress ip_addr; int addr_set = FALSE; if (pdu->get_v1_trap_address(gen_addr)) { /* User did set the v1 trap address */ if ((gen_addr.get_type() != Address::type_ip) && (gen_addr.get_type() != Address::type_udp) ) { LOG_BEGIN(ERROR_LOG | 4); LOG("SNMPMessage: Bad v1 trap address type in pdu"); LOG(gen_addr.get_type()); LOG_END; snmp_free_pdu( raw_pdu); return SNMP_CLASS_INVALID_PDU; } ip_addr = gen_addr; if (!ip_addr.valid()) { LOG_BEGIN(ERROR_LOG | 1); LOG("SNMPMessage: Copied v1 trap address not valid"); LOG_END; snmp_free_pdu( raw_pdu); return SNMP_CLASS_RESOURCE_UNAVAIL; } addr_set = TRUE; } else { /* User did not set the v1 trap address */ char addrString[256]; if (gethostname(addrString, 255) == 0) { ip_addr = addrString; addr_set = TRUE; } } struct sockaddr_in agent_addr; // agent address socket struct // prepare the agent address memset(&agent_addr, 0, sizeof(agent_addr)); agent_addr.sin_family = AF_INET; if (addr_set) { agent_addr.sin_addr.s_addr = inet_addr(((IpAddress &)ip_addr).IpAddress::get_printable()); LOG_BEGIN(INFO_LOG | 7); LOG("SNMPMessage: Setting v1 trap address"); LOG(((IpAddress &)ip_addr).IpAddress::get_printable()); LOG_END; } raw_pdu->agent_addr = agent_addr; //-----[ compute generic trap value ]------------------------------- // determine the generic value // 0 - cold start // 1 - warm start // 2 - link down // 3 - link up // 4 - authentication failure // 5 - egpneighborloss // 6 - enterprise specific Oid trapid; pdu->get_notify_id( trapid); if ( !trapid.valid() || trapid.len() < 2 ) { snmp_free_pdu( raw_pdu); return SNMP_CLASS_INVALID_NOTIFYID; } raw_pdu->specific_type=0; if ( trapid == coldStart) raw_pdu->trap_type = 0; // cold start else if ( trapid == warmStart) raw_pdu->trap_type = 1; // warm start else if( trapid == linkDown) raw_pdu->trap_type = 2; // link down else if ( trapid == linkUp) raw_pdu->trap_type = 3; // link up else if ( trapid == authenticationFailure ) raw_pdu->trap_type = 4; // authentication failure else if ( trapid == egpNeighborLoss) raw_pdu->trap_type = 5; // egp neighbor loss else { raw_pdu->trap_type = 6; // enterprise specific // last oid subid is the specific value // if 2nd to last subid is "0", remove it // enterprise is always the notify oid prefix raw_pdu->specific_type = (int) trapid[(int) (trapid.len()-1)]; trapid.trim(1); if ( trapid[(int)(trapid.len()-1)] == 0 ) trapid.trim(1); enterprise = trapid; } if ( raw_pdu->trap_type !=6) pdu->get_notify_enterprise( enterprise); if ( enterprise.len() >0) { // note!! // these are hooks into an SNMP++ oid // and therefor the raw_pdu enterprise // should not free them. null them out!! SmiLPOID rawOid; rawOid = enterprise.oidval(); raw_pdu->enterprise = rawOid->ptr; raw_pdu->enterprise_length = (int) rawOid->len; } // timestamp TimeTicks timestamp; pdu->get_notify_timestamp( timestamp); raw_pdu->time = ( unsigned long) timestamp; } // if its a v2 trap then we need to make a few adjustments // vb #1 is the timestamp // vb #2 is the id, represented as an Oid if (( raw_pdu->command == sNMP_PDU_TRAP) || ( raw_pdu->command == sNMP_PDU_INFORM)) { Vb tempvb; temppdu = *pdu; temppdu.trim(temppdu.get_vb_count()); // vb #1 is the timestamp TimeTicks timestamp; tempvb.set_oid(SNMP_MSG_OID_SYSUPTIME); // sysuptime pdu->get_notify_timestamp( timestamp); tempvb.set_value ( timestamp); temppdu += tempvb; // vb #2 is the id Oid trapid; tempvb.set_oid(SNMP_MSG_OID_TRAPID); pdu->get_notify_id( trapid); tempvb.set_value( trapid); temppdu += tempvb; // append the remaining vbs for (int z=0; z<pdu->get_vb_count(); z++) { pdu->get_vb( tempvb,z); temppdu += tempvb; } pdu = &temppdu; // reassign the pdu to the temp one } // load up the payload // for all Vbs in list, add them to the pdu int vb_count; Vb tempvb; Oid tempoid; SmiLPOID smioid; SmiVALUE smival; vb_count = pdu->get_vb_count(); for (int z=0;z<vb_count;z++) { pdu->get_vb( tempvb,z); tempvb.get_oid( tempoid); smioid = tempoid.oidval(); // clear the value portion, in case its // not already been done so by the app writer // only do it in the case its a get,next or bulk if ((raw_pdu->command == sNMP_PDU_GET) || (raw_pdu->command == sNMP_PDU_GETNEXT) || (raw_pdu->command == sNMP_PDU_GETBULK)) tempvb.set_null(); status = convertVbToSmival( tempvb, &smival ); if ( status != SNMP_CLASS_SUCCESS) { snmp_free_pdu( raw_pdu); return status; } // add the vb to the raw pdu snmp_add_var( raw_pdu, smioid->ptr, (int) smioid->len, &smival); freeSmivalDescriptor( &smival); } // ASN1 encode the pdu #ifdef _SNMPv3 if (version == version3) { if ((!engine_id) || (!security_name)) { LOG_BEGIN(ERROR_LOG | 4); LOG("SNMPMessage: Need security name and engine id for v3 message"); LOG_END; // prevention of SNMP++ Enterprise Oid death if ( enterprise.len() >0) { raw_pdu->enterprise = 0; raw_pdu->enterprise_length=0; } snmp_free_pdu( raw_pdu); return SNMP_CLASS_INVALID_TARGET; } status = v3MP::I->snmp_build(raw_pdu, databuff, (int *)&bufflen, *engine_id, *security_name, security_model, pdu->get_security_level(), pdu->get_context_engine_id(), pdu->get_context_name()); if (status == SNMPv3_MP_OK) { if ((pdu->get_type() == sNMP_PDU_RESPONSE) && ((int)pdu->get_maxsize_scopedpdu() < pdu->get_asn1_length())) { LOG_BEGIN(ERROR_LOG | 1); LOG("SNMPMessage: *BUG*: Serialized response pdu is too big (len) (max)"); LOG(pdu->get_asn1_length()); LOG(pdu->get_maxsize_scopedpdu()); LOG_END; // prevention of SNMP++ Enterprise Oid death if ( enterprise.len() >0) { raw_pdu->enterprise = 0; raw_pdu->enterprise_length=0; } snmp_free_pdu( raw_pdu); return SNMP_ERROR_TOO_BIG; } } } else #endif status = snmp_build( raw_pdu, databuff, (int *) &bufflen, version, community.data(), (int) community.len()); LOG_BEGIN(DEBUG_LOG | 4); LOG("SNMPMessage: return value for build message"); LOG(status); LOG_END; if ((status != 0) #ifdef _SNMPv3 && ((version != version3) || (status != SNMPv3_MP_OK)) #endif ) { valid_flag = false; // prevention of SNMP++ Enterprise Oid death if ( enterprise.len() >0) { raw_pdu->enterprise = 0; raw_pdu->enterprise_length=0; } snmp_free_pdu( raw_pdu); #ifdef _SNMPv3 if (version == version3) return status; else #endif // NOTE: This is an assumption - in most cases during normal // operation the reason is a tooBig - another could be a // damaged variable binding. return SNMP_ERROR_TOO_BIG; } valid_flag = true; // prevention of SNMP++ Enterprise Oid death if ( enterprise.len() >0) { raw_pdu->enterprise = 0; raw_pdu->enterprise_length=0; } snmp_free_pdu( raw_pdu); return SNMP_CLASS_SUCCESS; }
/** * \brief Convert the value to an OID. * * The conversion is done according to RFC 2578, * 7.7. "Mapping of the INDEX clause". The value is * converted to an Oid with a single subid. * * This method should not be overridden. * * \note If a TIMETICK is used in an INDEX clause, the * value 0 should be avoided according to * RFC 2578, 7.7. "Mapping of the INDEX clause". */ virtual Oid toOid() const { Oid oid; oid.push_back(v); return oid; }
// 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; }
set::set(int argc, char *argv[]): valid_(0) { Vb vb; // construct a Vb object Oid req; if ( argc < 2) return; target_.get_write_community(community_); address_ = argv[argc - 1]; if ( !address_.valid()) { cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ << argv[argc] << "\n"; return; } ACE_Get_Opt get_opt (argc, argv, "o:c:r:t:I:U:C:G:T:O:S:P:"); for (int c; (c = get_opt ()) != -1; ) switch (c) { case 'o': req = get_opt.optarg; if (req.valid() == 0) cout << "ERROR: oid value: " <<get_opt.optarg \ << "is not valid. using default.\n"; break; case 'c': community_ = get_opt.optarg; target_.set_write_community(community_); break; case 'r': target_.set_retry(ACE_OS::atoi (get_opt.optarg)); break; case 't': target_.set_timeout(ACE_OS::atoi (get_opt.optarg)); break; case 'I': // Integer32 { SnmpInt32 o(ACE_OS::atoi(get_opt.optarg)); vb.set_value(o); pdu_ += vb; } break; case 'U': // Unsigned32 { SnmpUInt32 o(ACE_OS::atoi(get_opt.optarg)); vb.set_value(o); pdu_ += vb; } break; case 'C': // Counter32 { Counter32 o(ACE_OS::atoi(get_opt.optarg)); vb.set_value(o); pdu_ += vb; } break; case 'G': // Gauge32 { Gauge32 o(ACE_OS::atoi(get_opt.optarg)); vb.set_value(o); pdu_ += vb; } break; case 'T': // TimeTicks { TimeTicks o(ACE_OS::atoi(get_opt.optarg)); vb.set_value(o); pdu_ += vb; } break; case 'O': // Oid as a variable identifier { oid_ = get_opt.optarg; vb.set_oid(oid_); // when value is set, pdu updated } break; case 'S': // Octet String { OctetStr o(get_opt.optarg); vb.set_value(o); // set the Oid portion of the Vb pdu_ += vb; } break; case 'P': // Oid String as a value { Oid o(get_opt.optarg); vb.set_value(o); // set the Oid portion of the Vb pdu_ += vb; } break; default: break; } // if user didn't set anything use defaults if (pdu_.get_vb_count() == 0) { Oid def_oid("1.3.6.1.2.1.1.4.0"); // defualt is sysName OctetStr def_value("sysName.0 updated by ASNMP set command"); vb.set_oid(def_oid); vb.set_value(def_value); pdu_ += vb; cout << "INFO: using defaults, setting sysName to : " << \ def_value.to_string() << endl; } valid_ = 1; }
bool Validator::verifySignature(const uint8_t* buf, const size_t size, const Signature& sig, const v1::PublicKey& key) { try { using namespace CryptoPP; switch (sig.getType()) { case tlv::SignatureSha256WithRsa: { if (key.getKeyType() != KeyType::RSA) return false; RSA::PublicKey publicKey; ByteQueue queue; queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size()); publicKey.Load(queue); RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey); return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size()); } case tlv::SignatureSha256WithEcdsa: { if (key.getKeyType() != KeyType::EC) return false; ECDSA<ECP, SHA256>::PublicKey publicKey; ByteQueue queue; queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size()); publicKey.Load(queue); ECDSA<ECP, SHA256>::Verifier verifier(publicKey); uint32_t length = 0; StringSource src(key.get().buf(), key.get().size(), true); BERSequenceDecoder subjectPublicKeyInfo(src); { BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo); { Oid algorithm; algorithm.decode(algorithmInfo); Oid curveId; curveId.decode(algorithmInfo); if (curveId == SECP256R1) length = 256; else if (curveId == SECP384R1) length = 384; else return false; } } switch (length) { case 256: { uint8_t buffer[64]; size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363, sig.getValue().value(), sig.getValue().value_size(), DSA_DER); return verifier.VerifyMessage(buf, size, buffer, usedSize); } case 384: { uint8_t buffer[96]; size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363, sig.getValue().value(), sig.getValue().value_size(), DSA_DER); return verifier.VerifyMessage(buf, size, buffer, usedSize); } default: return false; } } default: // Unsupported sig type return false; } } catch (const CryptoPP::Exception& e) { return false; } }
// unload the data into SNMP++ objects int SnmpMessage::unload(Pdu &pdu, // Pdu object OctetStr &community, // community object snmp_version &version, // SNMP version # OctetStr *engine_id, // optional v3 OctetStr *security_name, // optional v3 long int *security_model, UdpAddress *from_addr, Snmp *snmp_session) { pdu.clear(); if (!valid_flag) return SNMP_CLASS_INVALID; snmp_pdu *raw_pdu; raw_pdu = snmp_pdu_create(0); // do a "snmp_free_pdu( raw_pdu)" before return int status; #ifdef _SNMPv3 OctetStr context_engine_id; OctetStr context_name; long int security_level = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; if ((security_model) && (security_name) && (engine_id) && (snmp_session)) { status = v3MP::I->snmp_parse(snmp_session, raw_pdu, databuff, (int)bufflen, *engine_id, *security_name, context_engine_id, context_name, security_level, *security_model, version, *from_addr); if (status != SNMPv3_MP_OK) { pdu.set_request_id( raw_pdu->reqid); pdu.set_type( raw_pdu->command); snmp_free_pdu( raw_pdu); return status; } pdu.set_context_engine_id(context_engine_id); pdu.set_context_name(context_name); pdu.set_security_level(security_level); pdu.set_message_id(raw_pdu->msgid); pdu.set_maxsize_scopedpdu(raw_pdu->maxsize_scopedpdu); } else { #endif unsigned char community_name[MAX_LEN_COMMUNITY + 1]; int community_len = MAX_LEN_COMMUNITY + 1; status = snmp_parse(raw_pdu, databuff, (int) bufflen, community_name, community_len, version); if (status != SNMP_CLASS_SUCCESS) { snmp_free_pdu(raw_pdu); return status; } community.set_data( community_name, community_len); #ifdef _SNMPv3 } #endif // load up the SNMP++ variables pdu.set_request_id(raw_pdu->reqid); pdu.set_error_status((int) raw_pdu->errstat); pdu.set_error_index((int) raw_pdu->errindex); pdu.set_type( raw_pdu->command); // deal with traps a little different if ( raw_pdu->command == sNMP_PDU_V1TRAP) { // timestamp TimeTicks timestamp; timestamp = raw_pdu->time; pdu.set_notify_timestamp( timestamp); // set the agent address IpAddress agent_addr(inet_ntoa(raw_pdu->agent_addr.sin_addr)); if (agent_addr != "0.0.0.0") { pdu.set_v1_trap_address(agent_addr); LOG_BEGIN(DEBUG_LOG | 4); LOG("SNMPMessage: Trap address of received v1 trap"); LOG(agent_addr.get_printable()); LOG_END; } // set enterprise, notifyid Oid enterprise; if (raw_pdu->enterprise_length >0) { for (int i=0; i< raw_pdu->enterprise_length; i++) { enterprise += (int) (raw_pdu->enterprise[i]); } pdu.set_notify_enterprise(enterprise); } switch (raw_pdu->trap_type) { case 0: pdu.set_notify_id(coldStart); break; case 1: pdu.set_notify_id(warmStart); break; case 2: pdu.set_notify_id(linkDown); break; case 3: pdu.set_notify_id(linkUp); break; case 4: pdu.set_notify_id(authenticationFailure); break; case 5: pdu.set_notify_id(egpNeighborLoss); break; case 6: { // enterprise specific // base id + specific # Oid eOid = enterprise; eOid += 0ul; eOid += raw_pdu->specific_type; pdu.set_notify_id( eOid); break; } default: { LOG_BEGIN(WARNING_LOG | 3); LOG("SNMPMessage: Received trap with illegal trap type"); LOG(raw_pdu->trap_type); LOG_END; } } } // vbs Vb tempvb; Oid tempoid; struct variable_list *vp; int vb_nr = 1; for(vp = raw_pdu->variables; vp; vp = vp->next_variable, vb_nr++) { // extract the oid portion tempoid.set_data( (unsigned long *)vp->name, ( unsigned int) vp->name_length); tempvb.set_oid( tempoid); // extract the value portion switch(vp->type){ // octet string case sNMP_SYNTAX_OCTETS: { OctetStr octets( (unsigned char *) vp->val.string, (unsigned long) vp->val_len); tempvb.set_value( octets); } break; case sNMP_SYNTAX_OPAQUE: { OpaqueStr octets( (unsigned char *) vp->val.string, (unsigned long) vp->val_len); tempvb.set_value( octets); } break; // object id case sNMP_SYNTAX_OID: { Oid oid( (unsigned long*) vp->val.objid, (int) vp->val_len); tempvb.set_value( oid); if ((vb_nr == 2) && ((raw_pdu->command == sNMP_PDU_TRAP) || (raw_pdu->command == sNMP_PDU_INFORM)) && (tempoid == SNMP_MSG_OID_TRAPID)) { // set notify_id pdu.set_notify_id(oid); continue; // don't add vb to pdu } } break; // timeticks case sNMP_SYNTAX_TIMETICKS: { TimeTicks timeticks( (unsigned long) *(vp->val.integer)); tempvb.set_value( timeticks); if ((vb_nr == 1) && ((raw_pdu->command == sNMP_PDU_TRAP) || (raw_pdu->command == sNMP_PDU_INFORM)) && (tempoid == SNMP_MSG_OID_SYSUPTIME)) { // set notify_timestamp pdu.set_notify_timestamp( timeticks); continue; // don't add vb to pdu } } break; // 32 bit counter case sNMP_SYNTAX_CNTR32: { Counter32 counter32( (unsigned long) *(vp->val.integer)); tempvb.set_value( counter32); } break; // 32 bit gauge case sNMP_SYNTAX_GAUGE32: { Gauge32 gauge32( (unsigned long) *(vp->val.integer)); tempvb.set_value( gauge32); } break; // ip address case sNMP_SYNTAX_IPADDR: { char buffer[42]; if (vp->val_len == 16) sprintf( buffer, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:" "%02x%02x:%02x%02x:%02x%02x:%02x%02x", vp->val.string[ 0], vp->val.string[ 1], vp->val.string[ 2], vp->val.string[ 3], vp->val.string[ 4], vp->val.string[ 5], vp->val.string[ 6], vp->val.string[ 7], vp->val.string[ 8], vp->val.string[ 9], vp->val.string[10], vp->val.string[11], vp->val.string[12], vp->val.string[13], vp->val.string[14], vp->val.string[15]); else sprintf( buffer,"%d.%d.%d.%d", vp->val.string[0], vp->val.string[1], vp->val.string[2], vp->val.string[3]); IpAddress ipaddress( buffer); tempvb.set_value( ipaddress); } break; // 32 bit integer case sNMP_SYNTAX_INT: { SnmpInt32 int32( (long) *(vp->val.integer)); tempvb.set_value( int32); } break; // 32 bit unsigned integer /* Not distinguishable from Gauge32 case sNMP_SYNTAX_UINT32: { SnmpUInt32 uint32( (unsigned long) *(vp->val.integer)); tempvb.set_value( uint32); } break; */ // v2 counter 64's case sNMP_SYNTAX_CNTR64: { // Frank Fock (was empty before) Counter64 c64(((counter64*)vp->val.counter64)->high, ((counter64*)vp->val.counter64)->low); tempvb.set_value( c64); break; } case sNMP_SYNTAX_NULL: tempvb.set_null(); break; // v2 vb exceptions case sNMP_SYNTAX_NOSUCHOBJECT: case sNMP_SYNTAX_NOSUCHINSTANCE: case sNMP_SYNTAX_ENDOFMIBVIEW: tempvb.set_exception_status(vp->type); break; default: tempvb.set_null(); } // end switch // append the vb to the pdu pdu += tempvb; } snmp_free_pdu( raw_pdu); return SNMP_CLASS_SUCCESS; }
//=============[ int operator == oid,oid ]================================= // equivlence operator overloaded int operator==(const Oid &lhs, const Oid &rhs) { // ensure same len, then use nCompare if (rhs.len() != lhs.len()) return 0; return (lhs.nCompare(rhs.len(), rhs) == 0); }
int wpdu::set_trap_info(snmp_pdu *raw_pdu, const Pdu& pdu) const { Oid enterprise; Oid trapid; // validate caller has set this correctly pdu.get_notify_id( trapid); if ( !trapid.valid() || trapid.length() < 2 ) { cmu_snmp::free_pdu( raw_pdu); return SNMP_CLASS_INVALID_NOTIFYID; } raw_pdu->specific_type=0; // TODO: object should emit numeric instead of this kind of mess... if ( trapid == coldStart) raw_pdu->trap_type = V1_COLD_START; // cold start else if ( trapid == warmStart) raw_pdu->trap_type = V1_WARM_START; // warm start else if( trapid == linkDown) raw_pdu->trap_type = V1_LINK_DOWN; // link down else if ( trapid == linkUp) raw_pdu->trap_type = V1_LINK_UP; // link up else if ( trapid == authenticationFailure ) raw_pdu->trap_type = V1_AUTH_FAILURE; // authentication failure else if ( trapid == egpNeighborLoss) raw_pdu->trap_type = V1_EGP_NEIGHBOR_LOSS; // egp neighbor loss else { raw_pdu->trap_type = V1_ENT_SPECIFIC; // enterprise specific // last oid subid is the specific value // if 2nd to last subid is "0", remove it // enterprise is always the notify oid prefix raw_pdu->specific_type = (int) trapid[(int) (trapid.length() - 1)]; trapid.trim(1); if ( trapid[(int)(trapid.length() - 1)] == 0 ) trapid.trim(1); enterprise = trapid; } if ( raw_pdu->trap_type != V1_ENT_SPECIFIC) pdu.get_notify_enterprise( enterprise); if ( enterprise.length() > 0) { // note!! To the contrary, enterprise OID val is // copied here and raw_pdu->enterprise is freed in free_pdu // as it should be (HDN) // these are hooks into an SNMP++ oid // and therefor the raw_pdu enterprise // should not free them. null them out!! SmiLPOID rawOid; rawOid = enterprise.oidval(); // HDN - enterprise is a local object, cannot simply assign pointer //raw_pdu->enterprise = rawOid->ptr; raw_pdu->enterprise_length = (int) rawOid->len; ACE_NEW_RETURN(raw_pdu->enterprise, oid[raw_pdu->enterprise_length],-1); ACE_OS::memcpy((char *)raw_pdu->enterprise,(char *)rawOid->ptr, raw_pdu->enterprise_length * sizeof(oid)); } TimeTicks timestamp; pdu.get_notify_timestamp( timestamp); raw_pdu->time = ( unsigned long) timestamp; // HDN - set agent addr using the local hostname if possible char localHostName[MAXHOSTNAMELEN]; Snmp::get_host_name(localHostName, MAXHOSTNAMELEN); if (ACE_OS::strlen(localHostName) > 0) { GenAddress addr(localHostName); OctetStr octet; addr.to_octet(octet); ACE_OS::memcpy(&(raw_pdu->agent_addr.sin_addr), octet.data(), octet.length()); } return 0; }
//------------[ convert SNMP++ VB to WinSNMP smiVALUE ]---------------- int convertVbToSmival( const Vb &tempvb, SmiVALUE *smival ) { smival->syntax = tempvb.get_syntax(); switch ( smival->syntax ) { // case sNMP_SYNTAX_NULL case sNMP_SYNTAX_NULL: case sNMP_SYNTAX_NOSUCHOBJECT: case sNMP_SYNTAX_NOSUCHINSTANCE: case sNMP_SYNTAX_ENDOFMIBVIEW: break; // case sNMP_SYNTAX_INT32: case sNMP_SYNTAX_INT: tempvb.get_value(smival->value.sNumber); break; // case sNMP_SYNTAX_UINT32: case sNMP_SYNTAX_GAUGE32: case sNMP_SYNTAX_CNTR32: case sNMP_SYNTAX_TIMETICKS: // case sNMP_SYNTAX_UINT32: tempvb.get_value(smival->value.uNumber); break; // case Counter64 case sNMP_SYNTAX_CNTR64: { Counter64 c64; tempvb.get_value(c64); smival->value.hNumber.hipart = c64.high(); smival->value.hNumber.lopart = c64.low(); } break; case sNMP_SYNTAX_BITS: case sNMP_SYNTAX_OCTETS: case sNMP_SYNTAX_OPAQUE: case sNMP_SYNTAX_IPADDR: { OctetStr os; tempvb.get_value(os); smival->value.string.ptr = NULL; smival->value.string.len = os.len(); if ( smival->value.string.len > 0 ) { smival->value.string.ptr = (SmiLPBYTE) new unsigned char [smival->value.string.len]; if ( smival->value.string.ptr ) { for (int i=0; i<(int) smival->value.string.len ; i++) smival->value.string.ptr[i] = os[i]; } else { smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival return SNMP_CLASS_RESOURCE_UNAVAIL; } } } break; case sNMP_SYNTAX_OID: { Oid oid; tempvb.get_value(oid); smival->value.oid.ptr = NULL; smival->value.oid.len = oid.len(); if ( smival->value.oid.len > 0 ) { smival->value.oid.ptr = (SmiLPUINT32) new unsigned long [ smival->value.oid.len]; if ( smival->value.oid.ptr ) { for (int i=0; i<(int)smival->value.oid.len ; i++) smival->value.oid.ptr[i] = oid[i]; } else { smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival return SNMP_CLASS_RESOURCE_UNAVAIL; } } } break; default: return SNMP_CLASS_INTERNAL_ERROR; } return SNMP_CLASS_SUCCESS; }