diff options
Diffstat (limited to 'ASNMP/asnmp/snmp.cpp')
-rw-r--r-- | ASNMP/asnmp/snmp.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/ASNMP/asnmp/snmp.cpp b/ASNMP/asnmp/snmp.cpp new file mode 100644 index 00000000000..083b773911b --- /dev/null +++ b/ASNMP/asnmp/snmp.cpp @@ -0,0 +1,206 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// snmp.cpp +// +// = DESCRIPTION +// The basic SNMPv1 API - blocking version using UDP/IPv4 transport +// and addressing. +// +// = AUTHOR +// Peter E Mellquist class design/orig code +// Michael R MacFaden mrm@cisco.com / rework API, use ACE facilities +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + + +#define INCLUDE_SNMP_ERR_STRINGS_ + +//----[ snmp++ includes ]---------------------------------------------- +#include "asnmp/snmp.h" // class def for this module +#include "asnmp/oid.h" // class def for oids +#include "asnmp/enttraps.h" // class def for well known trap oids +#include "asnmp/vb.h" // class def for vbs +#include "asnmp/address.h" // class def for addresses +#include "asnmp/wpdu.h" // adapter to cmu_library / wire protocol +#include "asnmp/transaction.h" // synchronous transaction processor + +const coldStartOid coldStart; +const warmStartOid warmStart; +const linkDownOid linkDown; +const linkUpOid linkUp; +const authenticationFailureOid authenticationFailure; +const egpNeighborLossOid egpNeighborLoss; +const snmpTrapEnterpriseOid snmpTrapEnterprise; + +Snmp::Snmp(): construct_status_(SNMP_CLASS_ERROR), last_transaction_status_(0) +{ + ACE_TRACE("Snmp::Snmp"); + + ACE_INET_Addr addr; // any port,address is ok + if (iv_snmp_session_.open(addr) < 0) { + last_transaction_status_ = errno; // open udp/ipv4 socket + } + + // initial request id randomly generated then monotonically incremented + req_id_ = (unsigned) ACE_OS::time(NULL); + + construct_status_ = SNMP_CLASS_SUCCESS; + return; +} + +Snmp::~Snmp() +{ + ACE_TRACE("Snmp::~Snmp"); +} + +int Snmp::valid() const +{ + return construct_status_; +} + +// given error code, return string definition +// class version +// static +char * Snmp::error_string(int last_transaction_status_) +{ + ACE_TRACE("Snmp::error_string"); + + return ((last_transaction_status_ < 0) ? + ((last_transaction_status_ < MAX_NEG_ERROR)? + nErrs[ abs(MAX_NEG_ERROR) + 1] : nErrs[abs(last_transaction_status_)]): + ((last_transaction_status_ > MAX_POS_ERROR)? + pErrs[MAX_POS_ERROR+1] : pErrs[last_transaction_status_])); +} + +// instance version +char * Snmp::error_string() +{ + return Snmp::error_string(last_transaction_status_); +} + +void Snmp::check_default_port(UdpTarget& target, unsigned short port) +{ + UdpAddress tmp; + target.get_address(tmp); + if (tmp.get_port() == 0) { + tmp.set_port(port); + target.set_address(tmp); + } +} + +int Snmp::run_transaction(Pdu& pdu, UdpTarget& target) +{ + int rc, done = 0; + + // 1. set unique id to match this packet on return + int 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::validate_args(const Pdu& pdu, const UdpTarget& target) const +{ + // 0. check object status + if (construct_status_ != SNMP_CLASS_SUCCESS) + return construct_status_; + + // 1. check args passed + if ( !pdu.valid() || !target.valid() ) + return SNMP_INVALID_ARGS; + return 0; +} + +// SYNC API: write request to wire then wait for reply or timeout +int Snmp::get( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("Snmp::get"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_GET); + check_default_port(target); + return run_transaction(pdu, target); +} + +int Snmp::get_next( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("Snmp::get_next"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_GETNEXT); + check_default_port(target); + return run_transaction(pdu, target); +} + +int Snmp::set( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("Snmp::set"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_SET); + check_default_port(target); + return run_transaction(pdu, target); +} + +// one way, best of luck, non-confirmed alert +int Snmp::trap( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("Snmp::trap"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_V1TRAP); + check_default_port(target, DEF_TRAP_PORT); + + // 2. write request to agent + transaction trans(pdu, target, iv_snmp_session_); + if (trans.send() > 0) // expect number of bytes sent on + return 0; + + last_transaction_status_ = SNMP_CLASS_INTERNAL_ERROR; + return -1; +} + + |