// return a pdu from a buffer int wpdu::get_pdu(Pdu& pdu, snmp_version& version) { if (iovec_.iov_len == 0) return -1; // NO DATA snmp_pdu *raw_pdu; raw_pdu = cmu_snmp::pdu_create(0); if (!raw_pdu) { return SNMP_CLASS_RESOURCE_UNAVAIL; } // max value a client can send us - TODO: replace this with an // api to get actual string length int status = cmu_snmp::parse( raw_pdu, (unsigned char *)iovec_.iov_base, community_name, comm_len, version, iovec_.iov_len); if (status != 0) return SNMP_CLASS_INTERNAL_ERROR; community_name[comm_len] = 0; // set null based on returned length set_request_id( &pdu, raw_pdu->reqid); set_error_status( &pdu, (int) raw_pdu->errstat); set_error_index( &pdu, (int) raw_pdu->errindex); pdu.set_type( raw_pdu->command); if (restore_vbs(pdu, raw_pdu)) { cmu_snmp::free_pdu(raw_pdu); return SNMP_CLASS_INTERNAL_ERROR; } cmu_snmp::free_pdu(raw_pdu); return 0; }
int Snmp::run_transaction(Pdu& pdu, UdpTarget& target) { int rc, done = 0; // 1. set unique id to match this packet on return size_t hold_req_id = req_id_++; set_request_id(&pdu, hold_req_id); // 2. write request to agent transaction trans(pdu, target, iv_snmp_session_); // this call blocks while it attempts to retrieve agent response while (!done) { if ((rc = trans.run()) < 0) { last_transaction_status_ = rc; return rc; } else { trans.result(pdu); // verify this is the pdu we are after if (pdu.get_request_id() == hold_req_id) done = 1 ; } } return 0; }
int Snmp::run_transaction(Pdu& pdu, UdpTarget& target, Snmp_Result * cb) { if (!cb) return run_transaction(pdu, target); // 1. set unique id to match this packet on return hold_req_id_ = req_id_++; set_request_id(&pdu, hold_req_id_); pdu_ = &pdu; result_ = cb; // 2. write request to agent transaction * trans = new transaction(pdu, target, iv_snmp_session_); return trans->run(this); }