diff options
author | mrm <mrm@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-04 23:49:40 +0000 |
---|---|---|
committer | mrm <mrm@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-04 23:49:40 +0000 |
commit | 2509902cb2361f346ff9fb956939fd849e8ab0dc (patch) | |
tree | b86dfc055dce046123c7b56421f38b8ff3d2fd77 /ASNMP | |
parent | ef570e751faf30666708533b0b5678d8117fa783 (diff) | |
download | ATCD-2509902cb2361f346ff9fb956939fd849e8ab0dc.tar.gz |
added agent
Diffstat (limited to 'ASNMP')
-rw-r--r-- | ASNMP/agent/Makefile | 23 | ||||
-rw-r--r-- | ASNMP/agent/agent_impl.cpp | 154 | ||||
-rw-r--r-- | ASNMP/agent/agent_impl.h | 52 | ||||
-rw-r--r-- | ASNMP/agent/main.cpp | 26 | ||||
-rw-r--r-- | ASNMP/agent/snmp_agent.cpp | 95 | ||||
-rw-r--r-- | ASNMP/agent/snmp_agent.h | 46 |
6 files changed, 396 insertions, 0 deletions
diff --git a/ASNMP/agent/Makefile b/ASNMP/agent/Makefile new file mode 100644 index 00000000000..baea2a6d268 --- /dev/null +++ b/ASNMP/agent/Makefile @@ -0,0 +1,23 @@ +OBJS = main.o snmp_agent.o agent_impl.o +CC=CC +INCL = -I$(ACE_ROOT) -I$(ACE_ROOT)/ASNMP +DEBUG = -g +CFLAGS =$(INCL) -mt $(DEBUG) +RUNPATH = -R $(ACE_ROOT)/ace:$(ACE_ROOT)/ASNMP/asnmp +LIBS = -L $(ACE_ROOT)/ASNMP/asnmp -lasnmp -L $(ACE_ROOT)/ace -lACE -lnsl -lsocket + +agent: $(OBJS) + $(CC) -o agent -mt $(DEBUG) $(OBJS) $(LIBS) $(RUNPATH) + + +main.o: main.cpp + $(CC) -c $(CFLAGS) main.cpp + +snmp_agent.o: snmp_agent.cpp snmp_agent.h + $(CC) -c $(CFLAGS) snmp_agent.cpp + +agent_impl.o: agent_impl.cpp agent_impl.h + $(CC) -c $(CFLAGS) agent_impl.cpp + +clean: + -rm *.o agent *~ diff --git a/ASNMP/agent/agent_impl.cpp b/ASNMP/agent/agent_impl.cpp new file mode 100644 index 00000000000..4a2a04062a5 --- /dev/null +++ b/ASNMP/agent/agent_impl.cpp @@ -0,0 +1,154 @@ +/* -*-C++-*- */ +// implement a prototype SNMP Agent using ASNMP and ACE + +#include <ace/Reactor.h> +#include <ace/SOCK_Dgram.h> +#include <ace/INET_Addr.h> +#include "agent_impl.h" + + +agent_impl::agent_impl(unsigned short port, const char *rd, const char *wr) : +sagent(port) +{ + ACE_TRACE("agent_impl::agent_impl"); + tgt_.set_read_community(rd); + tgt_.set_write_community(wr); + agent_clock_.start(); +} + +agent_impl::~agent_impl() +{ + ACE_TRACE("agent_impl::~agent_impl"); +} + +// 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); +} + +// this routine makes up the brains of the agent +// it knows only the MIB II system group set of variables for a get operation +int agent_impl::get_response(Vb& vb) +{ + // these objects represent the MIB II system group per RFC 1213 + static Oid sysDescr("1.3.6.1.2.1.1.1.0"), + sysObjectID("1.3.6.1.2.1.1.2.0"), sysUpTime("1.3.6.1.2.1.1.3.0"), + sysContact("1.3.6.1.2.1.1.4.0"), sysName("1.3.6.1.2.1.1.5.0"), + sysLocation("1.3.6.1.2.1.1.6.0"), sysServices("1.3.6.1.2.1.1.7.0"); + + Oid oid; + vb.get_oid(oid); + if (oid == sysDescr) { + OctetStr desc("ASNMP Prototype Agent 1.0"); + vb.set_value(desc); + } + else if (oid == sysObjectID) { // the IANA gives assigns Enterprise Numbers + // see ftp://ftp.isi.edu/in-notes/iana/assignments/enterprise-numbers + // for the official list of enterprise numbers. Then under this tree + // assign a unique subtree to identify this agent + Oid id("1.3.6.1.4.1.2533.9.1"); + vb.set_value(id); + } + else if (oid == sysUpTime) { + ACE_Time_Value tv; + agent_clock_.elapsed_time (tv); + TimeTicks tt(tv.msec()); + vb.set_value(tt); + } + else if (oid == sysContact) { + OctetStr contact("mrm@acm.org"); + vb.set_value(contact); + } + else if (oid == sysName) { + OctetStr fqdn("foo.org"); // extract this from the gethostbyname() TODO + vb.set_value(fqdn); + } + else if (oid == sysLocation) { + OctetStr loc(""); + vb.set_value(loc); + } + else if (oid == sysServices) { + SnmpInt32 svcs(72); + vb.set_value(svcs); + } + else + return 1; // noSuchName + + return 0; +} + +int agent_impl::handle_get_next( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("agent_impl::handle_get_next -NI"); + return 0; +} + +int agent_impl::handle_set( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("agent_impl::handle_set -NI"); + return 0; +} + +// stuff used by process_requests + +// called when SIGINT +static sig_atomic_t finished = 0; + +extern "C" void +sig_handler (int) +{ + ACE_TRACE("::sig_handler"); + finished = 1; +} + +int agent_impl::process_requests() +{ + ACE_TRACE("agent_impl::process_requests"); + ACE_Reactor reactor; + + ACE_Sig_Action sa ((ACE_SignalHandler) sig_handler, SIGINT); + ACE_UNUSED_ARG (sa); + + // Read data from other side. + if (reactor.register_handler (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::register_handler"), -1); + + // TODO: register signal handler to shut down gracefully here + + while (!finished) + { + reactor.handle_events (); + ACE_DEBUG ((LM_DEBUG, "return from handle events\n")); + } + + ACE_DEBUG ((LM_DEBUG, "return from handle events - normal shut down\n")); + return 0; +} diff --git a/ASNMP/agent/agent_impl.h b/ASNMP/agent/agent_impl.h new file mode 100644 index 00000000000..ee107a88a99 --- /dev/null +++ b/ASNMP/agent/agent_impl.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ASNMP +// +// = FILENAME +// agent_impl.h +// +// = AUTHOR +// Michael R. MacFaden +// +// ============================================================================ + +#if !defined (AGENT_IMPL_H) +#define AGENT_IMPL_H + +#include <ace/Event_Handler.h> +#include <ace/SOCK_Dgram.h> +#include <ace/INET_Addr.h> +#include <ace/High_Res_Timer.h> +#include <asnmp/sagent.h> +#include <asnmp/vb.h> + +class agent_impl : public sagent +{ +public: + agent_impl(unsigned short port, const char *rd, const char *wr); + virtual ~agent_impl(); + + virtual int handle_get( Pdu &pdu, UdpTarget &target); + // retrieve data from a peer agent for a given list of oid values + + virtual int handle_get_next( Pdu &pdu, UdpTarget &target); + // retrieve data lexically adjacent to the oids specified in the pdu + // from the peer agent + + virtual int handle_set( Pdu &pdu, UdpTarget &target); + // set data in the agent from the list of oids in the pdu + + int process_requests(); + // main loop here using a reactor object + +private: + UdpTarget tgt_; // this agent's read, write community strings + int get_response(Vb& vb); // set values for a "get" cmd + ACE_High_Res_Timer agent_clock_; // agent "uptime" ticks reported in 1/100 second +}; + +#endif /* AGENT_IMPL_H */ diff --git a/ASNMP/agent/main.cpp b/ASNMP/agent/main.cpp new file mode 100644 index 00000000000..1aa15d00025 --- /dev/null +++ b/ASNMP/agent/main.cpp @@ -0,0 +1,26 @@ +/* -*-C++-*- */ +// $Id$ + +// This server daemon processes SNMP Version 1 get, get-next, and set +// commands. over the MIB II "System" group only. +// + +#include "snmp_agent.h" + +int main (int argc, char *argv[]) +{ + snmp_agent the_agent; + + if (the_agent.set_args(argc, argv)) { + return 1; + } + + if (!the_agent.valid()) { + return 1; + } + + the_agent.run(); // main loop + + return 0; +} + diff --git a/ASNMP/agent/snmp_agent.cpp b/ASNMP/agent/snmp_agent.cpp new file mode 100644 index 00000000000..81a7c2c6f70 --- /dev/null +++ b/ASNMP/agent/snmp_agent.cpp @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + +// This server daemon processes SNMPv1 requests over MIB II System group + +#include "snmp_agent.h" +#include "agent_impl.h" // actual implementation +#include "ace/Get_Opt.h" +#include "ace/Reactor.h" + +// module globals +#define SNMP_AGENT_PORT (161) +#define WR_COM ("private") +#define RD_COM ("public") + +snmp_agent::snmp_agent() : agent_(0) +{ + ACE_TRACE("snmp_agent::snmp_agent"); +} + +snmp_agent::~snmp_agent() +{ + ACE_TRACE("snmp_agent::~snmp_agent"); + delete agent_; +} + + +int snmp_agent::valid() const +{ + ACE_TRACE("snmp_agent::valid"); + return (agent_ != 0); +} + +int snmp_agent::set_args(int argc, char *argv[]) +{ + ACE_TRACE("snmp_agent::set_args"); + unsigned short port = SNMP_AGENT_PORT; + char *rd = RD_COM, *wr = WR_COM; + + ACE_Get_Opt get_opt (argc, argv, "p:w:r:hv"); + for (int c; (c = get_opt ()) != -1; ) { + switch (c) + { + case 'p': + port = (ACE_OS::atoi (get_opt.optarg)); + break; + case 'w': // write community string + wr = get_opt.optarg; + break; + case 'r': // read community string + rd = get_opt.optarg; + break; + + case 'h': // help & version info + case 'v': + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Example SNMP Version 1 Agent - ASNMP/ACE\n")); + return -1; + break; + + default: + return -1; // invalid arg + } + } + + + agent_ = new agent_impl(port, rd, wr); // opens OS IO port + return 0; +} + +int snmp_agent::run() +{ + ACE_TRACE("snmp_agent::run"); + ACE_ASSERT(agent_); + + // open service port +#if 0 + if (agent_->open_port()) { + ACE_DEBUG((LM_DEBUG, "(%P|%t) open port %d failed\n", agent_->get_port())); + return -1; + } +#endif + + // Run forever, processing SNMP requests. + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting up snmp agent (server) daemon\n")); + + agent_->process_requests(); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) shutting down snmp agent (server) daemon\n")); + return 0; +} + diff --git a/ASNMP/agent/snmp_agent.h b/ASNMP/agent/snmp_agent.h new file mode 100644 index 00000000000..a3c13ce89c1 --- /dev/null +++ b/ASNMP/agent/snmp_agent.h @@ -0,0 +1,46 @@ +/* -*-C++-*- */ + +#ifndef SNMP_AGENT_ +#define SNMP_AGENT_ +// ============================================================================ +// +// = LIBRARY +// ASNMP +// +// = FILENAME +// snmp_agent.h +// +// = AUTHOR +// Michael R. MacFaden (mrm@cisco.com) +// +// ============================================================================ + +class agent_impl; + +class snmp_agent { + // = TITLE + // An SNMP v1 agent class + // + // = DESCRIPTION + // Contructs agents that are capable of processing SNMPv1 requests + // over the MIB II System group + + public: + snmp_agent(); // uses port 161, public, private + ~snmp_agent(); + + int valid() const; + // did object construct ok + + int set_args(int argc, char *argv[]); + // runtime arguments such as community strings, port to use + + int run(); + // begin processing requests + + private: + snmp_agent(const snmp_agent&); + agent_impl *agent_; +}; + +#endif // SNMP_AGENT_ |