summaryrefslogtreecommitdiff
path: root/ASNMP
diff options
context:
space:
mode:
authormrm <mrm@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-04 23:49:40 +0000
committermrm <mrm@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-04 23:49:40 +0000
commit2509902cb2361f346ff9fb956939fd849e8ab0dc (patch)
treeb86dfc055dce046123c7b56421f38b8ff3d2fd77 /ASNMP
parentef570e751faf30666708533b0b5678d8117fa783 (diff)
downloadATCD-2509902cb2361f346ff9fb956939fd849e8ab0dc.tar.gz
added agent
Diffstat (limited to 'ASNMP')
-rw-r--r--ASNMP/agent/Makefile23
-rw-r--r--ASNMP/agent/agent_impl.cpp154
-rw-r--r--ASNMP/agent/agent_impl.h52
-rw-r--r--ASNMP/agent/main.cpp26
-rw-r--r--ASNMP/agent/snmp_agent.cpp95
-rw-r--r--ASNMP/agent/snmp_agent.h46
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_