// callback : have received a Pdu from the target host with given read comm str // this is really simplistic, but gives the general idea int agent_impl::handle_get( Pdu &pdu, UdpTarget &target) { ACE_TRACE("agent_impl::handle_get"); OctetStr mgr_rd_str, agent_rd_str; target.get_read_community(mgr_rd_str); // requster's read community string tgt_.get_read_community(agent_rd_str); // this agent's read community string // 1. verify we have a valid read string else drop pdu (no response to caller) if (mgr_rd_str != agent_rd_str) { ACE_DEBUG((LM_DEBUG, "agent_impl::handle_get: invalid read community recvd\n")); return 0; } // 2. iterate over each varbind in the pdu, filling providing responses int fdone = 0; for (int i = 0; (i < pdu.get_vb_count()) && !fdone; i++) { Vb vb; pdu.get_vb(vb, i); if (get_response(vb)) { // set a value for the oid if we can else set_error_status(&pdu, SNMP_ERROR_NO_SUCH_NAME); // these ought to be member set_error_index(&pdu, i); // functions but are not yet... fdone++; // trigger flag to exit loop early } else // failed, return noSuch error pdu.set_vb(vb, i); } // 3. lastly, return the pkt to the caller return respond(pdu, target); }
wpdu::wpdu(const Pdu& pdu, const UdpTarget& target): valid_flag_(SNMP_CLASS_INVALID ), comm_len(MAX_COMM_STR_LEN) { reset_iov(iovec_); version_ = target.get_version(); int status; OctetStr comm_str; community_name[0] = 0; snmp_pdu *raw_pdu; // create a raw pdu raw_pdu = cmu_snmp::pdu_create( (int) pdu.get_type()); if (!raw_pdu) { valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; return; } raw_pdu->reqid = pdu.get_request_id(); raw_pdu->errstat= (unsigned long) pdu.get_error_status(); raw_pdu->errindex= (unsigned long) pdu.get_error_index(); switch (raw_pdu->command) { case sNMP_PDU_GET: case sNMP_PDU_GETNEXT: target.get_read_community(comm_str); break; case sNMP_PDU_SET: target.get_write_community(comm_str); break; case sNMP_PDU_V1TRAP: target.get_read_community(comm_str); if (set_trap_info(raw_pdu, pdu)) // will free raw_pdu return; break; case sNMP_PDU_RESPONSE: break; default: ACE_ASSERT(0); return; } if (load_vbs(raw_pdu, pdu)) { cmu_snmp::free_pdu( raw_pdu); valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; return; } // TODO: determine how big raw_pdu serializes out to iovec_.iov_len = target.get_max_pdu_size(); ACE_NEW(iovec_.iov_base, char [iovec_.iov_len]); // create raw byte stream // The intermediate integer is to avoid type-punned pointer // dereferencing. int out_length = iovec_.iov_len; status = cmu_snmp::build( raw_pdu, (unsigned char *)iovec_.iov_base, &out_length, target.get_version(), comm_str.data(), comm_str.length()); iovec_.iov_len = out_length; if ( status != 0) { valid_flag_ = SNMP_ERROR_WRONG_ENCODING; cmu_snmp::free_pdu( raw_pdu); return; } cmu_snmp::free_pdu( raw_pdu); valid_flag_ = SNMP_CLASS_SUCCESS; }